001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.ioc.internal;
016:
017: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
018:
019: import java.lang.reflect.InvocationTargetException;
020: import java.lang.reflect.Method;
021: import java.util.Map;
022:
023: import org.apache.tapestry.ioc.Configuration;
024: import org.apache.tapestry.ioc.MappedConfiguration;
025: import org.apache.tapestry.ioc.ModuleBuilderSource;
026: import org.apache.tapestry.ioc.OrderedConfiguration;
027: import org.apache.tapestry.ioc.ObjectLocator;
028: import org.apache.tapestry.ioc.def.ContributionDef;
029: import org.apache.tapestry.ioc.internal.util.InternalUtils;
030: import org.apache.tapestry.ioc.services.ClassFactory;
031:
032: public class ContributionDefImpl implements ContributionDef {
033: private final String _serviceId;
034:
035: private final Method _contributorMethod;
036:
037: private final ClassFactory _classFactory;
038:
039: public ContributionDefImpl(String serviceId,
040: Method contributorMethod, ClassFactory classFactory) {
041: _serviceId = serviceId;
042: _contributorMethod = contributorMethod;
043: _classFactory = classFactory;
044: }
045:
046: @Override
047: public String toString() {
048: return InternalUtils
049: .asString(_contributorMethod, _classFactory);
050: }
051:
052: public String getServiceId() {
053: return _serviceId;
054: }
055:
056: public void contribute(ModuleBuilderSource moduleBuilderSource,
057: ObjectLocator locator, Configuration configuration) {
058: invokeMethod(moduleBuilderSource, locator, Configuration.class,
059: configuration);
060: }
061:
062: public void contribute(ModuleBuilderSource moduleBuilderSource,
063: ObjectLocator locator, OrderedConfiguration configuration) {
064: invokeMethod(moduleBuilderSource, locator,
065: OrderedConfiguration.class, configuration);
066: }
067:
068: public void contribute(ModuleBuilderSource moduleBuilderSource,
069: ObjectLocator locator, MappedConfiguration configuration) {
070: invokeMethod(moduleBuilderSource, locator,
071: MappedConfiguration.class, configuration);
072: }
073:
074: private <T> void invokeMethod(ModuleBuilderSource source,
075: ObjectLocator locator, Class<T> parameterType,
076: T parameterValue) {
077: Map<Class, Object> parameterDefaults = newMap();
078:
079: // The way it works is: the method will take Configuration, OrderedConfiguration or
080: // MappedConfiguration. So, if the method is for one type and the service is for a different
081: // type, then we'll see an error putting together the parameter.
082:
083: parameterDefaults.put(parameterType, parameterValue);
084: parameterDefaults.put(ObjectLocator.class, locator);
085:
086: Throwable fail = null;
087:
088: Object moduleBuilder = InternalUtils
089: .isStatic(_contributorMethod) ? null : source
090: .getModuleBuilder();
091:
092: try {
093: Object[] parameters = InternalUtils
094: .calculateParametersForMethod(_contributorMethod,
095: locator, parameterDefaults);
096:
097: _contributorMethod.invoke(moduleBuilder, parameters);
098: } catch (InvocationTargetException ex) {
099: fail = ex.getTargetException();
100: } catch (Exception ex) {
101: fail = ex;
102: }
103:
104: if (fail != null)
105: throw new RuntimeException(IOCMessages
106: .contributionMethodError(_contributorMethod, fail),
107: fail);
108: }
109: }
|