Moven tapestry-ioc Module classes to a modules package
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/233ff423 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/233ff423 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/233ff423 Branch: refs/heads/master Commit: 233ff423016fbcbc203e7aea72375361e83c870d Parents: aefd910 Author: Howard M. Lewis Ship <[email protected]> Authored: Sat Apr 20 19:47:50 2013 +0100 Committer: Howard M. Lewis Ship <[email protected]> Committed: Sat Apr 20 19:47:50 2013 +0100 ---------------------------------------------------------------------- 54_RELEASE_NOTES.txt | 11 +- .../tapestry5/internal/TapestryAppInitializer.java | 2 +- .../org/apache/tapestry5/ioc/RegistryBuilder.java | 2 +- .../services/metrics/MetricCollectorImpl.java | 2 +- .../tapestry5/ioc/modules/MetricsModule.java | 1 + .../tapestry5/ioc/modules/MetricsSymbols.java | 10 - .../tapestry5/ioc/modules/TapestryIOCModule.java | 534 +++++++++++++++ .../tapestry5/ioc/services/TapestryIOCModule.java | 534 --------------- .../ioc/services/metrics/MetricsSymbols.java | 10 + .../groovy/ioc/specs/OperationAdvisorSpec.groovy | 2 +- tapestry-ioc/src/test/resources/log4j.properties | 4 +- .../src/test/groovy/MongoDBSpec.groovy | 2 +- 12 files changed, 562 insertions(+), 552 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/54_RELEASE_NOTES.txt ---------------------------------------------------------------------- diff --git a/54_RELEASE_NOTES.txt b/54_RELEASE_NOTES.txt index 6b76a6b..da6c633 100644 --- a/54_RELEASE_NOTES.txt +++ b/54_RELEASE_NOTES.txt @@ -224,4 +224,13 @@ The interface for AssetPathConstructor was changed incompatibly, to allow for in ## StreamableResource Extended StreamableResource has been modified, adding a new `getChecksum()` method; this interface is rarely, if ever, -used or implemented by application code. \ No newline at end of file +used or implemented by application code. + +## Module classes moved to new modules + +Traditionally, Tapestry IoC Module classes have lived in the same package as the service interfaces they define, and +at the same time reference implementation classes in a separate (usually internal) package. This is not a desirable +approach, as proper practices is to avoid cases where separate packages import classes from each other. + +To resolve this, new `modules` packages have been created, and module classes have been moved there. Since module +classes are typically not used directly by end-user code, this is not expected to be a disruptive change. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryAppInitializer.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryAppInitializer.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryAppInitializer.java index c721754..730f179 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryAppInitializer.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryAppInitializer.java @@ -30,7 +30,7 @@ import java.util.List; /** * This class is used to build the {@link Registry}. The Registry contains - * {@link org.apache.tapestry5.ioc.services.TapestryIOCModule} and {@link TapestryModule}, any + * {@link org.apache.tapestry5.ioc.modules.TapestryIOCModule} and {@link TapestryModule}, any * modules identified by {@link #addModules(Class[])} )}, plus the application module. * <p/> * The application module is optional. http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/RegistryBuilder.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/RegistryBuilder.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/RegistryBuilder.java index 894bacb..7c8d946 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/RegistryBuilder.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/RegistryBuilder.java @@ -20,8 +20,8 @@ import org.apache.tapestry5.ioc.internal.*; import org.apache.tapestry5.ioc.internal.services.PlasticProxyFactoryImpl; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; import org.apache.tapestry5.ioc.internal.util.OneShotLock; +import org.apache.tapestry5.ioc.modules.TapestryIOCModule; import org.apache.tapestry5.ioc.services.PlasticProxyFactory; -import org.apache.tapestry5.ioc.services.TapestryIOCModule; import org.apache.tapestry5.ioc.util.ExceptionUtils; import org.slf4j.Logger; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/metrics/MetricCollectorImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/metrics/MetricCollectorImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/metrics/MetricCollectorImpl.java index 087ea39..dae5442 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/metrics/MetricCollectorImpl.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/metrics/MetricCollectorImpl.java @@ -7,11 +7,11 @@ import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.ioc.internal.util.LockSupport; -import org.apache.tapestry5.ioc.modules.MetricsSymbols; import org.apache.tapestry5.ioc.services.cron.IntervalSchedule; import org.apache.tapestry5.ioc.services.cron.PeriodicExecutor; import org.apache.tapestry5.ioc.services.metrics.Metric; import org.apache.tapestry5.ioc.services.metrics.MetricCollector; +import org.apache.tapestry5.ioc.services.metrics.MetricsSymbols; import org.apache.tapestry5.ioc.util.ExceptionUtils; import org.rrd4j.core.*; import org.slf4j.Logger; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsModule.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsModule.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsModule.java index a44f1c8..38b2732 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsModule.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsModule.java @@ -9,6 +9,7 @@ import org.apache.tapestry5.ioc.services.Builtin; import org.apache.tapestry5.ioc.services.FactoryDefaults; import org.apache.tapestry5.ioc.services.SymbolProvider; import org.apache.tapestry5.ioc.services.metrics.MetricCollector; +import org.apache.tapestry5.ioc.services.metrics.MetricsSymbols; @Marker(Builtin.class) public class MetricsModule http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsSymbols.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsSymbols.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsSymbols.java deleted file mode 100644 index 7a55aeb..0000000 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/MetricsSymbols.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.apache.tapestry5.ioc.modules; - -public class MetricsSymbols -{ - /** - * The directory in which RRDb database files are stored. If blank (the default), - * then RRD is set up for in-memory databases only (re-created on each launch of the application). - */ - public static final String RRD_DB_DIR = "tapestry.rrd-dir"; -} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/TapestryIOCModule.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/TapestryIOCModule.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/TapestryIOCModule.java new file mode 100644 index 0000000..178edf2 --- /dev/null +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/modules/TapestryIOCModule.java @@ -0,0 +1,534 @@ +// Copyright 2006-2012 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.tapestry5.ioc.modules; + +import org.apache.tapestry5.func.Flow; +import org.apache.tapestry5.ioc.*; +import org.apache.tapestry5.ioc.annotations.*; +import org.apache.tapestry5.ioc.internal.services.*; +import org.apache.tapestry5.ioc.internal.services.cron.PeriodicExecutorImpl; +import org.apache.tapestry5.ioc.internal.util.CollectionFactory; +import org.apache.tapestry5.ioc.internal.util.InternalUtils; +import org.apache.tapestry5.ioc.services.*; +import org.apache.tapestry5.ioc.services.cron.PeriodicExecutor; +import org.apache.tapestry5.ioc.util.TimeInterval; +import org.apache.tapestry5.services.UpdateListenerHub; + +import java.io.File; +import java.lang.reflect.Array; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import static org.apache.tapestry5.ioc.OrderConstraintBuilder.after; +import static org.apache.tapestry5.ioc.OrderConstraintBuilder.before; + +/** + * Defines the base set of services for the Tapestry IOC container. + */ +@SuppressWarnings("all") +@Marker(Builtin.class) +@SubModule(MetricsModule.class) +public final class TapestryIOCModule +{ + public static void bind(ServiceBinder binder) + { + binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class); + binder.bind(ChainBuilder.class, ChainBuilderImpl.class); + binder.bind(PropertyAccess.class, PropertyAccessImpl.class); + binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class); + binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class); + binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class).preventReloading(); + binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class); + binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class); + binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class); + binder.bind(TypeCoercer.class, TypeCoercerImpl.class).preventReloading(); + binder.bind(ThreadLocale.class, ThreadLocaleImpl.class); + binder.bind(SymbolSource.class, SymbolSourceImpl.class); + binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults") + .withMarker(ApplicationDefaults.class); + binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults") + .withMarker(FactoryDefaults.class); + binder.bind(Runnable.class, RegistryStartup.class).withSimpleId(); + binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class).preventReloading(); + binder.bind(ClassNameLocator.class, ClassNameLocatorImpl.class); + binder.bind(ClasspathScanner.class, ClasspathScannerImpl.class); + binder.bind(AspectDecorator.class, AspectDecoratorImpl.class); + binder.bind(ClasspathURLConverter.class, ClasspathURLConverterImpl.class); + binder.bind(ServiceOverride.class, ServiceOverrideImpl.class); + binder.bind(LoggingAdvisor.class, LoggingAdvisorImpl.class); + binder.bind(LazyAdvisor.class, LazyAdvisorImpl.class); + binder.bind(ThunkCreator.class, ThunkCreatorImpl.class); + binder.bind(UpdateListenerHub.class, UpdateListenerHubImpl.class).preventReloading(); + binder.bind(PeriodicExecutor.class, PeriodicExecutorImpl.class); + binder.bind(OperationAdvisor.class, OperationAdvisorImpl.class); + } + + /** + * Provides access to additional service lifecycles. One lifecycle is built in ("singleton") but additional ones are + * accessed via this service (and its mapped configuration). Only proxiable services (those with explicit service + * interfaces) can be managed in terms of a lifecycle. + */ + @PreventServiceDecoration + public static ServiceLifecycleSource build(Map<String, ServiceLifecycle> configuration) + { + final Map<String, ServiceLifecycle2> lifecycles = CollectionFactory.newCaseInsensitiveMap(); + + for (String name : configuration.keySet()) + { + lifecycles.put(name, InternalUtils.toServiceLifecycle2(configuration.get(name))); + } + + return new ServiceLifecycleSource() + { + public ServiceLifecycle get(String scope) + { + return lifecycles.get(scope); + } + }; + } + + /** + * Contributes the "perthread" scope. + */ + @Contribute(ServiceLifecycleSource.class) + public static void providePerthreadScope(MappedConfiguration<String, ServiceLifecycle> configuration) + { + configuration.addInstance(ScopeConstants.PERTHREAD, PerThreadServiceLifecycle.class); + } + + /** + * <dl> + * <dt>AnnotationBasedContributions</dt> + * <dd>Empty placeholder used to separate annotation-based ObjectProvider contributions (which come before) from + * non-annotation based (such as ServiceOverride) which come after.</dd> + * <dt>Value</dt> + * <dd>Supports the {@link org.apache.tapestry5.ioc.annotations.Value} annotation</dd> + * <dt>Symbol</dt> + * <dd>Supports the {@link org.apache.tapestry5.ioc.annotations.Symbol} annotations</dd> + * <dt>Autobuild</dt> + * <dd>Supports the {@link org.apache.tapestry5.ioc.annotations.Autobuild} annotation</dd> + * <dt>ServiceOverride</dt> + * <dd>Allows simple service overrides via the {@link org.apache.tapestry5.ioc.services.ServiceOverride} service + * (and its configuration) + * </dl> + */ + @Contribute(MasterObjectProvider.class) + public static void setupObjectProviders(OrderedConfiguration<ObjectProvider> configuration, @Local + final ServiceOverride serviceOverride) + { + configuration.add("AnnotationBasedContributions", null); + + configuration.addInstance("Value", ValueObjectProvider.class, before("AnnotationBasedContributions").build()); + configuration.addInstance("Symbol", SymbolObjectProvider.class, before("AnnotationBasedContributions").build()); + configuration.add("Autobuild", new AutobuildObjectProvider(), before("AnnotationBasedContributions").build()); + + ObjectProvider wrapper = new ObjectProvider() + { + public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator) + { + return serviceOverride.getServiceOverrideProvider().provide(objectType, annotationProvider, locator); + } + }; + + configuration.add("ServiceOverride", wrapper, after("AnnotationBasedContributions").build()); + } + + /** + * Contributes a set of standard type coercions to the {@link TypeCoercer} service: + * <ul> + * <li>Object to String</li> + * <li>Object to Boolean</li> + * <li>String to Double</li> + * <li>String to BigDecimal</li> + * <li>BigDecimal to Double</li> + * <li>Double to BigDecimal</li> + * <li>String to BigInteger</li> + * <li>BigInteger to Long</li> + * <li>String to Long</li> + * <li>Long to Byte</li> + * <li>Long to Short</li> + * <li>Long to Integer</li> + * <li>Double to Long</li> + * <li>Double to Float</li> + * <li>Float to Double</li> + * <li>Long to Double</li> + * <li>String to Boolean ("false" is always false, other non-blank strings are true)</li> + * <li>Number to Boolean (true if number value is non zero)</li> + * <li>Null to Boolean (always false)</li> + * <li>Collection to Boolean (false if empty)</li> + * <li>Object[] to List</li> + * <li>primitive[] to List</li> + * <li>Object to List (by wrapping as a singleton list)</li> + * <li>String to File</li> + * <li>String to {@link org.apache.tapestry5.ioc.util.TimeInterval}</li> + * <li>{@link org.apache.tapestry5.ioc.util.TimeInterval} to Long</li> + * <li>Object to Object[] (wrapping the object as an array)</li> + * <li>Collection to Object[] (via the toArray() method) + * <li>{@link Flow} to List</li> + * <li>{@link Flow} to Boolean (false if empty)</li> + * </ul> + */ + @Contribute(TypeCoercer.class) + public static void provideBasicTypeCoercions(Configuration<CoercionTuple> configuration) + { + add(configuration, Object.class, String.class, new Coercion<Object, String>() + { + public String coerce(Object input) + { + return input.toString(); + } + }); + + add(configuration, Object.class, Boolean.class, new Coercion<Object, Boolean>() + { + public Boolean coerce(Object input) + { + return input != null; + } + }); + + add(configuration, String.class, Double.class, new Coercion<String, Double>() + { + public Double coerce(String input) + { + return new Double(input); + } + }); + + // String to BigDecimal is important, as String->Double->BigDecimal would lose + // precision. + + add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>() + { + public BigDecimal coerce(String input) + { + return new BigDecimal(input); + } + }); + + add(configuration, BigDecimal.class, Double.class, new Coercion<BigDecimal, Double>() + { + public Double coerce(BigDecimal input) + { + return input.doubleValue(); + } + }); + + add(configuration, String.class, BigInteger.class, new Coercion<String, BigInteger>() + { + public BigInteger coerce(String input) + { + return new BigInteger(input); + } + }); + + add(configuration, String.class, Long.class, new Coercion<String, Long>() + { + public Long coerce(String input) + { + return new Long(input); + } + }); + + add(configuration, Long.class, Byte.class, new Coercion<Long, Byte>() + { + public Byte coerce(Long input) + { + return input.byteValue(); + } + }); + + add(configuration, Long.class, Short.class, new Coercion<Long, Short>() + { + public Short coerce(Long input) + { + return input.shortValue(); + } + }); + + add(configuration, Long.class, Integer.class, new Coercion<Long, Integer>() + { + public Integer coerce(Long input) + { + return input.intValue(); + } + }); + + add(configuration, Number.class, Long.class, new Coercion<Number, Long>() + { + public Long coerce(Number input) + { + return input.longValue(); + } + }); + + add(configuration, Double.class, Float.class, new Coercion<Double, Float>() + { + public Float coerce(Double input) + { + return input.floatValue(); + } + }); + + add(configuration, Long.class, Double.class, new Coercion<Long, Double>() + { + public Double coerce(Long input) + { + return input.doubleValue(); + } + }); + + add(configuration, String.class, Boolean.class, new Coercion<String, Boolean>() + { + public Boolean coerce(String input) + { + String trimmed = input == null ? "" : input.trim(); + + if (trimmed.equalsIgnoreCase("false") || trimmed.length() == 0) + return false; + + // Any non-blank string but "false" + + return true; + } + }); + + add(configuration, Number.class, Boolean.class, new Coercion<Number, Boolean>() + { + public Boolean coerce(Number input) + { + return input.longValue() != 0; + } + }); + + add(configuration, Void.class, Boolean.class, new Coercion<Void, Boolean>() + { + public Boolean coerce(Void input) + { + return false; + } + }); + + add(configuration, Collection.class, Boolean.class, new Coercion<Collection, Boolean>() + { + public Boolean coerce(Collection input) + { + return !input.isEmpty(); + } + }); + + add(configuration, Object.class, List.class, new Coercion<Object, List>() + { + public List coerce(Object input) + { + return Collections.singletonList(input); + } + }); + + add(configuration, Object[].class, List.class, new Coercion<Object[], List>() + { + public List coerce(Object[] input) + { + return Arrays.asList(input); + } + }); + + add(configuration, Object[].class, Boolean.class, new Coercion<Object[], Boolean>() + { + public Boolean coerce(Object[] input) + { + return input != null && input.length > 0; + } + }); + + add(configuration, Float.class, Double.class, new Coercion<Float, Double>() + { + public Double coerce(Float input) + { + return input.doubleValue(); + } + }); + + Coercion primitiveArrayCoercion = new Coercion<Object, List>() + { + public List<Object> coerce(Object input) + { + int length = Array.getLength(input); + Object[] array = new Object[length]; + for (int i = 0; i < length; i++) + { + array[i] = Array.get(input, i); + } + return Arrays.asList(array); + } + }; + + add(configuration, byte[].class, List.class, primitiveArrayCoercion); + add(configuration, short[].class, List.class, primitiveArrayCoercion); + add(configuration, int[].class, List.class, primitiveArrayCoercion); + add(configuration, long[].class, List.class, primitiveArrayCoercion); + add(configuration, float[].class, List.class, primitiveArrayCoercion); + add(configuration, double[].class, List.class, primitiveArrayCoercion); + add(configuration, char[].class, List.class, primitiveArrayCoercion); + add(configuration, boolean[].class, List.class, primitiveArrayCoercion); + + add(configuration, String.class, File.class, new Coercion<String, File>() + { + public File coerce(String input) + { + return new File(input); + } + }); + + add(configuration, String.class, TimeInterval.class, new Coercion<String, TimeInterval>() + { + public TimeInterval coerce(String input) + { + return new TimeInterval(input); + } + }); + + add(configuration, TimeInterval.class, Long.class, new Coercion<TimeInterval, Long>() + { + public Long coerce(TimeInterval input) + { + return input.milliseconds(); + } + }); + + add(configuration, Object.class, Object[].class, new Coercion<Object, Object[]>() + { + public Object[] coerce(Object input) + { + return new Object[] + {input}; + } + }); + + add(configuration, Collection.class, Object[].class, new Coercion<Collection, Object[]>() + { + public Object[] coerce(Collection input) + { + return input.toArray(); + } + }); + + add(configuration, Flow.class, List.class, new Coercion<Flow, List>() + { + public List coerce(Flow input) + { + return input.toList(); + } + }); + + add(configuration, Flow.class, Boolean.class, new Coercion<Flow, Boolean>() + { + public Boolean coerce(Flow input) + { + return !input.isEmpty(); + } + }); + + } + + private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType, + Class<T> targetType, Coercion<S, T> coercion) + { + configuration.add(CoercionTuple.create(sourceType, targetType, coercion)); + } + + /** + * <dl> + * <dt>SystemProperties</dt> + * <dd>Exposes JVM System properties as symbols (currently case-sensitive)</dd> + * <dt>EnvironmentVariables</dt> + * <dd>Exposes environment variables as symbols (adding a "env." prefix)</dd> + * <dt>ApplicationDefaults</dt> + * <dd>Values contributed to @{@link SymbolProvider} @{@link ApplicationDefaults}</dd> + * <dt>FactoryDefaults</dt> + * <dd>Values contributed to @{@link SymbolProvider} @{@link FactoryDefaults}</dd> + * </dl> + */ + @Contribute(SymbolSource.class) + public static void setupStandardSymbolProviders(OrderedConfiguration<SymbolProvider> configuration, + @ApplicationDefaults + SymbolProvider applicationDefaults, + + @FactoryDefaults + SymbolProvider factoryDefaults) + { + configuration.add("SystemProperties", new SystemPropertiesSymbolProvider(), "before:*"); + configuration.add("EnvironmentVariables", new SystemEnvSymbolProvider()); + configuration.add("ApplicationDefaults", applicationDefaults); + configuration.add("FactoryDefaults", factoryDefaults); + } + + public static ParallelExecutor buildDeferredExecution(@Symbol(IOCSymbols.THREAD_POOL_CORE_SIZE) + int coreSize, + + @Symbol(IOCSymbols.THREAD_POOL_MAX_SIZE) + int maxSize, + + @Symbol(IOCSymbols.THREAD_POOL_KEEP_ALIVE) + @IntermediateType(TimeInterval.class) + int keepAliveMillis, + + @Symbol(IOCSymbols.THREAD_POOL_ENABLED) + boolean threadPoolEnabled, + + @Symbol(IOCSymbols.THREAD_POOL_QUEUE_SIZE) + int queueSize, + + PerthreadManager perthreadManager, + + RegistryShutdownHub shutdownHub, + + ThunkCreator thunkCreator) + { + + if (!threadPoolEnabled) + return new NonParallelExecutor(); + + LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(queueSize); + + final ThreadPoolExecutor executorService = new ThreadPoolExecutor(coreSize, maxSize, keepAliveMillis, + TimeUnit.MILLISECONDS, workQueue); + + shutdownHub.addRegistryShutdownListener(new Runnable() + { + public void run() + { + executorService.shutdown(); + } + }); + + return new ParallelExecutorImpl(executorService, thunkCreator, perthreadManager); + } + + @Contribute(SymbolProvider.class) + @FactoryDefaults + public static void setupDefaultSymbols(MappedConfiguration<String, Object> configuration) + { + configuration.add(IOCSymbols.THREAD_POOL_CORE_SIZE, 3); + configuration.add(IOCSymbols.THREAD_POOL_MAX_SIZE, 20); + configuration.add(IOCSymbols.THREAD_POOL_KEEP_ALIVE, "1 m"); + configuration.add(IOCSymbols.THREAD_POOL_ENABLED, true); + configuration.add(IOCSymbols.THREAD_POOL_QUEUE_SIZE, 100); + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java deleted file mode 100644 index 80436b6..0000000 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright 2006-2012 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.tapestry5.ioc.services; - -import org.apache.tapestry5.func.Flow; -import org.apache.tapestry5.ioc.*; -import org.apache.tapestry5.ioc.annotations.*; -import org.apache.tapestry5.ioc.internal.services.*; -import org.apache.tapestry5.ioc.internal.services.cron.PeriodicExecutorImpl; -import org.apache.tapestry5.ioc.internal.util.CollectionFactory; -import org.apache.tapestry5.ioc.internal.util.InternalUtils; -import org.apache.tapestry5.ioc.modules.MetricsModule; -import org.apache.tapestry5.ioc.services.cron.PeriodicExecutor; -import org.apache.tapestry5.ioc.util.TimeInterval; -import org.apache.tapestry5.services.UpdateListenerHub; - -import java.io.File; -import java.lang.reflect.Array; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import static org.apache.tapestry5.ioc.OrderConstraintBuilder.after; -import static org.apache.tapestry5.ioc.OrderConstraintBuilder.before; - -/** - * Defines the base set of services for the Tapestry IOC container. - */ -@SuppressWarnings("all") -@Marker(Builtin.class) -@SubModule(MetricsModule.class) -public final class TapestryIOCModule -{ - public static void bind(ServiceBinder binder) - { - binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class); - binder.bind(ChainBuilder.class, ChainBuilderImpl.class); - binder.bind(PropertyAccess.class, PropertyAccessImpl.class); - binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class); - binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class); - binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class).preventReloading(); - binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class); - binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class); - binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class); - binder.bind(TypeCoercer.class, TypeCoercerImpl.class).preventReloading(); - binder.bind(ThreadLocale.class, ThreadLocaleImpl.class); - binder.bind(SymbolSource.class, SymbolSourceImpl.class); - binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults") - .withMarker(ApplicationDefaults.class); - binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults") - .withMarker(FactoryDefaults.class); - binder.bind(Runnable.class, RegistryStartup.class).withSimpleId(); - binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class).preventReloading(); - binder.bind(ClassNameLocator.class, ClassNameLocatorImpl.class); - binder.bind(ClasspathScanner.class, ClasspathScannerImpl.class); - binder.bind(AspectDecorator.class, AspectDecoratorImpl.class); - binder.bind(ClasspathURLConverter.class, ClasspathURLConverterImpl.class); - binder.bind(ServiceOverride.class, ServiceOverrideImpl.class); - binder.bind(LoggingAdvisor.class, LoggingAdvisorImpl.class); - binder.bind(LazyAdvisor.class, LazyAdvisorImpl.class); - binder.bind(ThunkCreator.class, ThunkCreatorImpl.class); - binder.bind(UpdateListenerHub.class, UpdateListenerHubImpl.class).preventReloading(); - binder.bind(PeriodicExecutor.class, PeriodicExecutorImpl.class); - binder.bind(OperationAdvisor.class, OperationAdvisorImpl.class); - } - - /** - * Provides access to additional service lifecycles. One lifecycle is built in ("singleton") but additional ones are - * accessed via this service (and its mapped configuration). Only proxiable services (those with explicit service - * interfaces) can be managed in terms of a lifecycle. - */ - @PreventServiceDecoration - public static ServiceLifecycleSource build(Map<String, ServiceLifecycle> configuration) - { - final Map<String, ServiceLifecycle2> lifecycles = CollectionFactory.newCaseInsensitiveMap(); - - for (String name : configuration.keySet()) - { - lifecycles.put(name, InternalUtils.toServiceLifecycle2(configuration.get(name))); - } - - return new ServiceLifecycleSource() - { - public ServiceLifecycle get(String scope) - { - return lifecycles.get(scope); - } - }; - } - - /** - * Contributes the "perthread" scope. - */ - @Contribute(ServiceLifecycleSource.class) - public static void providePerthreadScope(MappedConfiguration<String, ServiceLifecycle> configuration) - { - configuration.addInstance(ScopeConstants.PERTHREAD, PerThreadServiceLifecycle.class); - } - - /** - * <dl> - * <dt>AnnotationBasedContributions</dt> - * <dd>Empty placeholder used to separate annotation-based ObjectProvider contributions (which come before) from - * non-annotation based (such as ServiceOverride) which come after.</dd> - * <dt>Value</dt> - * <dd>Supports the {@link org.apache.tapestry5.ioc.annotations.Value} annotation</dd> - * <dt>Symbol</dt> - * <dd>Supports the {@link org.apache.tapestry5.ioc.annotations.Symbol} annotations</dd> - * <dt>Autobuild</dt> - * <dd>Supports the {@link org.apache.tapestry5.ioc.annotations.Autobuild} annotation</dd> - * <dt>ServiceOverride</dt> - * <dd>Allows simple service overrides via the {@link org.apache.tapestry5.ioc.services.ServiceOverride} service - * (and its configuration) - * </dl> - */ - @Contribute(MasterObjectProvider.class) - public static void setupObjectProviders(OrderedConfiguration<ObjectProvider> configuration, @Local - final ServiceOverride serviceOverride) - { - configuration.add("AnnotationBasedContributions", null); - - configuration.addInstance("Value", ValueObjectProvider.class, before("AnnotationBasedContributions").build()); - configuration.addInstance("Symbol", SymbolObjectProvider.class, before("AnnotationBasedContributions").build()); - configuration.add("Autobuild", new AutobuildObjectProvider(), before("AnnotationBasedContributions").build()); - - ObjectProvider wrapper = new ObjectProvider() - { - public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator) - { - return serviceOverride.getServiceOverrideProvider().provide(objectType, annotationProvider, locator); - } - }; - - configuration.add("ServiceOverride", wrapper, after("AnnotationBasedContributions").build()); - } - - /** - * Contributes a set of standard type coercions to the {@link TypeCoercer} service: - * <ul> - * <li>Object to String</li> - * <li>Object to Boolean</li> - * <li>String to Double</li> - * <li>String to BigDecimal</li> - * <li>BigDecimal to Double</li> - * <li>Double to BigDecimal</li> - * <li>String to BigInteger</li> - * <li>BigInteger to Long</li> - * <li>String to Long</li> - * <li>Long to Byte</li> - * <li>Long to Short</li> - * <li>Long to Integer</li> - * <li>Double to Long</li> - * <li>Double to Float</li> - * <li>Float to Double</li> - * <li>Long to Double</li> - * <li>String to Boolean ("false" is always false, other non-blank strings are true)</li> - * <li>Number to Boolean (true if number value is non zero)</li> - * <li>Null to Boolean (always false)</li> - * <li>Collection to Boolean (false if empty)</li> - * <li>Object[] to List</li> - * <li>primitive[] to List</li> - * <li>Object to List (by wrapping as a singleton list)</li> - * <li>String to File</li> - * <li>String to {@link org.apache.tapestry5.ioc.util.TimeInterval}</li> - * <li>{@link org.apache.tapestry5.ioc.util.TimeInterval} to Long</li> - * <li>Object to Object[] (wrapping the object as an array)</li> - * <li>Collection to Object[] (via the toArray() method) - * <li>{@link Flow} to List</li> - * <li>{@link Flow} to Boolean (false if empty)</li> - * </ul> - */ - @Contribute(TypeCoercer.class) - public static void provideBasicTypeCoercions(Configuration<CoercionTuple> configuration) - { - add(configuration, Object.class, String.class, new Coercion<Object, String>() - { - public String coerce(Object input) - { - return input.toString(); - } - }); - - add(configuration, Object.class, Boolean.class, new Coercion<Object, Boolean>() - { - public Boolean coerce(Object input) - { - return input != null; - } - }); - - add(configuration, String.class, Double.class, new Coercion<String, Double>() - { - public Double coerce(String input) - { - return new Double(input); - } - }); - - // String to BigDecimal is important, as String->Double->BigDecimal would lose - // precision. - - add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>() - { - public BigDecimal coerce(String input) - { - return new BigDecimal(input); - } - }); - - add(configuration, BigDecimal.class, Double.class, new Coercion<BigDecimal, Double>() - { - public Double coerce(BigDecimal input) - { - return input.doubleValue(); - } - }); - - add(configuration, String.class, BigInteger.class, new Coercion<String, BigInteger>() - { - public BigInteger coerce(String input) - { - return new BigInteger(input); - } - }); - - add(configuration, String.class, Long.class, new Coercion<String, Long>() - { - public Long coerce(String input) - { - return new Long(input); - } - }); - - add(configuration, Long.class, Byte.class, new Coercion<Long, Byte>() - { - public Byte coerce(Long input) - { - return input.byteValue(); - } - }); - - add(configuration, Long.class, Short.class, new Coercion<Long, Short>() - { - public Short coerce(Long input) - { - return input.shortValue(); - } - }); - - add(configuration, Long.class, Integer.class, new Coercion<Long, Integer>() - { - public Integer coerce(Long input) - { - return input.intValue(); - } - }); - - add(configuration, Number.class, Long.class, new Coercion<Number, Long>() - { - public Long coerce(Number input) - { - return input.longValue(); - } - }); - - add(configuration, Double.class, Float.class, new Coercion<Double, Float>() - { - public Float coerce(Double input) - { - return input.floatValue(); - } - }); - - add(configuration, Long.class, Double.class, new Coercion<Long, Double>() - { - public Double coerce(Long input) - { - return input.doubleValue(); - } - }); - - add(configuration, String.class, Boolean.class, new Coercion<String, Boolean>() - { - public Boolean coerce(String input) - { - String trimmed = input == null ? "" : input.trim(); - - if (trimmed.equalsIgnoreCase("false") || trimmed.length() == 0) - return false; - - // Any non-blank string but "false" - - return true; - } - }); - - add(configuration, Number.class, Boolean.class, new Coercion<Number, Boolean>() - { - public Boolean coerce(Number input) - { - return input.longValue() != 0; - } - }); - - add(configuration, Void.class, Boolean.class, new Coercion<Void, Boolean>() - { - public Boolean coerce(Void input) - { - return false; - } - }); - - add(configuration, Collection.class, Boolean.class, new Coercion<Collection, Boolean>() - { - public Boolean coerce(Collection input) - { - return !input.isEmpty(); - } - }); - - add(configuration, Object.class, List.class, new Coercion<Object, List>() - { - public List coerce(Object input) - { - return Collections.singletonList(input); - } - }); - - add(configuration, Object[].class, List.class, new Coercion<Object[], List>() - { - public List coerce(Object[] input) - { - return Arrays.asList(input); - } - }); - - add(configuration, Object[].class, Boolean.class, new Coercion<Object[], Boolean>() - { - public Boolean coerce(Object[] input) - { - return input != null && input.length > 0; - } - }); - - add(configuration, Float.class, Double.class, new Coercion<Float, Double>() - { - public Double coerce(Float input) - { - return input.doubleValue(); - } - }); - - Coercion primitiveArrayCoercion = new Coercion<Object, List>() - { - public List<Object> coerce(Object input) - { - int length = Array.getLength(input); - Object[] array = new Object[length]; - for (int i = 0; i < length; i++) - { - array[i] = Array.get(input, i); - } - return Arrays.asList(array); - } - }; - - add(configuration, byte[].class, List.class, primitiveArrayCoercion); - add(configuration, short[].class, List.class, primitiveArrayCoercion); - add(configuration, int[].class, List.class, primitiveArrayCoercion); - add(configuration, long[].class, List.class, primitiveArrayCoercion); - add(configuration, float[].class, List.class, primitiveArrayCoercion); - add(configuration, double[].class, List.class, primitiveArrayCoercion); - add(configuration, char[].class, List.class, primitiveArrayCoercion); - add(configuration, boolean[].class, List.class, primitiveArrayCoercion); - - add(configuration, String.class, File.class, new Coercion<String, File>() - { - public File coerce(String input) - { - return new File(input); - } - }); - - add(configuration, String.class, TimeInterval.class, new Coercion<String, TimeInterval>() - { - public TimeInterval coerce(String input) - { - return new TimeInterval(input); - } - }); - - add(configuration, TimeInterval.class, Long.class, new Coercion<TimeInterval, Long>() - { - public Long coerce(TimeInterval input) - { - return input.milliseconds(); - } - }); - - add(configuration, Object.class, Object[].class, new Coercion<Object, Object[]>() - { - public Object[] coerce(Object input) - { - return new Object[] - {input}; - } - }); - - add(configuration, Collection.class, Object[].class, new Coercion<Collection, Object[]>() - { - public Object[] coerce(Collection input) - { - return input.toArray(); - } - }); - - add(configuration, Flow.class, List.class, new Coercion<Flow, List>() - { - public List coerce(Flow input) - { - return input.toList(); - } - }); - - add(configuration, Flow.class, Boolean.class, new Coercion<Flow, Boolean>() - { - public Boolean coerce(Flow input) - { - return !input.isEmpty(); - } - }); - - } - - private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType, - Class<T> targetType, Coercion<S, T> coercion) - { - configuration.add(CoercionTuple.create(sourceType, targetType, coercion)); - } - - /** - * <dl> - * <dt>SystemProperties</dt> - * <dd>Exposes JVM System properties as symbols (currently case-sensitive)</dd> - * <dt>EnvironmentVariables</dt> - * <dd>Exposes environment variables as symbols (adding a "env." prefix)</dd> - * <dt>ApplicationDefaults</dt> - * <dd>Values contributed to @{@link SymbolProvider} @{@link ApplicationDefaults}</dd> - * <dt>FactoryDefaults</dt> - * <dd>Values contributed to @{@link SymbolProvider} @{@link FactoryDefaults}</dd> - * </dl> - */ - @Contribute(SymbolSource.class) - public static void setupStandardSymbolProviders(OrderedConfiguration<SymbolProvider> configuration, - @ApplicationDefaults - SymbolProvider applicationDefaults, - - @FactoryDefaults - SymbolProvider factoryDefaults) - { - configuration.add("SystemProperties", new SystemPropertiesSymbolProvider(), "before:*"); - configuration.add("EnvironmentVariables", new SystemEnvSymbolProvider()); - configuration.add("ApplicationDefaults", applicationDefaults); - configuration.add("FactoryDefaults", factoryDefaults); - } - - public static ParallelExecutor buildDeferredExecution(@Symbol(IOCSymbols.THREAD_POOL_CORE_SIZE) - int coreSize, - - @Symbol(IOCSymbols.THREAD_POOL_MAX_SIZE) - int maxSize, - - @Symbol(IOCSymbols.THREAD_POOL_KEEP_ALIVE) - @IntermediateType(TimeInterval.class) - int keepAliveMillis, - - @Symbol(IOCSymbols.THREAD_POOL_ENABLED) - boolean threadPoolEnabled, - - @Symbol(IOCSymbols.THREAD_POOL_QUEUE_SIZE) - int queueSize, - - PerthreadManager perthreadManager, - - RegistryShutdownHub shutdownHub, - - ThunkCreator thunkCreator) - { - - if (!threadPoolEnabled) - return new NonParallelExecutor(); - - LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(queueSize); - - final ThreadPoolExecutor executorService = new ThreadPoolExecutor(coreSize, maxSize, keepAliveMillis, - TimeUnit.MILLISECONDS, workQueue); - - shutdownHub.addRegistryShutdownListener(new Runnable() - { - public void run() - { - executorService.shutdown(); - } - }); - - return new ParallelExecutorImpl(executorService, thunkCreator, perthreadManager); - } - - @Contribute(SymbolProvider.class) - @FactoryDefaults - public static void setupDefaultSymbols(MappedConfiguration<String, Object> configuration) - { - configuration.add(IOCSymbols.THREAD_POOL_CORE_SIZE, 3); - configuration.add(IOCSymbols.THREAD_POOL_MAX_SIZE, 20); - configuration.add(IOCSymbols.THREAD_POOL_KEEP_ALIVE, "1 m"); - configuration.add(IOCSymbols.THREAD_POOL_ENABLED, true); - configuration.add(IOCSymbols.THREAD_POOL_QUEUE_SIZE, 100); - } -} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/metrics/MetricsSymbols.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/metrics/MetricsSymbols.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/metrics/MetricsSymbols.java new file mode 100644 index 0000000..39c9bb1 --- /dev/null +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/metrics/MetricsSymbols.java @@ -0,0 +1,10 @@ +package org.apache.tapestry5.ioc.services.metrics; + +public class MetricsSymbols +{ + /** + * The directory in which RRDb database files are stored. If blank (the default), + * then RRD is set up for in-memory databases only (re-created on each launch of the application). + */ + public static final String RRD_DB_DIR = "tapestry.rrd-dir"; +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/test/groovy/ioc/specs/OperationAdvisorSpec.groovy ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/OperationAdvisorSpec.groovy b/tapestry-ioc/src/test/groovy/ioc/specs/OperationAdvisorSpec.groovy index 819a4a7..3f2ef1b 100644 --- a/tapestry-ioc/src/test/groovy/ioc/specs/OperationAdvisorSpec.groovy +++ b/tapestry-ioc/src/test/groovy/ioc/specs/OperationAdvisorSpec.groovy @@ -5,10 +5,10 @@ import org.apache.tapestry5.ioc.internal.DefaultModuleDefImpl import org.apache.tapestry5.ioc.internal.LoggerSourceImpl import org.apache.tapestry5.ioc.internal.RegistryImpl import org.apache.tapestry5.ioc.internal.services.PlasticProxyFactoryImpl +import org.apache.tapestry5.ioc.modules.TapestryIOCModule import org.apache.tapestry5.ioc.services.OperationTrackedModule import org.apache.tapestry5.ioc.services.OperationTrackedService import org.apache.tapestry5.ioc.services.PlasticProxyFactory -import org.apache.tapestry5.ioc.services.TapestryIOCModule import spock.lang.AutoCleanup import spock.lang.Shared import spock.lang.Specification http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-ioc/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/resources/log4j.properties b/tapestry-ioc/src/test/resources/log4j.properties index 6a79bf8..80a5f2d 100644 --- a/tapestry-ioc/src/test/resources/log4j.properties +++ b/tapestry-ioc/src/test/resources/log4j.properties @@ -15,9 +15,9 @@ log4j.category.org.apache.tapestry5.ioc.FredModule=debug log4j.category.org.apache.tapestry5.ioc.AdviceDemoModule.Greeter=debug log4j.category.com.example=debug -log4j.category.org.apache.tapestry5.ioc.services.TapestryIOCModule.PeriodicExecutor=debug +log4j.category.org.apache.tapestry5.ioc.modules.TapestryIOCModule.PeriodicExecutor=debug # This makes things very verbose, but can be useful to figure what's happening and how long its taking. log4j.category.org.apache.tapestry5.ioc.Registry=debug -# log4j.category.org.apache.tapestry5.ioc.services.TapestryIOCModule.PlasticProxyFactory=debug +# log4j.category.org.apache.tapestry5.ioc.modules.TapestryIOCModule.PlasticProxyFactory=debug http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/233ff423/tapestry-mongodb/src/test/groovy/MongoDBSpec.groovy ---------------------------------------------------------------------- diff --git a/tapestry-mongodb/src/test/groovy/MongoDBSpec.groovy b/tapestry-mongodb/src/test/groovy/MongoDBSpec.groovy index c93a591..196bc54 100644 --- a/tapestry-mongodb/src/test/groovy/MongoDBSpec.groovy +++ b/tapestry-mongodb/src/test/groovy/MongoDBSpec.groovy @@ -8,7 +8,7 @@ import org.apache.tapestry5.internal.mongodb.MongoDBTestModule import org.apache.tapestry5.internal.mongodb.People import org.apache.tapestry5.ioc.Registry import org.apache.tapestry5.ioc.RegistryBuilder -import org.apache.tapestry5.ioc.services.TapestryIOCModule +import org.apache.tapestry5.ioc.modules.TapestryIOCModule import org.apache.tapestry5.mongodb.MongoDB import org.apache.tapestry5.mongodb.MongoDBSource import org.apache.tapestry5.mongodb.MongodbModule
