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 2007/09/25 02:06:34 UTC
svn commit: r579020 [1/2] - in /tapestry/tapestry5/trunk:
tapestry-core/src/main/java/org/apache/tapestry/internal/services/
tapestry-core/src/main/java/org/apache/tapestry/services/
tapestry-core/src/main/java/org/apache/tapestry/test/ tapestry-core/s...
Author: hlship
Date: Mon Sep 24 17:06:31 2007
New Revision: 579020
URL: http://svn.apache.org/viewvc?rev=579020&view=rev
Log:
TAPESTRY-1731: @Inject @Symbol does not work inside a component
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java
- copied, changed from r578523, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java
- copied, changed from r578523, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java
- copied, changed from r578523, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectResourcesWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java
- copied, changed from r578523, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java
- copied, changed from r578523, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java
- copied, changed from r578523, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectResourcesWorkerTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/services/
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/services/MasterObjectProvider.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImplTest.java
Removed:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectResourcesWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectResourcesWorkerTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FindFieldClass.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.html
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -40,7 +40,7 @@
_assetSource = assetSource;
}
- public boolean provideInjection(String fieldName, String fieldType, ObjectLocator locator,
+ public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
ClassTransformation transformation, MutableComponentModel componentModel)
{
Path path = transformation.getFieldAnnotation(fieldName, Path.class);
@@ -58,7 +58,7 @@
String statement = format(
"%s = (%s) %s.findAsset(%s.getBaseResource(), \"%s\", %s.getLocale());",
fieldName,
- fieldType,
+ fieldType.getName(),
sourceFieldName,
resourcesFieldName,
expanded,
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java (from r578523, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java&r1=578523&r2=579020&rev=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectBlockWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -14,70 +14,49 @@
package org.apache.tapestry.internal.services;
-import java.util.List;
-
import org.apache.tapestry.Block;
import org.apache.tapestry.annotations.Id;
import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.ioc.ObjectLocator;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
-import org.apache.tapestry.ioc.util.BodyBuilder;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.services.ClassTransformation;
-import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.InjectionProvider;
import org.apache.tapestry.services.TransformConstants;
/**
* Identifies fields of type {@link Block} that have the {@link Inject} annotation and converts them
* into read-only fields containing the injected Block from the template. The annotation's value is
- * the id of the block to inject; if ommitted, the block id is deduced from the field id.
+ * the id of the block to inject; if omitted, the block id is deduced from the field id.
* <p>
- * Must be scheduled before {@link InjectWorker} because it uses the same annotation, Inject, with a
- * different interpretation.
+ * Must be scheduled before {@link DefaultInjectionProvider} because it uses the same annotation,
+ * Inject, with a different interpretation.
*/
-public class InjectBlockWorker implements ComponentClassTransformWorker
+public class BlockInjectionProvider implements InjectionProvider
{
- static final String BLOCK_TYPE_NAME = Block.class.getName();
- public void transform(ClassTransformation transformation, MutableComponentModel model)
+ public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+ ClassTransformation transformation, MutableComponentModel componentModel)
{
- List<String> fieldNames = transformation.findFieldsOfType(BLOCK_TYPE_NAME);
-
- if (fieldNames.isEmpty()) return;
-
- BodyBuilder builder = new BodyBuilder();
- builder.begin();
-
- int count = 0;
+ if (!fieldType.equals(Block.class)) return false;
String resourcesFieldName = transformation.getResourcesFieldName();
- for (String fieldName : fieldNames)
- {
- Inject injectAnnotation = transformation.getFieldAnnotation(fieldName, Inject.class);
-
- if (injectAnnotation == null) continue;
-
- Id annotation = transformation.getFieldAnnotation(fieldName, Id.class);
-
- String blockId = getBlockId(fieldName, annotation);
-
- builder.addln("%s = %s.getBlock(\"%s\");", fieldName, resourcesFieldName, blockId);
-
- transformation.makeReadOnly(fieldName);
-
- transformation.claimField(fieldName, injectAnnotation);
+ Id annotation = transformation.getFieldAnnotation(fieldName, Id.class);
- count++;
- }
+ String blockId = getBlockId(fieldName, annotation);
- // Fields yes, but no annotations, so nothing to really do.
+ transformation.makeReadOnly(fieldName);
- if (count == 0) return;
+ String body = String.format(
+ "%s = %s.getBlock(\"%s\");",
+ fieldName,
+ resourcesFieldName,
+ blockId);
- builder.end();
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);
- transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
- .toString());
+ return true; // claim the field
}
private String getBlockId(String fieldName, Id annotation)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -31,7 +31,7 @@
*/
public class CommonResourcesInjectionProvider implements InjectionProvider
{
- private static final Map<String, String> _configuration = newMap();
+ private static final Map<Class, String> _configuration = newMap();
public CommonResourcesInjectionProvider()
{
@@ -43,16 +43,15 @@
private void add(Class fieldType, String methodName)
{
- _configuration.put(fieldType.getName(), methodName);
+ _configuration.put(fieldType, methodName);
}
- public boolean provideInjection(String fieldName, String fieldType, ObjectLocator locator,
+ public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
ClassTransformation transformation, MutableComponentModel componentModel)
{
String implementationMethodName = _configuration.get(fieldType);
- if (implementationMethodName == null)
- return false;
+ if (implementationMethodName == null) return false;
String resourcesField = transformation.getResourcesFieldName();
@@ -68,5 +67,4 @@
return true;
}
-
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -27,12 +27,10 @@
*/
public class ComponentResourcesInjectionProvider implements InjectionProvider
{
- private static final String COMPONENT_RESOURCES_CLASS_NAME = ComponentResources.class.getName();
-
- public boolean provideInjection(String fieldName, String fieldType, ObjectLocator locator,
+ public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
ClassTransformation transformation, MutableComponentModel componentModel)
{
- if (fieldType.equals(COMPONENT_RESOURCES_CLASS_NAME))
+ if (fieldType.equals(ComponentResources.class))
{
String body = format("%s = %s;", fieldName, transformation.getResourcesFieldName());
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectWorker.java?rev=579020&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectWorker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectWorker.java Mon Sep 24 17:06:31 2007
@@ -0,0 +1,70 @@
+// 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.services;
+
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Worker triggered by {@link Inject} annotation after all other injection related works have had a
+ * chance. This implementation is just a wrapper around {@link ObjectLocator#getService(Class)}.
+ */
+public class DefaultInjectWorker implements ComponentClassTransformWorker
+{
+ private final ObjectLocator _locator;
+
+ public DefaultInjectWorker(ObjectLocator locator)
+ {
+ _locator = locator;
+ }
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ for (String fieldName : transformation.findFieldsWithAnnotation(Inject.class))
+ {
+ Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
+
+ inject(fieldName, transformation, model);
+
+ transformation.claimField(fieldName, annotation);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void inject(String fieldName, ClassTransformation transformation,
+ MutableComponentModel model)
+ {
+ String fieldType = transformation.getFieldType(fieldName);
+
+ Class type = transformation.toClass(fieldType);
+
+ try
+ {
+ Object inject = _locator.getService(type);
+
+ transformation.injectField(fieldName, inject);
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(ServicesMessages.fieldInjectionError(transformation
+ .getClassName(), fieldName, ex), ex);
+ }
+
+ }
+
+}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java (from r578523, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java&r1=578523&r2=579020&rev=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -16,55 +16,37 @@
import java.lang.annotation.Annotation;
-import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.ioc.AnnotationProvider;
-import org.apache.tapestry.ioc.ObjectProvider;
import org.apache.tapestry.ioc.ObjectLocator;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.services.ClassTransformation;
-import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.InjectionProvider;
+import org.apache.tapestry.services.MasterObjectProvider;
/**
* Worker for the {@link org.apache.tapestry.annotations.Inject} annotation that delegates out to
- * the master {@link ObjectProvider} to access the value. This worker must be scheduled after
+ * the master {@link MasterObjectProvier} to access the value. This worker must be scheduled after
* certain other workers, such as {@link InjectBlockWorker} (which is keyed off a combination of
* type and the Inject annotation).
*
- * @see ObjectProvider
+ * @see MasterObjectProvier
*/
-public class InjectWorker implements ComponentClassTransformWorker
+public class DefaultInjectionProvider implements InjectionProvider
{
- private final ObjectProvider _objectProvider;
+ private final MasterObjectProvider _masterObjectProvider;
private final ObjectLocator _locator;
- public InjectWorker(ObjectProvider objectProvider, ObjectLocator locator)
+ public DefaultInjectionProvider(MasterObjectProvider masterObjectProvider, ObjectLocator locator)
{
- _objectProvider = objectProvider;
+ _masterObjectProvider = masterObjectProvider;
_locator = locator;
}
- public void transform(ClassTransformation transformation, MutableComponentModel model)
- {
- for (String fieldName : transformation.findFieldsWithAnnotation(Inject.class))
- {
- Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
-
- inject(fieldName, transformation, model);
-
- transformation.claimField(fieldName, annotation);
- }
-
- }
-
@SuppressWarnings("unchecked")
- private void inject(final String fieldName, final ClassTransformation transformation,
- MutableComponentModel model)
+ public boolean provideInjection(final String fieldName, Class fieldType, ObjectLocator locator,
+ final ClassTransformation transformation, MutableComponentModel componentModel)
{
- String fieldType = transformation.getFieldType(fieldName);
-
- Class type = transformation.toClass(fieldType);
-
AnnotationProvider annotationProvider = new AnnotationProvider()
{
public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
@@ -73,19 +55,22 @@
}
};
- Object inject = null;
+ Object inject = _masterObjectProvider.provide(
+ fieldType,
+ annotationProvider,
+ _locator,
+ false);
+
+ // Null means that no ObjectProvider could provide the value. We have set up the chain of
+ // command so that InjectResources can give it a try next. Later, we'll try to match against
+ // a service.
- try
+ if (inject != null)
{
- inject = _objectProvider.provide(type, annotationProvider, _locator);
- }
- catch (Exception ex)
- {
- throw new RuntimeException(ServicesMessages.fieldInjectionError(transformation
- .getClassName(), fieldName, ex), ex);
+ transformation.injectField(fieldName, inject);
+ return true;
}
- transformation.injectField(fieldName, inject);
+ return false;
}
-
}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java (from r578523, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectResourcesWorker.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectResourcesWorker.java&r1=578523&r2=579020&rev=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectResourcesWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java Mon Sep 24 17:06:31 2007
@@ -22,14 +22,12 @@
import org.apache.tapestry.services.InjectionProvider;
/**
- * Performs injection of resources, for the cases where a field is labled with the {@link Inject}
- * annotation, but no specific value was provided. This worker must be scheduled <em>before</em>
- * {@link InjectWorker}.
+ * Performs injection triggered by any field annotated with the {@link Inject} annotation.
* <p>
* The implementation of this worker mostly delegates to a chain of command of
* {@link InjectionProvider}s.
*/
-public class InjectResourcesWorker implements ComponentClassTransformWorker
+public class InjectWorker implements ComponentClassTransformWorker
{
private final ObjectLocator _locator;
@@ -37,33 +35,40 @@
private final InjectionProvider _injectionProvider;
- public InjectResourcesWorker(final ObjectLocator locator,
+ public InjectWorker(final ObjectLocator locator,
final InjectionProvider injectionProvider)
{
_locator = locator;
_injectionProvider = injectionProvider;
}
- public void transform(ClassTransformation transformation, MutableComponentModel model)
+ public final void transform(ClassTransformation transformation, MutableComponentModel model)
{
for (String fieldName : transformation.findFieldsWithAnnotation(Inject.class))
{
Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
- String fieldType = transformation.getFieldType(fieldName);
+ try
+ {
+ String fieldType = transformation.getFieldType(fieldName);
+
+ Class type = transformation.toClass(fieldType);
+
+ boolean success = _injectionProvider.provideInjection(
+ fieldName,
+ type,
+ _locator,
+ transformation,
+ model);
+
+ if (success) transformation.claimField(fieldName, annotation);
+ }
+ catch (RuntimeException ex)
+ {
+ throw new RuntimeException(ServicesMessages.fieldInjectionError(transformation
+ .getClassName(), fieldName, ex), ex);
+ }
- boolean result = _injectionProvider.provideInjection(
- fieldName,
- fieldType,
- _locator,
- transformation,
- model);
-
- // If true, claim the field; otherwise ignore it (it will be handled by a later
- // worker and an exception will be thrown if it ultimately can't be satisfied.
-
- if (result) transformation.claimField(fieldName, annotation);
}
}
-
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java Mon Sep 24 17:06:31 2007
@@ -151,8 +151,9 @@
"resources",
null);
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC | Modifier.FINAL,
- ComponentResources.class.getName(), "getComponentResources", null, null);
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC
+ | Modifier.FINAL, ComponentResources.class.getName(), "getComponentResources",
+ null, null);
addMethod(sig, "return " + _resourcesFieldName + ";");
}
@@ -816,19 +817,6 @@
return result;
}
- public List<String> findFieldsOfType(final String type)
- {
- FieldFilter filter = new FieldFilter()
- {
- public boolean accept(String fieldName, String fieldType)
- {
- return type.equals(fieldType);
- }
- };
-
- return findFields(filter);
- }
-
public List<TransformMethodSignature> findMethodsWithAnnotation(
Class<? extends Annotation> annotationClass)
{
@@ -881,8 +869,8 @@
String[] parameters = toTypeNames(method.getParameterTypes());
String[] exceptions = toTypeNames(method.getExceptionTypes());
- result = new TransformMethodSignature(method.getModifiers(), type, method.getName(),
- parameters, exceptions);
+ result = new TransformMethodSignature(method.getModifiers(), type,
+ method.getName(), parameters, exceptions);
_methodSignatures.put(method, result);
}
@@ -1331,8 +1319,8 @@
String fieldType = getFieldType(fieldName);
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, "void", methodName,
- new String[]
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, "void",
+ methodName, new String[]
{ fieldType }, null);
String message = ServicesMessages.readOnlyField(_ctClass.getName(), fieldName);
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java?rev=579020&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -0,0 +1,52 @@
+// 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.services;
+
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+
+/**
+ * A very late worker related to the {@link Inject} annotation that, when all other forms of
+ * injection have failed, matches the field type to a service interface.
+ */
+public class ServiceInjectionProvider implements InjectionProvider
+{
+ private final ObjectLocator _locator;
+
+ public ServiceInjectionProvider(ObjectLocator locator)
+ {
+ _locator = locator;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+ ClassTransformation transformation, MutableComponentModel componentModel)
+ {
+ Object inject = _locator.getService(fieldType);
+
+ assert inject != null;
+
+ transformation.injectField(fieldName, inject);
+
+ // If we make it this far without an exception, then we were successful
+ // and should claim the field.
+
+ return true;
+ }
+
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java Mon Sep 24 17:06:31 2007
@@ -76,12 +76,6 @@
*/
List<String> findFieldsWithAnnotation(Class<? extends Annotation> annotationClass);
- /**
- * Generates a list of the names of declared instance fields that exactly match the specified
- * type. Only the names of private instance fields are returned. Any
- * {@link #claimField(String, Object) claimed} fields are excluded.
- */
- List<String> findFieldsOfType(String type);
/**
* Finds all methods defined in the class that are marked with the provided annotation.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java Mon Sep 24 17:06:31 2007
@@ -12,41 +12,39 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.services;
-
-import org.apache.tapestry.ioc.ObjectLocator;
-import org.apache.tapestry.model.MutableComponentModel;
-
-/**
- * Provides some form of injection when the value for an
- * {@link org.apache.tapestry.annotations.Inject} annotation is blank. In this case, the provider is
- * responsible for determining the value to be injected from the field name and field type.
- * <p>
- * This interface will be used as part of a
- * {@link org.apache.tapestry.ioc.services.ChainBuilder chain of command}.
- *
- *
- */
-public interface InjectionProvider
-{
- /**
- * Peform the injection, if possible. Most often, this will result in a call to
- * {@link ClassTransformation#injectField(String, Object)}. The caller is responsible for
- * invoking {@link ClassTransformation#claimField(String, Object)}.
- *
- * @param fieldName
- * the name of the field requesting injection
- * @param fieldType
- * the type of the field (as a string)
- * @param locator
- * allows services to be located
- * @param transformation
- * allows the code for the class to be transformed
- * @param componentModel
- * defines the relevant aspects of the component
- * @return true if an injection has been made (terminates the command chain), false to continue
- * down the chain
- */
- boolean provideInjection(String fieldName, String fieldType, ObjectLocator locator,
- ClassTransformation transformation, MutableComponentModel componentModel);
-}
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.model.MutableComponentModel;
+
+/**
+ * Provides some form of injection when the value for an
+ * {@link org.apache.tapestry.annotations.Inject} annotation is present. In this case, the provider
+ * is responsible for determining the value to be injected from the field name and field type.
+ * <p>
+ * This interface will be used as part of a
+ * {@link org.apache.tapestry.ioc.services.ChainBuilder chain of command}.
+ */
+public interface InjectionProvider
+{
+ /**
+ * Peform the injection, if possible. Most often, this will result in a call to
+ * {@link ClassTransformation#injectField(String, Object)}. The caller is responsible for
+ * invoking {@link ClassTransformation#claimField(String, Object)}.
+ *
+ * @param fieldName
+ * the name of the field requesting injection
+ * @param fieldType
+ * the type of the field
+ * @param locator
+ * allows services to be located
+ * @param transformation
+ * allows the code for the class to be transformed
+ * @param componentModel
+ * defines the relevant aspects of the component
+ * @return true if an injection has been made (terminates the command chain), false to continue
+ * down the chain
+ */
+ boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+ ClassTransformation transformation, MutableComponentModel componentModel);
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Mon Sep 24 17:06:31 2007
@@ -80,6 +80,7 @@
import org.apache.tapestry.internal.services.BeanBlockSourceImpl;
import org.apache.tapestry.internal.services.BeanModelSourceImpl;
import org.apache.tapestry.internal.services.BindingSourceImpl;
+import org.apache.tapestry.internal.services.BlockInjectionProvider;
import org.apache.tapestry.internal.services.ClassResultProcessor;
import org.apache.tapestry.internal.services.ClasspathAssetAliasManagerImpl;
import org.apache.tapestry.internal.services.CommonResourcesInjectionProvider;
@@ -97,6 +98,7 @@
import org.apache.tapestry.internal.services.ContextImpl;
import org.apache.tapestry.internal.services.CookiesImpl;
import org.apache.tapestry.internal.services.DefaultDataTypeAnalyzer;
+import org.apache.tapestry.internal.services.DefaultInjectionProvider;
import org.apache.tapestry.internal.services.DefaultValidationDelegateCommand;
import org.apache.tapestry.internal.services.DocumentScriptBuilder;
import org.apache.tapestry.internal.services.DocumentScriptBuilderImpl;
@@ -109,12 +111,11 @@
import org.apache.tapestry.internal.services.FlashPersistentFieldStrategy;
import org.apache.tapestry.internal.services.GenericValueEncoderFactory;
import org.apache.tapestry.internal.services.HeartbeatImpl;
-import org.apache.tapestry.internal.services.InjectBlockWorker;
import org.apache.tapestry.internal.services.InjectComponentWorker;
import org.apache.tapestry.internal.services.InjectPageWorker;
-import org.apache.tapestry.internal.services.InjectResourcesWorker;
-import org.apache.tapestry.internal.services.InjectStandardStylesheetCommand;
import org.apache.tapestry.internal.services.InjectWorker;
+import org.apache.tapestry.internal.services.ServiceInjectionProvider;
+import org.apache.tapestry.internal.services.InjectStandardStylesheetCommand;
import org.apache.tapestry.internal.services.InternalModule;
import org.apache.tapestry.internal.services.LinkActionResponseGenerator;
import org.apache.tapestry.internal.services.LinkFactory;
@@ -386,9 +387,6 @@
ObjectLocator locator,
- @InjectService("MasterObjectProvider")
- ObjectProvider objectProvider,
-
InjectionProvider injectionProvider,
Environment environment,
@@ -403,6 +401,8 @@
BindingSource bindingsource,
+ MasterObjectProvider masterObjectProvider,
+
ApplicationStateManager applicationStateManager)
{
// TODO: Proper scheduling of all of this. Since a given field or method should
@@ -411,17 +411,8 @@
configuration.add("Meta", new MetaWorker());
configuration.add("ApplicationState", new ApplicationStateWorker(applicationStateManager));
- configuration.add("Inject", new InjectWorker(objectProvider, locator));
- // These next two "reinterpret" what @Inject does (in the presence of
- // a particular field type and must come before the normal Inject annotation
- // processing.
-
- configuration.add(
- "InjectResources",
- new InjectResourcesWorker(locator, injectionProvider),
- "before:Inject");
- configuration.add("InjectBlock", new InjectBlockWorker(), "before:Inject");
+ configuration.add("Inject", new InjectWorker(locator, injectionProvider));
configuration.add("MixinAfter", new MixinAfterWorker());
configuration.add("Component", new ComponentWorker(resolver));
@@ -470,8 +461,7 @@
add(configuration, TransformConstants.CLEANUP_RENDER_SIGNATURE, CleanupRender.class, true);
// Ideally, these should be ordered pretty late in the process to make sure there are no
- // side effects
- // with other workers that do work inside the page lifecycle methods.
+ // side effects with other workers that do work inside the page lifecycle methods.
add(
configuration,
@@ -491,6 +481,10 @@
configuration.add("Retain", new RetainWorker());
configuration.add("Persist", new PersistWorker());
+
+ // This one is always last. Any additional private fields that aren't annotated will
+ // be converted to clear out at the end of the request.
+
configuration.add("UnclaimedField", new UnclaimedFieldWorker(), "after:*");
}
@@ -526,8 +520,7 @@
configuration.add(String.class, "text");
// This may change; as currently implemented, "text" refers more to the edit component
- // (TextField) than to
- // the "flavor" of data.
+ // (TextField) than to the "flavor" of data.
configuration.add(Number.class, "text");
configuration.add(Enum.class, "enum");
@@ -579,24 +572,51 @@
}
/**
- * Contributes the elemental providers:
+ * Contributes the base set of injection providers:
* <ul>
+ * <li>Default -- based on {@link MasterObjectProvider}</li>
+ * <li>Block -- injects fields of type Block</li>
* <li>ComponentResources -- give component access to its resources</li>
* <li>CommonResources -- access to properties of resources (log, messages, etc.)</li>
* <li>Asset -- injection of assets (triggered via {@link Path} annotation), with the path
* relative to the component class</li>
+ * <li>Service -- ordered last, for use when Inject is present and nothing else works, matches
+ * field type against Tapestry IoC service</li>
* </ul>
*/
public static void contributeInjectionProvider(
OrderedConfiguration<InjectionProvider> configuration,
+ MasterObjectProvider masterObjectProvider,
+
+ ObjectLocator locator,
+
SymbolSource symbolSource,
AssetSource assetSource)
{
+ configuration.add("Default", new DefaultInjectionProvider(masterObjectProvider, locator));
+
configuration.add("ComponentResources", new ComponentResourcesInjectionProvider());
- configuration.add("CommonResources", new CommonResourcesInjectionProvider());
- configuration.add("Asset", new AssetInjectionProvider(symbolSource, assetSource));
+
+ // This comes after default, to deal with conflicts between injecting a String as the
+ // component id, and injecting a string with @Symbol or @Value.
+
+ configuration.add(
+ "CommonResources",
+ new CommonResourcesInjectionProvider(),
+ "after:Default");
+
+ configuration.add(
+ "Asset",
+ new AssetInjectionProvider(symbolSource, assetSource),
+ "before:Default");
+
+ configuration.add("Block", new BlockInjectionProvider(), "before:Default");
+
+ // This needs to be the last one, since it matches against services
+ // and might blow up if there is no match.
+ configuration.add("Service", new ServiceInjectionProvider(locator), "after:*");
}
/**
@@ -828,8 +848,8 @@
}
private static void add(OrderedConfiguration<ComponentClassTransformWorker> configuration,
- Class<? extends Annotation> annotationClass, TransformMethodSignature lifecycleMethodSignature,
- String methodAlias)
+ Class<? extends Annotation> annotationClass,
+ TransformMethodSignature lifecycleMethodSignature, String methodAlias)
{
ComponentClassTransformWorker worker = new PageLifecycleAnnotationWorker(annotationClass,
lifecycleMethodSignature, methodAlias);
@@ -840,7 +860,8 @@
}
private static void add(OrderedConfiguration<ComponentClassTransformWorker> configuration,
- TransformMethodSignature signature, Class<? extends Annotation> annotationClass, boolean reverse)
+ TransformMethodSignature signature, Class<? extends Annotation> annotationClass,
+ boolean reverse)
{
// make the name match the annotation class name.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Mon Sep 24 17:06:31 2007
@@ -86,12 +86,12 @@
import org.apache.tapestry.services.Heartbeat;
import org.apache.tapestry.services.InjectionProvider;
import org.apache.tapestry.services.MethodFilter;
-import org.apache.tapestry.services.TransformMethodSignature;
import org.apache.tapestry.services.Request;
import org.apache.tapestry.services.RequestHandler;
import org.apache.tapestry.services.ResourceDigestGenerator;
import org.apache.tapestry.services.Response;
import org.apache.tapestry.services.Session;
+import org.apache.tapestry.services.TransformMethodSignature;
import org.apache.tapestry.services.ValidationConstraintGenerator;
import org.apache.tapestry.services.ValidationMessagesSource;
import org.easymock.EasyMock;
@@ -454,12 +454,6 @@
expect(source.findAsset(root, path, locale)).andReturn(asset);
}
- protected final void train_findFieldsOfType(ClassTransformation transformation, String type,
- String... fieldNames)
- {
- expect(transformation.findFieldsOfType(type)).andReturn(Arrays.asList(fieldNames));
- }
-
protected final void train_findFieldsWithAnnotation(ClassTransformation transformation,
Class<? extends Annotation> annotationClass, List<String> fieldNames)
{
@@ -854,7 +848,7 @@
}
protected final void train_provideInjection(InjectionProvider provider, String fieldName,
- String fieldType, ObjectLocator locator, ClassTransformation transformation,
+ Class fieldType, ObjectLocator locator, ClassTransformation transformation,
MutableComponentModel model, boolean result)
{
expect(provider.provideInjection(fieldName, fieldType, locator, transformation, model))
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java Mon Sep 24 17:06:31 2007
@@ -18,16 +18,21 @@
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.annotations.InjectPage;
import org.apache.tapestry.annotations.OnEvent;
+import org.apache.tapestry.ioc.annotations.Symbol;
import org.apache.tapestry.services.BindingSource;
import org.apache.tapestry.services.Request;
public class InjectDemo
{
// Named --- now demonstrating case insensitivity
- // Now vestigal!
+ // Now vestigial!
@Inject
private Request _request;
+ @Inject
+ @Symbol("app.injected-symbol")
+ private String _injectedSymbol;
+
// Via ComponentResourcesInjectionProvider
@Inject
private ComponentResources _resources;
@@ -75,5 +80,10 @@
String clickWilma()
{
return "Wilma";
+ }
+
+ public String getInjectedSymbol()
+ {
+ return _injectedSymbol;
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java Mon Sep 24 17:06:31 2007
@@ -84,6 +84,7 @@
MappedConfiguration<String, String> configuration)
{
configuration.add("tapestry.supported-locales", "en,fr");
+ configuration.add("app.injected-symbol", "Symbol contributed to ApplicationDefaults");
}
public ToDoDatabase buildToDoDatabase()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java Mon Sep 24 17:06:31 2007
@@ -36,7 +36,6 @@
MutableComponentModel model = mockMutableComponentModel();
String fieldName = "myField";
- String fieldType = "java.lang.String";
train_getFieldAnnotation(ct, fieldName, Path.class, null);
@@ -44,7 +43,7 @@
InjectionProvider provider = new AssetInjectionProvider(symbolSource, assetSource);
- assertFalse(provider.provideInjection(fieldName, fieldType, locator, ct, model));
+ assertFalse(provider.provideInjection(fieldName, String.class, locator, ct, model));
verify();
}
@@ -60,7 +59,7 @@
Path annotation = mockPath();
String fieldName = "myField";
- String fieldType = "java.lang.Object";
+ Class fieldType = Object.class;
String value = "${foo}";
String expanded = "foo.gif";
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java (from r578523, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java&r1=578523&r2=579020&rev=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectBlockWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java Mon Sep 24 17:06:31 2007
@@ -14,49 +14,30 @@
package org.apache.tapestry.internal.services;
+import org.apache.tapestry.Block;
import org.apache.tapestry.annotations.Id;
-import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.ioc.ObjectLocator;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
import org.apache.tapestry.services.TransformConstants;
import org.apache.tapestry.test.TapestryTestCase;
import org.testng.annotations.Test;
-/**
- * Tests a couple of edge cases where there's nothing to inject.
- */
-public class InjectBlockWorkerTest extends TapestryTestCase
+public class BlockInjectionProviderTest extends TapestryTestCase
{
@Test
- public void no_fields_of_type_block()
+ public void not_type_block()
{
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
-
- train_findFieldsOfType(ct, InjectBlockWorker.BLOCK_TYPE_NAME);
+ ObjectLocator locator = mockObjectLocator();
replay();
- new InjectBlockWorker().transform(ct, model);
-
- verify();
- }
-
- @Test
- public void field_missing_annotation()
- {
- ClassTransformation ct = mockClassTransformation();
- MutableComponentModel model = mockMutableComponentModel();
-
- train_findFieldsOfType(ct, InjectBlockWorker.BLOCK_TYPE_NAME, "fred");
+ InjectionProvider provider = new BlockInjectionProvider();
- train_getResourcesFieldName(ct, "rez");
-
- train_getFieldAnnotation(ct, "fred", Inject.class, null);
-
- replay();
-
- new InjectBlockWorker().transform(ct, model);
+ assertFalse(provider.provideInjection("myfield", Object.class, locator, ct, model));
verify();
}
@@ -71,51 +52,68 @@
* generated code is valid and works.
*/
@Test
- public void fields_with_annotations()
+ public void explicit_block_id_provided_as_annotation()
{
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
- Inject fredAnnotation = mockInject();
- Inject barneyAnnotation = mockInject();
+ ObjectLocator locator = mockObjectLocator();
Id barneyId = newId();
String barneyFieldName = "_barneyBlock";
- String fredFieldName = "fred";
- train_findFieldsOfType(
+ train_getResourcesFieldName(ct, "rez");
+
+ train_getFieldAnnotation(ct, barneyFieldName, Id.class, barneyId);
+
+ train_value(barneyId, "barney");
+
+ ct.makeReadOnly(barneyFieldName);
+
+ train_extendMethod(
ct,
- InjectBlockWorker.BLOCK_TYPE_NAME,
- fredFieldName,
- barneyFieldName);
+ TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+ "_barneyBlock = rez.getBlock(\"barney\");");
- train_getResourcesFieldName(ct, "rez");
+ replay();
- train_getFieldAnnotation(ct, fredFieldName, Inject.class, fredAnnotation);
+ assertTrue(new BlockInjectionProvider().provideInjection(
+ barneyFieldName,
+ Block.class,
+ locator,
+ ct,
+ model));
- train_getFieldAnnotation(ct, fredFieldName, Id.class, null);
+ verify();
+ }
- ct.makeReadOnly(fredFieldName);
- ct.claimField(fredFieldName, fredAnnotation);
+ @Test
+ public void default_id_for_block_from_field_name()
+ {
+ ClassTransformation ct = mockClassTransformation();
+ MutableComponentModel model = mockMutableComponentModel();
+ ObjectLocator locator = mockObjectLocator();
- train_getFieldAnnotation(ct, barneyFieldName, Inject.class, barneyAnnotation);
- train_getFieldAnnotation(ct, barneyFieldName, Id.class, barneyId);
+ String barneyFieldName = "_barney";
- train_value(barneyId, "barney");
+ train_getResourcesFieldName(ct, "rez");
+
+ train_getFieldAnnotation(ct, barneyFieldName, Id.class, null);
ct.makeReadOnly(barneyFieldName);
- ct.claimField(barneyFieldName, barneyAnnotation);
train_extendMethod(
ct,
TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
- "{",
- "fred = rez.getBlock(\"fred\");",
- "_barneyBlock = rez.getBlock(\"barney\");",
- "}");
+ "_barney = rez.getBlock(\"barney\");");
replay();
- new InjectBlockWorker().transform(ct, model);
+ assertTrue(new BlockInjectionProvider().provideInjection(
+ barneyFieldName,
+ Block.class,
+ locator,
+ ct,
+ model));
verify();
}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java (from r578523, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java&r1=578523&r2=579020&rev=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java Mon Sep 24 17:06:31 2007
@@ -17,88 +17,64 @@
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.isA;
-import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.ioc.AnnotationProvider;
-import org.apache.tapestry.ioc.ObjectProvider;
import org.apache.tapestry.ioc.ObjectLocator;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.MasterObjectProvider;
import org.apache.tapestry.services.Request;
import org.testng.annotations.Test;
-public class InjectWorkerTest extends InternalBaseTestCase
+public class DefaultInjectionProviderTest extends InternalBaseTestCase
{
- private static final String WEBREQUEST_CLASS_NAME = Request.class.getName();
-
@Test
- public void annotation_has_value()
+ public void object_found()
{
- ObjectProvider provider = mockObjectProvider();
+ MasterObjectProvider master = mockMasterObjectProvider();
ObjectLocator locator = mockObjectLocator();
- Inject annotation = newMock(Inject.class);
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
Request injected = mockRequest();
- train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
- train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
-
- train_getFieldType(ct, "myfield", WEBREQUEST_CLASS_NAME);
- train_toClass(ct, WEBREQUEST_CLASS_NAME, Request.class);
-
- expect(provider.provide(eq(Request.class), isA(AnnotationProvider.class), eq(locator)))
- .andReturn(injected);
+ expect(
+ master.provide(
+ eq(Request.class),
+ isA(AnnotationProvider.class),
+ eq(locator),
+ eq(false))).andReturn(injected);
ct.injectField("myfield", injected);
- ct.claimField("myfield", annotation);
-
replay();
- InjectWorker worker = new InjectWorker(provider, locator);
+ DefaultInjectionProvider provider = new DefaultInjectionProvider(master, locator);
- worker.transform(ct, model);
+ assertTrue(provider.provideInjection("myfield", Request.class, locator, ct, model));
verify();
}
@Test
- public void provide_object_fails()
+ public void object_not_found()
{
- ObjectProvider provider = mockObjectProvider();
+ MasterObjectProvider master = mockMasterObjectProvider();
ObjectLocator locator = mockObjectLocator();
- Inject annotation = newMock(Inject.class);
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
- Throwable cause = new RuntimeException("Injection failed.");
-
- train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
- train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
-
- train_getFieldType(ct, "myfield", WEBREQUEST_CLASS_NAME);
- train_toClass(ct, WEBREQUEST_CLASS_NAME, Request.class);
- expect(provider.provide(eq(Request.class), isA(AnnotationProvider.class), eq(locator)))
- .andThrow(cause);
- train_getClassName(ct, "foo.pages.Bar");
+ expect(
+ master.provide(
+ eq(Request.class),
+ isA(AnnotationProvider.class),
+ eq(locator),
+ eq(false))).andReturn(null);
replay();
- InjectWorker worker = new InjectWorker(provider, locator);
+ DefaultInjectionProvider provider = new DefaultInjectionProvider(master, locator);
- try
- {
- worker.transform(ct, model);
- unreachable();
- }
- catch (RuntimeException ex)
- {
- assertEquals(
- ex.getMessage(),
- "Error obtaining injected value for field foo.pages.Bar.myfield: Injection failed.");
- assertSame(ex.getCause(), cause);
- }
+ assertFalse(provider.provideInjection("myfield", Request.class, locator, ct, model));
verify();
}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java (from r578523, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectResourcesWorkerTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectResourcesWorkerTest.java&r1=578523&r2=579020&rev=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectResourcesWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java Mon Sep 24 17:06:31 2007
@@ -24,31 +24,32 @@
import org.apache.tapestry.services.Request;
import org.testng.annotations.Test;
-public class InjectResourcesWorkerTest extends InternalBaseTestCase
+public class InjectWorkerTest extends InternalBaseTestCase
{
- private static final String WEBREQUEST_CLASS_NAME = Request.class.getName();
+ private static final String REQUEST_CLASS_NAME = Request.class.getName();
@Test
public void anonymous_injection()
{
ObjectLocator locator = mockObjectLocator();
InjectionProvider ip = newMock(InjectionProvider.class);
- Inject annotation = newMock(Inject.class);
+ Inject annotation = newInject();
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
- train_getFieldType(ct, "myfield", WEBREQUEST_CLASS_NAME);
+ train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
+ train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
- train_provideInjection(ip, "myfield", WEBREQUEST_CLASS_NAME, locator, ct, model, true);
+ train_provideInjection(ip, "myfield", Request.class, locator, ct, model, true);
ct.claimField("myfield", annotation);
replay();
- ComponentClassTransformWorker worker = new InjectResourcesWorker(locator, ip);
+ ComponentClassTransformWorker worker = new InjectWorker(locator, ip);
worker.transform(ct, model);
@@ -60,25 +61,71 @@
{
ObjectLocator locator = mockObjectLocator();
InjectionProvider ip = newMock(InjectionProvider.class);
- Inject annotation = newMock(Inject.class);
+ Inject annotation = newInject();
ClassTransformation ct = mockClassTransformation();
MutableComponentModel model = mockMutableComponentModel();
train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
- train_getFieldType(ct, "myfield", WEBREQUEST_CLASS_NAME);
+ train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
+ train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
- train_provideInjection(ip, "myfield", WEBREQUEST_CLASS_NAME, locator, ct, model, false);
+ train_provideInjection(ip, "myfield", Request.class, locator, ct, model, false);
replay();
- ComponentClassTransformWorker worker = new InjectResourcesWorker(locator, ip);
+ ComponentClassTransformWorker worker = new InjectWorker(locator, ip);
// Does the work but doesn't claim the field, since there was no match.
worker.transform(ct, model);
verify();
+ }
+
+ @Test
+ public void injection_provider_threw_exception()
+ {
+ ObjectLocator locator = mockObjectLocator();
+ InjectionProvider ip = newMock(InjectionProvider.class);
+ Inject annotation = newInject();
+ ClassTransformation ct = mockClassTransformation();
+ MutableComponentModel model = mockMutableComponentModel();
+ RuntimeException failure = new RuntimeException("Oops.");
+
+ train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
+ train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+
+ train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
+ train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+
+ expect(ip.provideInjection("myfield", Request.class, locator, ct, model)).andThrow(failure);
+
+ train_getClassName(ct, "foo.bar.Baz");
+
+ replay();
+
+ ComponentClassTransformWorker worker = new InjectWorker(locator, ip);
+
+ try
+ {
+ worker.transform(ct, model);
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertEquals(
+ ex.getMessage(),
+ "Error obtaining injected value for field foo.bar.Baz.myfield: Oops.");
+ assertSame(ex.getCause(), failure);
+ }
+
+ verify();
+ }
+
+ protected final Inject newInject()
+ {
+ return newMock(Inject.class);
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java Mon Sep 24 17:06:31 2007
@@ -45,7 +45,6 @@
import org.apache.tapestry.internal.transform.pages.ChildClassInheritsAnnotation;
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;
@@ -253,23 +252,6 @@
}
@Test
- public void find_fields_of_type() throws Exception
- {
- Logger logger = mockLogger();
-
- replay();
-
- ClassTransformation ct = createClassTransformation(FindFieldClass.class, logger);
-
- checkFindFields(ct, "boolean", "_booleanValue");
- checkFindFields(ct, "int[]", "_intArrayValue");
- checkFindFields(ct, "java.lang.String", "_stringValue");
- checkFindFields(ct, "java.util.Date[]", "_dateArrayValue");
-
- verify();
- }
-
- @Test
public void get_field_modifiers() throws Exception
{
Logger logger = mockLogger();
@@ -298,29 +280,6 @@
}
@Test
- public void find_fields_of_type_excludes_claimed_fields() throws Exception
- {
- Logger logger = mockLogger();
-
- replay();
-
- ClassTransformation ct = createClassTransformation(FindFieldClass.class, logger);
-
- ct.claimField("_booleanValue", this);
-
- checkFindFields(ct, "boolean");
-
- verify();
- }
-
- private void checkFindFields(ClassTransformation ct, String fieldType, String... expectedNames)
- {
- List<String> actual = ct.findFieldsOfType(fieldType);
-
- assertEquals(actual, Arrays.asList(expectedNames));
- }
-
- @Test
public void find_fields_with_annotation_excludes_claimed_files() throws Exception
{
Logger logger = mockLogger();
@@ -591,8 +550,8 @@
// This proves the the field is protected and can be used in subclasses.
- ct.addMethod(new TransformMethodSignature(Modifier.PUBLIC, "java.lang.String", "getValue", null,
- null), "return " + subclassFieldName + ";");
+ ct.addMethod(new TransformMethodSignature(Modifier.PUBLIC, "java.lang.String", "getValue",
+ null, null), "return " + subclassFieldName + ";");
ct.finish();
@@ -889,8 +848,8 @@
String fieldName = "_" + baseName;
String readMethodName = "_read_" + baseName;
- TransformMethodSignature readMethodSignature = new TransformMethodSignature(Modifier.PRIVATE,
- STRING_CLASS_NAME, readMethodName, null, null);
+ TransformMethodSignature readMethodSignature = new TransformMethodSignature(
+ Modifier.PRIVATE, STRING_CLASS_NAME, readMethodName, null, null);
ct.addMethod(readMethodSignature, String.format(
"throw new RuntimeException(\"read %s\");",
@@ -900,8 +859,8 @@
String writeMethodName = "_write_" + baseName;
- TransformMethodSignature writeMethodSignature = new TransformMethodSignature(Modifier.PRIVATE, "void",
- writeMethodName, new String[]
+ TransformMethodSignature writeMethodSignature = new TransformMethodSignature(
+ Modifier.PRIVATE, "void", writeMethodName, new String[]
{ STRING_CLASS_NAME }, null);
ct.addMethod(writeMethodSignature, String.format(
"throw new RuntimeException(\"write %s\");",
@@ -1045,7 +1004,9 @@
ClassTransformation ct = createClassTransformation(EventHandlerTarget.class, logger);
- OnEvent annotation = ct.getMethodAnnotation(new TransformMethodSignature("handler"), OnEvent.class);
+ OnEvent annotation = ct.getMethodAnnotation(
+ new TransformMethodSignature("handler"),
+ OnEvent.class);
// Check that the attributes of the annotation match the expectation.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.html?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.html (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.html Mon Sep 24 17:06:31 2007
@@ -3,6 +3,7 @@
<p>WebRequest: ${request}</p>
<p>ComponentResources: ${resources}</p>
<p>BindingSource: ${bindingSource}</p>
+ <p>Injected Symbol: ${injectedSymbol}</p>
<p>
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java Mon Sep 24 17:06:31 2007
@@ -24,8 +24,6 @@
* <p>
* In many cases, an object provider searches for additional annotations on the element (usually a
* parameter, or perhaps a field) for which a value is required.
- * <p>
- * A default ObjectProvider uses {@link ObjectLocator#getService(Class)}.
*/
public interface ObjectProvider
{
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Mon Sep 24 17:06:31 2007
@@ -33,7 +33,6 @@
import org.apache.tapestry.ioc.LoggerSource;
import org.apache.tapestry.ioc.MappedConfiguration;
import org.apache.tapestry.ioc.ObjectLocator;
-import org.apache.tapestry.ioc.ObjectProvider;
import org.apache.tapestry.ioc.OrderedConfiguration;
import org.apache.tapestry.ioc.Registry;
import org.apache.tapestry.ioc.ServiceDecorator;
@@ -56,6 +55,7 @@
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.ioc.services.TapestryIOCModule;
import org.apache.tapestry.ioc.services.ThreadCleanupHub;
+import org.apache.tapestry.services.MasterObjectProvider;
import org.slf4j.Logger;
public class RegistryImpl implements Registry, InternalRegistry
@@ -543,14 +543,14 @@
{
_lock.check();
- ObjectProvider masterProvider = getService(
+ MasterObjectProvider masterProvider = getService(
IOCConstants.MASTER_OBJECT_PROVIDER_SERVICE_ID,
- ObjectProvider.class);
+ MasterObjectProvider.class);
AnnotationProvider effectiveProvider = annotationProvider != null ? annotationProvider
: new NullAnnotationProvider();
- return masterProvider.provide(objectType, effectiveProvider, locator);
+ return masterProvider.provide(objectType, effectiveProvider, locator, true);
}
public <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java?rev=579020&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java Mon Sep 24 17:06:31 2007
@@ -0,0 +1,51 @@
+// 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.ioc.internal.services;
+
+import java.util.List;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.services.MasterObjectProvider;
+
+public class MasterObjectProviderImpl implements MasterObjectProvider
+{
+ private final List<ObjectProvider> _configuration;
+
+ public MasterObjectProviderImpl(List<ObjectProvider> configuration)
+ {
+ _configuration = configuration;
+ }
+
+ public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
+ ObjectLocator locator, boolean required)
+ {
+ for (ObjectProvider provider : _configuration)
+ {
+ T result = provider.provide(objectType, annotationProvider, locator);
+
+ if (result != null) return result;
+ }
+
+ // If required, then we must obtain it the hard way, by
+ // seeing if there's a single service that implements the interface.
+
+ if (required) return locator.getService(objectType);
+
+ return null;
+ }
+
+}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Mon Sep 24 17:06:31 2007
@@ -24,7 +24,6 @@
import java.util.List;
import java.util.Map;
-import org.apache.tapestry.ioc.AnnotationProvider;
import org.apache.tapestry.ioc.Configuration;
import org.apache.tapestry.ioc.MappedConfiguration;
import org.apache.tapestry.ioc.ObjectLocator;
@@ -40,6 +39,7 @@
import org.apache.tapestry.ioc.internal.services.ExceptionTrackerImpl;
import org.apache.tapestry.ioc.internal.services.LoggingDecoratorImpl;
import org.apache.tapestry.ioc.internal.services.MapSymbolProvider;
+import org.apache.tapestry.ioc.internal.services.MasterObjectProviderImpl;
import org.apache.tapestry.ioc.internal.services.PerThreadServiceLifecycle;
import org.apache.tapestry.ioc.internal.services.PipelineBuilderImpl;
import org.apache.tapestry.ioc.internal.services.PropertyAccessImpl;
@@ -52,6 +52,7 @@
import org.apache.tapestry.ioc.internal.services.ThreadLocaleImpl;
import org.apache.tapestry.ioc.internal.services.TypeCoercerImpl;
import org.apache.tapestry.ioc.internal.services.ValueObjectProvider;
+import org.apache.tapestry.services.MasterObjectProvider;
/**
* Defines the base set of services for the Tapestry IOC container.
@@ -75,6 +76,7 @@
binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults");
binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults");
binder.bind(Runnable.class, RegistryStartup.class).withId("RegistryStartup");
+ binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class);
}
/**
@@ -102,18 +104,6 @@
}
/**
- * The master {@link ObjectProvider} is responsible for identifying a particular ObjectProvider
- * by its prefix, and delegating to that instance.
- */
- public static ObjectProvider buildMasterObjectProvider(List<ObjectProvider> configuration,
-
- @InjectService("ChainBuilder")
- ChainBuilder chainBuilder)
- {
- return chainBuilder.build(ObjectProvider.class, configuration);
- }
-
- /**
* Contributes "DefaultProvider", ordered last, that delegates to
* {@link ObjectLocator#getService(Class)}.
* <p>
@@ -125,17 +115,6 @@
ObjectLocator locator)
{
- ObjectProvider defaultProvider = new ObjectProvider()
- {
-
- public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
- ObjectLocator locator)
- {
- return locator.getService(objectType);
- }
- };
-
- configuration.add("DefaultProvider", defaultProvider, "after:*");
configuration.add("Value", locator.autobuild(ValueObjectProvider.class));
configuration.add("Symbol", locator.autobuild(SymbolObjectProvider.class));
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java?rev=579020&r1=579019&r2=579020&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java Mon Sep 24 17:06:31 2007
@@ -45,6 +45,7 @@
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.ioc.services.ThreadLocale;
import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.MasterObjectProvider;
import org.slf4j.Logger;
/** Add factory and trainer methods for the public interfaces of Tapestry IOC. */
@@ -366,5 +367,10 @@
AnnotationProvider annotationProvider, Class<T> annotationClass, T annotation)
{
expect(annotationProvider.getAnnotation(annotationClass)).andReturn(annotation);
+ }
+
+ protected final MasterObjectProvider mockMasterObjectProvider()
+ {
+ return newMock(MasterObjectProvider.class);
}
}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/services/MasterObjectProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/services/MasterObjectProvider.java?rev=579020&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/services/MasterObjectProvider.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/services/MasterObjectProvider.java Mon Sep 24 17:06:31 2007
@@ -0,0 +1,57 @@
+// 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.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+
+/**
+ * Rolls up a number of {@link ObjectProvider}, but allows for the case where no object may be
+ * provided.
+ */
+public interface MasterObjectProvider
+{
+ /**
+ * Provides an object based on an expression. The process of providing objects occurs within a
+ * particular <em>context</em>, which will typically be a service builder method, service
+ * contributor method, or service decorator method. The locator parameter provides access to the
+ * services visible <em>to that context</em>.
+ * <p>
+ * When the value is required and no {@link ObjectProvider} provided a non-null value, then
+ * {@link ObjectLocator#getService(Class)} is invoked, to provide a unique matching service, or
+ * throw a failure exception.
+ *
+ * @param objectType
+ * the expected object type
+ * @param annotationProvider
+ * provides access to annotations (typically, the field or parameter to which an
+ * injection-related annotation is attached); annotations on the field or parameter
+ * may also be used when resolving the desired object
+ * @param locator
+ * locator for the <em>context</em> in which the provider is being used
+ * @param required
+ * if true (normal case) a value must be provided; if false then it is allowed for no
+ * ObjectProvider to provide a value, and this method may return null to indicate the
+ * failure
+ * @param <T>
+ * @return the requested object, or null if this object provider can not supply an object
+ * @throws RuntimeException
+ * if the expression can not be evaluated, or the type of object identified is not
+ * assignable to the type specified by the objectType parameter
+ */
+ <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
+ ObjectLocator locator, boolean required);
+}