001: // Copyright 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.Defense.notBlank;
018: import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
019:
020: import java.lang.reflect.Constructor;
021:
022: import org.apache.tapestry.ioc.IOCConstants;
023: import org.apache.tapestry.ioc.ObjectCreator;
024: import org.apache.tapestry.ioc.ServiceBinder;
025: import org.apache.tapestry.ioc.ServiceBindingOptions;
026: import org.apache.tapestry.ioc.ServiceBuilderResources;
027: import org.apache.tapestry.ioc.annotations.EagerLoad;
028: import org.apache.tapestry.ioc.annotations.Scope;
029: import org.apache.tapestry.ioc.def.ServiceDef;
030: import org.apache.tapestry.ioc.internal.util.InternalUtils;
031: import org.apache.tapestry.ioc.internal.util.OneShotLock;
032: import org.apache.tapestry.ioc.services.ClassFactory;
033:
034: public class ServiceBinderImpl implements ServiceBinder,
035: ServiceBindingOptions {
036: private final OneShotLock _lock = new OneShotLock();
037:
038: private final ServiceDefAccumulator _accumulator;
039:
040: private final ClassFactory _classFactory;
041:
042: public ServiceBinderImpl(ServiceDefAccumulator accumulator,
043: ClassFactory classFactory) {
044: _accumulator = accumulator;
045: _classFactory = classFactory;
046: }
047:
048: private String _serviceId;
049:
050: private Class _serviceInterface;
051:
052: private Class _serviceImplementation;
053:
054: private boolean _eagerLoad;
055:
056: private String _scope;
057:
058: public void finish() {
059: _lock.lock();
060:
061: flush();
062: }
063:
064: protected void flush() {
065: if (_serviceInterface == null)
066: return;
067:
068: final Constructor constructor = findConstructor();
069:
070: ObjectCreatorSource source = new ObjectCreatorSource() {
071: public ObjectCreator constructCreator(
072: ServiceBuilderResources resources) {
073: return new ConstructorServiceCreator(resources,
074: getDescription(), constructor);
075: }
076:
077: public String getDescription() {
078: return _classFactory
079: .getConstructorLocation(constructor).toString();
080: }
081: };
082:
083: ServiceDef serviceDef = new ServiceDefImpl(_serviceInterface,
084: _serviceId, _scope, _eagerLoad, source);
085:
086: _accumulator.addServiceDef(serviceDef);
087:
088: _serviceId = null;
089: _serviceInterface = null;
090: _serviceImplementation = null;
091: _eagerLoad = false;
092: _scope = null;
093: }
094:
095: private Constructor findConstructor() {
096: Constructor result = InternalUtils
097: .findAutobuildConstructor(_serviceImplementation);
098:
099: if (result == null)
100: throw new RuntimeException(IOCMessages.noConstructor(
101: _serviceImplementation, _serviceId));
102:
103: return result;
104: }
105:
106: public <T> ServiceBindingOptions bind(Class<T> implementationClass) {
107: return bind(implementationClass, implementationClass);
108: }
109:
110: public <T> ServiceBindingOptions bind(Class<T> serviceInterface,
111: Class<? extends T> serviceImplementation) {
112: notNull(serviceInterface, "serviceIterface");
113: notNull(serviceImplementation, "serviceImplementation");
114:
115: _lock.check();
116:
117: flush();
118:
119: _serviceInterface = serviceInterface;
120: _serviceImplementation = serviceImplementation;
121:
122: // Set defaults for the other properties.
123:
124: _eagerLoad = serviceImplementation
125: .getAnnotation(EagerLoad.class) != null;
126: _serviceId = serviceInterface.getSimpleName();
127:
128: Scope scope = serviceImplementation.getAnnotation(Scope.class);
129:
130: _scope = scope != null ? scope.value()
131: : IOCConstants.DEFAULT_SCOPE;
132:
133: return this ;
134: }
135:
136: public ServiceBindingOptions eagerLoad() {
137: _lock.check();
138:
139: _eagerLoad = true;
140:
141: return this ;
142: }
143:
144: public ServiceBindingOptions withId(String id) {
145: notBlank(id, "id");
146:
147: _lock.check();
148:
149: _serviceId = id;
150:
151: return this ;
152: }
153:
154: public ServiceBindingOptions scope(String scope) {
155: notBlank(scope, "scope");
156:
157: _lock.check();
158:
159: _scope = scope;
160:
161: return this;
162: }
163:
164: }
|