You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/07/25 02:16:31 UTC
svn commit: r425234 [1/2] - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/ioc/
main/java/org/apache/tapestry/internal/test/
main/java/org/apache/tapestry/ioc/
main/java/org/apache/tapestry/ioc/annotations/ main/...
Author: hlship
Date: Mon Jul 24 17:16:30 2006
New Revision: 425234
URL: http://svn.apache.org/viewvc?rev=425234&view=rev
Log:
Start adding support for configurations and contributions.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Configuration.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Contribute.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithAnnotationOtherModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithContributeAnnotationModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/MappedConfigurationModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/NoUsableContributionParameterModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/OrderedConfigurationModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/TooManyContributionParametersModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapperTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt
tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ConfigurationType.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,30 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+/**
+ * Defines the three types of configurations a service may request.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public enum ConfigurationType {
+
+ /** @see org.apache.tapestry.ioc.Configuration */
+ UNORDERED,
+ /** @see org.apache.tapestry.ioc.OrderedConfiguration */
+ ORDERED,
+ /** @see org.apache.tapestry.ioc.MappedConfiguration */
+ MAPPED
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ContributionDefImpl.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,119 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tapestry.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.ServiceLocator;
+import org.apache.tapestry.ioc.def.ContributionDef;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ContributionDefImpl implements ContributionDef
+{
+ private final String _serviceId;
+
+ private final Method _contributorMethod;
+
+ public ContributionDefImpl(String serviceId, Method contributorMethod)
+ {
+ _serviceId = serviceId;
+ _contributorMethod = contributorMethod;
+ }
+
+ @Override
+ public String toString()
+ {
+ return InternalUtils.asString(_contributorMethod);
+ }
+
+ public String getServiceId()
+ {
+ return _serviceId;
+ }
+
+ public void contribute(Object moduleBuilder, ServiceLocator locator, Configuration configuration)
+ {
+ invokeMethod(moduleBuilder, locator, Configuration.class, configuration);
+ }
+
+ public void contribute(Object moduleBuilder, ServiceLocator locator,
+ OrderedConfiguration configuration)
+ {
+ invokeMethod(moduleBuilder, locator, OrderedConfiguration.class, configuration);
+ }
+
+ public void contribute(Object moduleBuilder, ServiceLocator locator,
+ MappedConfiguration configuration)
+ {
+ invokeMethod(moduleBuilder, locator, MappedConfiguration.class, configuration);
+ }
+
+ private void invokeMethod(Object moduleBuilder, ServiceLocator locator, Class parameterType,
+ Object parameterValue)
+ {
+ Map<Class, Object> parameterDefaults = newMap();
+
+ // The way it works is: the method will take Configuration, OrderedConfiguration or
+ // MappedConfiguration.
+ // So, if the method is for one type and the service is for a different type,
+ // then we'll see an error putting together the parameter.
+
+ parameterDefaults.put(parameterType, parameterValue);
+
+ invokeMethod(moduleBuilder, locator, parameterDefaults);
+ }
+
+ private void invokeMethod(Object moduleBuilder, ServiceLocator locator,
+ Map<Class, Object> parameterDefaults)
+ {
+ // Alas, logging of this will occur elsewhere, since
+ // I don't want to clutter up the parameters by passing
+ // in the Log for the service.
+
+ Throwable fail = null;
+
+ try
+ {
+ Object[] parameters = IOCUtilities.calculateParametersForMethod(
+ _contributorMethod,
+ locator,
+ parameterDefaults);
+
+ _contributorMethod.invoke(moduleBuilder, parameters);
+ }
+ catch (InvocationTargetException ex)
+ {
+ fail = ex;
+ }
+ catch (Exception ex)
+ {
+ fail = ex;
+ }
+
+ if (fail != null)
+ throw new RuntimeException(IOCMessages
+ .contributionMethodError(_contributorMethod, fail), fail);
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java Mon Jul 24 17:16:30 2006
@@ -14,13 +14,6 @@
package org.apache.tapestry.internal.ioc;
-import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodConflict;
-import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodWrongReturnType;
-import static org.apache.tapestry.internal.ioc.IOCMessages.decoratorMethodWrongReturnType;
-import static org.apache.tapestry.ioc.IOCUtilities.qualifySimpleIdList;
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-import static org.apache.tapestry.util.CollectionFactory.newSet;
-
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
@@ -31,16 +24,32 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.annotations.Match;
+import org.apache.tapestry.ioc.Configuration;
import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.IOCUtilities;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
import org.apache.tapestry.ioc.annotations.After;
import org.apache.tapestry.ioc.annotations.Before;
+import org.apache.tapestry.ioc.annotations.Contribute;
import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.annotations.Lifecycle;
import org.apache.tapestry.ioc.annotations.Private;
+import org.apache.tapestry.ioc.def.ContributionDef;
import org.apache.tapestry.ioc.def.DecoratorDef;
import org.apache.tapestry.ioc.def.ModuleDef;
import org.apache.tapestry.ioc.def.ServiceDef;
+import static org.apache.tapestry.internal.ioc.ConfigurationType.MAPPED;
+import static org.apache.tapestry.internal.ioc.ConfigurationType.ORDERED;
+import static org.apache.tapestry.internal.ioc.ConfigurationType.UNORDERED;
+import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodConflict;
+import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodWrongReturnType;
+import static org.apache.tapestry.internal.ioc.IOCMessages.decoratorMethodWrongReturnType;
+import static org.apache.tapestry.ioc.IOCUtilities.qualifySimpleIdList;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.CollectionFactory.newSet;
+
/**
* Starting from the Class for a module builder, identifies all the services (service builder
* methods), decorators (service decorator methods) and (not yet implemented) contributions (service
@@ -56,6 +65,9 @@
/** The prefix used to identify service decorator methods. */
private static final String DECORATE_METHOD_NAME_PREFIX = "decorate";
+ /** The prefix used to identify service contribution methods. */
+ private static final String CONTRIBUTE_METHOD_NAME_PREFIX = "contribute";
+
private final Class _builderClass;
private final Log _log;
@@ -66,8 +78,18 @@
/** Keyed on fully qualified decorator id. */
private final Map<String, DecoratorDef> _decoratorDefs = newMap();
+ private final Set<ContributionDef> _contributionDefs = newSet();
+
private final String _moduleId;
+ private final Map<Class, ConfigurationType> _contributorParameterToConfigurationType = newMap();
+
+ {
+ _contributorParameterToConfigurationType.put(MappedConfiguration.class, MAPPED);
+ _contributorParameterToConfigurationType.put(OrderedConfiguration.class, ORDERED);
+ _contributorParameterToConfigurationType.put(Configuration.class, UNORDERED);
+ }
+
/**
* @param builderClass
* the class that is responsible for building services, etc.
@@ -166,7 +188,61 @@
addDecoratorDef(m);
continue;
}
+
+ if (name.startsWith(CONTRIBUTE_METHOD_NAME_PREFIX))
+ {
+ addContributionDef(m);
+ continue;
+ }
+
+ }
+ }
+
+ private void addContributionDef(Method method)
+ {
+ String serviceId = stripMethodPrefix(method, CONTRIBUTE_METHOD_NAME_PREFIX);
+
+ Class returnType = method.getReturnType();
+ if (!returnType.equals(void.class))
+ _log.warn(IOCMessages.contributionWrongReturnType(method));
+
+ Contribute contribute = method.getAnnotation(Contribute.class);
+ if (contribute != null)
+ serviceId = contribute.value();
+
+ ConfigurationType type = null;
+
+ for (Class parameterType : method.getParameterTypes())
+ {
+ ConfigurationType thisParameter = _contributorParameterToConfigurationType
+ .get(parameterType);
+
+ if (thisParameter != null)
+ {
+ if (type != null)
+ {
+ _log.warn(IOCMessages.tooManyContributionParameters(method));
+ return;
+ }
+
+ type = thisParameter;
+ }
+ }
+
+ if (type == null)
+ {
+ _log.warn(IOCMessages.noContributionParameter(method));
+ return;
}
+
+ // Any other parameters will be validated and worked out at runtime, when we invoke the
+ // service contribution method.
+
+ String qualifiedId = IOCUtilities.toQualifiedId(_moduleId, serviceId);
+
+ ContributionDef def = new ContributionDefImpl(qualifiedId, method);
+
+ _contributionDefs.add(def);
}
private void addDecoratorDef(Method method)
@@ -276,4 +352,8 @@
return newSet(_decoratorDefs.values());
}
+ public Set<ContributionDef> getContributionDefs()
+ {
+ return _contributionDefs;
+ }
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCMessages.java Mon Jul 24 17:16:30 2006
@@ -14,16 +14,18 @@
package org.apache.tapestry.internal.ioc;
-import static org.apache.tapestry.internal.util.InternalUtils.asString;
-
import java.lang.reflect.Method;
import java.util.List;
import org.apache.hivemind.Messages;
import org.apache.hivemind.impl.MessageFormatter;
import org.apache.tapestry.internal.annotations.Utility;
+import org.apache.tapestry.ioc.def.ContributionDef;
import org.apache.tapestry.ioc.def.ServiceDef;
+import static org.apache.tapestry.internal.util.InternalUtils.asString;
+import static org.apache.tapestry.ioc.services.ClassFabUtils.getJavaClassName;
+
/**
* @author Howard M. Lewis Ship
*/
@@ -164,5 +166,40 @@
static String recursiveServiceBuild(ServiceDef def)
{
return MESSAGES.format("recursive-service-build", def.getServiceId(), def.toString());
+ }
+
+ static String contributionWrongReturnType(Method method)
+ {
+ return MESSAGES.format(
+ "contribution-wrong-return-type",
+ asString(method),
+ getJavaClassName(method.getReturnType()));
+ }
+
+ static String tooManyContributionParameters(Method method)
+ {
+ return MESSAGES.format("too-many-contribution-parameters", asString(method));
+ }
+
+ static String noContributionParameter(Method method)
+ {
+ return MESSAGES.format("no-contribution-parameter", asString(method));
+ }
+
+ static String contributionMethodError(Method method, Throwable cause)
+ {
+ return MESSAGES.format("contribution-method-error", asString(method), cause);
+ }
+
+ static String contributionWasNull(String serviceId, ContributionDef def)
+ {
+ return MESSAGES.format("contribution-was-null", serviceId, def);
+ }
+
+ static String contributionWrongValueType(String serviceId, ContributionDef def,
+ Class actualClass, Class expectedClass)
+ {
+ return MESSAGES.format("contribution-wrong-value-type", new Object[]
+ { serviceId, def, actualClass.getName(), expectedClass.getName() });
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java Mon Jul 24 17:16:30 2006
@@ -19,7 +19,7 @@
import java.util.Map;
import org.apache.tapestry.internal.annotations.Utility;
-import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.ServiceLocator;
import org.apache.tapestry.ioc.annotations.InjectService;
/**
@@ -53,8 +53,8 @@
}
@SuppressWarnings("unchecked")
- public static Object calculateParameterValue(Class parameterType,
- Annotation[] parameterAnnotations, ServiceResources serviceResources,
+ private static Object calculateParameterValue(Class parameterType,
+ Annotation[] parameterAnnotations, ServiceLocator locator,
Map<Class, Object> parameterDefaults)
{
InjectService is = findAnnotation(parameterAnnotations, InjectService.class);
@@ -63,7 +63,7 @@
{
String serviceId = is.value();
- return serviceResources.getService(serviceId, parameterType);
+ return locator.getService(serviceId, parameterType);
}
// See if we have any "pre-determined" parameter type to object mappings
@@ -73,15 +73,15 @@
// This will return a non-null value, or throw an exception
if (result == null)
- result = serviceResources.getService(parameterType);
+ result = locator.getService(parameterType);
// ... so the result is never null
return result;
}
- public static Object[] calculateParametersForMethod(Method method,
- ServiceResources serviceResources, Map<Class, Object> parameterDefaults)
+ public static Object[] calculateParametersForMethod(Method method, ServiceLocator locator,
+ Map<Class, Object> parameterDefaults)
{
Class[] parameterTypes = method.getParameterTypes();
Annotation[][] annotations = method.getParameterAnnotations();
@@ -94,7 +94,7 @@
parameters[i] = calculateParameterValue(
parameterTypes[i],
annotations[i],
- serviceResources,
+ locator,
parameterDefaults);
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvoker.java Mon Jul 24 17:16:30 2006
@@ -66,10 +66,6 @@
*/
public Object createService()
{
- Object[] parameters = calculateParametersForMethod(
- _builderMethod,
- _resources,
- _parameterDefaults);
if (_log.isDebugEnabled())
_log.debug(IOCMessages.invokingMethod(_builderMethod));
@@ -79,6 +75,11 @@
try
{
+ Object[] parameters = calculateParametersForMethod(
+ _builderMethod,
+ _resources,
+ _parameterDefaults);
+
result = _builderMethod.invoke(_moduleBuilder, parameters);
}
catch (InvocationTargetException ite)
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ServiceDecoratorImpl.java Mon Jul 24 17:16:30 2006
@@ -68,11 +68,6 @@
Map<Class, Object> parameterDefaults = newMap(_parameterDefaults);
parameterDefaults.put(Object.class, delegate);
- Object[] parameters = calculateParametersForMethod(
- _decoratorMethod,
- _resources,
- parameterDefaults);
-
if (_log.isDebugEnabled())
_log.debug(IOCMessages.invokingMethod(_decoratorMethod));
@@ -81,6 +76,11 @@
try
{
+ Object[] parameters = calculateParametersForMethod(
+ _decoratorMethod,
+ _resources,
+ parameterDefaults);
+
result = _decoratorMethod.invoke(_moduleBuilder, parameters);
}
catch (InvocationTargetException ite)
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ValidatingConfigurationWrapper.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,68 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+
+/**
+ * Performs some validation before delegating to another Configuration.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public class ValidatingConfigurationWrapper implements Configuration
+{
+ private final String _serviceId;
+
+ private final ContributionDef _contributionDef;
+
+ private final Log _log;
+
+ private final Configuration _delegate;
+
+ private final Class _expectedClass;
+
+ // Need a strategy for determing the right order for this mass of parameters!
+
+ public ValidatingConfigurationWrapper(String serviceId, Log log, Class expectedClass,
+ ContributionDef contributionDef, Configuration delegate)
+ {
+ _serviceId = serviceId;
+ _contributionDef = contributionDef;
+ _log = log;
+ _delegate = delegate;
+ _expectedClass = expectedClass;
+ }
+
+ public void add(Object object)
+ {
+ if (object == null)
+ {
+ _log.warn(IOCMessages.contributionWasNull(_serviceId, _contributionDef));
+ return;
+ }
+
+ if (!_expectedClass.isInstance(object))
+ {
+ _log.warn(IOCMessages.contributionWrongValueType(_serviceId, _contributionDef, object
+ .getClass(), _expectedClass));
+ return;
+ }
+
+ _delegate.add(object);
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Mon Jul 24 17:16:30 2006
@@ -16,13 +16,11 @@
import java.util.List;
-import org.apache.commons.logging.Log;
import org.apache.tapestry.internal.InternalComponentResources;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import org.apache.tapestry.internal.ioc.InternalRegistry;
import org.apache.tapestry.internal.ioc.Module;
import org.apache.tapestry.internal.parser.ComponentTemplate;
-import org.apache.tapestry.ioc.LogSource;
import org.apache.tapestry.ioc.ServiceDecorator;
import org.apache.tapestry.ioc.ServiceLifecycle;
import org.apache.tapestry.ioc.def.ServiceDef;
@@ -76,27 +74,9 @@
return newMock(Module.class);
}
- protected final void trainCreateInterceptor(ServiceDecorator decorator, Object coreObject,
- Object interceptor)
- {
- decorator.createInterceptor(coreObject);
- setReturnValue(interceptor);
- }
-
- protected final ServiceDecorator newServiceDecorator()
- {
- return newMock(ServiceDecorator.class);
- }
-
protected void trainFindDecoratorsForService(InternalRegistry registry)
{
registry.findDecoratorsForService(EasyMock.isA(ServiceDef.class));
setReturnValue(CollectionFactory.newList());
- }
-
- protected final void trainGetLog(LogSource source, String serviceId, Log log)
- {
- source.getLog(serviceId);
- setReturnValue(log);
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Configuration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Configuration.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Configuration.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/Configuration.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,45 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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;
+
+/**
+ * Object passed into a service contributor method that allows the method provide contributed values
+ * to the service's configuration.
+ * <p>
+ * A service can <em>collect</em> contributions in three different ways:
+ * <ul>
+ * <li>As an un-ordered collection of values</li>
+ * <li>As an ordered list of values (where each value has a unique id, pre-requisited and
+ * post-requisites)</li>
+ * <li>As a map of keys and values
+ * </ul>
+ * <p>
+ * This implementation is used for un-ordered configuration data.
+ * <p>
+ * The service defines the <em>type</em> of contribution, in terms of a base class or service
+ * interface. Contributions must be compatible with the type.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface Configuration<T>
+{
+ /**
+ * Adds an object to the service's contribution.
+ *
+ * @param object
+ * to add to the service's configuration
+ */
+ void add(T object);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,49 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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;
+
+/**
+ * Object passed into a service contributor method that allows the method provide contributed values
+ * to the service's configuration.
+ * <p>
+ * A service can <em>collect</em> contributions in three different ways:
+ * <ul>
+ * <li>As an un-ordered collection of values</li>
+ * <li>As an ordered list of values (where each value has a unique id, pre-requisited and
+ * post-requisites)</li>
+ * <li>As a map of keys and values
+ * </ul>
+ * <p>
+ * The service defines the <em>type</em> of contribution, in terms of a base class or service
+ * interface. Contributions must be compatible with the type.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface MappedConfiguration<K, V>
+{
+
+ /**
+ * Adds a keyed object to the service's contribution.
+ *
+ * @param key
+ * unique id for the value
+ * @param value
+ * to contribute
+ * @throws IllegalArgumentException
+ * if key is not unique
+ */
+
+ void add(K key, V value);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,62 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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;
+
+/**
+ * Object passed into a service contributor method that allows the method provide contributed values
+ * to the service's configuration.
+ * <p>
+ * A service can <em>collect</em> contributions in three different ways:
+ * <ul>
+ * <li>As an un-ordered collection of values</li>
+ * <li>As an ordered list of values (where each value has a unique id, pre-requisited and
+ * post-requisites)</li>
+ * <li>As a map of keys and values
+ * </ul>
+ * <p>
+ * The service defines the <em>type</em> of contribution, in terms of a base class or service
+ * interface. Contributions must be compatible with the type.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface OrderedConfiguration<T>
+{
+ /**
+ * Adds an ordered object to a service's contribution. Each object has an id (which must be
+ * unique). Optionally, pre-requisites (a list of ids that must precede this object) and
+ * post-requisites (ids that must follow) can be provided.
+ *
+ * @param id
+ * a unique id for the object; the id will be fully qualified with the contributing
+ * module's id
+ * @param prerequisites
+ * comma separated list of ids, or "*", or null (aka "after")
+ * @param postrequisites
+ * comma separated list of ids, or, "*", or null (aka "before")
+ * @parm object to add to the service's configuration
+ */
+ void add(String id, String prerequisites, String postrequisites, T object);
+
+ /**
+ * Simplified version of {@link #add(String, String, String, T)} that assumes null for the pre-
+ * and post-requisites.
+ *
+ * @param id
+ * a unique id for the object; the id will be fully qualified with the contributing
+ * module's id
+ * @parm object to add to the service's configuration
+ */
+ void add(String id, T object);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Contribute.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Contribute.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Contribute.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/annotations/Contribute.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Optional (but frequently used) annotation used with service contribution methods. When this
+ * annotation is not used, the name of the method is used to derive the service id that the
+ * configuration contributes to.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Contribute {
+
+ /** The id of the service to which configuration will be contributed. */
+ String value();
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,73 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.def;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.ServiceLocator;
+
+/**
+ * Contribution to a service configuration.
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface ContributionDef
+{
+ /** Identifies the service contributed to. */
+ String getServiceId();
+
+ /**
+ * Performs the work needed to contribute into the configuration.
+ *
+ * @param moduleBuilder
+ * the module builder instance associated with the contribution
+ * @param locator
+ * allows access to services visible to the module builder instance
+ * @param configuration
+ * the unordered configuration into which values should be loaded. This instance will
+ * encapsulate all related error checks (such as passing of nulls or inappropriate
+ * classes).
+ */
+ void contribute(Object moduleBuilder, ServiceLocator locator, Configuration configuration);
+
+ /**
+ * Performs the work needed to contribute into the configuration.
+ *
+ * @param moduleBuilder
+ * the module builder instance associated with the contribution
+ * @param locator
+ * allows access to services visible to the module builder instance
+ * @param configuration
+ * the ordered configuration into which values should be loaded. This instance will
+ * encapsulate all related error checks (such as passing of nulls or inappropriate
+ * classes).
+ */
+ void contribute(Object moduleBuilder, ServiceLocator locator, OrderedConfiguration configuration);
+
+ /**
+ * Performs the work needed to contribute into the configuration.
+ *
+ * @param moduleBuilder
+ * the module builder instance associated with the contribution
+ * @param locator
+ * allows access to services visible to the module builder instance
+ * @param configuration
+ * the mapped configuration into which values should be loaded. This instance will
+ * encapsulate all related error checks (such as passing of null keys or values or
+ * inappropriate classes, or duplicate keys).
+ */
+ void contribute(Object moduleBuilder, ServiceLocator locator, MappedConfiguration configuration);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java Mon Jul 24 17:16:30 2006
@@ -42,6 +42,11 @@
Set<DecoratorDef> getDecoratorDefs();
/**
+ * Returns all the contribution definitions built/provided by this module.
+ */
+ Set<ContributionDef> getContributionDefs();
+
+ /**
* Returns the module id extracted from the {@link org.apache.tapestry.ioc.annotations.Id}
* annotation on the module builder class (or calculated from the module builder's package, if
* the annotation is not present).
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java Mon Jul 24 17:16:30 2006
@@ -20,6 +20,7 @@
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@@ -30,8 +31,15 @@
import org.apache.commons.logging.Log;
import org.apache.hivemind.Resource;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.LogSource;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
import org.apache.tapestry.ioc.ServiceCreator;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceLocator;
import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.ContributionDef;
import org.apache.tapestry.ioc.def.ServiceDef;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.transform.ClassTransformation;
@@ -176,17 +184,17 @@
}
- protected final <T> void trainGetService(ServiceResources resources, String serviceId,
+ protected final <T> void trainGetService(ServiceLocator locator, String serviceId,
Class<T> serviceInterface, T service)
{
- resources.getService(serviceId, serviceInterface);
+ locator.getService(serviceId, serviceInterface);
setReturnValue(service);
}
- protected final <T> void trainGetService(ServiceResources resources, Class<T> serviceInterface,
+ protected final <T> void trainGetService(ServiceLocator locator, Class<T> serviceInterface,
T service)
{
- resources.getService(serviceInterface);
+ locator.getService(serviceInterface);
setReturnValue(service);
}
@@ -211,6 +219,67 @@
{
resources.getServiceId();
setReturnValue(serviceId);
+ }
+
+ protected final void trainCreateInterceptor(ServiceDecorator decorator, Object coreObject, Object interceptor)
+ {
+ decorator.createInterceptor(coreObject);
+ setReturnValue(interceptor);
+ }
+
+ protected final ServiceDecorator newServiceDecorator()
+ {
+ return newMock(ServiceDecorator.class);
+ }
+
+ protected final void trainGetLog(LogSource source, String serviceId, Log log)
+ {
+ source.getLog(serviceId);
+ setReturnValue(log);
+ }
+
+ protected final Method findMethod(Class clazz, String methodName)
+ {
+ for (Method method : clazz.getMethods())
+ {
+ if (method.getName().equals(methodName))
+ return method;
+ }
+
+ throw new IllegalArgumentException(String.format(
+ "Class %s does not provide a method named '%s'.",
+ clazz.getName(),
+ methodName));
+ }
+
+ protected final Method findMethod(String methodName)
+ {
+ return findMethod(getClass(), methodName);
+ }
+
+ protected final Configuration newConfiguration()
+ {
+ return newMock(Configuration.class);
+ }
+
+ protected final ServiceLocator newServiceLocator()
+ {
+ return newMock(ServiceLocator.class);
+ }
+
+ protected final OrderedConfiguration newOrderedConfiguration()
+ {
+ return newMock(OrderedConfiguration.class);
+ }
+
+ protected final MappedConfiguration newMappedConfiguration()
+ {
+ return newMock(MappedConfiguration.class);
+ }
+
+ protected final ContributionDef newContributionDef()
+ {
+ return newMock(ContributionDef.class);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/ioc/IOCStrings.properties Mon Jul 24 17:16:30 2006
@@ -43,4 +43,16 @@
invoking-method=Invoking method {0}.
recursive-service-build=Construction of service ''{0}'' has failed due to recursion: \
the service depends on itself in some way. \
- Please check {1} for references to another service that is itself dependent on service ''{0}''.
\ No newline at end of file
+ Please check {1} for references to another service that is itself dependent on service ''{0}''.
+contribution-wrong-return-type=Method {0} is named like a service contributor method, \
+ but the return type ({1}) is not appropriate (try void). The return value will be ignored.
+too-many-contribution-parameters=Service contribution method {0} contains more than one parameter of type Configuration, \
+ OrderedConfiguration, or MappedConfiguration. Exactly one such parameter is required for a service contribution method. \
+ The method has been ignored.
+no-contribution-parameter=Service contribution method {0} does not contain a parameter of type \
+ Configuration, OrderedConfiguration or MappedConfiguration. This parameter is how the method \
+ make contributions into the service's configuration. The method has been ignored.
+contribution-method-error=Error invoking service contribution method {0}: {1}
+contribution-was-null=Service contribution (to service ''{0}'', by {1}) was null and has been ignored.
+contribution-wrong-value-type=Service contribution (to service ''{0}'', by {1}) was an instance of {2}, \
+ but {3} was expected. The contribution has been ignored.
\ No newline at end of file
Added: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/configuration.apt Mon Jul 24 17:16:30 2006
@@ -0,0 +1,230 @@
+ ----
+ Tapestry IoC Configurations
+ ----
+
+Tapestry IoC Configurations
+
+ One of the key concepts on Tapestry IoC is <distributed configuration>. This is an idea adapted
+ from the Eclipse Plugin API and evidenced in HiveMind prior to Tapestry 5 IoC.
+
+ So ... nice term, what does it mean?
+
+ Distributed configuration is the key feature of Tapestry IoC that supports <extensibility>.
+
+ The distributed part refers to the fact that <any module> may make <contributions> to
+ any service's configuration (subject to the normal visibility rules for private services).
+
+ This seems esoteric, but is quite handy, and is best explained by example.
+
+ Say you are building a service that, say, maps a file extension
+ to an interface called FileServicer. There's a bunch of different services, all implementing the
+ FileServicer interface, across many different modules, each doing something specific for a
+ particular type of file (identified by the file's extension).
+
+ A central service uses this configuration to select a particular FileService interface:
+
++------+
+ public FileServicer buildFileServicerDispatcher(Map<String,FileServicer> contributions)
+ {
+ return new FileServiceDispatcherImpl(contributions);
+ }
++------+
+
+ In order to provide a value for the contribution parameter, Tapestry will <collect> contributions
+ from service contribution methods. It will ensure that the keys and values match the generic
+ types shown (String for the key, FileServicer for the value). The map will be assembled and passed into
+ the service builder method, and from there, into the FileServiceDispatcherImpl contructor.
+
+ So where do the values come from? Service contributor methods, methods that start with
+ "contribute":
+
++------+
+ @Contribute("FileServicerDispatcher")
+ public void contributeFileServicers(MappedConfiguration<String,FileServicer> configuration)
+ {
+ configuration.add("txt", new TextFileServicer());
+ configuration.add("pdf", new PDFFileServicer());
+ }
++------+
+
+ Like service builder and service decorator methods, we can inject services if we like:
+
++------+
+ @Contribute("FileServicerDispatcher")
+ public void contributeFileServicers(MappedConfiguration<String,FileServicer> configuration,
+ @InjectService("TextFileServicer") FileServicer textFileServicer,
+ @InjectService("PDFFileServicer") FileServicer pdfFileServicer,
+ {
+ configuration.add("txt", textFileServicer);
+ configuration.add("pdf", pdfFileServicer);
+ }
++------+
+
+ The <<extensibility>> comes from the fact that many different methods in all kinds
+ of different module builder classes can make these contributions. So, another module
+ might understand Microsoft Office formats:
+
++------+
+ @Contribute("some.module.FileServicerDispatcher")
+ public void contributeOfficeFileServicers(MappedConfiguration<String,FileServicer> configuration)
+ {
+ configuration.add("doc", new WordFileServicer());
+ configuration.add("ppt", new PowerPointFileServicer());
+ }
++------+
+
+ Now the FileServicerDispatcher builder method gets a Map with at least four entries in it.
+
+ Because Tapestry IoC is highly dynamic (it scans the visible JAR manifest files to identify
+ module builder classes), the FileServicerDispatcher service may be in one module, and the
+ other contributing modules (such as the one that contributes the Office file services) may be written at
+ a much later date. With no change to the FileServicerDispatcher service or its module builder class,
+ the new services "plug into" the overall solution, simply by having their JAR's on runtime classpath.
+
+Configuration Types
+
+ There are three different styles of configurations (with matching contributions):
+
+ * Unordered Collection. Contributions are simply added in and order is not important.
+
+ * Ordered List. Contributions are provided as an ordered list. Contributions must
+ establish the order by giving each contributed object a unique id,
+ by establishing forward and backward dependencies between the values.
+
+ * Map. Contributions provide unique keys and corresponding values.
+
+ []
+
+* Unordered Collection
+
+ A service builder method can collect an unordered list of values by defining
+ a parameter of type java.util.Collection. Further, you should parameterize
+ the type of collection. Tapestry will identify the parameterized type
+ and ensure that all contributions match.
+
+ One thing to remember is that the order in which contributions occur
+ is unspecified. There will be a possibly large number modules, each having
+ zero or more methods that contribute into the service. The order in which these
+ methods are invoked is unknown.
+
+ For example, here's a kind of Startup service that needs some Runnable
+ objects. It doesn't care what order the Runnable objects are executed in.
+
++------+
+ public Runnable buildStartup(final Collection<Runnable> configuration)
+ {
+ return new Runnable()
+ {
+ public void run()
+ {
+ for (Runnable contribution : configuration)
+ contribution.run();
+ }
+ };
+ }
++------+
+
+ Here we don't even need a separate class for the implementation,
+ we use a inner class for the implementation. The point is, the configuration
+ is provided to the builder method, which passes it along to the implementation
+ of the service.
+
+ On the contribution side, a service contribution method sees a
+ {{{../apidocs/org/apache/tapestry/ioc/Configuration.html}Configuration}} object:
+
++------+
+ @Contribute("some.module.Startup")
+ public void contributeStartups(Configuration<Runnable> configuration)
+ {
+ configuration.add(new JMSStartup());
+ configuration.add(new FileSystemStartup());
+ }
++------+
+
+ The Configuration interface defines just a single method: add(). This is very
+ intentional: the only thing you can do is add new items. If we passed in a Collection,
+ you might be tempted to check it for values, or remove them ... but that flys in the face
+ of the fact that the order of execution of these service contribution methods is
+ entirely unknown.
+
+ For readability (if Java any longer supports that concept), we've parameterized the
+ configuration parameter of the method, constraining it to instances of java.lang.Runnable,
+ so as to match the corresponding parameter. This is optional, but often very helpful. In any case,
+ attempting to contribute an object that doesn't extend or implement the type (Runnable) will result
+ in a runtime warning (and the value will be ignored).
+
+ Tapestry supports only this simple form of parameterized types. Java generics supports a wider
+ form, "wildcards", that Tapestry doesn't understand.
+
+* Ordered List
+
+ Ordered lists are much more common. With an ordered list, the contributions are sorted into a
+ proper order before being provided to the service builder method.
+
+ Again, the order in which service contribution methods are invoked is unknown. Therefore, the order in
+ which objects are added to the configuration is not known. Instead, we enforce an order on the items
+ <after> all the contributions have been added. As with {{{decorator.html}service decorators}}, we
+ set the order by giving each contributed object a unique id, and identifying (by id) which items
+ must preceded it in the list, and which must follow.
+
+ So, if we changed our Startup service to require a specific order for startup:
+
++------+
+ public Runnable buildStartup(final List<Runnable> configuration)
+ {
+ return new Runnable()
+ {
+ public void run()
+ {
+ for (Runnable contribution : configuration)
+ contribution.run();
+ }
+ };
+ }
++------+
+
+ Notice that the service builder method is shielded from the details of how the items are
+ ordered. It doesn't have to know about ids and pre- and post-requisites. By using
+ a parameter type of List, we've triggered Tapestry to collected all the ordering information.
+
+ For our service contribution methods, we must provide a parameter
+ of type
+ {{{../apidocs/org/apache/tapestry/ioc/OrderedConfiguration.html}OrderedConfiguration}}:
+
++------+
+ @Contribute("some.module.Startup")
+ public void contributeStartups(OrderedConfiguration<Runnable> configuration)
+ {
+ configuration.add("jms", new JMSStartup());
+ configuration.add("filesystem", "some.other.module.classloader", null, new FileSystemStartup());
+ }
++------+
+
+ Often, you don't care about ordering, the first form of the add method is used then. The id value you
+ provide will be prefixed with the contributing module's id. The ordering algorithm will find a spot for the
+ object (here the JMSStartup instance) based on the constraints of other contributed objects.
+
+ The second form is more specific, it allows pre-requisites and post-requisites. Each is a comma
+ separated list of ids. Unqualified ids in the list will be qualified with the contributing module's id.
+ As elsewhere, you may use the value "*" to indicate the item must be last or first in the list.
+
+ The object passed in may be null; this is valid, and is considered a "join point": points of reference in the
+ list that don't actually have any meaning of their own, but can be used when ordering other elements.
+ <TODO: Show example for chain of command, once that's put together.>
+
+ Null values, once ordered,
+ are editted out (the List passed to the service builder method does not include any nulls). Again, they are
+ allowed as placeholders, for the actual contributed objects to organize themselves around.
+
+
+* Mapped Configurations
+
+ As discussed in the earlier examples, mapped configurations are also supported. The keys passed in must
+ be unique. When conflicts occur, Tapestry will log warnings (identifying the source, in terms of invoked methods, of
+ the conflict), and ignore the conflicting value.
+
+ The value may not be null.
+
+
+
+
\ No newline at end of file
Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt Mon Jul 24 17:16:30 2006
@@ -100,6 +100,9 @@
No annotation is needed for these cases.
+ See also {{{configuration.html}service configuration}} for additional special cases
+ of resources that can be injected.
+
Example:
+-----------------------------------------------------------------------------------+
Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/site.xml Mon Jul 24 17:16:30 2006
@@ -55,9 +55,10 @@
<item name="Modules" href="ioc/module.html"/>
<item name="Services" href="ioc/service.html"/>
<item name="Decorators" href="ioc/decorator.html"/>
+ <item name="Configuration" href="ioc/configuration.html"/>
</menu>
- ${reports}
+ ${reports}
</body>
</project>
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithAnnotationOtherModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithAnnotationOtherModule.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithAnnotationOtherModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithAnnotationOtherModule.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.annotations.Contribute;
+import org.apache.tapestry.ioc.annotations.Id;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Id("ioc.test")
+public class ConfigurationWithAnnotationOtherModule
+{
+ @Contribute("some.module.Wilma")
+ public void contributeOtherModule(Configuration configuration)
+ {
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithContributeAnnotationModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithContributeAnnotationModule.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithContributeAnnotationModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ConfigurationWithContributeAnnotationModule.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.annotations.Contribute;
+import org.apache.tapestry.ioc.annotations.Id;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Id("ioc.test")
+public class ConfigurationWithContributeAnnotationModule
+{
+ @Contribute("Fred")
+ public void contributeSomething(Configuration configuration)
+ {
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ContributionDefImplTest.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,187 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import java.lang.reflect.Method;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.ServiceLocator;
+import org.apache.tapestry.ioc.annotations.InjectService;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class ContributionDefImplTest extends InternalBaseTestCase
+{
+ private Object _toContribute;
+
+ @Test
+ public void unordered_contribution()
+ {
+ _toContribute = new Object();
+ Configuration configuration = newConfiguration();
+ ServiceLocator locator = newServiceLocator();
+
+ configuration.add(_toContribute);
+
+ replay();
+
+ Method m = findMethod("contributeUnordered");
+ ContributionDef def = new ContributionDefImpl("foo.Bar", m);
+
+ def.contribute(this, locator, configuration);
+
+ verify();
+ }
+
+ @Test
+ public void unordered_collection_with_service_lookup()
+ {
+ Configuration configuration = newConfiguration();
+ ServiceLocator locator = newServiceLocator();
+ UpcaseService service = newUpcaseService();
+
+ trainGetService(locator, "zip.Zap", UpcaseService.class, service);
+
+ configuration.add(service);
+
+ replay();
+
+ Method m = findMethod("contributeUnorderedParameter");
+ ContributionDef def = new ContributionDefImpl("foo.Bar", m);
+
+ def.contribute(this, locator, configuration);
+
+ verify();
+ }
+
+ @Test
+ public void unordered_collection_with_incorrect_configuration_parameter()
+ {
+ Configuration configuration = newConfiguration();
+ ServiceLocator locator = newServiceLocator();
+
+ Throwable t = new RuntimeException("Missing service.");
+
+ locator.getService(MappedConfiguration.class);
+ setThrowable(t);
+
+ replay();
+
+ Method m = findMethod("contributeUnorderedWrongParameter");
+ ContributionDef def = new ContributionDefImpl("foo.Bar", m);
+
+ try
+ {
+ def.contribute(this, locator, configuration);
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertEquals(ex.getMessage(), "Error invoking service contribution method "
+ + getClass().getName()
+ + ".contributeUnorderedWrongParameter(MappedConfiguration): Missing service.");
+ }
+
+ verify();
+ }
+
+ // From here on in, it's an almost identical code path, so we won't be
+ // as exhaustive.
+
+ @Test
+ public void ordered_collection_with_service_lookup()
+ {
+ OrderedConfiguration configuration = newOrderedConfiguration();
+ ServiceLocator locator = newServiceLocator();
+ UpcaseService service = newUpcaseService();
+
+ trainGetService(locator, "zip.Zap", UpcaseService.class, service);
+
+ configuration.add("fred", service);
+
+ replay();
+
+ Method m = findMethod("contributeOrderedParameter");
+ ContributionDef def = new ContributionDefImpl("foo.Bar", m);
+
+ def.contribute(this, locator, configuration);
+
+ verify();
+ }
+
+ @Test
+ public void mapped_collection_with_service_lookup()
+ {
+ MappedConfiguration configuration = newMappedConfiguration();
+ ServiceLocator locator = newServiceLocator();
+ UpcaseService service = newUpcaseService();
+
+ trainGetService(locator, "zip.Zap", UpcaseService.class, service);
+
+ configuration.add("upcase", service);
+
+ replay();
+
+ Method m = findMethod("contributeMappedParameter");
+ ContributionDef def = new ContributionDefImpl("foo.Bar", m);
+
+ def.contribute(this, locator, configuration);
+
+ verify();
+ }
+
+ private UpcaseService newUpcaseService()
+ {
+ return newMock(UpcaseService.class);
+ }
+
+ public void contributeUnordered(Configuration configuration)
+ {
+ configuration.add(_toContribute);
+ }
+
+ public void contributeUnorderedParameter(Configuration configuration, @InjectService("zip.Zap")
+ UpcaseService service)
+ {
+ configuration.add(service);
+ }
+
+ public void contributeOrderedParameter(OrderedConfiguration configuration,
+ @InjectService("zip.Zap")
+ UpcaseService service)
+ {
+ configuration.add("fred", service);
+ }
+
+ public void contributeMappedParameter(MappedConfiguration configuration,
+ @InjectService("zip.Zap")
+ UpcaseService service)
+ {
+ configuration.add("upcase", service);
+ }
+
+ public void contributeUnorderedWrongParameter(MappedConfiguration configuration)
+ {
+ unreachable();
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImplTest.java Mon Jul 24 17:16:30 2006
@@ -27,6 +27,7 @@
import org.apache.hivemind.ErrorLog;
import org.apache.tapestry.internal.util.InternalUtils;
import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.def.ContributionDef;
import org.apache.tapestry.ioc.def.DecoratorDef;
import org.apache.tapestry.ioc.def.ModuleDef;
import org.apache.tapestry.ioc.def.ServiceDef;
@@ -236,5 +237,121 @@
assertTrue(md.getDecoratorDefs().isEmpty());
verify();
+ }
+
+ @Test
+ public void contribution_without_annotation()
+ {
+ attemptConfigurationMethod(
+ SimpleModuleBuilder.class,
+ "ioc.Barney",
+ "contributeBarney(Configuration)");
+ }
+
+ @Test
+ public void contribution_with_annotation()
+ {
+ attemptConfigurationMethod(
+ ConfigurationWithContributeAnnotationModule.class,
+ "ioc.test.Fred",
+ "contributeSomething(Configuration)");
+
+ }
+
+ @Test
+ public void contribution_with_annotation_to_other_module()
+ {
+ attemptConfigurationMethod(
+ ConfigurationWithAnnotationOtherModule.class,
+ "some.module.Wilma",
+ "contributeOtherModule(Configuration)");
+ }
+
+ @Test
+ public void ordered_contribution_method()
+ {
+ attemptConfigurationMethod(
+ OrderedConfigurationModule.class,
+ "ioc.test.Ordered",
+ "contributeOrdered(OrderedConfiguration)");
+ }
+
+ @Test
+ public void mapped_contribution_method()
+ {
+ attemptConfigurationMethod(
+ MappedConfigurationModule.class,
+ "ioc.test.Mapped",
+ "contributeMapped(MappedConfiguration)");
+ }
+
+ private void attemptConfigurationMethod(Class moduleClass, String expectedServiceId,
+ String expectedMethodSignature)
+ {
+ Log log = newLog();
+
+ replay();
+
+ ModuleDef md = new DefaultModuleDefImpl(moduleClass, log);
+
+ Set<ContributionDef> defs = md.getContributionDefs();
+
+ assertEquals(defs.size(), 1);
+
+ ContributionDef cd = defs.iterator().next();
+
+ // The target service id is derived from the method name
+
+ assertEquals(cd.getServiceId(), expectedServiceId);
+ assertEquals(cd.toString(), moduleClass.getName() + "." + expectedMethodSignature);
+
+ verify();
+ }
+
+ @Test
+ public void contribution_with_too_many_parameters() throws Exception
+ {
+ Class moduleClass = TooManyContributionParametersModule.class;
+ Method m = findMethod(moduleClass, "contributeTooMany");
+
+ Log log = newLog();
+ log.warn(IOCMessages.tooManyContributionParameters(m));
+
+ replay();
+
+ ModuleDef md = new DefaultModuleDefImpl(moduleClass, log);
+
+ assertTrue(md.getContributionDefs().isEmpty());
+
+ verify();
+ }
+
+ @Test
+ public void contribution_with_no_contribution_parameter() throws Exception
+ {
+ Class moduleClass = NoUsableContributionParameterModule.class;
+ Method m = findMethod(moduleClass, "contributeNoParameter");
+
+ Log log = newLog();
+ log.warn(IOCMessages.noContributionParameter(m));
+
+ replay();
+
+ ModuleDef md = new DefaultModuleDefImpl(moduleClass, log);
+
+ assertTrue(md.getContributionDefs().isEmpty());
+
+ verify();
+ }
+
+ private Method findMethod(Class containingClass, String methodName)
+ {
+ for (Method method : containingClass.getMethods())
+ {
+ if (method.getName().equals(methodName))
+ return method;
+ }
+
+ throw new IllegalArgumentException(methodName);
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/MappedConfigurationModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/MappedConfigurationModule.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/MappedConfigurationModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/MappedConfigurationModule.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.annotations.Id;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Id("ioc.test")
+public class MappedConfigurationModule
+{
+ public void contributeMapped(MappedConfiguration configuration)
+ {
+
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ModuleImplTest.java Mon Jul 24 17:16:30 2006
@@ -269,10 +269,11 @@
registry.getService("ioc.test.PrimitiveRecursiveFoe", FoeService.class);
unreachable();
}
- catch (IllegalStateException ex)
+ catch (RuntimeException ex)
{
+ // The exception is now wrapped in a more generic exception.
assertEquals(
- ex.getMessage(),
+ ex.getCause().getMessage(),
"Construction of service 'ioc.test.PrimitiveRecursiveFoe' has failed due to recursion: "
+ "the service depends on itself in some way. Please check "
+ ModuleImplTestModule.class.getName()
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/NoUsableContributionParameterModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/NoUsableContributionParameterModule.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/NoUsableContributionParameterModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/NoUsableContributionParameterModule.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.ioc.annotations.InjectService;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Id("ioc.test")
+public class NoUsableContributionParameterModule
+{
+ public void contributeNoParameter(@InjectService("foo.Bar")
+ UpcaseService service)
+ {
+
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/OrderedConfigurationModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/OrderedConfigurationModule.java?rev=425234&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/OrderedConfigurationModule.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/OrderedConfigurationModule.java Mon Jul 24 17:16:30 2006
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// 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.ioc;
+
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.annotations.Id;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.DefaultModuleDefImpl}.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Id("ioc.test")
+public class OrderedConfigurationModule
+{
+ public void contributeOrdered(OrderedConfiguration configuration)
+ {
+
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/ServiceBuilderMethodInvokerTest.java Mon Jul 24 17:16:30 2006
@@ -46,23 +46,6 @@
private FoeService _expectedFoe;
- private Method findMethod(String name)
- {
- return findMethod(this, name);
- }
-
- private Method findMethod(Object source, String name)
- {
- Class clazz = source.getClass();
- for (Method m : clazz.getMethods())
- {
- if (m.getName().equals(name))
- return m;
- }
-
- throw new RuntimeException("No method named '" + name + "'.");
- }
-
@Test
public void noargs_method()
{
@@ -138,10 +121,10 @@
trainForConstructor(resources, log);
- trainGetService(resources, "Foe", FoeService.class, _expectedFoe);
-
trainIsDebugEnabled(log, false);
+ trainGetService(resources, "Foe", FoeService.class, _expectedFoe);
+
replay();
ServiceCreator sc = new ServiceBuilderMethodInvoker(findMethod("build_injected"), this,
@@ -239,9 +222,9 @@
trainForConstructor(resources, log);
- trainGetService(resources, FoeService.class, _expectedFoe);
-
trainIsDebugEnabled(log, false);
+
+ trainGetService(resources, FoeService.class, _expectedFoe);
replay();
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java?rev=425234&r1=425233&r2=425234&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SimpleModuleBuilder.java Mon Jul 24 17:16:30 2006
@@ -14,6 +14,7 @@
package org.apache.tapestry.internal.ioc;
+import org.apache.tapestry.ioc.Configuration;
import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.annotations.Lifecycle;
import org.apache.tapestry.ioc.annotations.Private;
@@ -49,5 +50,11 @@
public <T> T decorateLogging(Class<T> serviceInterace, T delegate)
{
return null;
+ }
+
+ /** Minimal contribution method. */
+ public void contributeBarney(Configuration configuration)
+ {
+
}
}