From c33ba2dea58e2d6a6b26317e1ea98262ecc213e6 Mon Sep 17 00:00:00 2001 From: markpollack Date: Mon, 2 Jun 2008 20:18:24 +0000 Subject: [PATCH] remove $Id keyword --- .../Aop/Config/AopNamespaceParser.cs | 109 +- .../Aop/Config/AopNamespaceUtils.cs | 197 +- .../Config/ConfigObjectDefinitionParser.cs | 315 +- .../Aop/Framework/AbstractMethodInvocation.cs | 697 +- .../AdvisorAdapterRegistrationManager.cs | 217 +- .../Adapter/AfterReturningAdviceAdapter.cs | 159 +- .../AfterReturningAdviceInterceptor.cs | 191 +- .../Framework/Adapter/BeforeAdviceAdapter.cs | 159 +- .../Adapter/DefaultAdvisorAdapterRegistry.cs | 309 +- .../Adapter/GlobalAdvisorAdapterRegistry.cs | 131 +- .../Aop/Framework/Adapter/IAdvisorAdapter.cs | 197 +- .../Adapter/IAdvisorAdapterRegistry.cs | 225 +- .../Adapter/MethodBeforeAdviceInterceptor.cs | 183 +- .../Framework/Adapter/ThrowsAdviceAdapter.cs | 157 +- .../Adapter/ThrowsAdviceInterceptor.cs | 635 +- .../Adapter/UnknownAdviceTypeException.cs | 207 +- .../Aop/Framework/AdvisedSupport.cs | 3123 +++++---- .../Aop/Framework/AdvisorChainFactoryUtils.cs | 241 +- .../Aop/Framework/AopConfigException.cs | 183 +- .../Spring.Aop/Aop/Framework/AopContext.cs | 341 +- .../Spring.Aop/Aop/Framework/AopUtils.cs | 541 +- .../AbstractAdvisorAutoProxyCreator.cs | 329 +- .../AutoProxy/AbstractAutoProxyCreator.cs | 1291 ++-- .../DefaultAdvisorAutoProxyCreator.cs | 393 +- .../AutoProxy/ITargetSourceCreator.cs | 103 +- .../AutoProxy/ObjectNameAutoProxyCreator.cs | 221 +- .../AbstractPrototypeTargetSourceCreator.cs | 212 +- .../Aop/Framework/DynamicMethodInvocation.cs | 249 +- .../AbstractAopProxyMethodBuilder.cs | 1575 +++-- .../AbstractAopProxyTypeBuilder.cs | 209 +- .../Framework/DynamicProxy/AdvisedProxy.cs | 861 ++- .../DynamicProxy/BaseAopProxyMethodBuilder.cs | 261 +- .../DynamicProxy/BaseCompositionAopProxy.cs | 241 +- .../DynamicProxy/CachedAopProxyFactory.cs | 365 +- .../CompositionAopProxyTypeBuilder.cs | 423 +- .../DecoratorAopProxyTypeBuilder.cs | 631 +- .../DynamicProxy/DefaultAopProxyFactory.cs | 217 +- .../IAdvisedProxyMethodBuilder.cs | 165 +- .../DynamicProxy/IAopProxyTypeGenerator.cs | 93 +- .../InheritanceAopProxyTypeBuilder.cs | 791 ++- .../IntroductionProxyMethodBuilder.cs | 233 +- .../TargetAopProxyMethodBuilder.cs | 303 +- .../Framework/DynamicTargetSourceWrapper.cs | 195 +- .../HashtableCachingAdvisorChainFactory.cs | 205 +- .../Spring.Aop/Aop/Framework/IAdvised.cs | 997 ++- .../Aop/Framework/IAdvisedSupportListener.cs | 129 +- .../Aop/Framework/IAdvisorChainFactory.cs | 117 +- .../Spring.Aop/Aop/Framework/IAopProxy.cs | 87 +- .../Aop/Framework/IAopProxyFactory.cs | 91 +- .../Spring.Aop/Aop/Framework/ITargetAware.cs | 89 +- .../Aop/Framework/ITargetSourceWrapper.cs | 75 +- .../InterceptorAndDynamicMethodMatcher.cs | 93 +- .../Spring.Aop/Aop/Framework/ProxyConfig.cs | 441 +- .../Spring.Aop/Aop/Framework/ProxyFactory.cs | 255 +- .../Aop/Framework/ProxyFactoryObject.cs | 1833 +++-- .../Framework/ReflectiveMethodInvocation.cs | 259 +- .../Framework/StaticTargetSourceWrapper.cs | 173 +- src/Spring/Spring.Aop/Aop/IAdvisor.cs | 189 +- src/Spring/Spring.Aop/Aop/IAdvisors.cs | 91 +- .../Spring.Aop/Aop/IAfterReturningAdvice.cs | 153 +- src/Spring/Spring.Aop/Aop/IBeforeAdvice.cs | 107 +- .../Spring.Aop/Aop/IIntroductionAdvisor.cs | 183 +- .../Aop/IIntroductionInterceptor.cs | 121 +- .../Spring.Aop/Aop/IMethodBeforeAdvice.cs | 143 +- src/Spring/Spring.Aop/Aop/IMethodMatcher.cs | 299 +- src/Spring/Spring.Aop/Aop/IPointcut.cs | 119 +- src/Spring/Spring.Aop/Aop/IPointcutAdvisor.cs | 97 +- src/Spring/Spring.Aop/Aop/ITargetSource.cs | 157 +- src/Spring/Spring.Aop/Aop/IThrowsAdvice.cs | 119 +- src/Spring/Spring.Aop/Aop/ITypeFilter.cs | 115 +- .../Support/AbstractGenericPointcutAdvisor.cs | 125 +- .../AbstractObjectFactoryPointcutAdvisor.cs | 271 +- .../Aop/Support/AbstractPointcutAdvisor.cs | 329 +- ...AbstractRegularExpressionMethodPointcut.cs | 548 +- .../Support/AttributeMatchMethodPointcut.cs | 405 +- .../AttributeMatchMethodPointcutAdvisor.cs | 233 +- .../Aop/Support/ComposablePointcut.cs | 349 +- .../Aop/Support/ControlFlowPointcut.cs | 485 +- .../Aop/Support/DefaultIntroductionAdvisor.cs | 479 +- .../DefaultObjectFactoryPointcutAdvisor.cs | 117 +- .../Aop/Support/DefaultPointcutAdvisor.cs | 219 +- .../Aop/Support/DynamicMethodMatcher.cs | 225 +- .../DynamicMethodMatcherPointcutAdvisor.cs | 349 +- .../Spring.Aop/Aop/Support/MethodMatchers.cs | 359 +- .../Aop/Support/NameMatchMethodPointcut.cs | 241 +- .../Support/NameMatchMethodPointcutAdvisor.cs | 257 +- .../Spring.Aop/Aop/Support/Pointcuts.cs | 289 +- .../RegularExpressionMethodPointcutAdvisor.cs | 278 +- .../Spring.Aop/Aop/Support/RootTypeFilter.cs | 157 +- .../SdkRegularExpressionMethodPointcut.cs | 412 +- .../Aop/Support/StaticMethodMatcher.cs | 203 +- .../Support/StaticMethodMatcherPointcut.cs | 167 +- .../StaticMethodMatcherPointcutAdvisor.cs | 265 +- .../Spring.Aop/Aop/Support/TypeFilters.cs | 313 +- .../Spring.Aop/Aop/Support/UnionPointcut.cs | 245 +- .../Aop/Target/AbstractPoolingTargetSource.cs | 405 +- .../Target/AbstractPrototypeTargetSource.cs | 473 +- .../Aop/Target/EmptyTargetSource.cs | 321 +- .../Aop/Target/HotSwappableTargetSource.cs | 341 +- .../Target/IThreadLocalTargetSourceStats.cs | 125 +- .../Spring.Aop/Aop/Target/PoolingConfig.cs | 101 +- .../Aop/Target/PrototypeTargetSource.cs | 156 +- .../Aop/Target/SimplePoolTargetSource.cs | 414 +- .../Aop/Target/SingletonTargetSource.cs | 321 +- .../Aop/Target/ThreadLocalTargetSource.cs | 485 +- .../Spring.Aop/Aop/TrueMethodMatcher.cs | 309 +- src/Spring/Spring.Aop/Aop/TruePointcut.cs | 242 +- src/Spring/Spring.Aop/Aop/TrueTypeFilter.cs | 245 +- .../AopAlliance/Aop/AspectException.cs | 157 +- .../Spring.Aop/AopAlliance/Aop/IAdvice.cs | 62 +- .../Intercept/IConstructorInterceptor.cs | 106 +- .../Intercept/IConstructorInvocation.cs | 100 +- .../AopAlliance/Intercept/IInterceptor.cs | 78 +- .../AopAlliance/Intercept/IInvocation.cs | 90 +- .../AopAlliance/Intercept/IJoinpoint.cs | 174 +- .../Intercept/IMethodInterceptor.cs | 110 +- .../Intercept/IMethodInvocation.cs | 152 +- .../Aspects/AbstractExceptionHandler.cs | 365 +- .../Aspects/AbstractExceptionHandlerAdvice.cs | 311 +- .../Aspects/Cache/BaseCacheAdvice.cs | 317 +- .../Spring.Aop/Aspects/Cache/CacheAspect.cs | 211 +- .../Aspects/Cache/CacheParameterAdvice.cs | 223 +- .../Aspects/Cache/CacheParameterAdvisor.cs | 223 +- .../Aspects/Cache/CacheResultAdvice.cs | 441 +- .../Aspects/Cache/CacheResultAdvisor.cs | 203 +- .../Aspects/Cache/InvalidateCacheAdvice.cs | 239 +- .../Aspects/Cache/InvalidateCacheAdvisor.cs | 161 +- .../Exceptions/ExceptionHandlerAdvice.cs | 779 ++- .../Aspects/Exceptions/LogExceptionHandler.cs | 179 +- .../Exceptions/ReturnValueExceptionHandler.cs | 141 +- .../Exceptions/SwallowExceptionHandler.cs | 113 +- .../Exceptions/TranslationExceptionHandler.cs | 157 +- .../Spring.Aop/Aspects/IExceptionHandler.cs | 191 +- .../Aspects/Logging/AbstractLoggingAdvice.cs | 477 +- .../Aspects/Logging/SimpleLoggingAdvice.cs | 915 ++- .../Aspects/ParsedAdviceExpression.cs | 227 +- src/Spring/Spring.Aop/Aspects/RetryAdvice.cs | 629 +- .../Aspects/RetryExceptionHandler.cs | 257 +- .../Validation/ParameterValidationAdvice.cs | 149 +- .../Validation/ParameterValidationAdvisor.cs | 225 +- src/Spring/Spring.Core/AssemblyInfo.cs | 66 +- .../Spring.Core/Caching/AbstractCache.cs | 401 +- .../Spring.Core/Caching/BaseCacheAttribute.cs | 349 +- .../Caching/CacheParameterAttribute.cs | 141 +- .../Caching/CacheResultAttribute.cs | 135 +- .../Caching/CacheResultItemsAttribute.cs | 137 +- src/Spring/Spring.Core/Caching/ICache.cs | 213 +- .../Caching/InvalidateCacheAttribute.cs | 289 +- .../Spring.Core/Caching/NonExpiringCache.cs | 283 +- .../Spring.Core/Collections/AbstractQueue.cs | 691 +- .../Spring.Core/Collections/DictionarySet.cs | 785 ++- .../Spring.Core/Collections/HashedSet.cs | 131 +- .../Spring.Core/Collections/HybridSet.cs | 149 +- src/Spring/Spring.Core/Collections/IQueue.cs | 463 +- src/Spring/Spring.Core/Collections/ISet.cs | 547 +- .../Spring.Core/Collections/ImmutableSet.cs | 711 +- .../Spring.Core/Collections/LinkedList.cs | 1087 ++- src/Spring/Spring.Core/Collections/ListSet.cs | 140 +- .../Collections/NoElementsException.cs | 179 +- .../Spring.Core/Collections/PriorityQueue.cs | 1664 ++--- src/Spring/Spring.Core/Collections/Set.cs | 1133 ++- .../Spring.Core/Collections/SortedSet.cs | 155 +- .../SynchronizedDictionaryEnumerator.cs | 149 +- .../Collections/SynchronizedEnumerator.cs | 135 +- .../Collections/SynchronizedHashtable.cs | 731 +- .../Collections/SynchronizedSet.cs | 659 +- .../Context/ApplicationContextException.cs | 173 +- .../Context/ApplicationEventArgs.cs | 141 +- .../Context/EventListenerAttribute.cs | 87 +- .../Context/Events/ConsoleListener.cs | 129 +- .../Context/Events/ContextEventArgs.cs | 165 +- .../Context/IApplicationContext.cs | 325 +- .../Context/IApplicationContextAware.cs | 196 +- .../Context/IApplicationEventListener.cs | 93 +- .../Context/IApplicationEventPublisher.cs | 95 +- .../IConfigurableApplicationContext.cs | 261 +- .../Context/IHierarchicalMessageSource.cs | 89 +- .../Spring.Core/Context/IMessageSource.cs | 613 +- .../Context/IMessageSourceAware.cs | 157 +- .../Context/IMessageSourceResolvable.cs | 157 +- .../Context/IResourceLoaderAware.cs | 165 +- .../Context/NoSuchMessageException.cs | 227 +- .../Support/AbstractApplicationContext.cs | 3505 +++++----- .../Context/Support/AbstractMessageSource.cs | 1231 ++-- .../Support/AbstractXmlApplicationContext.cs | 583 +- .../ApplicationContextAwareProcessor.cs | 295 +- .../Support/ApplicationObjectSupport.cs | 417 +- .../Context/Support/ContextHandler.cs | 1281 ++-- .../Context/Support/ContextRegistry.cs | 571 +- .../Support/DefaultMessageSourceResolvable.cs | 451 +- .../Context/Support/DefaultSectionHandler.cs | 127 +- .../Support/DelegatingMessageSource.cs | 771 ++- .../Support/GenericApplicationContext.cs | 515 +- .../Context/Support/MessageSourceAccessor.cs | 373 +- .../Support/MessageSourceResolvableVisitor.cs | 191 +- .../Support/NamespaceParsersSectionHandler.cs | 277 +- .../Context/Support/NullMessageSource.cs | 231 +- .../Support/ResourceHandlersSectionHandler.cs | 271 +- .../Support/ResourceSetMessageSource.cs | 473 +- .../Support/StaticApplicationContext.cs | 203 +- .../Context/Support/StaticMessageSource.cs | 401 +- .../Support/TypeAliasesSectionHandler.cs | 257 +- .../Support/TypeConvertersSectionHandler.cs | 293 +- .../Context/Support/XmlApplicationContext.cs | 467 +- .../Core/CannotLoadObjectTypeException.cs | 357 +- .../Spring.Core/Core/ComposedCriteria.cs | 230 +- .../Spring.Core/Core/ControlFlowFactory.cs | 299 +- src/Spring/Spring.Core/Core/Conventions.cs | 139 +- .../Spring.Core/Core/CriteriaMemberFilter.cs | 159 +- src/Spring/Spring.Core/Core/IControlFlow.cs | 155 +- src/Spring/Spring.Core/Core/ICriteria.cs | 101 +- src/Spring/Spring.Core/Core/IErrorCoded.cs | 117 +- .../Spring.Core/Core/IO/AbstractResource.cs | 1525 ++--- .../Spring.Core/Core/IO/AssemblyResource.cs | 541 +- .../Core/IO/ConfigSectionResource.cs | 405 +- .../Core/IO/ConfigurableResourceLoader.cs | 391 +- .../Spring.Core/Core/IO/FileSystemResource.cs | 785 ++- .../Spring.Core/Core/IO/IInputStreamSource.cs | 135 +- src/Spring/Spring.Core/Core/IO/IResource.cs | 389 +- .../Spring.Core/Core/IO/IResourceLoader.cs | 187 +- .../Core/IO/InputStreamResource.cs | 287 +- .../Spring.Core/Core/IO/ResourceConverter.cs | 427 +- .../Core/IO/ResourceHandlerRegistry.cs | 525 +- src/Spring/Spring.Core/Core/IO/UrlResource.cs | 535 +- src/Spring/Spring.Core/Core/IOrdered.cs | 129 +- .../Core/InvalidPropertyException.cs | 425 +- .../MethodGenericArgumentsCountCriteria.cs | 279 +- .../Core/MethodInvocationException.cs | 236 +- .../Core/MethodNameMatchCriteria.cs | 261 +- .../Core/MethodParametersCountCriteria.cs | 293 +- .../Core/MethodParametersCriteria.cs | 357 +- .../Core/MethodReturnTypeCriteria.cs | 239 +- .../Core/NotReadablePropertyException.cs | 229 +- .../Core/NotWritablePropertyException.cs | 293 +- .../Core/NullValueInNestedPathException.cs | 341 +- .../Spring.Core/Core/OrderComparator.cs | 161 +- .../Core/PropertyAccessException.cs | 315 +- .../Core/PropertyChangeEventArgs.cs | 164 +- .../Core/RegularExpressionCriteria.cs | 283 +- .../RegularExpressionEventNameCriteria.cs | 203 +- .../RegularExpressionMethodNameCriteria.cs | 203 +- .../TypeConversion/CredentialConverter.cs | 247 +- .../TypeConversion/CustomNumberConverter.cs | 373 +- .../Core/TypeConversion/FileInfoConverter.cs | 216 +- .../Core/TypeConversion/NameValueConverter.cs | 315 +- .../Core/TypeConversion/RGBColorConverter.cs | 337 +- .../Core/TypeConversion/RegexConverter.cs | 181 +- .../TypeConversion/RegistryKeyConverter.cs | 325 +- .../ResourceManagerConverter.cs | 316 +- .../TypeConversion/RuntimeTypeConverter.cs | 349 +- .../Core/TypeConversion/StreamConverter.cs | 252 +- .../TypeConversion/StringArrayConverter.cs | 363 +- .../Core/TypeConversion/TimeSpanConverter.cs | 217 +- .../TypeConversion/TypeConversionUtils.cs | 419 +- .../TypeConversion/TypeConverterRegistry.cs | 331 +- .../Core/TypeConversion/UniqueKeyConverter.cs | 321 +- .../Core/TypeConversion/UriConverter.cs | 227 +- .../Spring.Core/Core/TypeMismatchException.cs | 313 +- .../Core/TypeResolution/CachedTypeResolver.cs | 249 +- .../TypeResolution/GenericArgumentsHolder.cs | 446 +- .../TypeResolution/GenericTypeResolver.cs | 201 +- .../Core/TypeResolution/ITypeResolver.cs | 123 +- .../Core/TypeResolution/TypeAssemblyHolder.cs | 234 +- .../Core/TypeResolution/TypeRegistry.cs | 1367 ++-- .../TypeResolution/TypeResolutionUtils.cs | 427 +- .../Core/TypeResolution/TypeResolver.cs | 337 +- .../DataBinding/AbstractBinding.cs | 359 +- .../DataBinding/AbstractSimpleBinding.cs | 503 +- .../DataBinding/BaseBindingContainer.cs | 521 +- .../DataBinding/BaseBindingManager.cs | 89 +- .../DataBinding/BindingDirection.cs | 95 +- .../Spring.Core/DataBinding/IBinding.cs | 173 +- .../DataBinding/IBindingContainer.cs | 237 +- .../Spring.Core/DataBinding/IDataBound.cs | 71 +- .../Spring.Core/DataBinding/ListBinding.cs | 147 +- .../DataBinding/SimpleExpressionBinding.cs | 347 +- .../Expressions/ArrayConstructorNode.cs | 199 +- .../Spring.Core/Expressions/AssignNode.cs | 159 +- .../Spring.Core/Expressions/AttributeNode.cs | 167 +- .../Spring.Core/Expressions/BaseNode.cs | 531 +- .../Spring.Core/Expressions/BinaryOperator.cs | 127 +- .../Expressions/BooleanLiteralNode.cs | 145 +- .../Expressions/ConstructorNode.cs | 415 +- .../Expressions/DateLiteralNode.cs | 167 +- .../Spring.Core/Expressions/DefaultNode.cs | 123 +- .../Spring.Core/Expressions/Expression.cs | 567 +- .../Expressions/ExpressionConverter.cs | 171 +- .../Expressions/ExpressionEvaluator.cs | 193 +- .../Expressions/ExpressionListNode.cs | 135 +- .../Spring.Core/Expressions/FunctionNode.cs | 183 +- .../Spring.Core/Expressions/HexLiteralNode.cs | 161 +- .../Spring.Core/Expressions/IExpression.cs | 137 +- .../Spring.Core/Expressions/IndexerNode.cs | 585 +- .../Spring.Core/Expressions/IntLiteralNode.cs | 159 +- .../Expressions/LambdaExpressionNode.cs | 273 +- .../Expressions/ListInitializerNode.cs | 123 +- .../Expressions/LocalFunctionNode.cs | 167 +- .../Expressions/LocalVariableNode.cs | 171 +- .../Spring.Core/Expressions/MapEntryNode.cs | 125 +- .../Expressions/MapInitializerNode.cs | 141 +- .../Spring.Core/Expressions/MethodNode.cs | 573 +- .../Expressions/NamedArgumentNode.cs | 117 +- .../Expressions/NodeWithArguments.cs | 349 +- .../Expressions/NullLiteralNode.cs | 117 +- src/Spring/Spring.Core/Expressions/OpADD.cs | 237 +- src/Spring/Spring.Core/Expressions/OpAND.cs | 119 +- .../Spring.Core/Expressions/OpBetween.cs | 147 +- .../Spring.Core/Expressions/OpDIVIDE.cs | 149 +- src/Spring/Spring.Core/Expressions/OpEqual.cs | 185 +- .../Spring.Core/Expressions/OpGreater.cs | 125 +- .../Expressions/OpGreaterOrEqual.cs | 125 +- src/Spring/Spring.Core/Expressions/OpIn.cs | 161 +- src/Spring/Spring.Core/Expressions/OpIs.cs | 135 +- src/Spring/Spring.Core/Expressions/OpLess.cs | 125 +- .../Spring.Core/Expressions/OpLessOrEqual.cs | 127 +- src/Spring/Spring.Core/Expressions/OpLike.cs | 143 +- .../Spring.Core/Expressions/OpMODULUS.cs | 147 +- .../Spring.Core/Expressions/OpMULTIPLY.cs | 249 +- .../Spring.Core/Expressions/OpMatches.cs | 153 +- src/Spring/Spring.Core/Expressions/OpNOT.cs | 117 +- .../Spring.Core/Expressions/OpNotEqual.cs | 169 +- src/Spring/Spring.Core/Expressions/OpOR.cs | 119 +- src/Spring/Spring.Core/Expressions/OpPOWER.cs | 147 +- .../Spring.Core/Expressions/OpSUBTRACT.cs | 281 +- .../Spring.Core/Expressions/OpUnaryMinus.cs | 133 +- .../Spring.Core/Expressions/OpUnaryPlus.cs | 133 +- .../Processors/AverageAggregator.cs | 137 +- .../Processors/ConversionProcessor.cs | 175 +- .../Expressions/Processors/CountAggregator.cs | 107 +- .../Processors/DistinctProcessor.cs | 165 +- .../Processors/ICollectionProcessor.cs | 90 +- .../Expressions/Processors/MaxAggregator.cs | 115 +- .../Expressions/Processors/MinAggregator.cs | 115 +- .../Processors/NonNullProcessor.cs | 121 +- .../Processors/OrderByProcessor.cs | 329 +- .../Processors/ReverseProcessor.cs | 121 +- .../Expressions/Processors/SortProcessor.cs | 191 +- .../Expressions/Processors/SumAggregator.cs | 133 +- .../Spring.Core/Expressions/ProjectionNode.cs | 155 +- .../Expressions/PropertyOrFieldNode.cs | 1447 ++-- .../Expressions/QualifiedIdentifier.cs | 193 +- .../Expressions/RealLiteralNode.cs | 187 +- .../Spring.Core/Expressions/ReferenceNode.cs | 189 +- .../Expressions/SelectionFirstNode.cs | 159 +- .../Expressions/SelectionLastNode.cs | 163 +- .../Spring.Core/Expressions/SelectionNode.cs | 207 +- .../Spring.Core/Expressions/SpringAST.cs | 302 +- .../Expressions/StringLiteralNode.cs | 117 +- .../Spring.Core/Expressions/TernaryNode.cs | 179 +- .../Spring.Core/Expressions/TypeNode.cs | 165 +- .../Spring.Core/Expressions/UnaryOperator.cs | 111 +- .../Spring.Core/Expressions/VariableNode.cs | 177 +- .../Globalization/AbstractLocalizer.cs | 245 +- .../Globalization/AbstractResourceCache.cs | 161 +- .../Formatters/BooleanFormatter.cs | 291 +- .../Formatters/CurrencyFormatter.cs | 417 +- .../Formatters/DateTimeFormatter.cs | 239 +- .../Formatters/FilteringFormatter.cs | 199 +- .../Formatters/FloatFormatter.cs | 261 +- .../Formatters/HasTextFilteringFormatter.cs | 155 +- .../Formatters/IntegerFormatter.cs | 193 +- .../Globalization/Formatters/NullFormatter.cs | 129 +- .../Formatters/NumberFormatter.cs | 397 +- .../Formatters/PercentFormatter.cs | 465 +- .../Globalization/ICultureResolver.cs | 139 +- .../Spring.Core/Globalization/IFormatter.cs | 99 +- .../Spring.Core/Globalization/ILocalizer.cs | 119 +- .../Globalization/IResourceCache.cs | 97 +- .../Localizers/ResourceSetLocalizer.cs | 221 +- .../Globalization/NullResourceCache.cs | 97 +- .../Resolvers/DefaultCultureResolver.cs | 243 +- .../Spring.Core/Globalization/Resource.cs | 133 +- .../Objects/Events/IEventRegistry.cs | 115 +- .../Objects/Events/IEventRegistryAware.cs | 125 +- .../Events/Support/EventManipulationUtils.cs | 237 +- .../Objects/Events/Support/EventRegistry.cs | 247 +- .../Factory/Attributes/RequiredAttribute.cs | 77 +- .../RequiredAttributeObjectPostProcessor.cs | 369 +- .../Factory/Config/AbstractConfigurer.cs | 243 +- .../Factory/Config/AbstractFactoryObject.cs | 325 +- .../Objects/Factory/Config/AutoWiringMode.cs | 119 +- .../Config/CommandLineArgsVariableSource.cs | 253 +- .../Config/ConfigSectionVariableSource.cs | 269 +- .../Factory/Config/ConfigurationReader.cs | 691 +- .../Config/ConnectionStringsVariableSource.cs | 189 +- .../Config/ConstructorArgumentValues.cs | 1315 ++-- .../Config/CustomConverterConfigurer.cs | 605 +- .../Factory/Config/DelegateFactoryObject.cs | 355 +- .../Factory/Config/DictionaryFactoryObject.cs | 261 +- .../Factory/Config/EnvironmentVariableMode.cs | 101 +- .../Config/EnvironmentVariableSource.cs | 93 +- .../Objects/Factory/Config/EventValues.cs | 301 +- .../Factory/Config/ExpressionHolder.cs | 219 +- .../Config/FieldRetrievingFactoryObject.cs | 619 +- .../Config/IAutowireCapableObjectFactory.cs | 268 +- .../Config/IConfigurableFactoryObject.cs | 83 +- .../IConfigurableListableObjectFactory.cs | 246 +- .../Config/IConfigurableObjectFactory.cs | 469 +- .../IDestructionAwareObjectPostProcessor.cs | 111 +- .../IInstantiationAwareObjectPostProcessor.cs | 249 +- .../Factory/Config/IObjectDefinition.cs | 413 +- .../Config/IObjectFactoryPostProcessor.cs | 144 +- .../Factory/Config/IObjectPostProcessor.cs | 195 +- .../Objects/Factory/Config/IVariableSource.cs | 117 +- ...ntiationAwareObjectPostProcessorAdapter.cs | 445 +- .../Factory/Config/ListFactoryObject.cs | 259 +- .../Factory/Config/LogFactoryObject.cs | 339 +- .../Config/MethodInvokingFactoryObject.cs | 539 +- .../Factory/Config/ObjectDefinitionHolder.cs | 271 +- .../Factory/Config/ObjectDefinitionVisitor.cs | 757 +- .../ObjectFactoryCreatingFactoryObject.cs | 353 +- .../Config/ObjectReferenceFactoryObject.cs | 265 +- .../Config/PropertyFileVariableSource.cs | 201 +- .../Config/PropertyOverrideConfigurer.cs | 403 +- .../Config/PropertyPathFactoryObject.cs | 671 +- .../Config/PropertyPlaceholderConfigurer.cs | 825 ++- .../Config/PropertyResourceConfigurer.cs | 783 ++- .../Config/PropertyRetrievingFactoryObject.cs | 601 +- .../Factory/Config/RegistryVariableSource.cs | 165 +- .../Config/ResourceHandlerConfigurer.cs | 203 +- .../Config/ResourceManagerFactoryObject.cs | 307 +- .../Factory/Config/RuntimeObjectReference.cs | 258 +- .../Factory/Config/SetFactoryObject.cs | 245 +- ...rtInstantiationAwareObjectPostProcessor.cs | 123 +- .../Config/SpecialFolderVariableSource.cs | 117 +- .../Factory/Config/TypeAliasConfigurer.cs | 209 +- .../Factory/Config/TypedStringValue.cs | 283 +- .../Factory/Config/VariableAccessor.cs | 1573 +++-- .../Config/VariablePlaceholderConfigurer.cs | 629 +- .../FactoryObjectNotInitializedException.cs | 247 +- .../Objects/Factory/IFactoryObject.cs | 165 +- .../Objects/Factory/IGenericObjectFactory.cs | 103 +- .../Factory/IHierarchicalObjectFactory.cs | 93 +- .../Objects/Factory/IInitializingObject.cs | 159 +- .../Objects/Factory/IListableObjectFactory.cs | 431 +- .../Factory/IObjectDefinitionFactory.cs | 135 +- .../Objects/Factory/IObjectFactory.cs | 979 ++- .../Objects/Factory/IObjectFactoryAware.cs | 141 +- .../Objects/Factory/IObjectNameAware.cs | 136 +- .../NoSuchObjectDefinitionException.cs | 387 +- .../Factory/ObjectCreationException.cs | 663 +- .../ObjectCurrentlyInCreationException.cs | 365 +- .../Factory/ObjectDefinitionException.cs | 268 +- .../Factory/ObjectDefinitionStoreException.cs | 518 +- .../Objects/Factory/ObjectFactoryUtils.cs | 931 ++- .../Factory/ObjectInitializationException.cs | 196 +- .../Factory/ObjectIsNotAFactoryException.cs | 229 +- .../ObjectNotOfRequiredTypeException.cs | 370 +- .../Objects/Factory/Parsing/ReaderContext.cs | 111 +- .../AbstractAutowireCapableObjectFactory.cs | 4869 +++++++------ .../Factory/Support/AbstractMethodReplacer.cs | 255 +- .../Support/AbstractObjectDefinition.cs | 1491 ++-- .../Support/AbstractObjectDefinitionReader.cs | 541 +- .../Factory/Support/AbstractObjectFactory.cs | 3953 ++++++----- .../Objects/Factory/Support/AutowireUtils.cs | 569 +- .../Factory/Support/ChildObjectDefinition.cs | 508 +- .../Support/DefaultListableObjectFactory.cs | 1783 +++-- .../Support/DefaultObjectDefinitionFactory.cs | 225 +- .../Support/DefaultObjectNameGenerator.cs | 123 +- .../Support/DelegatingMethodReplacer.cs | 181 +- .../Factory/Support/DependencyCheckingMode.cs | 116 +- .../Support/IConfigurableObjectDefinition.cs | 391 +- .../Factory/Support/IInstantiationStrategy.cs | 235 +- .../Factory/Support/IManagedCollection.cs | 327 +- .../Factory/Support/IMethodReplacer.cs | 141 +- .../Support/IObjectDefinitionReader.cs | 253 +- .../Support/IObjectDefinitionRegistry.cs | 322 +- .../Factory/Support/IObjectNameGenerator.cs | 85 +- .../Factory/Support/LookupMethodOverride.cs | 229 +- .../Factory/Support/LookupMethodReplacer.cs | 175 +- .../Factory/Support/ManagedDictionary.cs | 339 +- .../Objects/Factory/Support/ManagedList.cs | 265 +- .../Objects/Factory/Support/ManagedSet.cs | 222 +- .../MethodInjectingInstantiationStrategy.cs | 1231 ++-- .../Objects/Factory/Support/MethodOverride.cs | 245 +- .../Factory/Support/MethodOverrides.cs | 397 +- .../Support/ObjectDefinitionBuilder.cs | 745 +- .../Support/ObjectDefinitionReaderUtils.cs | 511 +- .../ObjectDefinitionValidationException.cs | 186 +- .../PropertiesObjectDefinitionReader.cs | 1034 +-- .../Factory/Support/ReplacedMethodOverride.cs | 317 +- .../Factory/Support/RootObjectDefinition.cs | 583 +- .../Support/SimpleInstantiationStrategy.cs | 613 +- .../Support/StaticListableObjectFactory.cs | 1381 ++-- .../Factory/UnsatisfiedDependencyException.cs | 317 +- .../Xml/AbstractObjectDefinitionParser.cs | 423 +- .../AbstractSimpleObjectDefinitionParser.cs | 71 +- .../AbstractSingleObjectDefinitionParser.cs | 283 +- .../DefaultObjectDefinitionDocumentReader.cs | 679 +- .../Factory/Xml/DocumentDefaultsDefinition.cs | 132 +- .../Objects/Factory/Xml/INamespaceParser.cs | 197 +- .../Xml/IObjectDefinitionDocumentReader.cs | 112 +- .../Factory/Xml/IObjectDefinitionParser.cs | 117 +- .../Factory/Xml/NamespaceParserAttribute.cs | 199 +- .../Factory/Xml/NamespaceParserRegistry.cs | 571 +- .../Factory/Xml/NamespaceParserSupport.cs | 239 +- .../Factory/Xml/ObjectDefinitionConstants.cs | 1541 +++-- .../Xml/ObjectDefinitionParserHelper.cs | 419 +- .../Xml/ObjectFactorySectionHandler.cs | 181 +- .../Factory/Xml/ObjectsNamespaceParser.cs | 2839 ++++---- .../Objects/Factory/Xml/ParserContext.cs | 256 +- .../Factory/Xml/XmlObjectDefinitionReader.cs | 655 +- .../Xml/XmlObjectDefinitionStoreException.cs | 240 +- .../Objects/Factory/Xml/XmlObjectFactory.cs | 297 +- .../Objects/Factory/Xml/XmlReaderContext.cs | 477 +- .../Objects/FatalObjectException.cs | 178 +- .../Spring.Core/Objects/IEventHandlerValue.cs | 143 +- .../Spring.Core/Objects/IObjectWrapper.cs | 414 +- .../Spring.Core/Objects/IPropertyValues.cs | 179 +- .../Objects/MutablePropertyValues.cs | 693 +- .../Spring.Core/Objects/ObjectWrapper.cs | 1091 ++- .../Spring.Core/Objects/ObjectsException.cs | 176 +- .../PropertyAccessExceptionsException.cs | 515 +- .../Spring.Core/Objects/PropertyValue.cs | 395 +- .../Support/AbstractEventHandlerValue.cs | 305 +- .../AbstractWiringEventHandlerValue.cs | 315 +- .../ArgumentConvertingMethodInvoker.cs | 237 +- .../Support/AutoWiringEventHandlerValue.cs | 639 +- .../Objects/Support/ISortDefinition.cs | 132 +- .../Support/InstanceEventHandlerValue.cs | 229 +- .../Objects/Support/MethodInvoker.cs | 1107 ++- .../Objects/Support/MutableSortDefinition.cs | 434 +- .../Objects/Support/PropertyComparator.cs | 393 +- .../Support/StaticEventHandlerValue.cs | 195 +- src/Spring/Spring.Core/Pool/IObjectPool.cs | 299 +- .../Pool/IPoolableObjectFactory.cs | 247 +- src/Spring/Spring.Core/Pool/PoolException.cs | 159 +- .../Spring.Core/Pool/Support/SimplePool.cs | 587 +- .../Proxy/AbstractProxyMethodBuilder.cs | 1 - .../Proxy/AbstractProxyTypeBuilder.cs | 1 - .../Proxy/BaseProxyMethodBuilder.cs | 1 - .../Proxy/CompositionProxyTypeBuilder.cs | 1 - .../Spring.Core/Proxy/DynamicProxyManager.cs | 1 - .../Spring.Core/Proxy/IProxyMethodBuilder.cs | 1 - .../Spring.Core/Proxy/IProxyTypeBuilder.cs | 1 - .../Spring.Core/Proxy/IProxyTypeGenerator.cs | 1 - .../Proxy/InheritanceProxyTypeBuilder.cs | 1 - .../Spring.Core/Proxy/ProxyIgnoreAttribute.cs | 1 - .../Proxy/TargetProxyMethodBuilder.cs | 1 - .../Reflection/Dynamic/BaseDynamicMember.cs | 291 +- .../Reflection/Dynamic/DynamicConstructor.cs | 397 +- .../Reflection/Dynamic/DynamicField.cs | 972 ++- .../Reflection/Dynamic/DynamicIndexer.cs | 1037 ++- .../Reflection/Dynamic/DynamicMethod.cs | 581 +- .../Reflection/Dynamic/DynamicProperty.cs | 894 ++- .../Dynamic/DynamicReflectionManager.cs | 1111 ++- .../Threading/CallContextStorage.cs | 79 +- src/Spring/Spring.Core/Threading/ISync.cs | 183 +- .../Spring.Core/Threading/IThreadStorage.cs | 77 +- src/Spring/Spring.Core/Threading/Latch.cs | 261 +- .../Threading/LogicalThreadContext.cs | 191 +- src/Spring/Spring.Core/Threading/Semaphore.cs | 373 +- .../Spring.Core/Threading/SyncHolder.cs | 140 +- .../Threading/ThreadStaticStorage.cs | 105 +- .../Spring.Core/Threading/TimeoutException.cs | 254 +- .../Spring.Core/Threading/TimeoutSync.cs | 156 +- src/Spring/Spring.Core/Threading/Utils.cs | 270 +- src/Spring/Spring.Core/Util/ArrayUtils.cs | 323 +- src/Spring/Spring.Core/Util/AssertUtils.cs | 463 +- .../Spring.Core/Util/CollectionUtils.cs | 411 +- src/Spring/Spring.Core/Util/CompareUtils.cs | 179 +- .../Spring.Core/Util/ConfigurationUtils.cs | 441 +- src/Spring/Spring.Core/Util/DelegateInfo.cs | 509 +- .../Spring.Core/Util/DynamicCodeManager.cs | 285 +- src/Spring/Spring.Core/Util/EventUtils.cs | 214 +- .../Util/FatalReflectionException.cs | 180 +- .../Util/Generic/CollectionUtils.cs | 271 +- src/Spring/Spring.Core/Util/NumberUtils.cs | 695 +- src/Spring/Spring.Core/Util/ObjectUtils.cs | 981 ++- src/Spring/Spring.Core/Util/PathMatcher.cs | 455 +- .../Spring.Core/Util/PatternMatchUtils.cs | 195 +- src/Spring/Spring.Core/Util/Properties.cs | 647 +- .../Spring.Core/Util/ReflectionException.cs | 174 +- .../Spring.Core/Util/ReflectionUtils.cs | 2944 ++++---- src/Spring/Spring.Core/Util/StringUtils.cs | 1147 ++-- src/Spring/Spring.Core/Util/SystemUtils.cs | 231 +- src/Spring/Spring.Core/Util/UniqueKey.cs | 348 +- src/Spring/Spring.Core/Util/XmlUtils.cs | 299 +- .../Validation/Actions/ErrorMessageAction.cs | 239 +- .../Validation/Actions/ExpressionAction.cs | 223 +- .../Validation/AnyValidatorGroup.cs | 1 - .../Validation/BaseValidationAction.cs | 1 - .../Spring.Core/Validation/BaseValidator.cs | 1 - .../Validation/CollectionValidator.cs | 1 - .../Config/ValidationNamespaceParser.cs | 763 +-- .../Spring.Core/Validation/ErrorMessage.cs | 1 - .../Validation/ExclusiveValidatorGroup.cs | 1 - .../Validation/IValidationAction.cs | 1 - .../Validation/IValidationErrors.cs | 1 - .../Spring.Core/Validation/IValidator.cs | 1 - .../Validation/ValidatedAttribute.cs | 1 - .../Validation/ValidationErrors.cs | 1 - .../Validation/ValidationException.cs | 1 - .../Spring.Core/Validation/ValidatorGroup.cs | 1 - .../Validation/ValidatorReference.cs | 1 - .../Validators/ConditionValidator.cs | 173 +- .../Validators/CreditCardValidator.cs | 642 +- .../Validation/Validators/EmailValidator.cs | 230 +- .../Validation/Validators/ISBNValidator.cs | 334 +- .../Validators/RegularExpressionValidator.cs | 277 +- .../Validators/RequiredValidator.cs | 283 +- .../Validation/Validators/UrlValidator.cs | 214 +- .../Data/NHibernate/HibernateAccessor.cs | 1459 ++-- .../Data/NHibernate/HibernateAdoException.cs | 181 +- .../Data/NHibernate/HibernateDelegate.cs | 86 +- ...ibernateObjectRetrievalFailureException.cs | 217 +- ...ernateOptimisticLockingFailureException.cs | 179 +- .../NHibernate/HibernateQueryException.cs | 167 +- .../NHibernate/HibernateSystemException.cs | 159 +- .../Data/NHibernate/HibernateTemplate.cs | 4475 ++++++------ .../NHibernate/HibernateTransactionManager.cs | 1831 +++-- .../NHibernate/ICommonHibernateOperations.cs | 489 +- .../Data/NHibernate/IHibernateCallback.cs | 113 +- .../Data/NHibernate/IHibernateOperations.cs | 875 ++- .../NHibernate/LocalSessionFactoryObject.cs | 781 ++- .../Data/NHibernate/SessionFactoryUtils.cs | 1425 ++-- .../Data/NHibernate/SessionHolder.cs | 749 +- .../SpringSessionSynchronization.cs | 549 +- .../NHibernate/Support/HibernateDaoSupport.cs | 1 - .../Support/OpenSessionInViewModule.cs | 1 - .../Data/NHibernate/TemplateFlushMode.cs | 195 +- .../Generic/FindHibernateDelegate.cs | 1 - .../NHibernate/Generic/HibernateDaoSupport.cs | 1 - .../NHibernate/Generic/HibernateDelegate.cs | 1 - .../NHibernate/Generic/HibernateTemplate.cs | 1 - .../Generic/IFindHibernateCallback.cs | 1 - .../NHibernate/Generic/IHibernateCallback.cs | 1 - .../Generic/IHibernateOperations.cs | 1 - .../Data/NHibernate/HibernateAccessor.cs | 1 - ...ernateOptimisticLockingFailureException.cs | 1 - .../NHibernate/LocalSessionFactoryObject.cs | 1 - .../Data/NHibernate/SessionFactoryUtils.cs | 1 - .../Data/NHibernate/SpringSessionContext.cs | 1 - .../SpringSessionSynchronization.cs | 1 - .../Dao/CannotAcquireLockException.cs | 175 +- .../CannotSerializeTransactionException.cs | 175 +- .../Dao/CleanupFailureDataAccessException.cs | 185 +- .../Dao/ConcurrencyFailureException.cs | 177 +- .../Spring.Data/Dao/DataAccessException.cs | 162 +- .../Dao/DataAccessResourceFailureException.cs | 163 +- .../Dao/DataIntegrityViolationException.cs | 175 +- .../Dao/DataRetrievalFailureException.cs | 175 +- .../Dao/DeadlockLoserDataAccessException.cs | 163 +- .../Dao/EmptyResultDataAccessException.cs | 187 +- .../IncorrectResultSizeDataAccessException.cs | 343 +- ...rrectUpdateSemanticsDataAccessException.cs | 191 +- .../Dao/InvalidDataAccessApiUsageException.cs | 175 +- ...InvalidDataAccessResourceUsageException.cs | 173 +- ...ObjectOptimisticLockingFailureException.cs | 349 +- .../Dao/ObjectRetrievalFailureException.cs | 311 +- .../Dao/OptimisticLockingFailureException.cs | 173 +- .../PermissionDeniedDataAccessException.cs | 163 +- .../Dao/PessimisticLockingFailureException.cs | 179 +- .../Spring.Data/Dao/Support/DaoSupport.cs | 229 +- .../Dao/Support/DataAccessUtils.cs | 143 +- .../Dao/Support/Generic/DataAccessUtils.cs | 149 +- .../Dao/TypeMismatchDataAccessException.cs | 165 +- .../Dao/UncategorizedDataAccessException.cs | 165 +- .../Data/BadSqlGrammarException.cs | 261 +- .../Data/CannotGetAdoConnectionException.cs | 177 +- .../Spring.Data/Data/CommandDelegate.cs | 84 +- .../Spring.Data/Data/CommandSetterDelegate.cs | 68 +- .../Spring.Data/Data/Common/DbMetadata.cs | 837 ++- .../Spring.Data/Data/Common/DbParameter.cs | 387 +- .../Spring.Data/Data/Common/DbParameters.cs | 601 +- .../Data/Common/DbParametersBuilder.cs | 219 +- .../Spring.Data/Data/Common/DbProvider.cs | 499 +- .../Data/Common/DbProviderFactory.cs | 329 +- .../Data/Common/DbProviderFactoryObject.cs | 304 +- .../Data/Common/DelegatingDbProvider.cs | 453 +- .../Spring.Data/Data/Common/ErrorCodes.cs | 311 +- .../Spring.Data/Data/Common/IDbMetadata.cs | 341 +- .../Spring.Data/Data/Common/IDbParameter.cs | 167 +- .../Spring.Data/Data/Common/IDbParameters.cs | 258 +- .../Data/Common/IDbParametersBuilder.cs | 67 +- .../Spring.Data/Data/Common/IDbProvider.cs | 252 +- .../Data/Common/MultiDelegatingDbProvider.cs | 533 +- .../Data/Common/UserCredentialsDbProvider.cs | 272 +- .../Data/Config/DatabaseNamespaceParser.cs | 339 +- .../Spring.Data/Data/Core/AdoAccessor.cs | 432 +- .../Spring.Data/Data/Core/AdoDaoSupport.cs | 284 +- .../Core/AdoPlatformTransactionManager.cs | 861 ++- .../Spring.Data/Data/Core/AdoTemplate.cs | 6099 ++++++++--------- .../Data/Core/RowMapperResultSetExtractor.cs | 273 +- ...ServiceDomainPlatformTransactionManager.cs | 803 ++- .../Data/Core/TxScopeTransactionManager.cs | 565 +- .../Spring.Data/Data/Generic/AdoDaoSupport.cs | 304 +- .../Spring.Data/Data/Generic/AdoTemplate.cs | 3411 +++++---- .../Data/Generic/CommandDelegate.cs | 96 +- .../Data/Generic/DataAdapterDelegate.cs | 76 +- .../Data/Generic/IAdoOperations.cs | 471 +- .../Data/Generic/ICommandCallback.cs | 118 +- .../Data/Generic/IDataAdapterCallback.cs | 121 +- .../Data/Generic/IDbCommandCallback.cs | 130 +- .../Data/Generic/IDbCommandDelegate.cs | 97 +- .../Data/Generic/IResultSetExtractor.cs | 124 +- .../Spring.Data/Data/Generic/IRowMapper.cs | 119 +- .../Data/Generic/NamedResultSetProcessor.cs | 245 +- .../Generic/ResultSetExtractorDelegate.cs | 80 +- .../Data/Generic/RowMapperDelegate.cs | 76 +- .../Generic/RowMapperResultSetExtractor.cs | 299 +- src/Spring/Spring.Data/Data/IAdoOperations.cs | 1493 ++-- .../Spring.Data/Data/ICommandCallback.cs | 106 +- src/Spring/Spring.Data/Data/ICommandSetter.cs | 85 +- .../Spring.Data/Data/ICommandTextProvider.cs | 78 +- .../Spring.Data/Data/ICommonAdoOperations.cs | 494 +- .../Spring.Data/Data/IDataAdapterCallback.cs | 125 +- .../Spring.Data/Data/IDataAdapterSetter.cs | 111 +- .../Spring.Data/Data/IDataReaderWrapper.cs | 105 +- .../Data/IDataSetFillLifecycleProcessor.cs | 131 +- .../Spring.Data/Data/IDbCommandCreator.cs | 95 +- .../Data/IDbCommandCreatorFactory.cs | 463 +- .../Spring.Data/Data/IDbDataAdapterCreator.cs | 97 +- .../Spring.Data/Data/IResultSetExtractor.cs | 118 +- src/Spring/Spring.Data/Data/IRowCallback.cs | 70 +- src/Spring/Spring.Data/Data/IRowMapper.cs | 119 +- .../Data/InvalidResultSetAccessException.cs | 275 +- .../Data/Objects/AbstractAdoOperation.cs | 657 +- .../Spring.Data/Data/Objects/AdoNonQuery.cs | 167 +- .../Spring.Data/Data/Objects/AdoOperation.cs | 397 +- .../Spring.Data/Data/Objects/AdoQuery.cs | 223 +- .../Spring.Data/Data/Objects/AdoScalar.cs | 155 +- .../Data/Objects/Generic/AdoOperation.cs | 401 +- .../Data/Objects/Generic/AdoQuery.cs | 301 +- .../Data/Objects/Generic/MappingAdoQuery.cs | 149 +- .../Generic/MappingAdoQueryWithContext.cs | 201 +- .../Data/Objects/Generic/StoredProcedure.cs | 507 +- .../Data/Objects/MappingAdoQuery.cs | 149 +- .../Objects/MappingAdoQueryWithContext.cs | 193 +- .../Data/Objects/StoredProcedure.cs | 359 +- .../Data/ResultSetExtractorDelegate.cs | 80 +- .../Spring.Data/Data/RowCallbackDelegate.cs | 16 +- .../Spring.Data/Data/RowMapperDelegate.cs | 70 +- .../Support/AdoTransactionObjectSupport.cs | 337 +- .../Spring.Data/Data/Support/AdoUtils.cs | 178 +- .../Data/Support/ConnectionHolder.cs | 144 +- .../Data/Support/ConnectionSynchronization.cs | 258 +- .../Data/Support/ConnectionTxPair.cs | 128 +- .../Data/Support/ConnectionUtils.cs | 492 +- .../Support/DefaultServiceDomainAdapter.cs | 187 +- .../Support/DefaultTransactionScopeAdapter.cs | 215 +- .../Support/ErrorCodeExceptionTranslator.cs | 601 +- .../Support/FallbackExceptionTranslator.cs | 141 +- .../Data/Support/IAdoExceptionTranslator.cs | 111 +- .../Data/Support/IServiceDomainAdapter.cs | 151 +- .../Data/Support/ITransactionScopeAdapter.cs | 145 +- .../Data/Support/NamedResultSetProcessor.cs | 211 +- .../Data/Support/NullMappingDataReader.cs | 695 +- .../Data/Support/ParameterUtils.cs | 347 +- .../Support/RowCallbackResultSetExtractor.cs | 173 +- .../Data/Support/SimpleServiceConfig.cs | 251 +- .../Data/Support/TypedDataSetUtils.cs | 337 +- .../Data/UncategorizedAdoException.cs | 271 +- .../CannotCreateTransactionException.cs | 155 +- .../AttributeDrivenObjectDefinitionParser.cs | 238 +- .../Config/TxAdviceObjectDefinitionParser.cs | 351 +- .../Transaction/Config/TxNamespaceParser.cs | 118 +- .../Transaction/Config/TxNamespaceUtils.cs | 101 +- .../HeuristicCompletionException.cs | 291 +- .../IPlatformTransactionManager.cs | 219 +- .../Transaction/ISavepointManager.cs | 197 +- .../Transaction/ITransactionDefinition.cs | 243 +- .../Transaction/ITransactionStatus.cs | 169 +- .../IllegalTransactionStateException.cs | 157 +- ...tractFallbackTransactionAttributeSource.cs | 595 +- .../AttributesTransactionAttributeSource.cs | 261 +- .../DefaultTransactionAttribute.cs | 197 +- ...efaultTransactionAttributeSourceAdvisor.cs | 161 +- .../DelegatingTransactionAttributeWithName.cs | 350 +- .../Interceptor/ITransactionAttribute.cs | 85 +- .../ITransactionAttributeSource.cs | 111 +- .../MatchAlwaysTransactionAttributeSource.cs | 251 +- .../MethodMapTransactionAttributeSource.cs | 587 +- .../NameMatchTransactionAttributeSource.cs | 405 +- .../Interceptor/NoRollbackRuleAttribute.cs | 97 +- .../Interceptor/RollbackRuleAttribute.cs | 403 +- .../RuleBasedTransactionAttribute.cs | 317 +- .../Interceptor/TransactionAspectSupport.cs | 991 ++- .../Interceptor/TransactionAttribute.cs | 405 +- .../TransactionAttributeConverter.cs | 177 +- .../Interceptor/TransactionAttributeEditor.cs | 307 +- .../TransactionAttributeSourceAdvisor.cs | 261 +- .../TransactionAttributeSourceEditor.cs | 297 +- .../Interceptor/TransactionInterceptor.cs | 179 +- .../TransactionProxyFactoryObject.cs | 705 +- .../InvalidIsolationLevelException.cs | 159 +- .../Transaction/InvalidTimeoutException.cs | 257 +- .../NestedTransactionNotSupportedException.cs | 155 +- .../Transaction/NoTransactionException.cs | 157 +- .../AbstractPlatformTransactionManager.cs | 2356 +++---- .../Support/DefaultTransactionDefinition.cs | 577 +- .../Support/DefaultTransactionStatus.cs | 655 +- .../Support/ISmartTransactionObject.cs | 101 +- .../Support/ITransactionCallback.cs | 99 +- .../Support/ITransactionOperations.cs | 127 +- .../Support/ITransactionSynchronization.cs | 259 +- .../Support/ResourceHolderSupport.cs | 397 +- .../TransactionCallbackWithoutResult.cs | 149 +- .../Support/TransactionDelegate.cs | 84 +- .../TransactionSynchronizationAdapter.cs | 291 +- .../TransactionSynchronizationManager.cs | 981 ++- .../TransactionSynchronizationState.cs | 99 +- .../TransactionSynchronizationStatus.cs | 89 +- .../Support/TransactionTemplate.cs | 435 +- .../Transaction/TransactionException.cs | 167 +- .../Transaction/TransactionOutcomeState.cs | 73 +- .../Transaction/TransactionPropagation.cs | 205 +- ...nsactionSuspensionNotSupportedException.cs | 155 +- .../Transaction/TransactionSystemException.cs | 155 +- .../TransactionTimedOutException.cs | 112 +- .../Transaction/TransactionUsageException.cs | 155 +- .../UnexpectedRollbackException.cs | 153 +- .../EnterpriseServicesExporter.cs | 633 +- .../ServicedComponentExporter.cs | 449 +- .../ServicedComponentFactory.cs | 365 +- .../Spring.Services/Remoting/CaoExporter.cs | 585 +- .../Remoting/CaoFactoryObject.cs | 299 +- .../Config/RemotingNamespaceParser.cs | 979 ++- .../Remoting/RemoteObjectFactory.cs | 365 +- .../Remoting/RemotingConfigurer.cs | 337 +- .../Spring.Services/Remoting/SaoExporter.cs | 679 +- .../Remoting/SaoFactoryObject.cs | 279 +- .../Remoting/Support/BaseRemoteObject.cs | 325 +- .../Remoting/Support/ConfigurableLifetime.cs | 189 +- .../Remoting/Support/ICaoRemoteFactory.cs | 125 +- .../Remoting/Support/ILifetime.cs | 131 +- .../Support/RemoteObjectProxyTypeBuilder.cs | 353 +- .../Activation/ServiceHostFactory.cs | 153 +- .../ServiceModel/ServiceExporter.cs | 441 +- .../ServiceModel/ServiceHost.cs | 191 +- .../Support/ServiceProxyTypeBuilder.cs | 271 +- .../Web/Services/WebServiceProxyFactory.cs | 2353 ++++--- .../Spring.Testing.NUnit.xml | 4 - ...ctDependencyInjectionSpringContextTests.cs | 1 - .../NUnit/AbstractSpringContextTests.cs | 1 - ...ansactionalDbProviderSpringContextTests.cs | 1 - ...AbstractTransactionalSpringContextTests.cs | 1 - .../Spring.Web.Extensions.xml | 1 - .../Script/Services/ScriptHandlerFactory.cs | 1 - src/Spring/Spring.Web/Caching/AspNetCache.cs | 1 - .../Support/HttpApplicationConfigurer.cs | 1 - .../Context/Support/WebContextHandler.cs | 1 - .../Context/Support/WebSupportModule.cs | 1 - src/Spring/Spring.Web/Core/IO/WebResource.cs | 1 - .../HttpRequestBindingContainer.cs | 1 - .../Globalization/AspNetResourceCache.cs | 1 - .../Resolvers/CookieCultureResolver.cs | 1 - .../Resolvers/DefaultWebCultureResolver.cs | 1 - .../Resolvers/RequestCultureResolver.cs | 1 - .../Resolvers/SessionCultureResolver.cs | 1 - .../Support/ChildWebObjectDefinition.cs | 1 - .../Factory/Support/IWebObjectDefinition.cs | 1 - .../Objects/Factory/Support/ObjectScope.cs | 1 - .../Support/RootWebObjectDefinition.cs | 1 - .../Support/WebInstantiationStrategy.cs | 1 - .../Support/WebObjectDefinitionFactory.cs | 1 - .../Factory/Support/WebObjectFactory.cs | 1 - .../Objects/Factory/Support/WebObjectUtils.cs | 1 - .../Factory/Xml/WebObjectsNamespaceParser.cs | 1 - .../Threading/HttpContextStorage.cs | 1 - .../Threading/HybridContextStorage.cs | 1 - src/Spring/Spring.Web/Util/ControlAccessor.cs | 1 - .../Util/ControlCollectionAccessor.cs | 1 - .../Spring.Web/Util/HttpContextSwitch.cs | 1 - .../Spring.Web/Util/VirtualEnvironment.cs | 1 - src/Spring/Spring.Web/Util/WebUtils.cs | 1 - .../Spring.Web/Web/Process/IProcessAware.cs | 1 - .../Spring.Web/Web/Process/ProcessManager.cs | 1 - ...urableActiveDirectoryMembershipProvider.cs | 1 - .../ConfigurableSqlMembershipProvider.cs | 1 - .../ConfigurableSqlProfileProvider.cs | 1 - .../Providers/ConfigurableSqlRoleProvider.cs | 1 - .../ConfigurableXmlSiteMapProvider.cs | 1 - .../Providers/MembershipProviderAdapter.cs | 1 - .../Web/Services/WebServiceExporter.cs | 1 - .../Web/Services/WebServiceHandlerFactory.cs | 1 - .../Web/Support/AbstractHandlerFactory.cs | 1 - .../Web/Support/AbstractProcessHandler.cs | 1 - .../Spring.Web/Web/Support/ContextMonitor.cs | 1 - .../Web/Support/ControlInterceptor.cs | 1 - .../Web/Support/IInterceptionStrategy.cs | 1 - .../ISupportsWebDependencyInjection.cs | 1 - ...InterceptControlCollectionOwnerStrategy.cs | 1 - .../InterceptControlCollectionStrategy.cs | 1 - .../Spring.Web/Web/Support/MimeMediaType.cs | 1 - .../Web/Support/PageHandlerFactory.cs | 1 - src/Spring/Spring.Web/Web/Support/Result.cs | 1 - .../Spring.Web/Web/Support/ResultMode.cs | 1 - src/Spring/Spring.Web/Web/Support/Script.cs | 4 - .../Web/Support/SharedStateResourceCache.cs | 1 - ...ortsWebDependencyInjectionMethodBuilder.cs | 1 - ...upportsWebDependencyInjectionOwnerProxy.cs | 1 - ...pportsWebDependencyInjectionTypeBuilder.cs | 1 - .../Support/WebDependencyInjectionUtils.cs | 7 +- .../Spring.Web/Web/UI/AbstractWizard.cs | 1 - .../Web/UI/Controls/AbstractBaseValidator.cs | 1 - .../UI/Controls/AbstractValidationControl.cs | 1 - .../Spring.Web/Web/UI/Controls/Calendar.cs | 1 - .../Web/UI/Controls/CheckBoxList.cs | 1 - .../Web/UI/Controls/CheckBoxValidator.cs | 1 - .../Spring.Web/Web/UI/Controls/Content.cs | 1 - .../Web/UI/Controls/ContentPlaceholder.cs | 1 - .../Web/UI/Controls/ContentReplacer.cs | 1 - .../Web/UI/Controls/ControlState.cs | 1 - .../Web/UI/Controls/DataBindingPanel.cs | 1 - src/Spring/Spring.Web/Web/UI/Controls/Form.cs | 1 - src/Spring/Spring.Web/Web/UI/Controls/Head.cs | 1 - .../Web/UI/Controls/LocalizedImage.cs | 1 - .../Spring.Web/Web/UI/Controls/MultiView.cs | 1 - .../Spring.Web/Web/UI/Controls/Panel.cs | 1 - .../Web/UI/Controls/RadioButtonGroup.cs | 1 - .../Web/UI/Controls/TabCommandEventArgs.cs | 1 - .../Web/UI/Controls/TabCommandEventHandler.cs | 1 - .../Web/UI/Controls/TabContainer.cs | 1 - .../Web/UI/Controls/TabularMultiView.cs | 1 - .../Spring.Web/Web/UI/Controls/TabularView.cs | 1 - .../Web/UI/Controls/TabularViewCollection.cs | 1 - .../Web/UI/Controls/ValidationError.cs | 1 - .../Web/UI/Controls/ValidationSummary.cs | 1 - .../Web/UI/Controls/ViewCollection.cs | 1 - .../Spring.Web/Web/UI/DialogAttribute.cs | 1 - .../Spring.Web/Web/UI/IValidationContainer.cs | 1 - src/Spring/Spring.Web/Web/UI/MasterPage.cs | 2 - src/Spring/Spring.Web/Web/UI/Page.cs | 1 - src/Spring/Spring.Web/Web/UI/UserControl.cs | 1 - .../AbstractValidationErrorsRenderer.cs | 1 - .../Validation/DivValidationErrorsRenderer.cs | 1 - .../Validation/IValidationErrorsRenderer.cs | 1 - .../IconValidationErrorsRenderer.cs | 1 - .../SpanValidationErrorsRenderer.cs | 1 - .../Aop/Advice/DebugAdvice.cs | 1 - .../Aop/Config/AopNamespaceParserTests.cs | 1 - .../AbstractMethodInvocationTests.cs | 1 - .../UnknownAdviceTypeExceptionTests.cs | 1 - .../Aop/Framework/AopContextTests.cs | 1 - ...AutoProxyCreatorCircularReferencesTests.cs | 1 - .../AutoProxy/AdvisorAutoProxyCreatorTests.cs | 1 - .../Framework/AutoProxy/CreatesTestObject.cs | 1 - .../ObjectNameAutoProxyCreatorTests.cs | 1 - ...OrderedLogicalThreadContextCheckAdvisor.cs | 1 - .../Framework/CountingAfterReturningAdvice.cs | 1 - .../Aop/Framework/CountingBeforeAdvice.cs | 1 - .../Aop/Framework/CountingMultiAdvice.cs | 1 - .../Aop/Framework/CountingThrowsAdvice.cs | 1 - .../Framework/DynamicMethodInvocationTests.cs | 1 - .../DynamicProxy/AbstractAopProxyTests.cs | 1 - .../Framework/DynamicProxy/AopUtilsTests.cs | 1 - .../CachedAopProxyFactoryTests.cs | 1 - .../DynamicProxy/CompositionAopProxyTests.cs | 1 - .../DynamicProxy/DecoratorAopProxyTests.cs | 1 - .../DefaultAopProxyFactoryTests.cs | 1 - .../DynamicProxy/InheritanceAopProxyTests.cs | 1 - .../DynamicProxy/MockTargetSource.cs | 1 - ...ashtableCachingAdvisorChainFactoryTests.cs | 1 - .../Aop/Framework/ITimeStamped.cs | 1 - .../Aop/Framework/MethodCounter.cs | 1 - .../Aop/Framework/ProxyConfigTests.cs | 1 - .../Aop/Framework/ProxyFactoryObjectTests.cs | 1 - .../Aop/Framework/ProxyFactoryTests.cs | 1 - .../ReflectiveMethodInvocationTests.cs | 1 - .../Aop/Interceptor/NopInterceptor.cs | 1 - .../AttributeMatchMethodPointcutTests.cs | 1 - .../DelegatingIntroductionInterceptorTests.cs | 1 - .../Aop/Support/RootTypeFilterTests.cs | 1 - .../Aop/Support/TypeFiltersTests.cs | 1 - .../Aop/Target/EmptyTargetSourceTests.cs | 1 - .../Target/HotSwappableTargetSourceTests.cs | 1 - .../Aop/Target/PrototypeTargetSourceTests.cs | 1 - .../Aop/Target/SimplePoolTargetSourceTests.cs | 2 - .../Aop/Target/SingletonTargetSourceTests.cs | 1 - .../Target/ThreadLocalTargetSourceTests.cs | 2 - .../Aop/TrueMethodMatcherTests.cs | 1 - .../Spring.Aop.Tests/Aop/TruePointcutTests.cs | 1 - .../Aop/TrueTypeFilterTests.cs | 1 - .../Spring.Aop.Tests/AopExceptionTests.cs | 1 - .../Cache/CacheAspectIntegrationTests.cs | 1 - .../Cache/CacheParameterAdviceTests.cs | 1 - .../Aspects/Cache/CacheResultAdviceTests.cs | 1 - .../Cache/InvalidateCacheAdviceTests.cs | 1 - .../ExceptionHandlerAspectIntegrationTests.cs | 1 - .../Logging/SimpleLoggingAdviceTests.cs | 1 - .../Logging/TestableSimpleLoggingAdvice.cs | 1 - .../Aspects/RetryAdviceTests.cs | 1 - .../ParameterValidationAdviceTests.cs | 1 - .../Spring/Aop/Framework/innerBeanTarget.xml | 1 - .../Spring/Aop/Framework/throwsAdvice.xml | 1 - .../Caching/AbstractCacheTests.cs | 1 - .../Caching/BaseCacheAttributeTests.cs | 1 - .../Collections/AbstractQueueTests.cs | 1 - .../Collections/HashedSetTests.cs | 1 - .../Collections/HybridSetTests.cs | 1 - .../Collections/ImmutableSetTests.cs | 1 - .../Collections/ListSetTests.cs | 1 - .../Spring.Core.Tests/Collections/SetTests.cs | 1 - .../Collections/SortedSetTests.cs | 1 - .../Collections/StaticSetTests.cs | 1 - .../Context/ContextExceptionTests.cs | 1 - .../Support/AbstractMessageSourceTests.cs | 2 - .../Context/Support/Assembler.cs | 1 - .../Context/Support/ContextRegistryTests.cs | 1 - .../Support/DelegatingMessageSourceTests.cs | 1 - .../Context/Support/Logic.cs | 1 - .../Context/Support/NullMessageSourceTests.cs | 1 - .../Support/ResourceSetMessageSourceTests.cs | 1 - .../Context/Support/Service.cs | 1 - .../Support/StaticMessageSourceTests.cs | 2 - .../Core/ControlFlowFactoryTests.cs | 1 - .../Core/IO/AssemblyResourceTest.cs | 1 - .../IO/ConfigurableResourceLoaderTests.cs | 1 - .../Core/IO/FileSystemResourceCommonTests.cs | 1 - .../Core/IO/FileSystemResourceTests.cs | 1 - .../Core/IO/InputStreamResourceTests.cs | 1 - .../Core/IO/ResourceConverterTests.cs | 1 - .../Core/IO/ResourceHandlerRegistryTests.cs | 1 - ...ethodGenericArgumentsCountCriteriaTests.cs | 1 - .../MethodParametersCountCriteriaTests.cs | 1 - .../Core/MethodParametersCriteriaTests.cs | 1 - .../Core/MethodReturnTypeCriteriaTests.cs | 1 - .../Core/OrderComparatorTests.cs | 1 - .../CredentialConverterTests.cs | 1 - .../CustomNumberConverterTests.cs | 1 - .../TypeConversion/FileInfoConverterTests.cs | 1 - .../TypeConversion/NameValueConverterTests.cs | 1 - .../TypeConversion/RGBColorConverterTests.cs | 1 - .../TypeConversion/RegexConverterTests.cs | 1 - .../RegistryKeyConverterTests.cs | 1 - .../RuntimeTypeConverterTests.cs | 1 - .../TypeConversion/StreamConverterTests.cs | 1 - .../StringArrayConverterTests.cs | 1 - .../TypeConversion/TimeSpanConverterTests.cs | 1 - .../TypeConverterRegistryTests.cs | 1 - .../TypeConversion/UniqueKeyConverterTests.cs | 1 - .../Core/TypeConversion/UriConverterTests.cs | 1 - .../TypeResolution/CachedTypeResolverTests.cs | 1 - .../GenericTypeResolverTests.cs | 1 - .../TypeResolutionUtilsTests.cs | 1 - .../Core/TypeResolution/TypeResolverTests.cs | 1 - .../Spring.Core.Tests/CoreExceptionTests.cs | 1 - .../DataBinding/BaseBindingManagerTests.cs | 1 - .../SimpleExpressionBindingTests.cs | 1 - .../Expressions/ExpressionEvaluatorTests.cs | 1 - .../Expressions/FunctionNodeTests.cs | 1 - .../Expressions/MethodNodeTests.cs | 1 - .../Processors/ConversionProcessorTests.cs | 1 - .../Processors/OrderByProcessorTests.cs | 1 - .../Expressions/ReferenceNodeTests.cs | 1 - .../Expressions/SelectionNodeTests.cs | 1 - .../Globalization/AbstractLocalizerTests.cs | 1 - .../Globalization/CultureTestScope.cs | 1 - .../Formatters/CurrencyFormatterTests.cs | 1 - .../Formatters/DateTimeFormatterTests.cs | 1 - .../Formatters/FilteringFormatterTests.cs | 1 - .../Formatters/FloatFormatterTests.cs | 1 - .../HasTextFilteringFormatterTests.cs | 1 - .../Formatters/IntegerFormatterTests.cs | 1 - .../Formatters/NumberFormatterTests.cs | 1 - .../Formatters/PercentFormatterTests.cs | 1 - .../Localizers/ResourceSetLocalizerTests.cs | 2 - .../Resolvers/DefaultCultureResolverTests.cs | 1 - .../HookableContextHandler.cs | 1 - .../Factory/Attributes/MyRequiredAttribute.cs | 1 - ...quiredAttributeObjectPostProcessorTests.cs | 1 - .../Factory/Attributes/RequiredTestObject.cs | 1 - .../Config/AbstractFactoryObjectTests.cs | 1 - .../CommandLineArgsVariableSourceTests.cs | 1 - .../ConfigSectionVariableSourceTests.cs | 1 - .../Config/ConfigurationReaderTests.cs | 1 - .../ConnectionStringsVariableSourceTests.cs | 1 - .../Config/CustomConverterConfigurerTests.cs | 1 - .../Config/DelegateFactoryObjectTests.cs | 1 - .../Config/DictionaryFactoryObjectTests.cs | 1 - .../Config/EnvironmentVariableSourceTests.cs | 1 - .../FieldRetrievingFactoryObjectTests.cs | 1 - .../Factory/Config/ListFactoryObjectTests.cs | 1 - .../Factory/Config/LogFactoryObjectTests.cs | 1 - .../ObjectReferenceFactoryObjectTests.cs | 1 - .../Config/PropertyFileVariableSourceTests.cs | 1 - .../Config/PropertyOverrideConfigurerTests.cs | 1 - .../Config/PropertyPathFactoryObjectTests.cs | 1 - .../PropertyPlaceholderConfigurerTests.cs | 1 - .../PropertyRetrievingFactoryObjectTests.cs | 1 - .../Config/RegistryVariableSourceTests.cs | 1 - .../Config/RuntimeObjectReferenceTests.cs | 1 - .../Factory/Config/SetFactoryObjectTests.cs | 1 - .../SpecialFolderVariableSourceTests.cs | 1 - .../Factory/Config/TypedStringValueTests.cs | 1 - .../Factory/Config/VariableAccessorTests.cs | 1 - .../VariablePlaceholderConfigurerTests.cs | 1 - .../DefaultListableObjectFactoryPerfTests.cs | 1 - .../Factory/DummyConfigurableFactory.cs | 1 - .../Objects/Factory/MethodReplacerTests.cs | 1 - .../NoSuchObjectDefinitionExceptionTests.cs | 1 - .../ObjectDefinitionStoreExceptionTests.cs | 1 - .../Factory/Support/AutowireUtilsTests.cs | 1 - .../Support/ChildObjectDefinitionTests.cs | 1 - .../DefaultObjectDefinitionFactoryTests.cs | 1 - .../Support/DelegatingMethodReplacerTests.cs | 1 - .../Support/LookupMethodOverrideTests.cs | 1 - .../Support/LookupMethodReplacerTests.cs | 1 - .../Support/ObjectDefinitionBuilderTests.cs | 1 - .../ObjectDefinitionReaderUtilsTests.cs | 1 - .../Support/ReplacedMethodOverrideTests.cs | 1 - .../Support/RootObjectDefinitionTests.cs | 1 - .../SimpleInstantiationStrategyTests.cs | 1 - .../Objects/Factory/Xml/FactoryMethods.cs | 1 - .../Objects/Factory/Xml/InstanceFactory.cs | 1 - .../Objects/Factory/Xml/LocaleTests.cs | 1 - .../Objects/Factory/Xml/NullAppender.cs | 2 - .../Objects/Factory/Xml/TestObjectCreator.cs | 1 - .../Factory/Xml/XmlObjectCollectionTests.cs | 1 - .../Factory/Xml/XmlObjectFactoryTests.cs | 1 - .../Factory/Xml/XmlParserResolverTests.cs | 1 - .../Spring.Core.Tests/Objects/IOther.cs | 1 - .../Objects/LazyTestObject.cs | 1 - .../Objects/MutablePropertyValuesTests.cs | 1 - .../NotWritablePropertyExceptionTests.cs | 1 - .../Objects/ObjectWrapperTests.cs | 1 - .../PropertyAccessExceptionsExceptionTests.cs | 2 - .../Objects/PropertyValueTests.cs | 1 - .../Objects/StaticTestEventHandler.cs | 1 - .../ArgumentConvertingMethodInvokerTests.cs | 1 - .../AutoWiringEventHandlerValueTests.cs | 1 - .../Support/InstanceEventHandlerValueTests.cs | 1 - .../Objects/Support/MethodInvokerTests.cs | 1 - .../Support/MutableSortDefinitionTests.cs | 1 - .../Support/PropertyComparatorTests.cs | 1 - .../Support/StaticEventHandlerValueTests.cs | 1 - .../Objects/TestGenericObject.cs | 1 - .../Objects/TypeMismatchExceptionTests.cs | 1 - .../Proxy/AbstractProxyTypeBuilderTests.cs | 1 - .../Proxy/CompositionProxyTypeBuilderTests.cs | 1 - .../Proxy/DynamicProxyManagerTests.cs | 1 - ...xplicitCompositionProxyTypeBuilderTests.cs | 1 - .../Proxy/InheritanceProxyTypeBuilderTests.cs | 1 - .../Reflection/Dynamic/BasePropertyTests.cs | 1 - .../Dynamic/DynamicConstructorTests.cs | 1 - .../Reflection/Dynamic/DynamicFieldTests.cs | 1 - .../Reflection/Dynamic/DynamicIndexerTests.cs | 1 - .../Reflection/Dynamic/DynamicMethodTests.cs | 1 - .../Dynamic/DynamicPropertyTests.cs | 1 - .../Reflection/Dynamic/SafeFieldTests.cs | 1 - .../Reflection/Dynamic/SafePropertyTests.cs | 1 - test/Spring/Spring.Core.Tests/StopWatch.cs | 1 - .../StreamHelperDecorator.cs | 1 - .../Spring.Core.Tests/StringResource.cs | 1 - .../Threading/AsyncTestMethod.cs | 1 - .../Threading/AsyncTestTask.cs | 1 - .../Threading/CallContextStorageTests.cs | 1 - .../Threading/CommonThreadStorageTests.cs | 1 - .../Threading/LogicalThreadContextTest.cs | 1 - .../Threading/ThreadStaticStorageTests.cs | 1 - .../Spring.Core.Tests/Util/ArrayUtilsTests.cs | 1 - .../Util/AssertUtilsTests.cs | 1 - .../Util/DefensiveEventRaiserTests.cs | 1 - .../Util/DelegateInfoTests.cs | 1 - .../Util/EventRaiserTests.cs | 1 - .../Util/NumberUtilsTests.cs | 1 - .../Util/ObjectUtilsTests.cs | 1 - .../Util/PatternMatchUtilsTests.cs | 1 - .../Util/ReflectionUtilsTests.cs | 1 - .../Util/StringUtilsTests.cs | 1 - .../Util/SystemUtilsTests.cs | 1 - .../Spring.Core.Tests/Util/UniqueKeyTests.cs | 1 - .../Actions/ErrorMessageActionTests.cs | 1 - .../Actions/ExpressionActionTests.cs | 1 - .../Validation/AnyValidatorGroupTests.cs | 1 - .../ExclusiveValidatorGroupTests.cs | 1 - .../Validation/HelperClasses.cs | 1 - .../Validation/ValidationConfigParserTests.cs | 1 - .../Validation/ValidationErrorsTests.cs | 1 - .../Validation/ValidationExceptionTests.cs | 1 - .../Validation/ValidatorGroupTests.cs | 1 - .../Validation/ValidatorReferenceTests.cs | 1 - .../Validators/ConditionValidatorTests.cs | 1 - .../Validators/RequiredValidatorTests.cs | 1 - .../Data/AdoTemplatePerformanceTests.cs | 1 - .../Data/AdoTemplateTests.cs | 1 - .../Data/AutoDeclarativeTxTests.cs | 1 - .../Data/CallCreateTestObject.cs | 1 - .../Data/CreateTestObjectNonQuery.cs | 1 - .../Data/DeclarativeTxTests.cs | 1 - .../Data/Generic/TestObjectDao.cs | 1 - .../Data/Generic/TestObjectRowMapper.cs | 1 - .../Data/MappingAdoQueryTests.cs | 1 - .../Data/NestedTxScopeTests.cs | 1 - .../Data/Northwind/AdoTemplateShipperDao.cs | 1 - .../Data/Northwind/IShipperDao.cs | 1 - .../Data/Northwind/NativeAdoShipperDao.cs | 4 - .../Data/Northwind/Shipper.cs | 4 - .../Objects/Generic/StoredProcedureTests.cs | 1 - .../Data/Objects/Generic/VacationRowMapper.cs | 1 - .../Data/SQLiteTests.cs | 1 - .../Data/StoredProcedureTests.cs | 1 - .../SimpleExceptionTranslationTests.cs | 5 - .../Data/TestObjectManager.cs | 1 - .../Data/TestObjectQuery.cs | 1 - .../Data/TestObjectStoredProcedure.cs | 1 - .../Data/TestTxIsolationLevelTests.cs | 1 - .../Data/TransactionTemplateTests.cs | 1 - .../NHibernate/DbProviderTemplateTests.cs | 1 - .../Data/NHibernate/ITestObjectDao.cs | 1 - .../Data/NHibernate/MultipleDbTests.cs | 1 - .../Data/NHibernate/NHDAOTests.cs | 5 - .../Data/NHibernate/NHTestObjectDao.cs | 5 - .../Data/NHibernate/NativeNHTestObjectDao.cs | 5 - .../Data/NHibernate/TemplateTests.cs | 1 - .../Data/NHibernate/TestObject.cs | 1 - .../NHibernate/Config/AopConfiguration.cs | 1 - .../HibernateTransactionManagerTests.cs | 1 - .../Data/NHibernate/ITestObjectDao.cs | 1 - .../LocalSessionFactoryObjectTests.cs | 1 - .../Data/NHibernate/NHTestObjectDao.cs | 1 - .../Data/NHibernate/SimpleService.cs | 8 - .../ConfigSectionSessionScopeSettingsTests.cs | 1 - .../Support/SessionScopeSettingsTests.cs | 1 - .../NHibernate/Support/SessionScopeTests.cs | 1 - .../Data/NHibernate/TestObject.cs | 1 - .../AdoPlatformTransactionManagerTests.cs | 1 - .../Data/AutoDeclarativeTxTests.cs | 1 - .../Data/Common/DbParametersTests.cs | 1 - .../Data/Common/DbProviderFactoryTests.cs | 1 - .../Common/UserCredentialsDbProviderTests.cs | 1 - .../ServiceDomainTransactionManagerTests.cs | 1 - ...ScopeTransactionManagerIntegrationTests.cs | 1 - .../Core/TxScopeTransactionManagerTests.cs | 1 - .../Data/Objects/AdoOperationTests.cs | 1 - .../Data/Objects/AdoQueryTests.cs | 1 - .../Data/Objects/StoredProcedureTests.cs | 1 - .../Spring.Data.Tests/Data/TestObjectMgr.cs | 1 - .../Spring.Data.Tests/DataExceptionTests.cs | 1 - .../ErrorCodeExceptionTranslatorTests.cs | 1 - .../Support/TestDbProvider.cs | 1 - .../Support/TestSqlException.cs | 1 - .../CallCountingTransactionManager.cs | 1 - .../AbstractTransactionAspectTests.cs | 1 - ...chAlwaysTransactionAttributeSourceTests.cs | 1 - .../TransactionAttributeSourceTests.cs | 1 - .../TransactionInterceptorTests.cs | 1 - .../ServicedComponentExporterTests.cs | 1 - .../Remoting/CaoExporterTests.cs | 1 - .../Remoting/CaoFactoryObjectTests.cs | 1 - .../Remoting/RemoteObjectFactoryTests.cs | 1 - .../Remoting/RemotingConfigParserTests.cs | 1 - .../Remoting/RemotingConfigurerTests.cs | 1 - .../Remoting/SaoExporterTests.cs | 1 - .../Remoting/SaoFactoryObjectTests.cs | 1 - .../Services/WebServiceProxyFactoryTests.cs | 1 - .../NUnit/AnotherTest/LoadAppContextTests.cs | 1 - .../Testing/NUnit/BaseTestAppContextTests.cs | 1 - .../Testing/NUnit/CachedAppContextTests.cs | 1 - .../Caching/AspNetCacheTests.cs | 1 - .../Support/HttpApplicationConfigurerTests.cs | 1 - .../Support/WebApplicationContextTests.cs | 1 - .../Core/IO/WebResourceTests.cs | 1 - .../DefaultWebCultureResolverTests.cs | 1 - .../Spring.Web.Tests/MyNUnitAddinHelper.cs | 1 - .../WebObjectDefinitionFactoryTests.cs | 1 - .../Factory/Support/WebObjectFactoryTests.cs | 1 - .../TestSupport/TestWebContextTests.cs | 1 - .../TestSupport/VirtualEnvironmentMock.cs | 1 - .../Threading/HttpContextStorageTests.cs | 1 - .../Threading/HybridContextStorageTests.cs | 1 - .../Util/ControlInterceptionTests.cs | 1 - .../Spring.Web.Tests/Util/WebUtilsTests.cs | 1 - .../Web/Services/WebServiceExporterTests.cs | 1 - .../Support/AbstractHandlerFactoryTests.cs | 1 - .../Web/Support/MimeMediaTypeTests.cs | 1 - .../Web/Support/PageHandlerFactoryTests.cs | 1 - .../Web/Support/ResultTests.cs | 1 - .../AbstractValidationControlTests.cs | 1 - .../Web/UI/Controls/HeadTests.cs | 1 - .../Web/UI/Controls/ValidationErrorsTests.cs | 1 - .../Web/UI/Controls/ValidationSummaryTests.cs | 1 - .../Spring.Web.Tests/Web/UI/PageTests.cs | 1 - .../Web/UI/UserControlTests.cs | 1 - 1275 files changed, 144209 insertions(+), 145452 deletions(-) diff --git a/src/Spring/Spring.Aop/Aop/Config/AopNamespaceParser.cs b/src/Spring/Spring.Aop/Aop/Config/AopNamespaceParser.cs index 3a54a5ea..fcf18dbf 100644 --- a/src/Spring/Spring.Aop/Aop/Config/AopNamespaceParser.cs +++ b/src/Spring/Spring.Aop/Aop/Config/AopNamespaceParser.cs @@ -1,56 +1,55 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Objects.Factory.Xml; - -namespace Spring.Aop.Config -{ - /// - /// Namespace parser for the aop namespace. - /// - /// - /// Using the advisor tag you can configure an and have it - /// applied to all the relevant objects in your application context automatically. The - /// advisor tag supports only referenced s. - /// - /// Rob harrop - /// Adrian Colyer - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: AopNamespaceParser.cs,v 1.3 2007/08/09 02:42:35 markpollack Exp $ - [ - NamespaceParser( - Namespace = "http://www.springframework.net/aop", - SchemaLocationAssemblyHint = typeof (AopNamespaceParser), - SchemaLocation = "/Spring.Aop.Config/spring-aop-1.1.xsd" - ) - ] - public class AopNamespaceParser : NamespaceParserSupport - { - /// - /// Register the for the 'config' tag. - /// - public override void Init() - { - RegisterObjectDefinitionParser("config", new ConfigObjectDefinitionParser()); - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Objects.Factory.Xml; + +namespace Spring.Aop.Config +{ + /// + /// Namespace parser for the aop namespace. + /// + /// + /// Using the advisor tag you can configure an and have it + /// applied to all the relevant objects in your application context automatically. The + /// advisor tag supports only referenced s. + /// + /// Rob harrop + /// Adrian Colyer + /// Rod Johnson + /// Mark Pollack (.NET) + [ + NamespaceParser( + Namespace = "http://www.springframework.net/aop", + SchemaLocationAssemblyHint = typeof (AopNamespaceParser), + SchemaLocation = "/Spring.Aop.Config/spring-aop-1.1.xsd" + ) + ] + public class AopNamespaceParser : NamespaceParserSupport + { + /// + /// Register the for the 'config' tag. + /// + public override void Init() + { + RegisterObjectDefinitionParser("config", new ConfigObjectDefinitionParser()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Config/AopNamespaceUtils.cs b/src/Spring/Spring.Aop/Aop/Config/AopNamespaceUtils.cs index 63d44501..0f839e44 100644 --- a/src/Spring/Spring.Aop/Aop/Config/AopNamespaceUtils.cs +++ b/src/Spring/Spring.Aop/Aop/Config/AopNamespaceUtils.cs @@ -1,99 +1,98 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Xml; -using Spring.Aop.Framework.AutoProxy; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -#endregion - - -namespace Spring.Aop.Config -{ - /// - /// Utility class for handling registration of auto-proxy creators used internally by the - /// aop namespace tags. - /// - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: AopNamespaceUtils.cs,v 1.4 2007/05/26 19:25:48 markpollack Exp $ - public class AopNamespaceUtils - { - - /// - /// The object name of the internally managed auto-proxy creator. - /// - public const string AUTO_PROXY_CREATOR_OBJECT_NAME = - "Spring.Aop.Config.InternalAutoProxyCreator"; - - - - /// - /// Registers the auto proxy creator if necessary. - /// - /// The parser context. - /// The source element. - public static void RegisterAutoProxyCreatorIfNecessary(ParserContext parserContext, XmlElement sourceElement) - { - RegisterApcAsRequired(typeof(DefaultAdvisorAutoProxyCreator), parserContext); - } - - /// - /// Registries the or escalate apc as required. - /// - /// The type. - /// The parser context. - private static void RegisterApcAsRequired(Type type, ParserContext parserContext) - { - AssertUtils.ArgumentNotNull(parserContext, "parserContext"); - IObjectDefinitionRegistry registry = parserContext.Registry; - - - if (!registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME)) - { - RootObjectDefinition objectDefinition = new RootObjectDefinition(type); - //TODO source/role not yet implemented in .NET - objectDefinition.PropertyValues.Add("order", int.MaxValue); - registry.RegisterObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME, objectDefinition); - } - - } - - /// - /// Forces the auto proxy creator to use decorator proxy. - /// - /// The registry. - public static void ForceAutoProxyCreatorToUseDecoratorProxy(IObjectDefinitionRegistry registry) - { - if (registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME)) - { - IObjectDefinition definition = registry.GetObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME); - definition.PropertyValues.Add("ProxyTargetType", true); - } - } - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Xml; +using Spring.Aop.Framework.AutoProxy; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +#endregion + + +namespace Spring.Aop.Config +{ + /// + /// Utility class for handling registration of auto-proxy creators used internally by the + /// aop namespace tags. + /// + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class AopNamespaceUtils + { + + /// + /// The object name of the internally managed auto-proxy creator. + /// + public const string AUTO_PROXY_CREATOR_OBJECT_NAME = + "Spring.Aop.Config.InternalAutoProxyCreator"; + + + + /// + /// Registers the auto proxy creator if necessary. + /// + /// The parser context. + /// The source element. + public static void RegisterAutoProxyCreatorIfNecessary(ParserContext parserContext, XmlElement sourceElement) + { + RegisterApcAsRequired(typeof(DefaultAdvisorAutoProxyCreator), parserContext); + } + + /// + /// Registries the or escalate apc as required. + /// + /// The type. + /// The parser context. + private static void RegisterApcAsRequired(Type type, ParserContext parserContext) + { + AssertUtils.ArgumentNotNull(parserContext, "parserContext"); + IObjectDefinitionRegistry registry = parserContext.Registry; + + + if (!registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME)) + { + RootObjectDefinition objectDefinition = new RootObjectDefinition(type); + //TODO source/role not yet implemented in .NET + objectDefinition.PropertyValues.Add("order", int.MaxValue); + registry.RegisterObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME, objectDefinition); + } + + } + + /// + /// Forces the auto proxy creator to use decorator proxy. + /// + /// The registry. + public static void ForceAutoProxyCreatorToUseDecoratorProxy(IObjectDefinitionRegistry registry) + { + if (registry.ContainsObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME)) + { + IObjectDefinition definition = registry.GetObjectDefinition(AUTO_PROXY_CREATOR_OBJECT_NAME); + definition.PropertyValues.Add("ProxyTargetType", true); + } + } + } +} diff --git a/src/Spring/Spring.Aop/Aop/Config/ConfigObjectDefinitionParser.cs b/src/Spring/Spring.Aop/Aop/Config/ConfigObjectDefinitionParser.cs index 4767c280..9a69bf31 100644 --- a/src/Spring/Spring.Aop/Aop/Config/ConfigObjectDefinitionParser.cs +++ b/src/Spring/Spring.Aop/Aop/Config/ConfigObjectDefinitionParser.cs @@ -1,159 +1,158 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - - -using System.Xml; -using Spring.Aop.Support; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -namespace Spring.Aop.Config -{ - /// - /// The for the <aop:config> tag. - /// - /// Mark Pollack (.NET) - /// $Id: ConfigObjectDefinitionParser.cs,v 1.3 2008/02/20 14:29:13 bbaia Exp $ - public class ConfigObjectDefinitionParser : IObjectDefinitionParser - { - /// - /// The 'proxy-target-type' attribute - /// - private static readonly string PROXY_TARGET_TYPE = "proxy-target-type"; - - private static readonly string ID = "id"; - - private static readonly string ORDER_PROPERTY = "order"; - - private static readonly string ADVICE_REF = "advice-ref"; - - private static readonly string ADVICE_OBJECT_NAME = "adviceObjectName"; - - private static readonly string POINTCUT_REF = "pointcut-ref"; - - - #region IObjectDefinitionParser Members - - /// - /// Parse the specified XmlElement and register the resulting - /// ObjectDefinitions with the IObjectDefinitionRegistry - /// embedded in the supplied - /// - /// The element to be parsed. - /// The object encapsulating the current state of the parsing process. - /// Provides access to a IObjectDefinitionRegistry - /// The primary object definition. - /// - ///

- /// This method is never invoked if the parser is namespace aware - /// and was called to process the root node. - ///

- ///
- public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - ConfigureAutoProxyCreator(parserContext, element); - XmlNodeList advisorNodes = element.GetElementsByTagName("advisor", element.NamespaceURI); - - //XmlNodeList advisorNodes = element.SelectNodes("*[local-name()='advisor' and namespace-uri()='" + element.NamespaceURI + "']"); - foreach (XmlElement advisorElement in advisorNodes) - { - ParseAdvisor(advisorElement, parserContext); - } - - return null; - } - - /// - /// Parses the supplied advisor element and registers the resulting - /// - /// The advisor element. - /// The parser context. - private void ParseAdvisor(XmlElement advisorElement, ParserContext parserContext) - { - AbstractObjectDefinition advisorDef = CreateAdvisorObjectDefinition(advisorElement, parserContext); - string id = advisorElement.GetAttribute(ID); - - string pointcutObjectName = ParsePointcutProperty(advisorElement, parserContext); - advisorDef.PropertyValues.Add(POINTCUT_REF, new RuntimeObjectReference(pointcutObjectName)); - string advisorObjectName = id; - if (StringUtils.HasText(advisorObjectName)) - { - parserContext.Registry.RegisterObjectDefinition(advisorObjectName, advisorDef); - } - else - { - parserContext.ReaderContext.RegisterWithGeneratedName(advisorDef); - } - } - - - private string ParsePointcutProperty(XmlElement element, ParserContext parserContext) - { - if (element.HasAttribute(POINTCUT_REF)) - { - string pointcutRef = element.GetAttribute(POINTCUT_REF); - if (!StringUtils.HasText(pointcutRef)) - { - parserContext.ReaderContext.ReportException(element, "advisor", "'pointcut-ref' attribute contains empty value."); - } - return pointcutRef; - } - else - { - parserContext.ReaderContext.ReportException(element, "advisor", "'must define 'pointcut-ref' on tag."); - return null; - } - } - - - private AbstractObjectDefinition CreateAdvisorObjectDefinition(XmlElement advisorElement, ParserContext parserContext) - { - ObjectDefinitionBuilder advisorDefinitionBuilder = - parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof(DefaultObjectFactoryPointcutAdvisor)); - - if (advisorElement.HasAttribute(ORDER_PROPERTY)) - { - advisorDefinitionBuilder.AddPropertyValue(ORDER_PROPERTY, advisorElement.GetAttribute(ORDER_PROPERTY)); - } - - advisorDefinitionBuilder.AddPropertyValue(ADVICE_OBJECT_NAME, advisorElement.GetAttribute(ADVICE_REF)); - - - return advisorDefinitionBuilder.ObjectDefinition; - } - - - private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element) - { - AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element); - - bool proxyTargetClass = - parserContext.ParserHelper.IsTrueStringValue(element.GetAttribute(PROXY_TARGET_TYPE)); - if (proxyTargetClass) - { - AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry); - } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + + +using System.Xml; +using Spring.Aop.Support; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +namespace Spring.Aop.Config +{ + /// + /// The for the <aop:config> tag. + /// + /// Mark Pollack (.NET) + public class ConfigObjectDefinitionParser : IObjectDefinitionParser + { + /// + /// The 'proxy-target-type' attribute + /// + private static readonly string PROXY_TARGET_TYPE = "proxy-target-type"; + + private static readonly string ID = "id"; + + private static readonly string ORDER_PROPERTY = "order"; + + private static readonly string ADVICE_REF = "advice-ref"; + + private static readonly string ADVICE_OBJECT_NAME = "adviceObjectName"; + + private static readonly string POINTCUT_REF = "pointcut-ref"; + + + #region IObjectDefinitionParser Members + + /// + /// Parse the specified XmlElement and register the resulting + /// ObjectDefinitions with the IObjectDefinitionRegistry + /// embedded in the supplied + /// + /// The element to be parsed. + /// The object encapsulating the current state of the parsing process. + /// Provides access to a IObjectDefinitionRegistry + /// The primary object definition. + /// + ///

+ /// This method is never invoked if the parser is namespace aware + /// and was called to process the root node. + ///

+ ///
+ public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + ConfigureAutoProxyCreator(parserContext, element); + XmlNodeList advisorNodes = element.GetElementsByTagName("advisor", element.NamespaceURI); + + //XmlNodeList advisorNodes = element.SelectNodes("*[local-name()='advisor' and namespace-uri()='" + element.NamespaceURI + "']"); + foreach (XmlElement advisorElement in advisorNodes) + { + ParseAdvisor(advisorElement, parserContext); + } + + return null; + } + + /// + /// Parses the supplied advisor element and registers the resulting + /// + /// The advisor element. + /// The parser context. + private void ParseAdvisor(XmlElement advisorElement, ParserContext parserContext) + { + AbstractObjectDefinition advisorDef = CreateAdvisorObjectDefinition(advisorElement, parserContext); + string id = advisorElement.GetAttribute(ID); + + string pointcutObjectName = ParsePointcutProperty(advisorElement, parserContext); + advisorDef.PropertyValues.Add(POINTCUT_REF, new RuntimeObjectReference(pointcutObjectName)); + string advisorObjectName = id; + if (StringUtils.HasText(advisorObjectName)) + { + parserContext.Registry.RegisterObjectDefinition(advisorObjectName, advisorDef); + } + else + { + parserContext.ReaderContext.RegisterWithGeneratedName(advisorDef); + } + } + + + private string ParsePointcutProperty(XmlElement element, ParserContext parserContext) + { + if (element.HasAttribute(POINTCUT_REF)) + { + string pointcutRef = element.GetAttribute(POINTCUT_REF); + if (!StringUtils.HasText(pointcutRef)) + { + parserContext.ReaderContext.ReportException(element, "advisor", "'pointcut-ref' attribute contains empty value."); + } + return pointcutRef; + } + else + { + parserContext.ReaderContext.ReportException(element, "advisor", "'must define 'pointcut-ref' on tag."); + return null; + } + } + + + private AbstractObjectDefinition CreateAdvisorObjectDefinition(XmlElement advisorElement, ParserContext parserContext) + { + ObjectDefinitionBuilder advisorDefinitionBuilder = + parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof(DefaultObjectFactoryPointcutAdvisor)); + + if (advisorElement.HasAttribute(ORDER_PROPERTY)) + { + advisorDefinitionBuilder.AddPropertyValue(ORDER_PROPERTY, advisorElement.GetAttribute(ORDER_PROPERTY)); + } + + advisorDefinitionBuilder.AddPropertyValue(ADVICE_OBJECT_NAME, advisorElement.GetAttribute(ADVICE_REF)); + + + return advisorDefinitionBuilder.ObjectDefinition; + } + + + private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element) + { + AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element); + + bool proxyTargetClass = + parserContext.ParserHelper.IsTrueStringValue(element.GetAttribute(PROXY_TARGET_TYPE)); + if (proxyTargetClass) + { + AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AbstractMethodInvocation.cs b/src/Spring/Spring.Aop/Aop/Framework/AbstractMethodInvocation.cs index ddb7dbf8..945a450d 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AbstractMethodInvocation.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AbstractMethodInvocation.cs @@ -1,350 +1,349 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Text; - -using AopAlliance.Intercept; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Convenience base class for - /// implementations. - /// - /// - ///

- /// Subclasses can override the - /// - /// method to change this behavior, so this is a useful/ base class for - /// implementations. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// Rick Evans (.NET) - /// Bruno Baia (.NET) - /// $Id: AbstractMethodInvocation.cs,v 1.8 2007/07/05 20:29:21 bbaia Exp $ - [Serializable] - public abstract class AbstractMethodInvocation : IMethodInvocation - { - /// - /// The arguments (if any = may be ) to the method - /// that is to be invoked. - /// - protected object[] arguments; - - /// - /// The target object that the method is to be invoked on. - /// - protected object target; - - /// - /// The AOP proxy for the target object. - /// - protected object proxy; - - /// - /// The method invocation that is to be invoked. - /// - protected MethodInfo method; - - /// - /// The list of and - /// - /// that need dynamic checks. - /// - protected IList interceptors; - - /// - /// The declaring type of the method that is to be invoked. - /// - protected Type targetType; - - /// - /// The index from 0 of the current interceptor we're invoking. - /// - protected int currentInterceptorIndex; - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an abstract class, and as such exposes no publicly visible - /// constructors. - ///

- ///

- /// - /// The list can also contain any - /// s - /// that need evaluation at runtime. - /// s included in an - /// - /// must already have been found to have matched as far as was possible - /// statically. Passing an array might be about 10% faster, but - /// would complicate the code, and it would work only for static - /// pointcuts. - /// - ///

- ///
- /// The AOP proxy. - /// The target object. - /// the target method. - /// The target method's arguments. - /// - /// The of the target object. - /// - /// The list of interceptors that are to be applied. May be - /// . - /// - /// - /// If the is . - /// - protected AbstractMethodInvocation(object proxy, object target, - MethodInfo method, object[] arguments, Type targetType, IList interceptors) - { - #region Sanity Check - - AssertUtils.ArgumentNotNull(target, "target"); - AssertUtils.ArgumentNotNull(method, "method"); - - #endregion - - this.proxy = proxy; - this.target = target; - this.method = method; - this.targetType = targetType; - this.arguments = arguments; - this.interceptors = interceptors; - } - - /// - /// Gets the method invocation that is to be invoked. - /// - /// - ///

- /// May or may not correspond with a method invoked on an underlying - /// implementation of that interface. - ///

- ///
- /// - public virtual MethodInfo Method - { - get { return method; } - } - - /// - /// Gets the static part of this joinpoint. - /// - /// - /// The proxied member's information. - /// - /// - public virtual MemberInfo StaticPart - { - get { return Method; } - } - - /// - /// Gets the proxy that this interception was made through. - /// - /// - /// The proxy that this interception was made through. - /// - public virtual object Proxy - { - get { return this.proxy; } - } - /// - /// Gets the target object for the invocation. - /// - /// - /// The target object for this method invocation. - /// - public virtual object Target - { - get { return this.target; } - } - /// - /// Gets the type of the target object. - /// - /// - /// The type of the target object. - /// - public virtual Type TargetType - { - get { return this.targetType; } - } - - /// - /// Gets and sets the arguments (if any - may be ) - /// to the method that is to be invoked. - /// - /// - /// The arguments (if any - may be ) to the - /// method that is to be invoked. - /// - /// - public virtual object[] Arguments - { - get { return this.arguments; } - set { this.arguments = value; } - } - - /// - /// The list of method interceptors. - /// - /// - ///

- /// May be . - ///

- ///
- public virtual IList Interceptors - { - get { return this.interceptors; } - set { this.interceptors = value; } - } - - /// - /// Gets the target object. - /// - public virtual object This - { - get { return this.target; } - } - - /// - /// Proceeds to the next interceptor in the chain. - /// - /// - /// The return value of the method invocation. - /// - /// - /// If any of the interceptors at the joinpoint throws an exception. - /// - /// - public virtual object Proceed() - { - if (this.interceptors == null || - this.currentInterceptorIndex == this.interceptors.Count) - { - return InvokeJoinpoint(); - } - object interceptor = this.interceptors[this.currentInterceptorIndex]; - InterceptorAndDynamicMethodMatcher dynamicMatcher - = interceptor as InterceptorAndDynamicMethodMatcher; - IMethodInvocation nextInvocation = PrepareMethodInvocationForProceed(this); - if (dynamicMatcher != null) - { - // evaluate dynamic method matcher here: static part will already have - // been evaluated and found to match... - if (dynamicMatcher.MethodMatcher.Matches( - nextInvocation.Method, nextInvocation.TargetType, nextInvocation.Arguments)) - { - return dynamicMatcher.Interceptor.Invoke(nextInvocation); - } - else - { - // dynamic match failed; skip this interceptor and invoke the next in the chain... - return nextInvocation.Proceed(); - } - } - else - { - // it's an interceptor so we just invoke it: the pointcut will have - // been evaluated statically before this object was constructed... - return ((IMethodInterceptor)interceptor).Invoke(nextInvocation); - } - } - - /// - /// Retrieves a new instance - /// for the next Proceed method call. - /// - /// - /// The current instance. - /// - /// - /// The new instance to use. - /// - /// - protected abstract IMethodInvocation PrepareMethodInvocationForProceed( - IMethodInvocation invocation); - - /// - /// Invokes the joinpoint. - /// - /// - ///

- /// Subclasses can override this to use custom invocation. - ///

- ///
- /// - /// The return value of the invocation of the joinpoint. - /// - /// - /// If invoking the joinpoint resulted in an exception. - /// - /// - protected abstract object InvokeJoinpoint(); - - /// - /// A that represents the current - /// invocation. - /// - /// - ///

- /// - /// Does not invoke on the - /// target - /// object, as that too may be proxied. - /// - ///

- ///
- /// - /// A that represents the current invocation. - /// - public override string ToString() - { - StringBuilder buffer = new StringBuilder("Invocation: method '"); - buffer.Append(Method.Name).Append("', ").Append("arguments "); - buffer.Append(this.arguments != null ? StringUtils.ArrayToCommaDelimitedString(this.arguments) : "[none]"); - buffer.Append("; "); - if (this.target == null) - { - buffer.Append("target is null."); - } - else - { - buffer.Append("target is of Type [").Append(this.targetType.FullName).Append(']'); - } - return buffer.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Text; + +using AopAlliance.Intercept; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Convenience base class for + /// implementations. + /// + /// + ///

+ /// Subclasses can override the + /// + /// method to change this behavior, so this is a useful/ base class for + /// implementations. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// Rick Evans (.NET) + /// Bruno Baia (.NET) + [Serializable] + public abstract class AbstractMethodInvocation : IMethodInvocation + { + /// + /// The arguments (if any = may be ) to the method + /// that is to be invoked. + /// + protected object[] arguments; + + /// + /// The target object that the method is to be invoked on. + /// + protected object target; + + /// + /// The AOP proxy for the target object. + /// + protected object proxy; + + /// + /// The method invocation that is to be invoked. + /// + protected MethodInfo method; + + /// + /// The list of and + /// + /// that need dynamic checks. + /// + protected IList interceptors; + + /// + /// The declaring type of the method that is to be invoked. + /// + protected Type targetType; + + /// + /// The index from 0 of the current interceptor we're invoking. + /// + protected int currentInterceptorIndex; + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an abstract class, and as such exposes no publicly visible + /// constructors. + ///

+ ///

+ /// + /// The list can also contain any + /// s + /// that need evaluation at runtime. + /// s included in an + /// + /// must already have been found to have matched as far as was possible + /// statically. Passing an array might be about 10% faster, but + /// would complicate the code, and it would work only for static + /// pointcuts. + /// + ///

+ ///
+ /// The AOP proxy. + /// The target object. + /// the target method. + /// The target method's arguments. + /// + /// The of the target object. + /// + /// The list of interceptors that are to be applied. May be + /// . + /// + /// + /// If the is . + /// + protected AbstractMethodInvocation(object proxy, object target, + MethodInfo method, object[] arguments, Type targetType, IList interceptors) + { + #region Sanity Check + + AssertUtils.ArgumentNotNull(target, "target"); + AssertUtils.ArgumentNotNull(method, "method"); + + #endregion + + this.proxy = proxy; + this.target = target; + this.method = method; + this.targetType = targetType; + this.arguments = arguments; + this.interceptors = interceptors; + } + + /// + /// Gets the method invocation that is to be invoked. + /// + /// + ///

+ /// May or may not correspond with a method invoked on an underlying + /// implementation of that interface. + ///

+ ///
+ /// + public virtual MethodInfo Method + { + get { return method; } + } + + /// + /// Gets the static part of this joinpoint. + /// + /// + /// The proxied member's information. + /// + /// + public virtual MemberInfo StaticPart + { + get { return Method; } + } + + /// + /// Gets the proxy that this interception was made through. + /// + /// + /// The proxy that this interception was made through. + /// + public virtual object Proxy + { + get { return this.proxy; } + } + /// + /// Gets the target object for the invocation. + /// + /// + /// The target object for this method invocation. + /// + public virtual object Target + { + get { return this.target; } + } + /// + /// Gets the type of the target object. + /// + /// + /// The type of the target object. + /// + public virtual Type TargetType + { + get { return this.targetType; } + } + + /// + /// Gets and sets the arguments (if any - may be ) + /// to the method that is to be invoked. + /// + /// + /// The arguments (if any - may be ) to the + /// method that is to be invoked. + /// + /// + public virtual object[] Arguments + { + get { return this.arguments; } + set { this.arguments = value; } + } + + /// + /// The list of method interceptors. + /// + /// + ///

+ /// May be . + ///

+ ///
+ public virtual IList Interceptors + { + get { return this.interceptors; } + set { this.interceptors = value; } + } + + /// + /// Gets the target object. + /// + public virtual object This + { + get { return this.target; } + } + + /// + /// Proceeds to the next interceptor in the chain. + /// + /// + /// The return value of the method invocation. + /// + /// + /// If any of the interceptors at the joinpoint throws an exception. + /// + /// + public virtual object Proceed() + { + if (this.interceptors == null || + this.currentInterceptorIndex == this.interceptors.Count) + { + return InvokeJoinpoint(); + } + object interceptor = this.interceptors[this.currentInterceptorIndex]; + InterceptorAndDynamicMethodMatcher dynamicMatcher + = interceptor as InterceptorAndDynamicMethodMatcher; + IMethodInvocation nextInvocation = PrepareMethodInvocationForProceed(this); + if (dynamicMatcher != null) + { + // evaluate dynamic method matcher here: static part will already have + // been evaluated and found to match... + if (dynamicMatcher.MethodMatcher.Matches( + nextInvocation.Method, nextInvocation.TargetType, nextInvocation.Arguments)) + { + return dynamicMatcher.Interceptor.Invoke(nextInvocation); + } + else + { + // dynamic match failed; skip this interceptor and invoke the next in the chain... + return nextInvocation.Proceed(); + } + } + else + { + // it's an interceptor so we just invoke it: the pointcut will have + // been evaluated statically before this object was constructed... + return ((IMethodInterceptor)interceptor).Invoke(nextInvocation); + } + } + + /// + /// Retrieves a new instance + /// for the next Proceed method call. + /// + /// + /// The current instance. + /// + /// + /// The new instance to use. + /// + /// + protected abstract IMethodInvocation PrepareMethodInvocationForProceed( + IMethodInvocation invocation); + + /// + /// Invokes the joinpoint. + /// + /// + ///

+ /// Subclasses can override this to use custom invocation. + ///

+ ///
+ /// + /// The return value of the invocation of the joinpoint. + /// + /// + /// If invoking the joinpoint resulted in an exception. + /// + /// + protected abstract object InvokeJoinpoint(); + + /// + /// A that represents the current + /// invocation. + /// + /// + ///

+ /// + /// Does not invoke on the + /// target + /// object, as that too may be proxied. + /// + ///

+ ///
+ /// + /// A that represents the current invocation. + /// + public override string ToString() + { + StringBuilder buffer = new StringBuilder("Invocation: method '"); + buffer.Append(Method.Name).Append("', ").Append("arguments "); + buffer.Append(this.arguments != null ? StringUtils.ArrayToCommaDelimitedString(this.arguments) : "[none]"); + buffer.Append("; "); + if (this.target == null) + { + buffer.Append("target is null."); + } + else + { + buffer.Append("target is of Type [").Append(this.targetType.FullName).Append(']'); + } + return buffer.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/AdvisorAdapterRegistrationManager.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/AdvisorAdapterRegistrationManager.cs index 943ec624..09f251a8 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/AdvisorAdapterRegistrationManager.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/AdvisorAdapterRegistrationManager.cs @@ -1,110 +1,109 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// implementation - /// that registers instances of any non-default - /// instances with the - /// - /// singleton. - /// - /// - ///

- /// The only requirement for it to work is that it needs to be defined - /// in an application context along with any arbitrary "non-native" Spring.NET - /// instances that need - /// to be recognized by Spring.NET's AOP framework. - ///

- ///
- /// Dmitriy Kopylenko - /// Aleksandar Seovic (.NET) - /// $Id: AdvisorAdapterRegistrationManager.cs,v 1.5 2007/08/22 08:49:08 markpollack Exp $ - public class AdvisorAdapterRegistrationManager : IObjectPostProcessor - { - /// - /// Apply this - /// to the given new object instance before any object initialization callbacks. - /// - /// - ///

- /// Does nothing, simply returns the supplied as is. - ///

- ///
- /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - public virtual object PostProcessBeforeInitialization(object instance, string name) - { - return instance; - } - - /// - /// Apply this to the - /// given new object instance after any object initialization callbacks. - /// - /// - ///

- /// Registers the supplied with the - /// - /// singleton if it is an - /// instance. - ///

- ///
- /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - public virtual object PostProcessAfterInitialization(object instance, string objectName) - { - IAdvisorAdapter adapter = instance as IAdvisorAdapter; - if (adapter != null) - { - GlobalAdvisorAdapterRegistry.Instance.RegisterAdvisorAdapter(adapter); - } - return instance; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// implementation + /// that registers instances of any non-default + /// instances with the + /// + /// singleton. + /// + /// + ///

+ /// The only requirement for it to work is that it needs to be defined + /// in an application context along with any arbitrary "non-native" Spring.NET + /// instances that need + /// to be recognized by Spring.NET's AOP framework. + ///

+ ///
+ /// Dmitriy Kopylenko + /// Aleksandar Seovic (.NET) + public class AdvisorAdapterRegistrationManager : IObjectPostProcessor + { + /// + /// Apply this + /// to the given new object instance before any object initialization callbacks. + /// + /// + ///

+ /// Does nothing, simply returns the supplied as is. + ///

+ ///
+ /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + public virtual object PostProcessBeforeInitialization(object instance, string name) + { + return instance; + } + + /// + /// Apply this to the + /// given new object instance after any object initialization callbacks. + /// + /// + ///

+ /// Registers the supplied with the + /// + /// singleton if it is an + /// instance. + ///

+ ///
+ /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + public virtual object PostProcessAfterInitialization(object instance, string objectName) + { + IAdvisorAdapter adapter = instance as IAdvisorAdapter; + if (adapter != null) + { + GlobalAdvisorAdapterRegistry.Instance.RegisterAdvisorAdapter(adapter); + } + return instance; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceAdapter.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceAdapter.cs index ad2d38ff..10eb92f3 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceAdapter.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceAdapter.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// implementation - /// to enable to be used in the - /// Spring.NET AOP framework. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: AfterReturningAdviceAdapter.cs,v 1.5 2007/03/16 04:01:20 aseovic Exp $ - [Serializable] - internal class AfterReturningAdviceAdapter : IAdvisorAdapter - { - /// - /// Returns if the supplied - /// is an instance of the - /// interface. - /// - /// The advice to check. - /// - /// if the supplied is - /// an instance of the interface; - /// if not or if the supplied - /// is . - /// - public virtual bool SupportsAdvice(IAdvice advice) - { - return advice is IAfterReturningAdvice; - } - - /// - /// Wraps the supplied 's - /// within a - /// - /// instance. - /// - /// - /// The advisor exposing the that - /// is to be wrapped. - /// - /// - /// The supplied 's - /// wrapped within a - /// - /// instance. - /// - public virtual IInterceptor GetInterceptor(IAdvisor advisor) - { - IAfterReturningAdvice advice = (IAfterReturningAdvice) advisor.Advice; - return new AfterReturningAdviceInterceptor(advice); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// implementation + /// to enable to be used in the + /// Spring.NET AOP framework. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + internal class AfterReturningAdviceAdapter : IAdvisorAdapter + { + /// + /// Returns if the supplied + /// is an instance of the + /// interface. + /// + /// The advice to check. + /// + /// if the supplied is + /// an instance of the interface; + /// if not or if the supplied + /// is . + /// + public virtual bool SupportsAdvice(IAdvice advice) + { + return advice is IAfterReturningAdvice; + } + + /// + /// Wraps the supplied 's + /// within a + /// + /// instance. + /// + /// + /// The advisor exposing the that + /// is to be wrapped. + /// + /// + /// The supplied 's + /// wrapped within a + /// + /// instance. + /// + public virtual IInterceptor GetInterceptor(IAdvisor advisor) + { + IAfterReturningAdvice advice = (IAfterReturningAdvice) advisor.Advice; + return new AfterReturningAdviceInterceptor(advice); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceInterceptor.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceInterceptor.cs index 3288fcd9..89ef5a17 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceInterceptor.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/AfterReturningAdviceInterceptor.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Intercept; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// Interceptor to wrap an - /// instance. - /// - /// - ///

- /// A more efficient alternative solution in cases where there is no - /// interception advice and therefore no need to create an - /// object may be - /// offered in future. - ///

- ///

- /// Used internally by the AOP framework: application developers should not need - /// to use this class directly. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: AfterReturningAdviceInterceptor.cs,v 1.8 2007/03/16 04:01:21 aseovic Exp $ - [Serializable] - public sealed class AfterReturningAdviceInterceptor : IMethodInterceptor - { - private IAfterReturningAdvice advice; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The advice to be applied after a target method successfully - /// returns. - /// - /// - /// If the supplied is . - /// - public AfterReturningAdviceInterceptor(IAfterReturningAdvice advice) - { - AssertUtils.ArgumentNotNull(advice, "advice"); - this.advice = advice; - } - - /// - /// Executes interceptor after the target method successfully returns. - /// - /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied ; this return value may - /// well have been intercepted by the interceptor. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public object Invoke(IMethodInvocation invocation) - { - object returnValue = invocation.Proceed(); - advice.AfterReturning( - returnValue, invocation.Method, invocation.Arguments, invocation.This); - return returnValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Intercept; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// Interceptor to wrap an + /// instance. + /// + /// + ///

+ /// A more efficient alternative solution in cases where there is no + /// interception advice and therefore no need to create an + /// object may be + /// offered in future. + ///

+ ///

+ /// Used internally by the AOP framework: application developers should not need + /// to use this class directly. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class AfterReturningAdviceInterceptor : IMethodInterceptor + { + private IAfterReturningAdvice advice; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The advice to be applied after a target method successfully + /// returns. + /// + /// + /// If the supplied is . + /// + public AfterReturningAdviceInterceptor(IAfterReturningAdvice advice) + { + AssertUtils.ArgumentNotNull(advice, "advice"); + this.advice = advice; + } + + /// + /// Executes interceptor after the target method successfully returns. + /// + /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied ; this return value may + /// well have been intercepted by the interceptor. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public object Invoke(IMethodInvocation invocation) + { + object returnValue = invocation.Proceed(); + advice.AfterReturning( + returnValue, invocation.Method, invocation.Arguments, invocation.This); + return returnValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/BeforeAdviceAdapter.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/BeforeAdviceAdapter.cs index 4bff5394..a5bd744b 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/BeforeAdviceAdapter.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/BeforeAdviceAdapter.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// implementation - /// to enable to be used in the - /// Spring.NET AOP framework. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: BeforeAdviceAdapter.cs,v 1.4 2007/03/16 04:01:21 aseovic Exp $ - [Serializable] - internal class BeforeAdviceAdapter : IAdvisorAdapter - { - /// - /// Returns if the supplied - /// is an instance of the - /// interface. - /// - /// The advice to check. - /// - /// if the supplied is - /// an instance of the interface; - /// if not or if the supplied - /// is . - /// - public virtual bool SupportsAdvice(IAdvice advice) - { - return advice is IMethodBeforeAdvice; - } - - /// - /// Wraps the supplied 's - /// within a - /// - /// instance. - /// - /// - /// The advisor exposing the that - /// is to be wrapped. - /// - /// - /// The supplied 's - /// wrapped within a - /// - /// instance. - /// - public virtual IInterceptor GetInterceptor(IAdvisor advisor) - { - IMethodBeforeAdvice advice = (IMethodBeforeAdvice) advisor.Advice; - return new MethodBeforeAdviceInterceptor(advice); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// implementation + /// to enable to be used in the + /// Spring.NET AOP framework. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + internal class BeforeAdviceAdapter : IAdvisorAdapter + { + /// + /// Returns if the supplied + /// is an instance of the + /// interface. + /// + /// The advice to check. + /// + /// if the supplied is + /// an instance of the interface; + /// if not or if the supplied + /// is . + /// + public virtual bool SupportsAdvice(IAdvice advice) + { + return advice is IMethodBeforeAdvice; + } + + /// + /// Wraps the supplied 's + /// within a + /// + /// instance. + /// + /// + /// The advisor exposing the that + /// is to be wrapped. + /// + /// + /// The supplied 's + /// wrapped within a + /// + /// instance. + /// + public virtual IInterceptor GetInterceptor(IAdvisor advisor) + { + IMethodBeforeAdvice advice = (IMethodBeforeAdvice) advisor.Advice; + return new MethodBeforeAdviceInterceptor(advice); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs index 432d4e8b..81f99df4 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs @@ -1,156 +1,155 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -using AopAlliance.Aop; -using AopAlliance.Intercept; - -using Spring.Aop; -using Spring.Aop.Support; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// Default implementation of the - /// - /// interface. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: DefaultAdvisorAdapterRegistry.cs,v 1.5 2006/04/09 07:18:35 markpollack Exp $ - public class DefaultAdvisorAdapterRegistry : IAdvisorAdapterRegistry - { - private IList adapters = new ArrayList(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This constructor will also register the well-known - /// types. - ///

- ///
- /// - public DefaultAdvisorAdapterRegistry() - { - // register well-known adapters... - RegisterAdvisorAdapter(new BeforeAdviceAdapter()); - RegisterAdvisorAdapter(new AfterReturningAdviceAdapter()); - RegisterAdvisorAdapter(new ThrowsAdviceAdapter()); - } - - /// - /// Returns an wrapping the supplied - /// . - /// - /// - /// The object that should be an advice, such as - /// or - /// . - /// - /// - /// An wrapping the supplied - /// . Never returns . If - /// the parameter is an - /// , it will simply be returned. - /// - /// - /// If no registered - /// can wrap - /// the supplied . - /// - public virtual IAdvisor Wrap(object advice) - { - if (advice is IAdvisor) - { - return (IAdvisor) advice; - } - if (!(advice is IAdvice)) - { - throw new UnknownAdviceTypeException(advice); - } - IAdvice adviceObject = (IAdvice) advice; - if (adviceObject is IInterceptor) - { - // so well-known it doesn't even need an adapter... - return new DefaultPointcutAdvisor(adviceObject); - } - foreach (IAdvisorAdapter adapter in this.adapters) - { - // check that it is supported... - if (adapter.SupportsAdvice(adviceObject)) - { - return new DefaultPointcutAdvisor(adviceObject); - } - } - throw new UnknownAdviceTypeException(advice); - } - - /// - /// Returns an to - /// allow the use of the supplied in an - /// interception-based framework. - /// - /// The advisor to find an interceptor for. - /// - /// An interceptor to expose this advisor's behaviour. - /// - /// - /// If the advisor type is not understood by any registered - /// . - /// - public virtual IInterceptor GetInterceptor(IAdvisor advisor) - { - IAdvice advice = advisor.Advice; - if (advice is IInterceptor) - { - return (IInterceptor) advice; - } - foreach (IAdvisorAdapter adapter in this.adapters) - { - if (adapter.SupportsAdvice(advice)) - { - return adapter.GetInterceptor(advisor); - } - } - throw new UnknownAdviceTypeException(advice); - } - - /// - /// Register the given . - /// - /// - /// An that - /// understands the particular advisor and advice types. - /// - public virtual void RegisterAdvisorAdapter(IAdvisorAdapter adapter) - { - this.adapters.Add(adapter); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +using AopAlliance.Aop; +using AopAlliance.Intercept; + +using Spring.Aop; +using Spring.Aop.Support; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// Default implementation of the + /// + /// interface. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public class DefaultAdvisorAdapterRegistry : IAdvisorAdapterRegistry + { + private IList adapters = new ArrayList(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This constructor will also register the well-known + /// types. + ///

+ ///
+ /// + public DefaultAdvisorAdapterRegistry() + { + // register well-known adapters... + RegisterAdvisorAdapter(new BeforeAdviceAdapter()); + RegisterAdvisorAdapter(new AfterReturningAdviceAdapter()); + RegisterAdvisorAdapter(new ThrowsAdviceAdapter()); + } + + /// + /// Returns an wrapping the supplied + /// . + /// + /// + /// The object that should be an advice, such as + /// or + /// . + /// + /// + /// An wrapping the supplied + /// . Never returns . If + /// the parameter is an + /// , it will simply be returned. + /// + /// + /// If no registered + /// can wrap + /// the supplied . + /// + public virtual IAdvisor Wrap(object advice) + { + if (advice is IAdvisor) + { + return (IAdvisor) advice; + } + if (!(advice is IAdvice)) + { + throw new UnknownAdviceTypeException(advice); + } + IAdvice adviceObject = (IAdvice) advice; + if (adviceObject is IInterceptor) + { + // so well-known it doesn't even need an adapter... + return new DefaultPointcutAdvisor(adviceObject); + } + foreach (IAdvisorAdapter adapter in this.adapters) + { + // check that it is supported... + if (adapter.SupportsAdvice(adviceObject)) + { + return new DefaultPointcutAdvisor(adviceObject); + } + } + throw new UnknownAdviceTypeException(advice); + } + + /// + /// Returns an to + /// allow the use of the supplied in an + /// interception-based framework. + /// + /// The advisor to find an interceptor for. + /// + /// An interceptor to expose this advisor's behaviour. + /// + /// + /// If the advisor type is not understood by any registered + /// . + /// + public virtual IInterceptor GetInterceptor(IAdvisor advisor) + { + IAdvice advice = advisor.Advice; + if (advice is IInterceptor) + { + return (IInterceptor) advice; + } + foreach (IAdvisorAdapter adapter in this.adapters) + { + if (adapter.SupportsAdvice(advice)) + { + return adapter.GetInterceptor(advisor); + } + } + throw new UnknownAdviceTypeException(advice); + } + + /// + /// Register the given . + /// + /// + /// An that + /// understands the particular advisor and advice types. + /// + public virtual void RegisterAdvisorAdapter(IAdvisorAdapter adapter) + { + this.adapters.Add(adapter); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/GlobalAdvisorAdapterRegistry.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/GlobalAdvisorAdapterRegistry.cs index 8bb50524..b321f2b7 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/GlobalAdvisorAdapterRegistry.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/GlobalAdvisorAdapterRegistry.cs @@ -1,67 +1,66 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// Provides Singleton-style access to the default - /// instance. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: GlobalAdvisorAdapterRegistry.cs,v 1.5 2006/04/09 07:18:35 markpollack Exp $ - public sealed class GlobalAdvisorAdapterRegistry : DefaultAdvisorAdapterRegistry - { - private static readonly GlobalAdvisorAdapterRegistry instance - = new GlobalAdvisorAdapterRegistry(); - - /// - /// The default instance. - /// - public static GlobalAdvisorAdapterRegistry Instance - { - get { return instance; } - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This contructor is marked as to enforce the - /// Singleton pattern - ///

- ///
- private GlobalAdvisorAdapterRegistry() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// Provides Singleton-style access to the default + /// instance. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public sealed class GlobalAdvisorAdapterRegistry : DefaultAdvisorAdapterRegistry + { + private static readonly GlobalAdvisorAdapterRegistry instance + = new GlobalAdvisorAdapterRegistry(); + + /// + /// The default instance. + /// + public static GlobalAdvisorAdapterRegistry Instance + { + get { return instance; } + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This contructor is marked as to enforce the + /// Singleton pattern + ///

+ ///
+ private GlobalAdvisorAdapterRegistry() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapter.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapter.cs index ffbc16e2..8aee8821 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapter.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapter.cs @@ -1,100 +1,99 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// Permits the handling of new advisors and advice types as extensions to - /// the Spring AOP framework. - /// - /// - ///

- /// Implementors can create AOP Alliance - /// s from custom advice - /// types, enabling these advice types to be used in the Spring.NET AOP - /// framework, which uses interception under the covers. - ///

- ///

- /// There is no need for most Spring.NET users to implement this interface; - /// do so only if you need to introduce more - /// or - /// types to Spring.NET. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAdvisorAdapter.cs,v 1.4 2006/04/09 07:18:35 markpollack Exp $ - public interface IAdvisorAdapter - { - /// - /// Does this adapter understand the supplied ? - /// - /// - ///

- /// Is it valid to invoke the - /// - /// method with the given advice as an argument? - ///

- ///
- /// - /// such as - /// . - /// - /// if this adapter understands the - /// supplied . - /// - bool SupportsAdvice(IAdvice advice); - - /// - /// Return an AOP Alliance - /// exposing the - /// behaviour of the given advice to an interception-based AOP - /// framework. - /// - /// - ///

- /// Don't worry about any - /// contained in the supplied ; - /// the AOP framework will take care of checking the pointcut. - ///

- ///
- /// - /// The advice. The - /// - /// method must have previously returned on the - /// supplied . - /// - /// - /// An AOP Alliance - /// exposing the - /// behaviour of the given advice to an interception-based AOP - /// framework. - /// - IInterceptor GetInterceptor(IAdvisor advisor); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// Permits the handling of new advisors and advice types as extensions to + /// the Spring AOP framework. + /// + /// + ///

+ /// Implementors can create AOP Alliance + /// s from custom advice + /// types, enabling these advice types to be used in the Spring.NET AOP + /// framework, which uses interception under the covers. + ///

+ ///

+ /// There is no need for most Spring.NET users to implement this interface; + /// do so only if you need to introduce more + /// or + /// types to Spring.NET. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IAdvisorAdapter + { + /// + /// Does this adapter understand the supplied ? + /// + /// + ///

+ /// Is it valid to invoke the + /// + /// method with the given advice as an argument? + ///

+ ///
+ /// + /// such as + /// . + /// + /// if this adapter understands the + /// supplied . + /// + bool SupportsAdvice(IAdvice advice); + + /// + /// Return an AOP Alliance + /// exposing the + /// behaviour of the given advice to an interception-based AOP + /// framework. + /// + /// + ///

+ /// Don't worry about any + /// contained in the supplied ; + /// the AOP framework will take care of checking the pointcut. + ///

+ ///
+ /// + /// The advice. The + /// + /// method must have previously returned on the + /// supplied . + /// + /// + /// An AOP Alliance + /// exposing the + /// behaviour of the given advice to an interception-based AOP + /// framework. + /// + IInterceptor GetInterceptor(IAdvisor advisor); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapterRegistry.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapterRegistry.cs index 125cd0a1..833f3774 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapterRegistry.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/IAdvisorAdapterRegistry.cs @@ -1,114 +1,113 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// A registry of - /// instances. - /// - /// - ///

- /// Implementations must also automatically register adapters for - /// types. - ///

- /// - /// This is an SPI interface, that should not need to be implemented by any - /// Spring.NET user. - /// - ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAdvisorAdapterRegistry.cs,v 1.3 2006/04/09 07:18:35 markpollack Exp $ - public interface IAdvisorAdapterRegistry - { - /// - /// Returns an wrapping the supplied - /// . - /// - /// - /// The object that should be an advice, such as - /// or - /// . - /// - /// - /// An wrapping the supplied - /// . Never returns . If - /// the parameter is an - /// , it will simply be returned. - /// - /// - /// If no registered - /// can wrap - /// the supplied . - /// - IAdvisor Wrap(object advice); - - /// - /// Returns an to - /// allow the use of the supplied in an - /// interception-based framework. - /// - /// - ///

- /// Don't worry about the pointcut associated with the - /// ; if it's an - /// , just return an - /// interceptor. - ///

- ///
- /// - /// The advisor to find an interceptor for. - /// - /// - /// An interceptor to expose this advisor's behaviour. - /// - /// - /// If the advisor type is not understood by any registered - /// . - /// - IInterceptor GetInterceptor(IAdvisor advisor); - - /// - /// Register the given . - /// - /// - ///

- /// Note that it is not necessary to register adapters for - /// instances: these - /// must be automatically recognized by an - /// - /// implementation. - ///

- ///
- /// - /// An that - /// understands the particular advisor and advice types. - /// - void RegisterAdvisorAdapter(IAdvisorAdapter adapter); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// A registry of + /// instances. + /// + /// + ///

+ /// Implementations must also automatically register adapters for + /// types. + ///

+ /// + /// This is an SPI interface, that should not need to be implemented by any + /// Spring.NET user. + /// + ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IAdvisorAdapterRegistry + { + /// + /// Returns an wrapping the supplied + /// . + /// + /// + /// The object that should be an advice, such as + /// or + /// . + /// + /// + /// An wrapping the supplied + /// . Never returns . If + /// the parameter is an + /// , it will simply be returned. + /// + /// + /// If no registered + /// can wrap + /// the supplied . + /// + IAdvisor Wrap(object advice); + + /// + /// Returns an to + /// allow the use of the supplied in an + /// interception-based framework. + /// + /// + ///

+ /// Don't worry about the pointcut associated with the + /// ; if it's an + /// , just return an + /// interceptor. + ///

+ ///
+ /// + /// The advisor to find an interceptor for. + /// + /// + /// An interceptor to expose this advisor's behaviour. + /// + /// + /// If the advisor type is not understood by any registered + /// . + /// + IInterceptor GetInterceptor(IAdvisor advisor); + + /// + /// Register the given . + /// + /// + ///

+ /// Note that it is not necessary to register adapters for + /// instances: these + /// must be automatically recognized by an + /// + /// implementation. + ///

+ ///
+ /// + /// An that + /// understands the particular advisor and advice types. + /// + void RegisterAdvisorAdapter(IAdvisorAdapter adapter); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/MethodBeforeAdviceInterceptor.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/MethodBeforeAdviceInterceptor.cs index ad558e5a..1ebd20f2 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/MethodBeforeAdviceInterceptor.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/MethodBeforeAdviceInterceptor.cs @@ -1,93 +1,92 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Intercept; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// implementation that - /// wraps instances. - /// - /// - ///

- /// In the future Spring.NET may also offer a more efficient alternative - /// solution in cases where there is no interception advice and therefore - /// no need to create an - /// object. - ///

- ///

- /// Used internally by the Spring.NET AOP framework: application developers - /// should not need to use this class directly. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: MethodBeforeAdviceInterceptor.cs,v 1.5 2007/03/16 04:01:21 aseovic Exp $ - [Serializable] - internal sealed class MethodBeforeAdviceInterceptor : IMethodInterceptor - { - private IMethodBeforeAdvice advice; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The that is to be wrapped. - /// - /// - /// If the supplied is . - /// - public MethodBeforeAdviceInterceptor(IMethodBeforeAdvice advice) - { - AssertUtils.ArgumentNotNull(advice, "advice"); - this.advice = advice; - } - - /// - /// Executes interceptor before the target method successfully returns. - /// - /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied . - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public object Invoke(IMethodInvocation invocation) - { - advice.Before(invocation.Method, invocation.Arguments, invocation.This); - return invocation.Proceed(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Intercept; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// implementation that + /// wraps instances. + /// + /// + ///

+ /// In the future Spring.NET may also offer a more efficient alternative + /// solution in cases where there is no interception advice and therefore + /// no need to create an + /// object. + ///

+ ///

+ /// Used internally by the Spring.NET AOP framework: application developers + /// should not need to use this class directly. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + internal sealed class MethodBeforeAdviceInterceptor : IMethodInterceptor + { + private IMethodBeforeAdvice advice; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The that is to be wrapped. + /// + /// + /// If the supplied is . + /// + public MethodBeforeAdviceInterceptor(IMethodBeforeAdvice advice) + { + AssertUtils.ArgumentNotNull(advice, "advice"); + this.advice = advice; + } + + /// + /// Executes interceptor before the target method successfully returns. + /// + /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied . + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public object Invoke(IMethodInvocation invocation) + { + advice.Before(invocation.Method, invocation.Arguments, invocation.This); + return invocation.Proceed(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceAdapter.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceAdapter.cs index 5730836a..8a97dd35 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceAdapter.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceAdapter.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// implementation - /// to enable to be used in the - /// Spring.NET AOP framework. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: ThrowsAdviceAdapter.cs,v 1.4 2007/03/16 04:01:21 aseovic Exp $ - [Serializable] - internal class ThrowsAdviceAdapter : IAdvisorAdapter - { - /// - /// Returns if the supplied - /// is an instance of the - /// interface. - /// - /// The advice to check. - /// - /// if the supplied is - /// an instance of the interface; - /// if not or if the supplied - /// is . - /// - public virtual bool SupportsAdvice(IAdvice advice) - { - return advice is IThrowsAdvice; - } - - /// - /// Wraps the supplied 's - /// within a - /// - /// instance. - /// - /// - /// The advisor exposing the that - /// is to be wrapped. - /// - /// - /// The supplied 's - /// wrapped within a - /// - /// instance. - /// - public virtual IInterceptor GetInterceptor(IAdvisor advisor) - { - return new ThrowsAdviceInterceptor(advisor.Advice); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// implementation + /// to enable to be used in the + /// Spring.NET AOP framework. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + internal class ThrowsAdviceAdapter : IAdvisorAdapter + { + /// + /// Returns if the supplied + /// is an instance of the + /// interface. + /// + /// The advice to check. + /// + /// if the supplied is + /// an instance of the interface; + /// if not or if the supplied + /// is . + /// + public virtual bool SupportsAdvice(IAdvice advice) + { + return advice is IThrowsAdvice; + } + + /// + /// Wraps the supplied 's + /// within a + /// + /// instance. + /// + /// + /// The advisor exposing the that + /// is to be wrapped. + /// + /// + /// The supplied 's + /// wrapped within a + /// + /// instance. + /// + public virtual IInterceptor GetInterceptor(IAdvisor advisor) + { + return new ThrowsAdviceInterceptor(advisor.Advice); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceInterceptor.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceInterceptor.cs index 217a9c48..b03627d1 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceInterceptor.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/ThrowsAdviceInterceptor.cs @@ -1,319 +1,318 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using AopAlliance.Intercept; -using Common.Logging; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// Interceptor to wrap an after throwing advice. - /// - ///

- /// Implementations of the interface - /// must define methods of the form... - /// - /// AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass); - /// - /// The method name is fixed (i.e. your methods must be named - /// AfterThrowing. The first three arguments (as a whole) are - /// optional, and only useful if futher information about the joinpoint is - /// required. The return type can be anything, but is almost always - /// by convention. - ///

- ///

- /// Please note that the object encapsulating the throws advice does not - /// need to implement the interface. - /// Throws advice methods are discovered via reflection... the - /// interface serves merely to - /// discover objects that are to be considered as throws advice. - /// Other mechanisms for discovering throws advice such as attributes are - /// also equally valid... all that this class cares about is that a throws - /// advice object implement one or more methods with a valid throws advice - /// signature (see above, and the examples below). - ///

- ///

- /// This is a framework class that should not normally need to be used - /// directly by Spring.NET users. - ///

- ///
- /// - ///

- /// Find below some examples of valid - /// method signatures... - ///

- /// - /// public class GlobalExceptionHandlingAdvice : IThrowsAdvice - /// { - /// public void AfterThrowing(Exception ex) { - /// // handles absolutely any and every Exception... - /// } - /// } - /// - /// - /// public class RemotingExceptionHandlingAdvice : IThrowsAdvice - /// { - /// public void AfterThrowing(RemotingException ex) { - /// // handles any and every RemotingException (and subclasses of RemotingException)... - /// } - /// } - /// - /// - /// using System.Data; - /// - /// public class DataExceptionHandlingAdvice - /// { - /// public void AfterThrowing(ConstraintException ex) { - /// // specialised handling of ConstraintExceptions - /// } - /// - /// public void AfterThrowing(NoNullAllowedException ex) { - /// // specialised handling of NoNullAllowedExceptions - /// } - /// - /// public void AfterThrowing(DataException ex) { - /// // handles all other DataExceptions... - /// } - /// } - /// - ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: ThrowsAdviceInterceptor.cs,v 1.8 2007/05/04 13:16:44 bbaia Exp $ - /// - [Serializable] - public sealed class ThrowsAdviceInterceptor : IMethodInterceptor - { - private static readonly ILog log = LogManager.GetLogger(typeof(ThrowsAdviceInterceptor)); - - private const string SpecialThrowingMethodName = "AfterThrowing"; - - private readonly object throwsAdvice; - - /// - /// The mapping of exception Types to MethodInfo handlers. - /// - private readonly IDictionary exceptionHandlers; - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// - /// - /// The throws advice to check for exception handler methods. - /// - /// - /// If the supplied is . - /// - /// - /// If no (0) handler methods were discovered on the supplied ; - /// or if more than one handler method suitable for a particular - /// type was discovered on the supplied - /// . - /// - public ThrowsAdviceInterceptor(object advice) - { - AssertUtils.ArgumentNotNull(advice, "advice"); - this.exceptionHandlers = new Hashtable(); - this.throwsAdvice = advice; - MapAllExceptionHandlingMethods(advice); - if (exceptionHandlers.Count == 0) - { - throw new ArgumentException( - "At least one handler method must be found in class [" - + advice.GetType().FullName + "]."); - } - } - - private void MapAllExceptionHandlingMethods(object advice) - { - MethodInfo[] methods = advice.GetType().GetMethods(); - foreach (MethodInfo method in methods) - { - int numParams = method.GetParameters().Length; - if (method.Name.Equals(SpecialThrowingMethodName) - && (numParams == 1 || numParams == 4)) - { - Type lastParametersType = method.GetParameters()[numParams - 1].ParameterType; - if (typeof (Exception).IsAssignableFrom(lastParametersType)) - { - #region Instrumentation - - if(log.IsDebugEnabled) - { - log.Debug("Found exception handler method: " + method); - } - - #endregion - - if(this.exceptionHandlers.Contains(lastParametersType)) - { - throw new ArgumentException( - "Throws advice handler method for the [" + - lastParametersType + "] type already exists; don't define " + - "both single and multiple argument methods for the same " + - "Exception type in the same class."); - } - this.exceptionHandlers[lastParametersType] = method; - } - } - } - } - - /// - /// Convenience property that returns the number of exception handler - /// methods managed by this interceptor. - /// - /// - /// The number of exception handler methods managed by this interceptor. - /// - public int HandlerMethodCount - { - get { return exceptionHandlers.Count; } - } - - /// - /// Executes interceptor if (and only if) the supplied - /// throws an exception that is mapped to - /// an appropriate exception handler. - /// - /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied (this assumes no - /// exception was thrown by the call to the supplied . - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - /// - public object Invoke(IMethodInvocation invocation) - { - try - { - return invocation.Proceed(); - } - catch (TargetInvocationException ex) - { - // bah, this is a tad gross... - Exception realException = ex.InnerException; - LookupAndInvokeAnyHandler(realException, invocation); - throw realException; - } - catch (Exception ex) - { - LookupAndInvokeAnyHandler(ex, invocation); - throw ex; - } - } - - private void LookupAndInvokeAnyHandler(Exception ex, IMethodInvocation invocation) - { - MethodInfo handlerMethod = GetExceptionHandler(ex); - if (handlerMethod != null) - { - InvokeHandlerMethod(invocation, ex, handlerMethod); - } - } - - /// - /// Gets the exception handler (if any) that has been mapped to the - /// supplied . - /// - /// - ///

- /// Will return if not found. - ///

- ///
- /// - /// The exception handler for the of the - /// supplied given exception. - /// - /// exception that was thrown - private MethodInfo GetExceptionHandler(Exception exception) - { - Type exceptionClass = exception.GetType(); - - #region Instrumentation - - if(log.IsDebugEnabled) - { - log.Debug("Trying to find handler for exception of type [" + exception.GetType().Name + "]."); - } - - #endregion - - MethodInfo handler = (MethodInfo) this.exceptionHandlers[exceptionClass]; - while (handler == null && !exceptionClass.Equals(typeof(Exception))) - { - exceptionClass = exceptionClass.BaseType; - handler = (MethodInfo) this.exceptionHandlers[exceptionClass]; - } - return handler; - } - - /// - /// Invokes handler method with appropriate number of parameters - /// - /// - /// The original method invocation that was intercepted. - /// - /// - /// The exception that triggered this interceptor. - /// - /// - /// The exception handler method to invoke. - /// - private void InvokeHandlerMethod( - IMethodInvocation invocation, Exception triggeringException, MethodInfo handlerMethod) - { - object[] handlerArgs; - if (handlerMethod.GetParameters().Length == 1) - { - handlerArgs = new object[] {triggeringException}; - } - else - { - handlerArgs = new object[] {invocation.Method, invocation.Arguments, invocation.This, triggeringException}; - } - try - { - handlerMethod.Invoke(this.throwsAdvice, handlerArgs); - } - catch (TargetInvocationException ex) - { - throw ex.InnerException; - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using AopAlliance.Intercept; +using Common.Logging; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// Interceptor to wrap an after throwing advice. + /// + ///

+ /// Implementations of the interface + /// must define methods of the form... + /// + /// AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass); + /// + /// The method name is fixed (i.e. your methods must be named + /// AfterThrowing. The first three arguments (as a whole) are + /// optional, and only useful if futher information about the joinpoint is + /// required. The return type can be anything, but is almost always + /// by convention. + ///

+ ///

+ /// Please note that the object encapsulating the throws advice does not + /// need to implement the interface. + /// Throws advice methods are discovered via reflection... the + /// interface serves merely to + /// discover objects that are to be considered as throws advice. + /// Other mechanisms for discovering throws advice such as attributes are + /// also equally valid... all that this class cares about is that a throws + /// advice object implement one or more methods with a valid throws advice + /// signature (see above, and the examples below). + ///

+ ///

+ /// This is a framework class that should not normally need to be used + /// directly by Spring.NET users. + ///

+ ///
+ /// + ///

+ /// Find below some examples of valid + /// method signatures... + ///

+ /// + /// public class GlobalExceptionHandlingAdvice : IThrowsAdvice + /// { + /// public void AfterThrowing(Exception ex) { + /// // handles absolutely any and every Exception... + /// } + /// } + /// + /// + /// public class RemotingExceptionHandlingAdvice : IThrowsAdvice + /// { + /// public void AfterThrowing(RemotingException ex) { + /// // handles any and every RemotingException (and subclasses of RemotingException)... + /// } + /// } + /// + /// + /// using System.Data; + /// + /// public class DataExceptionHandlingAdvice + /// { + /// public void AfterThrowing(ConstraintException ex) { + /// // specialised handling of ConstraintExceptions + /// } + /// + /// public void AfterThrowing(NoNullAllowedException ex) { + /// // specialised handling of NoNullAllowedExceptions + /// } + /// + /// public void AfterThrowing(DataException ex) { + /// // handles all other DataExceptions... + /// } + /// } + /// + ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + [Serializable] + public sealed class ThrowsAdviceInterceptor : IMethodInterceptor + { + private static readonly ILog log = LogManager.GetLogger(typeof(ThrowsAdviceInterceptor)); + + private const string SpecialThrowingMethodName = "AfterThrowing"; + + private readonly object throwsAdvice; + + /// + /// The mapping of exception Types to MethodInfo handlers. + /// + private readonly IDictionary exceptionHandlers; + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// + /// + /// The throws advice to check for exception handler methods. + /// + /// + /// If the supplied is . + /// + /// + /// If no (0) handler methods were discovered on the supplied ; + /// or if more than one handler method suitable for a particular + /// type was discovered on the supplied + /// . + /// + public ThrowsAdviceInterceptor(object advice) + { + AssertUtils.ArgumentNotNull(advice, "advice"); + this.exceptionHandlers = new Hashtable(); + this.throwsAdvice = advice; + MapAllExceptionHandlingMethods(advice); + if (exceptionHandlers.Count == 0) + { + throw new ArgumentException( + "At least one handler method must be found in class [" + + advice.GetType().FullName + "]."); + } + } + + private void MapAllExceptionHandlingMethods(object advice) + { + MethodInfo[] methods = advice.GetType().GetMethods(); + foreach (MethodInfo method in methods) + { + int numParams = method.GetParameters().Length; + if (method.Name.Equals(SpecialThrowingMethodName) + && (numParams == 1 || numParams == 4)) + { + Type lastParametersType = method.GetParameters()[numParams - 1].ParameterType; + if (typeof (Exception).IsAssignableFrom(lastParametersType)) + { + #region Instrumentation + + if(log.IsDebugEnabled) + { + log.Debug("Found exception handler method: " + method); + } + + #endregion + + if(this.exceptionHandlers.Contains(lastParametersType)) + { + throw new ArgumentException( + "Throws advice handler method for the [" + + lastParametersType + "] type already exists; don't define " + + "both single and multiple argument methods for the same " + + "Exception type in the same class."); + } + this.exceptionHandlers[lastParametersType] = method; + } + } + } + } + + /// + /// Convenience property that returns the number of exception handler + /// methods managed by this interceptor. + /// + /// + /// The number of exception handler methods managed by this interceptor. + /// + public int HandlerMethodCount + { + get { return exceptionHandlers.Count; } + } + + /// + /// Executes interceptor if (and only if) the supplied + /// throws an exception that is mapped to + /// an appropriate exception handler. + /// + /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied (this assumes no + /// exception was thrown by the call to the supplied . + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + /// + public object Invoke(IMethodInvocation invocation) + { + try + { + return invocation.Proceed(); + } + catch (TargetInvocationException ex) + { + // bah, this is a tad gross... + Exception realException = ex.InnerException; + LookupAndInvokeAnyHandler(realException, invocation); + throw realException; + } + catch (Exception ex) + { + LookupAndInvokeAnyHandler(ex, invocation); + throw ex; + } + } + + private void LookupAndInvokeAnyHandler(Exception ex, IMethodInvocation invocation) + { + MethodInfo handlerMethod = GetExceptionHandler(ex); + if (handlerMethod != null) + { + InvokeHandlerMethod(invocation, ex, handlerMethod); + } + } + + /// + /// Gets the exception handler (if any) that has been mapped to the + /// supplied . + /// + /// + ///

+ /// Will return if not found. + ///

+ ///
+ /// + /// The exception handler for the of the + /// supplied given exception. + /// + /// exception that was thrown + private MethodInfo GetExceptionHandler(Exception exception) + { + Type exceptionClass = exception.GetType(); + + #region Instrumentation + + if(log.IsDebugEnabled) + { + log.Debug("Trying to find handler for exception of type [" + exception.GetType().Name + "]."); + } + + #endregion + + MethodInfo handler = (MethodInfo) this.exceptionHandlers[exceptionClass]; + while (handler == null && !exceptionClass.Equals(typeof(Exception))) + { + exceptionClass = exceptionClass.BaseType; + handler = (MethodInfo) this.exceptionHandlers[exceptionClass]; + } + return handler; + } + + /// + /// Invokes handler method with appropriate number of parameters + /// + /// + /// The original method invocation that was intercepted. + /// + /// + /// The exception that triggered this interceptor. + /// + /// + /// The exception handler method to invoke. + /// + private void InvokeHandlerMethod( + IMethodInvocation invocation, Exception triggeringException, MethodInfo handlerMethod) + { + object[] handlerArgs; + if (handlerMethod.GetParameters().Length == 1) + { + handlerArgs = new object[] {triggeringException}; + } + else + { + handlerArgs = new object[] {invocation.Method, invocation.Arguments, invocation.This, triggeringException}; + } + try + { + handlerMethod.Invoke(this.throwsAdvice, handlerArgs); + } + catch (TargetInvocationException ex) + { + throw ex.InnerException; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/UnknownAdviceTypeException.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/UnknownAdviceTypeException.cs index 9adf977b..9dde8b65 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/UnknownAdviceTypeException.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/UnknownAdviceTypeException.cs @@ -1,105 +1,104 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Aop.Framework.Adapter -{ - /// - /// Exception thrown when an attempt is made to use an unsupported - /// or - /// type. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: UnknownAdviceTypeException.cs,v 1.4 2006/04/09 07:18:35 markpollack Exp $ - [Serializable] - public class UnknownAdviceTypeException : ArgumentException - { - /// - /// Creates a new instance of the - /// class. - /// - /// The advice that caused the exception. - public UnknownAdviceTypeException(object advice) - : base("No adapter for IAdvice of type [" - + (advice != null ? advice.GetType().FullName : "null") + "].") - { - } - - /// - /// Creates a new instance of the - /// class. - /// - public UnknownAdviceTypeException() - { - } - - /// - /// Creates a new instance of the - /// class with - /// the specified message. - /// - /// - /// A message about the exception. - /// - public UnknownAdviceTypeException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class with - /// the specified message and root cause. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public UnknownAdviceTypeException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected UnknownAdviceTypeException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Aop.Framework.Adapter +{ + /// + /// Exception thrown when an attempt is made to use an unsupported + /// or + /// type. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class UnknownAdviceTypeException : ArgumentException + { + /// + /// Creates a new instance of the + /// class. + /// + /// The advice that caused the exception. + public UnknownAdviceTypeException(object advice) + : base("No adapter for IAdvice of type [" + + (advice != null ? advice.GetType().FullName : "null") + "].") + { + } + + /// + /// Creates a new instance of the + /// class. + /// + public UnknownAdviceTypeException() + { + } + + /// + /// Creates a new instance of the + /// class with + /// the specified message. + /// + /// + /// A message about the exception. + /// + public UnknownAdviceTypeException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class with + /// the specified message and root cause. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public UnknownAdviceTypeException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected UnknownAdviceTypeException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AdvisedSupport.cs b/src/Spring/Spring.Aop/Aop/Framework/AdvisedSupport.cs index 056bfe46..4a9eeaf8 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AdvisedSupport.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AdvisedSupport.cs @@ -1,1563 +1,1562 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Reflection; -using System.Text; - -using AopAlliance.Aop; -using AopAlliance.Intercept; -using Spring.Aop; -using Spring.Aop.Support; -using Spring.Aop.Target; -using Spring.Util; -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Superclass for AOP proxy configuration managers. - /// - /// - ///

- /// Instances of this class are not themselves AOP proxies, but - /// subclasses of this class are normally factories from which AOP proxy - /// instances are obtained directly. - ///

- ///

- /// This class frees subclasses of the housekeeping of - /// and - /// instances, but doesn't actually - /// implement proxy creation methods, the functionality for which - /// is provided by subclasses. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: AdvisedSupport.cs,v 1.36 2008/01/14 20:49:47 oakinger Exp $ - /// - [Serializable] - public class AdvisedSupport : ProxyConfig, IAdvised - { - #region Fields - - /// The list of advice. - /// - ///

- /// If an is added, it - /// will be wrapped in an advice before being added to this list. - ///

- ///
- private IList _advisors = new ArrayList(); - - /// - /// Array updated on changes to the advisors list, which is easier to - /// manipulate internally - /// - private IAdvisor[] _advisorsArray = new IAdvisor[] {}; - - /// - /// List of introductions. - /// - private IList _introductions = new ArrayList(); - - /// - /// Array updated on changes to the advisors list, which is easier to - /// manipulate internally - /// - private IIntroductionAdvisor[] _introductionsArray - = new IIntroductionAdvisor[] {}; - - /// - /// Interface map specifying which object should interface methods be - /// delegated to. - /// - /// - ///

- /// If entry value is methods should be delegated - /// to the target object. - ///

- ///
- private IDictionary interfaceMap = new ListDictionary(); - - /// - /// The for this instance. - /// - protected internal ITargetSource m_targetSource = EmptyTargetSource.Empty; - - /// - /// Set to when the first AOP proxy has been - /// created, meaning that we must track advice changes via the - /// OnAdviceChange() callback. - /// - private bool isActive; - - private Type proxyType; - private ConstructorInfo proxyConstructor; - - /// - /// The list of event listeners. - /// - private IList listeners = new ArrayList(); - - /// - /// The advisor chain factory. - /// - private IAdvisorChainFactory advisorChainFactory; - - #endregion - - #region Constructor(s) - - /// - /// Creates a new instance of the - /// class using the - /// default advisor chain factory. - /// - public AdvisedSupport() - { - AdvisorChainFactory = new HashtableCachingAdvisorChainFactory(); - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The interfaces that are to be proxied. - /// - /// If this - /// - public AdvisedSupport(Type[] interfaces) : this() - { - if (interfaces != null) - { - foreach (Type intf in interfaces) - { - AddInterfaceInternal(intf); - } - } - } - - #endregion - - #region IAdvised implementation - - /// - /// Gets and sets the - /// - /// implementation that will be used to get the interceptor - /// chains for the advised - /// . - /// - /// - /// The - /// implementation that will be used to get the interceptor - /// chains for the advised - /// . - /// - public virtual IAdvisorChainFactory AdvisorChainFactory - { - get - { - lock(this.SyncRoot) - { - return this.advisorChainFactory; - } - } - set - { - lock(this.SyncRoot) - { - if (this.advisorChainFactory != null) - { - RemoveListener(this.advisorChainFactory); - } - this.advisorChainFactory = value; - AddListener(this.advisorChainFactory); - } - } - } - - /// - /// Returns the current used - /// by this object. - /// - /// - /// The used by this - /// object. - /// - /// - public ITargetSource TargetSource - { - get { return this.m_targetSource; } - set - { - bool initialized = !(this.m_targetSource is EmptyTargetSource); - this.m_targetSource = value; - - if (this.m_targetSource != null && !initialized && interfaceMap.Count == 0) - { - Type[] interfaces = ReflectionUtils.GetInterfaces(this.m_targetSource.TargetType); - foreach (Type intf in interfaces) - { - AddInterfaceInternal(intf); - } - } - } - } - - /// - /// Returns a boolean specifying if this - /// instance can be serialized. - /// - /// - /// true if this instance can be serialized, false otherwise. - /// - public bool IsSerializable - { - get - { - bool canBeSerialized = TargetSource.TargetType.IsSerializable; - if (canBeSerialized) - { - for (int i = 0; canBeSerialized && i < _advisorsArray.Length; i++) - { - IAdvisor advisor = _advisorsArray[i]; - canBeSerialized = advisor.GetType().IsSerializable - && advisor.Advice.GetType().IsSerializable; - } - for (int i = 0; canBeSerialized && i < _introductionsArray.Length; i++) - { - IIntroductionAdvisor advisor = _introductionsArray[i]; - canBeSerialized = advisor.GetType().IsSerializable - && advisor.Advice.GetType().IsSerializable; - } - } - - return canBeSerialized; - } - } - - /// - /// Returns the collection of interface s - /// to be (or that are being) proxied by this proxy. - /// - /// - /// The collection of interface s - /// to be (or that are being) proxied by this proxy. - /// - /// - public virtual Type[] Interfaces - { - get - { - lock(this.SyncRoot) - { - Type[] proxiedInterfaces = new Type[this.interfaceMap.Keys.Count]; - this.interfaceMap.Keys.CopyTo(proxiedInterfaces, 0); - return proxiedInterfaces; - } - } - set - { - lock(this.SyncRoot) - { - this.interfaceMap.Clear(); - for (int i = 0; i < value.Length; i++) - { - AddInterfaceInternal(value[i]); - } - InterfacesChanged(); - } - } - } - - /// - /// Returns the mapping of the proxied interface - /// s to their delegates. - /// - /// - /// The mapping of the proxied interface - /// s to their delegates. - /// - /// - public virtual IDictionary InterfaceMap - { - get - { - lock(this.SyncRoot) - { - return new Hashtable(this.interfaceMap); - } - } - } - - /// - /// Is the supplied (interface) - /// proxied? - /// - /// - /// The interface to test. - /// - /// - /// if the supplied - /// (interface) is proxied; - /// if not or the supplied - /// is . - /// - /// - public virtual bool IsInterfaceProxied(Type intf) - { - if (intf != null) - { - lock(this.SyncRoot) - { - foreach (Type proxyInterface in this.interfaceMap.Keys) - { - if (intf.IsAssignableFrom(proxyInterface)) - { - return true; - } - } - } - } - return false; - } - - /// - /// Returns the collection of - /// instances that have been applied to this proxy. - /// - /// - /// The collection of - /// instances that have been applied to this proxy. - /// - /// - public virtual IAdvisor[] Advisors - { - get - { - lock(this.SyncRoot) - { - return (IAdvisor[]) this._advisorsArray.Clone(); - } - } - } - - /// - /// Returns the collection of - /// instances that have been applied to this proxy. - /// - /// - ///

- /// Will never return , but may return an - /// empty array (in the case where no - /// instances have been - /// applied to this proxy). - ///

- ///
- /// - /// The collection of - /// instances that have been applied to this proxy. - /// - /// - public virtual IIntroductionAdvisor[] Introductions - { - get - { - lock(this.SyncRoot) - { - return (IIntroductionAdvisor[]) this._introductionsArray.Clone(); - } - } - } - - /// - /// Adds the supplied to the end (or tail) - /// of the advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// - public void AddAdvice(IAdvice advice) - { - //int position = this._advisors != null ? this._advisors.Count : 0; - AddAdvice(-1, advice); - } - - /// - /// Adds the supplied to the supplied - /// in the advice (interceptor) chain. - /// - /// - /// The zero (0) indexed position (from the head) at which the - /// supplied is to be inserted into the - /// advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// If the supplied is ; - /// or is not an - /// reference; or if the supplied is a - /// . - /// - /// - /// - public void AddAdvice(int position, IAdvice advice) - { - if (advice is IInterceptor && !(advice is IMethodInterceptor)) - { - throw new AopConfigException( - GetType().FullName + " can only handle AOP Alliance IMethodInterceptor advice."); - } - if (advice is IIntroductionInterceptor) - { - throw - new AopConfigException( - "IIntroductionInterceptors may only be added as part of IIntroductionAdvisor."); - } - - AddAdvisor(position, new DefaultPointcutAdvisor(advice)); - } - - /// - /// Return the index (0 based) of the supplied - /// in the interceptor - /// (advice) chain for this proxy. - /// - /// - /// The to search for. - /// - /// - /// The zero (0) based index of this advisor, or -1 if the - /// supplied is not an advisor for this - /// proxy. - /// - public virtual int IndexOf(IAdvisor advisor) - { - lock(this.SyncRoot) - { - return IndexOfInternal(advisor); - } - } - - /// - /// Return the index (0 based) of the supplied - /// in the introductions - /// for this proxy. - /// - /// - /// The to search for. - /// - /// - /// The zero (0) based index of this advisor, or -1 if the - /// supplied is not an introduction advisor - /// for this proxy. - /// - public virtual int IndexOf(IIntroductionAdvisor advisor) - { - lock(this.SyncRoot) - { - return IndexOfInternal(advisor); - } - } - - /// - /// Removes the supplied the list of advisors - /// for this proxy. - /// - /// The advisor to remove. - /// - /// if advisor was found in the list of - /// for this - /// proxy and was successfully removed; if not - /// or if the supplied is . - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be removed. - /// - public bool RemoveAdvisor(IAdvisor advisor) - { - DieIfFrozen("Cannot remove advisor: config is frozen"); - bool wasRemoved = false; - if (advisor != null) - { - lock(this.SyncRoot) - { - int index = IndexOf(advisor); - if (index == -1) - { - wasRemoved = false; - } - else - { - RemoveAdvisorInternal(index); - wasRemoved = true; - } - } - } - return wasRemoved; - } - - /// - /// Removes the at the supplied - /// in the - /// list - /// from the list of - /// for this proxy. - /// - /// - /// The index of the to remove. - /// - /// - /// If this proxy configuration is frozen and the - /// at the supplied - /// cannot be removed; or if the supplied is out of - /// range. - /// - public virtual void RemoveAdvisor(int index) - { - DieIfFrozen("Cannot remove advisor: config is frozen"); - lock(this.SyncRoot) - { - RemoveAdvisorInternal(index); - } - } - - /// - /// Removes the supplied from the list - /// of . - /// - /// - /// The to remove. - /// - /// - /// if the supplied was - /// found in the list of - /// and successfully removed. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be removed. - /// - public bool RemoveAdvice(IAdvice advice) - { - lock(this.SyncRoot) - { - int index = IndexOf(advice); - if (index == -1) - { - return false; - } - else - { - RemoveAdvisorInternal(index); - return true; - } - } - } - - /// - /// Removes the supplied from the list - /// of . - /// - /// - /// The to remove. - /// - /// - /// if the supplied was - /// found in the list of - /// and successfully removed. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be removed. - /// - public bool RemoveIntroduction(IIntroductionAdvisor introduction) - { - DieIfFrozen("Cannot remove introduction: config is frozen"); - bool wasRemoved = false; - if (introduction != null) - { - lock(this.SyncRoot) - { - int index = IndexOf(introduction); - if (index == -1) - { - wasRemoved = false; - } - else - { - RemoveIntroduction(index); - wasRemoved = true; - } - } - } - return wasRemoved; - } - - /// - /// Removes the at the supplied - /// in the list of - /// for this proxy. - /// - /// The index of the advisor to remove. - /// - /// - /// If this proxy configuration is frozen and the - /// at the supplied - /// cannot be removed; or if the supplied - /// is out of range. - /// - public virtual void RemoveIntroduction(int index) - { - DieIfFrozen("Cannot remove introduction: config is frozen"); - lock(this.SyncRoot) - { - if (index < 0 || index >= _introductions.Count) - { - throw new AopConfigException( - "Introduction index " + index + " is out of bounds: Only have " + _introductions.Count + - " introductions."); - } - IIntroductionAdvisor advisor = (IIntroductionAdvisor) _introductions[index]; - // remove all interfaces introduced by the advisor... - foreach (Type intf in advisor.Interfaces) - { - RemoveInterface(intf); - } - this._introductions.RemoveAt(index); - UpdateIntroductionsArray(); - } - } - -// -// /// -// /// Removes the supplied from the list of -// /// for this -// /// proxy. -// /// -// /// -// /// The to be removed. -// /// -// /// -// /// If this proxy configuration is frozen and the -// /// cannot be added. -// /// -// public bool RemoveInterceptor(IInterceptor interceptor) -// { -// AssertFrozen("Cannot remove interceptor: config is frozen"); -// int index = IndexOf(interceptor); -// if (index == -1) -// { -// return false; -// } -// else -// { -// RemoveAdvisor(index); -// return true; -// } -// } - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The index in the - /// list at which the supplied - /// is to be inserted. If -1, appends to the end of the list. - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - public virtual void AddAdvisor(int index, IAdvisor advisor) - { - DieIfFrozen("Cannot add advisor: config is frozen"); - lock(this.SyncRoot) - { - // advisor already in list (SPRNET-846) - if (_advisors.Contains(advisor)) return; - - if(index == -1) - { - this._advisors.Add(advisor); - } - else - { - this._advisors.Insert(index, advisor); - } - UpdateAdvisorsArray(); - InterceptorsChanged(); - } - } - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - public virtual void AddAdvisor(IAdvisor advisor) - { - AddAdvisor(this._advisors.Count, advisor); - } - - /// - /// Adds the advisors from the supplied - /// to the list of . - /// - /// - /// The to add advisors from. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - public void AddAdvisors(IAdvisors advisors) - { - foreach (IAdvisor advisor in advisors.Advisors) - { - if (advisor is IIntroductionAdvisor) - { - AddIntroduction((IIntroductionAdvisor) advisor); - } - else - { - AddAdvisor(advisor); - } - } - } - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The index in the - /// list at which the supplied - /// is to be inserted. - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - public virtual void AddIntroduction(int index, IIntroductionAdvisor introductionAdvisor) - { - DieIfFrozen("Cannot add introduction: config is frozen"); - introductionAdvisor.ValidateInterfaces(); - - lock(this.SyncRoot) - { - if (index < this._introductions.Count) - { - this._introductions.RemoveAt(index); - } - this._introductions.Insert(index, introductionAdvisor); - - int intfCount = this.interfaceMap.Count; - // If the advisor passed validation we can make the change - foreach (Type intf in introductionAdvisor.Interfaces) - { - this.interfaceMap[intf] = introductionAdvisor; - } - UpdateIntroductionsArray(); - if (this.interfaceMap.Count != intfCount) - { - InterfacesChanged(); - } - } - } - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - public virtual void AddIntroduction(IIntroductionAdvisor introductionAdvisor) - { - Type introductionType = introductionAdvisor.Advice.GetType(); - lock(this.SyncRoot) - { - int pos = this._introductions.Count; - for (int i = 0; i < pos; i++) - { - IIntroductionAdvisor introduction - = (IIntroductionAdvisor) this._introductions[i]; - if (introduction.Advice.GetType() == introductionType) - { - pos = i; - } - } - AddIntroduction(pos, introductionAdvisor); - } - } - - /// - /// Replaces the that - /// exists at the supplied in the list of - /// - /// with the supplied . - /// - /// - /// The index of the - /// in the list of - /// - /// that is to be replaced. - /// - /// - /// The new (replacement) . - /// - /// - /// If the supplied is out of range. - /// - public virtual void ReplaceIntroduction(int index, IIntroductionAdvisor introduction) - { - lock(this.SyncRoot) - { - if(index < 0 || index >= _introductions.Count) - { - throw new AopConfigException( - "Introduction index " + index + " is out of bounds:" + - " there are currently " + _introductions.Count + - " introductions." ); - } - - _introductions[index] = introduction; - } - } - - /// - /// Replaces the with the - /// . - /// - /// - /// The original (old) advisor to be replaced. - /// - /// - /// The new advisor to replace the with. - /// - /// - /// if the was - /// replaced; if the was not found in the - /// advisors collection (or the is - /// , this method returns - /// and (effectively) does nothing. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be replaced. - /// - /// - public bool ReplaceAdvisor(IAdvisor oldAdvisor, IAdvisor newAdvisor) - { - DieIfFrozen("Cannot replace advisor: config is frozen."); - lock(this.SyncRoot) - { - int index = IndexOf(oldAdvisor); - if (index == -1 || newAdvisor == null) - { - return false; - } - RemoveAdvisor(index); - AddAdvisor(index, newAdvisor); - } - return true; - } - - /// - /// As will normally be passed straight through - /// to the advised target, this method returns the - /// equivalent for the AOP proxy itself. - /// - /// - /// A description of the proxy configuration. - /// - public virtual string ToProxyConfigString() - { - lock(this.SyncRoot) - { - return ToStringInternal(); - } - } - - #endregion - - #region ITargetTypeAware implementation - - /// - /// Gets the target type behind the implementing object. - /// Ttypically a proxy configuration or an actual proxy. - /// - /// The type of the target or null if not known. - public Type TargetType - { - get { return TargetSource.TargetType; } - } - - #endregion - - #region Properties - /// - /// Sets the target object that is to be advised. - /// - /// - ///

- /// This is a convenience write-only property that allows client code - /// to set the target object... the target object will be implicitly - /// wrapped within a new - /// instance. - ///

- ///
- public virtual object Target - { - set { TargetSource = new SingletonTargetSource(value); } - } - - /// - /// Called by subclasses to get a value indicating whether any AOP proxies have been created yet. - /// - /// true if this AOp proxies have been created; otherwise, false. - protected bool IsActive - { - get { return isActive; } - } - - #endregion - - /// - /// Specifies the of proxies that are to be - /// created for this instance of proxy config. - /// - /// - ///

- /// If this property value is it simply means that - /// no proxies have been created yet. Only when the first proxy is - /// created will this property value be set by the AOP framework. - ///

- ///

- /// Users will be able to add interceptors dynamically without proxy - /// regeneration, but if they add introductions the proxy - /// will have to be regenerated. - ///

- ///
- /// - /// The of proxies that are to be - /// created for this instance of proxy config; if - /// no proxies have been created yet. - /// - internal Type ProxyType - { - get { return this.proxyType; } - set { this.proxyType = value; } - } - - /// - /// Caches proxy constructor for performance reasons. - /// - internal ConstructorInfo ProxyConstructor - { - get { return this.proxyConstructor; } - set { this.proxyConstructor = value; } - } - - /// - /// Registers the supplied as a listener for - /// notifications. - /// - /// - /// The to - /// register. - /// - public virtual void AddListener(IAdvisedSupportListener listener) - { - lock(this.SyncRoot) - { - this.listeners.Add(listener); - } - } - - /// - /// Removes the supplied . - /// - /// - /// The to - /// be removed. - /// - public virtual void RemoveListener(IAdvisedSupportListener listener) - { - lock(this.SyncRoot) - { - this.listeners.Remove(listener); - } - } - - /// - /// Adds a new interface to the list of interfaces that are proxied by this proxy. - /// - /// - /// The interface to be proxied by this proxy. - /// - /// - /// If this proxy configuration is frozen - /// (); - /// - /// - /// If the supplied is . - /// - public virtual void AddInterface(Type intf) - { - DieIfFrozen("Cannot add interface: configuration is frozen."); - AssertUtils.ArgumentNotNull(intf, "intf", "Cannot proxy a null interface."); - - lock(this.SyncRoot) - { - AddInterfaceInternal(intf); - InterfacesChanged(); - } - } - - /// - /// Adds a new interface to the list of interfaces that are proxied by this proxy. - /// - /// - /// The interface to be proxied by this proxy. - /// - /// - /// Access is not synchronized. - /// - protected virtual void AddInterfaceInternal(Type intf) - { - this.interfaceMap[intf] = null; - } - - /// - /// Removes the supplied (proxied) . - /// - /// - ///

- /// Does nothing if the supplied (proxied) - /// isn't proxied. - ///

- ///
- /// The interface to remove. - /// - /// if the interface was removed. - public virtual bool RemoveInterface(Type intf) - { - DieIfFrozen("Cannot remove interface: configuration is frozen."); - lock(this.SyncRoot) - { - if (intf != null && this.interfaceMap.Contains(intf)) - { - this.interfaceMap.Remove(intf); - InterfacesChanged(); - return true; - } - } - return false; - } - - /// - /// Return the index (0 based) of the supplied - /// in the interceptor - /// (advice) chain for this proxy. - /// - /// - ///

- /// The return value of this method can be used to index into - /// the - /// list. - ///

- ///
- /// - /// The to search for. - /// - /// - /// The zero (0) based index of this interceptor, or -1 if the - /// supplied is not an advice for this - /// proxy. - /// - public virtual int IndexOf(IAdvice advice) - { - lock(this.SyncRoot) - { - return IndexOfInternal(advice); - } - } - - /// - /// Return the index (0 based) of the supplied - /// in the interceptor - /// (advice) chain for this proxy. - /// - /// - ///

Acces is not synchronized

- ///

- /// The return value of this method can be used to index into - /// the - /// list. - ///

- ///
- /// - /// The to search for. - /// - /// - /// The zero (0) based index of this interceptor, or -1 if the - /// supplied is not an advice for this - /// proxy. - /// - private int IndexOfInternal(IAdvice advice) - { - if (this._advisors != null) - { - for (int i = 0; i < this._advisors.Count; ++i) - { - IAdvisor advisor = (IAdvisor) this._advisors[i]; - if (advisor.Advice == advice) - { - return i; - } - } - } - return -1; - } - - /// - /// Return the index (0 based) of the supplied - /// in the interceptor - /// (advice) chain for this proxy. - /// - /// - /// The to search for. - /// - /// - /// The zero (0) based index of this advisor, or -1 if the - /// supplied is not an advisor for this - /// proxy. - /// - /// - /// Access is not synchronized. - /// - private int IndexOfInternal(IAdvisor advisor) - { - return this._advisors != null ? this._advisors.IndexOf(advisor) : -1; - } - - /// - /// Return the index (0 based) of the supplied - /// in the introductions - /// for this proxy. - /// - /// - /// The to search for. - /// - /// - /// The zero (0) based index of this advisor, or -1 if the - /// supplied is not an introduction advisor - /// for this proxy. - /// - /// - /// Access is not synchronized - /// - private int IndexOfInternal(IIntroductionAdvisor advisor) - { - return this._introductions.IndexOf(advisor); - } - - /// - /// Removes the at the supplied - /// in the - /// list - /// from the list of - /// for this proxy. - /// - /// - /// The index of the to remove. - /// - /// - /// If this proxy configuration is frozen and the - /// at the supplied - /// cannot be removed; or if the supplied is out of - /// range. - /// - /// - /// Does not synchronize access. - /// - private void RemoveAdvisorInternal(int index) - { - if (index < 0 || index >= this._advisors.Count) - { - throw - new AopConfigException( - "Advisor index " + index + " is out of bounds: Only have " + this._advisors.Count + " advisors"); - } - this._advisors.RemoveAt(index); - this.UpdateAdvisorsArray(); - this.InterceptorsChanged(); - } - - /// - /// Is the supplied included in any - /// advisor? - /// - /// - /// The to check for the - /// inclusion of. - /// - /// - /// if the supplied - /// could be run in an invocation (this does not imply that said - /// will be run). - /// - public bool AdviceIncluded(IAdvice advice) - { - return (IndexOf(advice) != -1); - } - - /// - /// Returns a count of all of the - /// type-compatible with the supplied . - /// - /// - /// The of the - /// to check. - /// - /// - /// A count of all of the - /// type-compatible with the supplied . - /// - public int CountAdviceOfType(Type interceptorType) - { - int count = 0; - lock(this.SyncRoot) - { - foreach (IAdvisor advisor in this._advisors) - { - if (interceptorType.IsAssignableFrom(advisor.Advice.GetType())) - { - ++count; - } - } - } - return count; - } - - /// - /// Throws an if - /// this instances proxy configuration data is frozen. - /// - /// - /// The message that will be passed through to the constructor of any - /// thrown . - /// - /// - /// If the configuration for this proxy is frozen. - /// - /// - private void DieIfFrozen(string message) - { - if (IsFrozen) - { - throw new AopConfigException(message); - } - } - - /// - /// Bring the advisors array up to date with the list. - /// - private void UpdateAdvisorsArray() - { - this._advisorsArray = new IAdvisor[this._advisors.Count]; - this._advisors.CopyTo(this._advisorsArray, 0); - } - - /// - /// Bring the introductions array up to date with the list. - /// - private void UpdateIntroductionsArray() - { - this._introductionsArray = new IIntroductionAdvisor[this._introductions.Count]; - this._introductions.CopyTo(this._introductionsArray, 0); - } - - /// - /// Callback method that is invoked when the list of proxied interfaces - /// has changed. - /// - /// - ///

- /// An example of such a change would be when a new introduction is - /// added. Resetting - /// to - /// will cause a new proxy - /// to be generated on the next call to get a proxy. - ///

- ///
- private void InterfacesChanged() - { - ProxyType = null; - if (this.isActive) - { - foreach (IAdvisedSupportListener listener in this.listeners) - { - listener.InterfacesChanged(this); - } - } - } - - /// - /// Callback method that is invoked when the interceptor list has changed. - /// - private void InterceptorsChanged() - { - if (this.isActive) - { - foreach (IAdvisedSupportListener listener in this.listeners) - { - listener.AdviceChanged(this); - } - } - } - - /// - /// Activates this instance. - /// - protected void Activate() - { - lock (this.SyncRoot) - { - this.isActive = true; - foreach (IAdvisedSupportListener listener in this.listeners) - { - listener.Activated(this); - } - } - } - - /// - /// Creates an AOP proxy using this instance's configuration data. - /// - /// - ///

- /// Subclasses must not create a proxy by any other means (at least - /// without having a well thought out and cogent reason for doing so). - /// This is because the implementation of this method performs some - /// required housekeeping logic prior to creating an AOP proxy. - ///

- ///
- /// - protected internal virtual IAopProxy CreateAopProxy() - { - lock (this.SyncRoot) - { - if (!this.isActive) - { - Activate(); - } - return AopProxyFactory.CreateAopProxy(this); - } - } - - /// - /// Copies the configuration from the supplied other - /// into this instance. - /// - /// - ///

- /// Useful when this instance has been created using the no-argument - /// constructor, and needs to get all of its confiuration data from - /// another (most - /// usually to have an independant copy of said configuration data). - ///

- ///
- /// - /// The instance - /// containing the configiration data that is to be copied into this - /// instance. - /// - protected internal virtual void CopyConfigurationFrom(AdvisedSupport other) - { - CopyFrom(other); - this.m_targetSource = other.m_targetSource; - this.proxyType = other.proxyType; - this.proxyConstructor = other.proxyConstructor; - - foreach (Type intf in other.interfaceMap.Keys) - { - this.interfaceMap[intf] = other.interfaceMap[intf]; - } - this._advisors = new ArrayList(); - foreach (IAdvisor advisor in other._advisors) - { - AddAdvisor(advisor); - } - this._introductions = new ArrayList(); - foreach (IIntroductionAdvisor advisor in other._introductions) - { - AddIntroduction(advisor); - } - } - - /// - /// A that represents the current - /// configuration. - /// - /// - /// A that represents the current - /// configuration. - /// - public override string ToString() - { - lock(this.SyncRoot) - { - return ToStringInternal(); - } - } - - /// - /// A that represents the current - /// configuration. - /// - /// - /// A that represents the current - /// configuration. - /// - private string ToStringInternal() - { - StringBuilder buffer = new StringBuilder(this.GetType().FullName + ":\n"); - buffer.Append(this.interfaceMap.Count + " interfaces=["); - this.InterfacesToString(buffer); - buffer.Append("];\n"); - buffer.Append(this._advisors.Count + " pointcuts=["); - this.AdvisorsToString(buffer); - buffer.Append("];\n"); - buffer.Append("targetSource=[" + this.m_targetSource + "];\n"); - buffer.Append("advisorChainFactory=" + this.advisorChainFactory + ";\n"); - buffer.Append(base.ToString()); - return buffer.ToString(); - } - - /// - /// Helper method that adds the names of all of the proxied interfaces - /// to the buffer of the supplied . - /// - /// - /// The to append the proxied interface - /// names to. - /// - private void InterfacesToString(StringBuilder buffer) - { - string separator = string.Empty; - foreach (Type intf in this.interfaceMap.Keys) - { - buffer.Append(separator).Append("[").Append(intf.FullName).Append("] -> "); - IIntroductionAdvisor advisor = this.interfaceMap[intf] as IIntroductionAdvisor; - if (advisor == null) - { - if (TargetSource.TargetType != null) - { - buffer.Append("target[").Append(TargetSource.TargetType.FullName).Append("]"); - } - else - { - buffer.Append("target[NOT SPECIFIED (=null)]"); - } - } - else - { - buffer.Append("introduction[").Append(advisor.Advice.GetType().FullName).Append("]"); - } - separator = ", "; - } - } - - /// - /// Helper method that adds advisor's - /// to the buffer of the supplied . - /// - /// - /// The to append the advisor details to. - /// - private void AdvisorsToString(StringBuilder buffer) - { - string separator = string.Empty; - foreach (IAdvisor advisor in this._advisors) - { - buffer.Append(separator).Append(advisor); - separator = ", "; - } - } - - /// - /// Gets all of the interfaces implemented by the - /// of the supplied - /// . - /// - /// - /// The object to get the interfaces of. - /// - /// - /// All of the interfaces implemented by the - /// of the supplied - /// . - /// - /// - /// If the supplied is . - /// - protected static Type[] GetInterfaces(object target) - { - if (target == null) - { - throw new AopConfigException("Can't proxy null object"); - } - return ReflectionUtils.GetInterfaces(target.GetType()); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Reflection; +using System.Text; + +using AopAlliance.Aop; +using AopAlliance.Intercept; +using Spring.Aop; +using Spring.Aop.Support; +using Spring.Aop.Target; +using Spring.Util; +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Superclass for AOP proxy configuration managers. + /// + /// + ///

+ /// Instances of this class are not themselves AOP proxies, but + /// subclasses of this class are normally factories from which AOP proxy + /// instances are obtained directly. + ///

+ ///

+ /// This class frees subclasses of the housekeeping of + /// and + /// instances, but doesn't actually + /// implement proxy creation methods, the functionality for which + /// is provided by subclasses. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + [Serializable] + public class AdvisedSupport : ProxyConfig, IAdvised + { + #region Fields + + /// The list of advice. + /// + ///

+ /// If an is added, it + /// will be wrapped in an advice before being added to this list. + ///

+ ///
+ private IList _advisors = new ArrayList(); + + /// + /// Array updated on changes to the advisors list, which is easier to + /// manipulate internally + /// + private IAdvisor[] _advisorsArray = new IAdvisor[] {}; + + /// + /// List of introductions. + /// + private IList _introductions = new ArrayList(); + + /// + /// Array updated on changes to the advisors list, which is easier to + /// manipulate internally + /// + private IIntroductionAdvisor[] _introductionsArray + = new IIntroductionAdvisor[] {}; + + /// + /// Interface map specifying which object should interface methods be + /// delegated to. + /// + /// + ///

+ /// If entry value is methods should be delegated + /// to the target object. + ///

+ ///
+ private IDictionary interfaceMap = new ListDictionary(); + + /// + /// The for this instance. + /// + protected internal ITargetSource m_targetSource = EmptyTargetSource.Empty; + + /// + /// Set to when the first AOP proxy has been + /// created, meaning that we must track advice changes via the + /// OnAdviceChange() callback. + /// + private bool isActive; + + private Type proxyType; + private ConstructorInfo proxyConstructor; + + /// + /// The list of event listeners. + /// + private IList listeners = new ArrayList(); + + /// + /// The advisor chain factory. + /// + private IAdvisorChainFactory advisorChainFactory; + + #endregion + + #region Constructor(s) + + /// + /// Creates a new instance of the + /// class using the + /// default advisor chain factory. + /// + public AdvisedSupport() + { + AdvisorChainFactory = new HashtableCachingAdvisorChainFactory(); + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The interfaces that are to be proxied. + /// + /// If this + /// + public AdvisedSupport(Type[] interfaces) : this() + { + if (interfaces != null) + { + foreach (Type intf in interfaces) + { + AddInterfaceInternal(intf); + } + } + } + + #endregion + + #region IAdvised implementation + + /// + /// Gets and sets the + /// + /// implementation that will be used to get the interceptor + /// chains for the advised + /// . + /// + /// + /// The + /// implementation that will be used to get the interceptor + /// chains for the advised + /// . + /// + public virtual IAdvisorChainFactory AdvisorChainFactory + { + get + { + lock(this.SyncRoot) + { + return this.advisorChainFactory; + } + } + set + { + lock(this.SyncRoot) + { + if (this.advisorChainFactory != null) + { + RemoveListener(this.advisorChainFactory); + } + this.advisorChainFactory = value; + AddListener(this.advisorChainFactory); + } + } + } + + /// + /// Returns the current used + /// by this object. + /// + /// + /// The used by this + /// object. + /// + /// + public ITargetSource TargetSource + { + get { return this.m_targetSource; } + set + { + bool initialized = !(this.m_targetSource is EmptyTargetSource); + this.m_targetSource = value; + + if (this.m_targetSource != null && !initialized && interfaceMap.Count == 0) + { + Type[] interfaces = ReflectionUtils.GetInterfaces(this.m_targetSource.TargetType); + foreach (Type intf in interfaces) + { + AddInterfaceInternal(intf); + } + } + } + } + + /// + /// Returns a boolean specifying if this + /// instance can be serialized. + /// + /// + /// true if this instance can be serialized, false otherwise. + /// + public bool IsSerializable + { + get + { + bool canBeSerialized = TargetSource.TargetType.IsSerializable; + if (canBeSerialized) + { + for (int i = 0; canBeSerialized && i < _advisorsArray.Length; i++) + { + IAdvisor advisor = _advisorsArray[i]; + canBeSerialized = advisor.GetType().IsSerializable + && advisor.Advice.GetType().IsSerializable; + } + for (int i = 0; canBeSerialized && i < _introductionsArray.Length; i++) + { + IIntroductionAdvisor advisor = _introductionsArray[i]; + canBeSerialized = advisor.GetType().IsSerializable + && advisor.Advice.GetType().IsSerializable; + } + } + + return canBeSerialized; + } + } + + /// + /// Returns the collection of interface s + /// to be (or that are being) proxied by this proxy. + /// + /// + /// The collection of interface s + /// to be (or that are being) proxied by this proxy. + /// + /// + public virtual Type[] Interfaces + { + get + { + lock(this.SyncRoot) + { + Type[] proxiedInterfaces = new Type[this.interfaceMap.Keys.Count]; + this.interfaceMap.Keys.CopyTo(proxiedInterfaces, 0); + return proxiedInterfaces; + } + } + set + { + lock(this.SyncRoot) + { + this.interfaceMap.Clear(); + for (int i = 0; i < value.Length; i++) + { + AddInterfaceInternal(value[i]); + } + InterfacesChanged(); + } + } + } + + /// + /// Returns the mapping of the proxied interface + /// s to their delegates. + /// + /// + /// The mapping of the proxied interface + /// s to their delegates. + /// + /// + public virtual IDictionary InterfaceMap + { + get + { + lock(this.SyncRoot) + { + return new Hashtable(this.interfaceMap); + } + } + } + + /// + /// Is the supplied (interface) + /// proxied? + /// + /// + /// The interface to test. + /// + /// + /// if the supplied + /// (interface) is proxied; + /// if not or the supplied + /// is . + /// + /// + public virtual bool IsInterfaceProxied(Type intf) + { + if (intf != null) + { + lock(this.SyncRoot) + { + foreach (Type proxyInterface in this.interfaceMap.Keys) + { + if (intf.IsAssignableFrom(proxyInterface)) + { + return true; + } + } + } + } + return false; + } + + /// + /// Returns the collection of + /// instances that have been applied to this proxy. + /// + /// + /// The collection of + /// instances that have been applied to this proxy. + /// + /// + public virtual IAdvisor[] Advisors + { + get + { + lock(this.SyncRoot) + { + return (IAdvisor[]) this._advisorsArray.Clone(); + } + } + } + + /// + /// Returns the collection of + /// instances that have been applied to this proxy. + /// + /// + ///

+ /// Will never return , but may return an + /// empty array (in the case where no + /// instances have been + /// applied to this proxy). + ///

+ ///
+ /// + /// The collection of + /// instances that have been applied to this proxy. + /// + /// + public virtual IIntroductionAdvisor[] Introductions + { + get + { + lock(this.SyncRoot) + { + return (IIntroductionAdvisor[]) this._introductionsArray.Clone(); + } + } + } + + /// + /// Adds the supplied to the end (or tail) + /// of the advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// + public void AddAdvice(IAdvice advice) + { + //int position = this._advisors != null ? this._advisors.Count : 0; + AddAdvice(-1, advice); + } + + /// + /// Adds the supplied to the supplied + /// in the advice (interceptor) chain. + /// + /// + /// The zero (0) indexed position (from the head) at which the + /// supplied is to be inserted into the + /// advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// If the supplied is ; + /// or is not an + /// reference; or if the supplied is a + /// . + /// + /// + /// + public void AddAdvice(int position, IAdvice advice) + { + if (advice is IInterceptor && !(advice is IMethodInterceptor)) + { + throw new AopConfigException( + GetType().FullName + " can only handle AOP Alliance IMethodInterceptor advice."); + } + if (advice is IIntroductionInterceptor) + { + throw + new AopConfigException( + "IIntroductionInterceptors may only be added as part of IIntroductionAdvisor."); + } + + AddAdvisor(position, new DefaultPointcutAdvisor(advice)); + } + + /// + /// Return the index (0 based) of the supplied + /// in the interceptor + /// (advice) chain for this proxy. + /// + /// + /// The to search for. + /// + /// + /// The zero (0) based index of this advisor, or -1 if the + /// supplied is not an advisor for this + /// proxy. + /// + public virtual int IndexOf(IAdvisor advisor) + { + lock(this.SyncRoot) + { + return IndexOfInternal(advisor); + } + } + + /// + /// Return the index (0 based) of the supplied + /// in the introductions + /// for this proxy. + /// + /// + /// The to search for. + /// + /// + /// The zero (0) based index of this advisor, or -1 if the + /// supplied is not an introduction advisor + /// for this proxy. + /// + public virtual int IndexOf(IIntroductionAdvisor advisor) + { + lock(this.SyncRoot) + { + return IndexOfInternal(advisor); + } + } + + /// + /// Removes the supplied the list of advisors + /// for this proxy. + /// + /// The advisor to remove. + /// + /// if advisor was found in the list of + /// for this + /// proxy and was successfully removed; if not + /// or if the supplied is . + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be removed. + /// + public bool RemoveAdvisor(IAdvisor advisor) + { + DieIfFrozen("Cannot remove advisor: config is frozen"); + bool wasRemoved = false; + if (advisor != null) + { + lock(this.SyncRoot) + { + int index = IndexOf(advisor); + if (index == -1) + { + wasRemoved = false; + } + else + { + RemoveAdvisorInternal(index); + wasRemoved = true; + } + } + } + return wasRemoved; + } + + /// + /// Removes the at the supplied + /// in the + /// list + /// from the list of + /// for this proxy. + /// + /// + /// The index of the to remove. + /// + /// + /// If this proxy configuration is frozen and the + /// at the supplied + /// cannot be removed; or if the supplied is out of + /// range. + /// + public virtual void RemoveAdvisor(int index) + { + DieIfFrozen("Cannot remove advisor: config is frozen"); + lock(this.SyncRoot) + { + RemoveAdvisorInternal(index); + } + } + + /// + /// Removes the supplied from the list + /// of . + /// + /// + /// The to remove. + /// + /// + /// if the supplied was + /// found in the list of + /// and successfully removed. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be removed. + /// + public bool RemoveAdvice(IAdvice advice) + { + lock(this.SyncRoot) + { + int index = IndexOf(advice); + if (index == -1) + { + return false; + } + else + { + RemoveAdvisorInternal(index); + return true; + } + } + } + + /// + /// Removes the supplied from the list + /// of . + /// + /// + /// The to remove. + /// + /// + /// if the supplied was + /// found in the list of + /// and successfully removed. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be removed. + /// + public bool RemoveIntroduction(IIntroductionAdvisor introduction) + { + DieIfFrozen("Cannot remove introduction: config is frozen"); + bool wasRemoved = false; + if (introduction != null) + { + lock(this.SyncRoot) + { + int index = IndexOf(introduction); + if (index == -1) + { + wasRemoved = false; + } + else + { + RemoveIntroduction(index); + wasRemoved = true; + } + } + } + return wasRemoved; + } + + /// + /// Removes the at the supplied + /// in the list of + /// for this proxy. + /// + /// The index of the advisor to remove. + /// + /// + /// If this proxy configuration is frozen and the + /// at the supplied + /// cannot be removed; or if the supplied + /// is out of range. + /// + public virtual void RemoveIntroduction(int index) + { + DieIfFrozen("Cannot remove introduction: config is frozen"); + lock(this.SyncRoot) + { + if (index < 0 || index >= _introductions.Count) + { + throw new AopConfigException( + "Introduction index " + index + " is out of bounds: Only have " + _introductions.Count + + " introductions."); + } + IIntroductionAdvisor advisor = (IIntroductionAdvisor) _introductions[index]; + // remove all interfaces introduced by the advisor... + foreach (Type intf in advisor.Interfaces) + { + RemoveInterface(intf); + } + this._introductions.RemoveAt(index); + UpdateIntroductionsArray(); + } + } + +// +// /// +// /// Removes the supplied from the list of +// /// for this +// /// proxy. +// /// +// /// +// /// The to be removed. +// /// +// /// +// /// If this proxy configuration is frozen and the +// /// cannot be added. +// /// +// public bool RemoveInterceptor(IInterceptor interceptor) +// { +// AssertFrozen("Cannot remove interceptor: config is frozen"); +// int index = IndexOf(interceptor); +// if (index == -1) +// { +// return false; +// } +// else +// { +// RemoveAdvisor(index); +// return true; +// } +// } + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The index in the + /// list at which the supplied + /// is to be inserted. If -1, appends to the end of the list. + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + public virtual void AddAdvisor(int index, IAdvisor advisor) + { + DieIfFrozen("Cannot add advisor: config is frozen"); + lock(this.SyncRoot) + { + // advisor already in list (SPRNET-846) + if (_advisors.Contains(advisor)) return; + + if(index == -1) + { + this._advisors.Add(advisor); + } + else + { + this._advisors.Insert(index, advisor); + } + UpdateAdvisorsArray(); + InterceptorsChanged(); + } + } + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + public virtual void AddAdvisor(IAdvisor advisor) + { + AddAdvisor(this._advisors.Count, advisor); + } + + /// + /// Adds the advisors from the supplied + /// to the list of . + /// + /// + /// The to add advisors from. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + public void AddAdvisors(IAdvisors advisors) + { + foreach (IAdvisor advisor in advisors.Advisors) + { + if (advisor is IIntroductionAdvisor) + { + AddIntroduction((IIntroductionAdvisor) advisor); + } + else + { + AddAdvisor(advisor); + } + } + } + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The index in the + /// list at which the supplied + /// is to be inserted. + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + public virtual void AddIntroduction(int index, IIntroductionAdvisor introductionAdvisor) + { + DieIfFrozen("Cannot add introduction: config is frozen"); + introductionAdvisor.ValidateInterfaces(); + + lock(this.SyncRoot) + { + if (index < this._introductions.Count) + { + this._introductions.RemoveAt(index); + } + this._introductions.Insert(index, introductionAdvisor); + + int intfCount = this.interfaceMap.Count; + // If the advisor passed validation we can make the change + foreach (Type intf in introductionAdvisor.Interfaces) + { + this.interfaceMap[intf] = introductionAdvisor; + } + UpdateIntroductionsArray(); + if (this.interfaceMap.Count != intfCount) + { + InterfacesChanged(); + } + } + } + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + public virtual void AddIntroduction(IIntroductionAdvisor introductionAdvisor) + { + Type introductionType = introductionAdvisor.Advice.GetType(); + lock(this.SyncRoot) + { + int pos = this._introductions.Count; + for (int i = 0; i < pos; i++) + { + IIntroductionAdvisor introduction + = (IIntroductionAdvisor) this._introductions[i]; + if (introduction.Advice.GetType() == introductionType) + { + pos = i; + } + } + AddIntroduction(pos, introductionAdvisor); + } + } + + /// + /// Replaces the that + /// exists at the supplied in the list of + /// + /// with the supplied . + /// + /// + /// The index of the + /// in the list of + /// + /// that is to be replaced. + /// + /// + /// The new (replacement) . + /// + /// + /// If the supplied is out of range. + /// + public virtual void ReplaceIntroduction(int index, IIntroductionAdvisor introduction) + { + lock(this.SyncRoot) + { + if(index < 0 || index >= _introductions.Count) + { + throw new AopConfigException( + "Introduction index " + index + " is out of bounds:" + + " there are currently " + _introductions.Count + + " introductions." ); + } + + _introductions[index] = introduction; + } + } + + /// + /// Replaces the with the + /// . + /// + /// + /// The original (old) advisor to be replaced. + /// + /// + /// The new advisor to replace the with. + /// + /// + /// if the was + /// replaced; if the was not found in the + /// advisors collection (or the is + /// , this method returns + /// and (effectively) does nothing. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be replaced. + /// + /// + public bool ReplaceAdvisor(IAdvisor oldAdvisor, IAdvisor newAdvisor) + { + DieIfFrozen("Cannot replace advisor: config is frozen."); + lock(this.SyncRoot) + { + int index = IndexOf(oldAdvisor); + if (index == -1 || newAdvisor == null) + { + return false; + } + RemoveAdvisor(index); + AddAdvisor(index, newAdvisor); + } + return true; + } + + /// + /// As will normally be passed straight through + /// to the advised target, this method returns the + /// equivalent for the AOP proxy itself. + /// + /// + /// A description of the proxy configuration. + /// + public virtual string ToProxyConfigString() + { + lock(this.SyncRoot) + { + return ToStringInternal(); + } + } + + #endregion + + #region ITargetTypeAware implementation + + /// + /// Gets the target type behind the implementing object. + /// Ttypically a proxy configuration or an actual proxy. + /// + /// The type of the target or null if not known. + public Type TargetType + { + get { return TargetSource.TargetType; } + } + + #endregion + + #region Properties + /// + /// Sets the target object that is to be advised. + /// + /// + ///

+ /// This is a convenience write-only property that allows client code + /// to set the target object... the target object will be implicitly + /// wrapped within a new + /// instance. + ///

+ ///
+ public virtual object Target + { + set { TargetSource = new SingletonTargetSource(value); } + } + + /// + /// Called by subclasses to get a value indicating whether any AOP proxies have been created yet. + /// + /// true if this AOp proxies have been created; otherwise, false. + protected bool IsActive + { + get { return isActive; } + } + + #endregion + + /// + /// Specifies the of proxies that are to be + /// created for this instance of proxy config. + /// + /// + ///

+ /// If this property value is it simply means that + /// no proxies have been created yet. Only when the first proxy is + /// created will this property value be set by the AOP framework. + ///

+ ///

+ /// Users will be able to add interceptors dynamically without proxy + /// regeneration, but if they add introductions the proxy + /// will have to be regenerated. + ///

+ ///
+ /// + /// The of proxies that are to be + /// created for this instance of proxy config; if + /// no proxies have been created yet. + /// + internal Type ProxyType + { + get { return this.proxyType; } + set { this.proxyType = value; } + } + + /// + /// Caches proxy constructor for performance reasons. + /// + internal ConstructorInfo ProxyConstructor + { + get { return this.proxyConstructor; } + set { this.proxyConstructor = value; } + } + + /// + /// Registers the supplied as a listener for + /// notifications. + /// + /// + /// The to + /// register. + /// + public virtual void AddListener(IAdvisedSupportListener listener) + { + lock(this.SyncRoot) + { + this.listeners.Add(listener); + } + } + + /// + /// Removes the supplied . + /// + /// + /// The to + /// be removed. + /// + public virtual void RemoveListener(IAdvisedSupportListener listener) + { + lock(this.SyncRoot) + { + this.listeners.Remove(listener); + } + } + + /// + /// Adds a new interface to the list of interfaces that are proxied by this proxy. + /// + /// + /// The interface to be proxied by this proxy. + /// + /// + /// If this proxy configuration is frozen + /// (); + /// + /// + /// If the supplied is . + /// + public virtual void AddInterface(Type intf) + { + DieIfFrozen("Cannot add interface: configuration is frozen."); + AssertUtils.ArgumentNotNull(intf, "intf", "Cannot proxy a null interface."); + + lock(this.SyncRoot) + { + AddInterfaceInternal(intf); + InterfacesChanged(); + } + } + + /// + /// Adds a new interface to the list of interfaces that are proxied by this proxy. + /// + /// + /// The interface to be proxied by this proxy. + /// + /// + /// Access is not synchronized. + /// + protected virtual void AddInterfaceInternal(Type intf) + { + this.interfaceMap[intf] = null; + } + + /// + /// Removes the supplied (proxied) . + /// + /// + ///

+ /// Does nothing if the supplied (proxied) + /// isn't proxied. + ///

+ ///
+ /// The interface to remove. + /// + /// if the interface was removed. + public virtual bool RemoveInterface(Type intf) + { + DieIfFrozen("Cannot remove interface: configuration is frozen."); + lock(this.SyncRoot) + { + if (intf != null && this.interfaceMap.Contains(intf)) + { + this.interfaceMap.Remove(intf); + InterfacesChanged(); + return true; + } + } + return false; + } + + /// + /// Return the index (0 based) of the supplied + /// in the interceptor + /// (advice) chain for this proxy. + /// + /// + ///

+ /// The return value of this method can be used to index into + /// the + /// list. + ///

+ ///
+ /// + /// The to search for. + /// + /// + /// The zero (0) based index of this interceptor, or -1 if the + /// supplied is not an advice for this + /// proxy. + /// + public virtual int IndexOf(IAdvice advice) + { + lock(this.SyncRoot) + { + return IndexOfInternal(advice); + } + } + + /// + /// Return the index (0 based) of the supplied + /// in the interceptor + /// (advice) chain for this proxy. + /// + /// + ///

Acces is not synchronized

+ ///

+ /// The return value of this method can be used to index into + /// the + /// list. + ///

+ ///
+ /// + /// The to search for. + /// + /// + /// The zero (0) based index of this interceptor, or -1 if the + /// supplied is not an advice for this + /// proxy. + /// + private int IndexOfInternal(IAdvice advice) + { + if (this._advisors != null) + { + for (int i = 0; i < this._advisors.Count; ++i) + { + IAdvisor advisor = (IAdvisor) this._advisors[i]; + if (advisor.Advice == advice) + { + return i; + } + } + } + return -1; + } + + /// + /// Return the index (0 based) of the supplied + /// in the interceptor + /// (advice) chain for this proxy. + /// + /// + /// The to search for. + /// + /// + /// The zero (0) based index of this advisor, or -1 if the + /// supplied is not an advisor for this + /// proxy. + /// + /// + /// Access is not synchronized. + /// + private int IndexOfInternal(IAdvisor advisor) + { + return this._advisors != null ? this._advisors.IndexOf(advisor) : -1; + } + + /// + /// Return the index (0 based) of the supplied + /// in the introductions + /// for this proxy. + /// + /// + /// The to search for. + /// + /// + /// The zero (0) based index of this advisor, or -1 if the + /// supplied is not an introduction advisor + /// for this proxy. + /// + /// + /// Access is not synchronized + /// + private int IndexOfInternal(IIntroductionAdvisor advisor) + { + return this._introductions.IndexOf(advisor); + } + + /// + /// Removes the at the supplied + /// in the + /// list + /// from the list of + /// for this proxy. + /// + /// + /// The index of the to remove. + /// + /// + /// If this proxy configuration is frozen and the + /// at the supplied + /// cannot be removed; or if the supplied is out of + /// range. + /// + /// + /// Does not synchronize access. + /// + private void RemoveAdvisorInternal(int index) + { + if (index < 0 || index >= this._advisors.Count) + { + throw + new AopConfigException( + "Advisor index " + index + " is out of bounds: Only have " + this._advisors.Count + " advisors"); + } + this._advisors.RemoveAt(index); + this.UpdateAdvisorsArray(); + this.InterceptorsChanged(); + } + + /// + /// Is the supplied included in any + /// advisor? + /// + /// + /// The to check for the + /// inclusion of. + /// + /// + /// if the supplied + /// could be run in an invocation (this does not imply that said + /// will be run). + /// + public bool AdviceIncluded(IAdvice advice) + { + return (IndexOf(advice) != -1); + } + + /// + /// Returns a count of all of the + /// type-compatible with the supplied . + /// + /// + /// The of the + /// to check. + /// + /// + /// A count of all of the + /// type-compatible with the supplied . + /// + public int CountAdviceOfType(Type interceptorType) + { + int count = 0; + lock(this.SyncRoot) + { + foreach (IAdvisor advisor in this._advisors) + { + if (interceptorType.IsAssignableFrom(advisor.Advice.GetType())) + { + ++count; + } + } + } + return count; + } + + /// + /// Throws an if + /// this instances proxy configuration data is frozen. + /// + /// + /// The message that will be passed through to the constructor of any + /// thrown . + /// + /// + /// If the configuration for this proxy is frozen. + /// + /// + private void DieIfFrozen(string message) + { + if (IsFrozen) + { + throw new AopConfigException(message); + } + } + + /// + /// Bring the advisors array up to date with the list. + /// + private void UpdateAdvisorsArray() + { + this._advisorsArray = new IAdvisor[this._advisors.Count]; + this._advisors.CopyTo(this._advisorsArray, 0); + } + + /// + /// Bring the introductions array up to date with the list. + /// + private void UpdateIntroductionsArray() + { + this._introductionsArray = new IIntroductionAdvisor[this._introductions.Count]; + this._introductions.CopyTo(this._introductionsArray, 0); + } + + /// + /// Callback method that is invoked when the list of proxied interfaces + /// has changed. + /// + /// + ///

+ /// An example of such a change would be when a new introduction is + /// added. Resetting + /// to + /// will cause a new proxy + /// to be generated on the next call to get a proxy. + ///

+ ///
+ private void InterfacesChanged() + { + ProxyType = null; + if (this.isActive) + { + foreach (IAdvisedSupportListener listener in this.listeners) + { + listener.InterfacesChanged(this); + } + } + } + + /// + /// Callback method that is invoked when the interceptor list has changed. + /// + private void InterceptorsChanged() + { + if (this.isActive) + { + foreach (IAdvisedSupportListener listener in this.listeners) + { + listener.AdviceChanged(this); + } + } + } + + /// + /// Activates this instance. + /// + protected void Activate() + { + lock (this.SyncRoot) + { + this.isActive = true; + foreach (IAdvisedSupportListener listener in this.listeners) + { + listener.Activated(this); + } + } + } + + /// + /// Creates an AOP proxy using this instance's configuration data. + /// + /// + ///

+ /// Subclasses must not create a proxy by any other means (at least + /// without having a well thought out and cogent reason for doing so). + /// This is because the implementation of this method performs some + /// required housekeeping logic prior to creating an AOP proxy. + ///

+ ///
+ /// + protected internal virtual IAopProxy CreateAopProxy() + { + lock (this.SyncRoot) + { + if (!this.isActive) + { + Activate(); + } + return AopProxyFactory.CreateAopProxy(this); + } + } + + /// + /// Copies the configuration from the supplied other + /// into this instance. + /// + /// + ///

+ /// Useful when this instance has been created using the no-argument + /// constructor, and needs to get all of its confiuration data from + /// another (most + /// usually to have an independant copy of said configuration data). + ///

+ ///
+ /// + /// The instance + /// containing the configiration data that is to be copied into this + /// instance. + /// + protected internal virtual void CopyConfigurationFrom(AdvisedSupport other) + { + CopyFrom(other); + this.m_targetSource = other.m_targetSource; + this.proxyType = other.proxyType; + this.proxyConstructor = other.proxyConstructor; + + foreach (Type intf in other.interfaceMap.Keys) + { + this.interfaceMap[intf] = other.interfaceMap[intf]; + } + this._advisors = new ArrayList(); + foreach (IAdvisor advisor in other._advisors) + { + AddAdvisor(advisor); + } + this._introductions = new ArrayList(); + foreach (IIntroductionAdvisor advisor in other._introductions) + { + AddIntroduction(advisor); + } + } + + /// + /// A that represents the current + /// configuration. + /// + /// + /// A that represents the current + /// configuration. + /// + public override string ToString() + { + lock(this.SyncRoot) + { + return ToStringInternal(); + } + } + + /// + /// A that represents the current + /// configuration. + /// + /// + /// A that represents the current + /// configuration. + /// + private string ToStringInternal() + { + StringBuilder buffer = new StringBuilder(this.GetType().FullName + ":\n"); + buffer.Append(this.interfaceMap.Count + " interfaces=["); + this.InterfacesToString(buffer); + buffer.Append("];\n"); + buffer.Append(this._advisors.Count + " pointcuts=["); + this.AdvisorsToString(buffer); + buffer.Append("];\n"); + buffer.Append("targetSource=[" + this.m_targetSource + "];\n"); + buffer.Append("advisorChainFactory=" + this.advisorChainFactory + ";\n"); + buffer.Append(base.ToString()); + return buffer.ToString(); + } + + /// + /// Helper method that adds the names of all of the proxied interfaces + /// to the buffer of the supplied . + /// + /// + /// The to append the proxied interface + /// names to. + /// + private void InterfacesToString(StringBuilder buffer) + { + string separator = string.Empty; + foreach (Type intf in this.interfaceMap.Keys) + { + buffer.Append(separator).Append("[").Append(intf.FullName).Append("] -> "); + IIntroductionAdvisor advisor = this.interfaceMap[intf] as IIntroductionAdvisor; + if (advisor == null) + { + if (TargetSource.TargetType != null) + { + buffer.Append("target[").Append(TargetSource.TargetType.FullName).Append("]"); + } + else + { + buffer.Append("target[NOT SPECIFIED (=null)]"); + } + } + else + { + buffer.Append("introduction[").Append(advisor.Advice.GetType().FullName).Append("]"); + } + separator = ", "; + } + } + + /// + /// Helper method that adds advisor's + /// to the buffer of the supplied . + /// + /// + /// The to append the advisor details to. + /// + private void AdvisorsToString(StringBuilder buffer) + { + string separator = string.Empty; + foreach (IAdvisor advisor in this._advisors) + { + buffer.Append(separator).Append(advisor); + separator = ", "; + } + } + + /// + /// Gets all of the interfaces implemented by the + /// of the supplied + /// . + /// + /// + /// The object to get the interfaces of. + /// + /// + /// All of the interfaces implemented by the + /// of the supplied + /// . + /// + /// + /// If the supplied is . + /// + protected static Type[] GetInterfaces(object target) + { + if (target == null) + { + throw new AopConfigException("Can't proxy null object"); + } + return ReflectionUtils.GetInterfaces(target.GetType()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AdvisorChainFactoryUtils.cs b/src/Spring/Spring.Aop/Aop/Framework/AdvisorChainFactoryUtils.cs index ecb8821f..00b3db2d 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AdvisorChainFactoryUtils.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AdvisorChainFactoryUtils.cs @@ -1,122 +1,121 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using AopAlliance.Intercept; -using Spring.Aop.Framework.Adapter; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Utility methods for use by - /// implementations. - /// - /// - ///

- /// Not intended to be used directly by applications. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: AdvisorChainFactoryUtils.cs,v 1.7 2006/04/09 07:18:35 markpollack Exp $ - public sealed class AdvisorChainFactoryUtils - { - /// - /// Gets the list of - /// interceptors and dynamic interception - /// advice that may apply to the supplied - /// invocation. - /// - /// The proxy configuration. - /// The object proxy. - /// - /// The method to evaluate interceptors for. - /// - /// - /// The of the target object. - /// - /// - /// A of - /// (if there's - /// a dynamic method matcher that needs evaluation at runtime). - /// - public static IList CalculateInterceptors( - IAdvised config, object proxy, MethodInfo method, Type targetType) - { - IList interceptors = new ArrayList(config.Advisors.Length); - foreach (IAdvisor advisor in config.Advisors) - { - if (advisor is IPointcutAdvisor) - { - IPointcutAdvisor pointcutAdvisor = (IPointcutAdvisor) advisor; - if (pointcutAdvisor.Pointcut.TypeFilter.Matches(targetType)) - { - IMethodInterceptor interceptor = - (IMethodInterceptor) GlobalAdvisorAdapterRegistry.Instance.GetInterceptor(advisor); - IMethodMatcher mm = pointcutAdvisor.Pointcut.MethodMatcher; - if (mm.Matches(method, targetType)) - { - if (mm.IsRuntime) - { - // Creating a new object instance in the GetInterceptor() method - // isn't a problem as we normally cache created chains... - interceptors.Add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); - } - else - { - interceptors.Add(interceptor); - } - } - } - } - } - return interceptors; - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible - /// constructors. - ///

- ///
- private AdvisorChainFactoryUtils() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using AopAlliance.Intercept; +using Spring.Aop.Framework.Adapter; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Utility methods for use by + /// implementations. + /// + /// + ///

+ /// Not intended to be used directly by applications. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public sealed class AdvisorChainFactoryUtils + { + /// + /// Gets the list of + /// interceptors and dynamic interception + /// advice that may apply to the supplied + /// invocation. + /// + /// The proxy configuration. + /// The object proxy. + /// + /// The method to evaluate interceptors for. + /// + /// + /// The of the target object. + /// + /// + /// A of + /// (if there's + /// a dynamic method matcher that needs evaluation at runtime). + /// + public static IList CalculateInterceptors( + IAdvised config, object proxy, MethodInfo method, Type targetType) + { + IList interceptors = new ArrayList(config.Advisors.Length); + foreach (IAdvisor advisor in config.Advisors) + { + if (advisor is IPointcutAdvisor) + { + IPointcutAdvisor pointcutAdvisor = (IPointcutAdvisor) advisor; + if (pointcutAdvisor.Pointcut.TypeFilter.Matches(targetType)) + { + IMethodInterceptor interceptor = + (IMethodInterceptor) GlobalAdvisorAdapterRegistry.Instance.GetInterceptor(advisor); + IMethodMatcher mm = pointcutAdvisor.Pointcut.MethodMatcher; + if (mm.Matches(method, targetType)) + { + if (mm.IsRuntime) + { + // Creating a new object instance in the GetInterceptor() method + // isn't a problem as we normally cache created chains... + interceptors.Add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); + } + else + { + interceptors.Add(interceptor); + } + } + } + } + } + return interceptors; + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible + /// constructors. + ///

+ ///
+ private AdvisorChainFactoryUtils() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AopConfigException.cs b/src/Spring/Spring.Aop/Aop/Framework/AopConfigException.cs index e471ecc4..e7dbcf06 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AopConfigException.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AopConfigException.cs @@ -1,93 +1,92 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Thrown in response to the misconfiguration of an AOP proxy. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: AopConfigException.cs,v 1.4 2006/04/09 07:18:35 markpollack Exp $ - [Serializable] - public class AopConfigException : ApplicationException - { - /// - /// Creates a new instance of the - /// class. - /// - public AopConfigException () - { - } - - /// - /// Creates a new instance of the - /// class with - /// the specified message. - /// - /// - /// A message about the exception. - /// - public AopConfigException (string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class with - /// the specified message and root cause. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public AopConfigException (string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected AopConfigException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Thrown in response to the misconfiguration of an AOP proxy. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class AopConfigException : ApplicationException + { + /// + /// Creates a new instance of the + /// class. + /// + public AopConfigException () + { + } + + /// + /// Creates a new instance of the + /// class with + /// the specified message. + /// + /// + /// A message about the exception. + /// + public AopConfigException (string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class with + /// the specified message and root cause. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public AopConfigException (string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected AopConfigException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AopContext.cs b/src/Spring/Spring.Aop/Aop/Framework/AopContext.cs index 42e1e534..45260de6 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AopContext.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AopContext.cs @@ -1,172 +1,171 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using Spring.Threading; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// This class contains various methods used to - /// obtain information about the current AOP invocation. - /// - /// - ///

- /// The - /// property is - /// usable if the AOP framework is configured to expose the current proxy - /// (not the default)... it returns the AOP proxy in use. Target objects or - /// advice can use this to make advised calls. They can also use it to find - /// advice configuration. - ///

- /// - /// The AOP framework does not expose proxies by default, as there is a - /// performance cost in doing so. - /// - ///

- /// The functionality in this class might be used by a target object that - /// needed access to resources on the invocation. However, this approach - /// should not be used when there is a reasonable alternative, as it makes - /// application code dependent on usage under AOP and the Spring.NET AOP - /// framework. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: AopContext.cs,v 1.7 2006/09/15 21:25:16 markpollack Exp $ - public sealed class AopContext - { - private const string CURRENTPROXY_SLOTNAME = "AopContext.CurrentProxySlotName"; - - /// - /// The AOP proxy associated with this thread. - /// - /// - ///

- /// Will be unless the - /// property - /// on the controlling proxy has been set to . - ///

- ///

- /// The default value for the - /// property - /// is , for performance reasons. - ///

- ///
- private static Stack ProxyStack - { - get - { - Stack proxyStack = LogicalThreadContext.GetData(CURRENTPROXY_SLOTNAME) as Stack; - if (proxyStack == null) - { - proxyStack = new Stack(); - LogicalThreadContext.SetData(CURRENTPROXY_SLOTNAME, proxyStack); - } - return proxyStack; - } - } - - /// - /// Gets the current AOP proxy. - /// - /// - /// If the proxy stack is empty. - /// - public static object CurrentProxy - { - get - { - if (ProxyStack.Count == 0) - { - throw new AopConfigException( - "Cannot find proxy: Set the 'ExposeProxy' property " + - "to 'true' on IAdvised to make it available."); - } - return ProxyStack.Peek(); - } - } - - /// - /// Sets the current proxy by pushing it to the proxy stack. - /// - /// - ///

- /// This method is for internal use only, and should never be called by - /// client code. - ///

- ///
- /// - /// The proxy to put on top of the proxy stack. - /// - public static void PushProxy(object proxy) - { - ProxyStack.Push(proxy); - } - - /// - /// Removes the current proxy from the proxy stack, making the previous - /// proxy (if any) the current proxy. - /// - /// - ///

- /// This method is for internal use only, and should never be called by - /// client code. - ///

- ///
- /// - /// If the proxy stack is empty. - /// - public static void PopProxy() - { - if (ProxyStack.Count == 0) - { - throw new AopConfigException( - "Proxy stack empty. Always call 'PushProxy' before 'PopProxy'."); - } - ProxyStack.Pop(); - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private AopContext() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using Spring.Threading; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// This class contains various methods used to + /// obtain information about the current AOP invocation. + /// + /// + ///

+ /// The + /// property is + /// usable if the AOP framework is configured to expose the current proxy + /// (not the default)... it returns the AOP proxy in use. Target objects or + /// advice can use this to make advised calls. They can also use it to find + /// advice configuration. + ///

+ /// + /// The AOP framework does not expose proxies by default, as there is a + /// performance cost in doing so. + /// + ///

+ /// The functionality in this class might be used by a target object that + /// needed access to resources on the invocation. However, this approach + /// should not be used when there is a reasonable alternative, as it makes + /// application code dependent on usage under AOP and the Spring.NET AOP + /// framework. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public sealed class AopContext + { + private const string CURRENTPROXY_SLOTNAME = "AopContext.CurrentProxySlotName"; + + /// + /// The AOP proxy associated with this thread. + /// + /// + ///

+ /// Will be unless the + /// property + /// on the controlling proxy has been set to . + ///

+ ///

+ /// The default value for the + /// property + /// is , for performance reasons. + ///

+ ///
+ private static Stack ProxyStack + { + get + { + Stack proxyStack = LogicalThreadContext.GetData(CURRENTPROXY_SLOTNAME) as Stack; + if (proxyStack == null) + { + proxyStack = new Stack(); + LogicalThreadContext.SetData(CURRENTPROXY_SLOTNAME, proxyStack); + } + return proxyStack; + } + } + + /// + /// Gets the current AOP proxy. + /// + /// + /// If the proxy stack is empty. + /// + public static object CurrentProxy + { + get + { + if (ProxyStack.Count == 0) + { + throw new AopConfigException( + "Cannot find proxy: Set the 'ExposeProxy' property " + + "to 'true' on IAdvised to make it available."); + } + return ProxyStack.Peek(); + } + } + + /// + /// Sets the current proxy by pushing it to the proxy stack. + /// + /// + ///

+ /// This method is for internal use only, and should never be called by + /// client code. + ///

+ ///
+ /// + /// The proxy to put on top of the proxy stack. + /// + public static void PushProxy(object proxy) + { + ProxyStack.Push(proxy); + } + + /// + /// Removes the current proxy from the proxy stack, making the previous + /// proxy (if any) the current proxy. + /// + /// + ///

+ /// This method is for internal use only, and should never be called by + /// client code. + ///

+ ///
+ /// + /// If the proxy stack is empty. + /// + public static void PopProxy() + { + if (ProxyStack.Count == 0) + { + throw new AopConfigException( + "Proxy stack empty. Always call 'PushProxy' before 'PopProxy'."); + } + ProxyStack.Pop(); + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private AopContext() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs b/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs index 02d83063..257289ec 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs @@ -1,272 +1,271 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Collections; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Utility methods used by the AOP framework. - /// - /// - ///

- /// Not intended to be used directly by applications. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Aleksandar Seovic (.NET) - /// $Id: AopUtils.cs,v 1.4 2007/10/10 18:07:38 markpollack Exp $ - public sealed class AopUtils - { - - // This is a leaky abstraction as we have hardcoded known IAopProxyFactory implementations. - private const string COMPOSITION_PROXY_TYPE_NAME = "CompositionAopProxy"; - - private const string DECORATOR_PROXY_TYPE_NAME = "DecoratorAopProxy"; - - /// - /// Is the supplied an AOP proxy? - /// - /// - /// Return whether the given object is either - /// a composition-based proxy or a decorator-based proxy. - /// - /// The instance to be checked. - /// - /// if the supplied is - /// an AOP proxy. - /// - public static bool IsAopProxy(object instance) - { - return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance); - } - - /// - /// Is the supplied a composition-based AOP proxy? - /// - /// The instance to be checked. - /// - /// if the supplied is - /// an composition-based AOP proxy. - /// - public static bool IsCompositionAopProxy(Object instance) - { - return ((instance != null) && instance.GetType().FullName.StartsWith(COMPOSITION_PROXY_TYPE_NAME)); - } - - /// - /// Is the supplied a decorator-based AOP proxy? - /// - /// The instance to be checked. - /// - /// if the supplied is - /// an decorator-based AOP proxy. - /// - public static bool IsDecoratorAopProxy(Object instance) - { - return ((instance != null) && instance.GetType().FullName.StartsWith(DECORATOR_PROXY_TYPE_NAME)); - } - - /// - /// Gets all of the interfaces that the of the - /// supplied implements. - /// - /// - ///

- /// This includes interfaces implemented by any superclasses. - ///

- ///
- /// - /// The object to analyse for interfaces. - /// - /// - /// All of the interfaces that the of the - /// supplied implements; or an empty - /// array if the supplied is - /// . - /// - public static Type[] GetAllInterfaces(object instance) - { - if (instance != null) - { - ISet interfaces = new HybridSet(); - Type type = instance.GetType(); - do - { - Type[] ifcs = type.GetInterfaces(); - foreach (Type ifc in ifcs) - { - interfaces.Add(ifc); - } - type = type.BaseType; - } while (type != null); - if (interfaces.Count > 0) - { - Type[] types = new Type[interfaces.Count]; - interfaces.CopyTo(types, 0); - return types; - } - } - return Type.EmptyTypes; - } - - /// - /// Can the supplied apply at all on the - /// supplied ? - /// - /// - ///

- /// This is an important test as it can be used to optimize out a - /// pointcut for a class. - ///

- ///

- /// Invoking this method with a that is - /// an interface type will always yield a - /// return value. - ///

- ///
- /// The pointcut being tested. - /// The class being tested. - /// - /// The interfaces being proxied. If , all - /// methods on a class may be proxied. - /// - /// - /// if the pointcut can apply on any method. - /// - public static bool CanApply( - IPointcut pointcut, Type targetType, Type[] proxyInterfaces) - { - if (!pointcut.TypeFilter.Matches(targetType)) - { - return false; - } - - // It may apply to the class - // Check whether it can apply on any method - // Checks public methods, including inherited methods - MethodInfo[] methods = targetType.GetMethods(); - for (int i = 0; i < methods.Length; ++i) - { - MethodInfo m = methods[i]; - // If we're looking only at interfaces and this method - // isn't on any of them, skip it - if (proxyInterfaces != null - && !ReflectionUtils.MethodIsOnOneOfTheseInterfaces(m, proxyInterfaces)) - { - continue; - } - if (pointcut.MethodMatcher.Matches(m, targetType)) - { - return true; - } - } - return false; - } - - /// - /// Can the supplied apply at all on the - /// supplied ? - /// - /// - ///

- /// This is an important test as it can be used to optimize out an - /// advisor for a class. - ///

- ///
- /// The advisor to check. - /// The class being tested. - /// - /// The interfaces being proxied. If , all - /// methods on a class may be proxied. - /// - /// - /// if the advisor can apply on any method. - /// - public static bool CanApply( - IAdvisor advisor, Type targetType, Type[] proxyInterfaces) - { - if (advisor is IIntroductionAdvisor) - { - return ((IIntroductionAdvisor) advisor).TypeFilter.Matches(targetType); - } - else if (advisor is IPointcutAdvisor) - { - IPointcutAdvisor pca = (IPointcutAdvisor) advisor; - return CanApply(pca.Pointcut, targetType, proxyInterfaces); - } - // no pointcut specified so assume it applies... - return true; - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly - /// visible constructors. - ///

- ///
- private AopUtils() - { - } - - // CLOVER:ON - - #endregion - - /// - /// Gets the type of the target. - /// - /// The candidate. - /// - public static Type GetTargetType(object candidate) - { - AssertUtils.ArgumentNotNull(candidate,"candidate", "Candidate object must not be null"); - if (candidate is ITargetSource) - { - return ((ITargetSource) candidate).TargetType; - } - if (candidate is IAdvised) - { - return ((IAdvised) candidate).TargetSource.TargetType; - } - if (IsDecoratorAopProxy(candidate)) - { - return candidate.GetType().BaseType; - } - return candidate.GetType(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Collections; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Utility methods used by the AOP framework. + /// + /// + ///

+ /// Not intended to be used directly by applications. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Aleksandar Seovic (.NET) + public sealed class AopUtils + { + + // This is a leaky abstraction as we have hardcoded known IAopProxyFactory implementations. + private const string COMPOSITION_PROXY_TYPE_NAME = "CompositionAopProxy"; + + private const string DECORATOR_PROXY_TYPE_NAME = "DecoratorAopProxy"; + + /// + /// Is the supplied an AOP proxy? + /// + /// + /// Return whether the given object is either + /// a composition-based proxy or a decorator-based proxy. + /// + /// The instance to be checked. + /// + /// if the supplied is + /// an AOP proxy. + /// + public static bool IsAopProxy(object instance) + { + return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance); + } + + /// + /// Is the supplied a composition-based AOP proxy? + /// + /// The instance to be checked. + /// + /// if the supplied is + /// an composition-based AOP proxy. + /// + public static bool IsCompositionAopProxy(Object instance) + { + return ((instance != null) && instance.GetType().FullName.StartsWith(COMPOSITION_PROXY_TYPE_NAME)); + } + + /// + /// Is the supplied a decorator-based AOP proxy? + /// + /// The instance to be checked. + /// + /// if the supplied is + /// an decorator-based AOP proxy. + /// + public static bool IsDecoratorAopProxy(Object instance) + { + return ((instance != null) && instance.GetType().FullName.StartsWith(DECORATOR_PROXY_TYPE_NAME)); + } + + /// + /// Gets all of the interfaces that the of the + /// supplied implements. + /// + /// + ///

+ /// This includes interfaces implemented by any superclasses. + ///

+ ///
+ /// + /// The object to analyse for interfaces. + /// + /// + /// All of the interfaces that the of the + /// supplied implements; or an empty + /// array if the supplied is + /// . + /// + public static Type[] GetAllInterfaces(object instance) + { + if (instance != null) + { + ISet interfaces = new HybridSet(); + Type type = instance.GetType(); + do + { + Type[] ifcs = type.GetInterfaces(); + foreach (Type ifc in ifcs) + { + interfaces.Add(ifc); + } + type = type.BaseType; + } while (type != null); + if (interfaces.Count > 0) + { + Type[] types = new Type[interfaces.Count]; + interfaces.CopyTo(types, 0); + return types; + } + } + return Type.EmptyTypes; + } + + /// + /// Can the supplied apply at all on the + /// supplied ? + /// + /// + ///

+ /// This is an important test as it can be used to optimize out a + /// pointcut for a class. + ///

+ ///

+ /// Invoking this method with a that is + /// an interface type will always yield a + /// return value. + ///

+ ///
+ /// The pointcut being tested. + /// The class being tested. + /// + /// The interfaces being proxied. If , all + /// methods on a class may be proxied. + /// + /// + /// if the pointcut can apply on any method. + /// + public static bool CanApply( + IPointcut pointcut, Type targetType, Type[] proxyInterfaces) + { + if (!pointcut.TypeFilter.Matches(targetType)) + { + return false; + } + + // It may apply to the class + // Check whether it can apply on any method + // Checks public methods, including inherited methods + MethodInfo[] methods = targetType.GetMethods(); + for (int i = 0; i < methods.Length; ++i) + { + MethodInfo m = methods[i]; + // If we're looking only at interfaces and this method + // isn't on any of them, skip it + if (proxyInterfaces != null + && !ReflectionUtils.MethodIsOnOneOfTheseInterfaces(m, proxyInterfaces)) + { + continue; + } + if (pointcut.MethodMatcher.Matches(m, targetType)) + { + return true; + } + } + return false; + } + + /// + /// Can the supplied apply at all on the + /// supplied ? + /// + /// + ///

+ /// This is an important test as it can be used to optimize out an + /// advisor for a class. + ///

+ ///
+ /// The advisor to check. + /// The class being tested. + /// + /// The interfaces being proxied. If , all + /// methods on a class may be proxied. + /// + /// + /// if the advisor can apply on any method. + /// + public static bool CanApply( + IAdvisor advisor, Type targetType, Type[] proxyInterfaces) + { + if (advisor is IIntroductionAdvisor) + { + return ((IIntroductionAdvisor) advisor).TypeFilter.Matches(targetType); + } + else if (advisor is IPointcutAdvisor) + { + IPointcutAdvisor pca = (IPointcutAdvisor) advisor; + return CanApply(pca.Pointcut, targetType, proxyInterfaces); + } + // no pointcut specified so assume it applies... + return true; + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ private AopUtils() + { + } + + // CLOVER:ON + + #endregion + + /// + /// Gets the type of the target. + /// + /// The candidate. + /// + public static Type GetTargetType(object candidate) + { + AssertUtils.ArgumentNotNull(candidate,"candidate", "Candidate object must not be null"); + if (candidate is ITargetSource) + { + return ((ITargetSource) candidate).TargetType; + } + if (candidate is IAdvised) + { + return ((IAdvised) candidate).TargetSource.TargetType; + } + if (IsDecoratorAopProxy(candidate)) + { + return candidate.GetType().BaseType; + } + return candidate.GetType(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAdvisorAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAdvisorAutoProxyCreator.cs index 32c77446..fbb67b99 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAdvisorAutoProxyCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAdvisorAutoProxyCreator.cs @@ -1,166 +1,165 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Aop.Framework.DynamicProxy; -using Spring.Core; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Aop.Framework.AutoProxy -{ - /// - /// Abstract IOBjectPostProcessor implementation that creates AOP proxies. - /// This class is completely generic; it contains no special code to handle - /// any particular aspects, such as pooling aspects. - /// - /// - ///

Subclasses must implement the abstract findCandidateAdvisors() method - /// to return a list of Advisors applying to any object. Subclasses can also - /// override the inherited shouldSkip() method to exclude certain objects - /// from autoproxying, but they must be careful to invoke the shouldSkip() - /// method of this class, which tries to avoid circular reference problems - /// and infinite loops.

- ///

Advisors or advices requiring ordering should implement the Ordered interface. - /// This class sorts advisors by Ordered order value. Advisors that don't implement - /// the Ordered interface will be considered to be unordered, and will appear - /// at the end of the advisor chain in undefined order.

- ///
- /// - /// Rod Johnson - /// Adhari C Mahendra (.NET) - /// $Id: AbstractAdvisorAutoProxyCreator.cs,v 1.5 2007/08/22 08:49:08 markpollack Exp $ - public abstract class AbstractAdvisorAutoProxyCreator : AbstractAutoProxyCreator - { - /// - /// We override this method to ensure that all candidate advisors are materialized - /// under a stack trace including this object. Otherwise, the dependencies won't - /// be apparent to the circular-reference prevention strategy in AbstractObjectFactory. - /// - public override IObjectFactory ObjectFactory - { - //TODO investigate override... - set - { - base.ObjectFactory = value; - if (!(value is IConfigurableListableObjectFactory)) - { - throw new InvalidOperationException( - "Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory"); - } - } - get { return base.ObjectFactory; } - } - - /// - /// Return whether the given object is to be proxied, what additional - /// advices (e.g. AOP Alliance interceptors) and advisors to apply. - /// - /// the new object instance - /// the name of the object - /// targetSource returned by TargetSource property: - /// may be ignored. Will be null unless a custom target source is in use. - /// - /// an array of additional interceptors for the particular object; - /// or an empty array if no additional interceptors but just the common ones; - /// or null if no proxy at all, not even with the common interceptors. - /// - /// - ///

The previous name of this method was "GetInterceptorAndAdvisorForObject". - /// It has been renamed in the course of general terminology clarification - /// in Spring 1.1. An AOP Alliance Interceptor is just a special form of - /// Advice, so the generic Advice term is preferred now.

- ///

The third parameter, customTargetSource, is new in Spring 1.1; - /// add it to existing implementations of this method.

- ///
- protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource) - { - IList advisors = FindEligibleAdvisors(objType); - if (advisors.Count == 0) - { - return DO_NOT_PROXY; - } - advisors = SortAdvisors(advisors); - if (advisors is ArrayList) - return ((ArrayList) advisors).ToArray(); - else - { - return advisors as object[]; - } - } - - /// - /// Find all eligible advices and for autoproxying this class. - /// - /// - /// the empty list, not null, if there are no pointcuts or interceptors - protected IList FindEligibleAdvisors(Type type) - { - IList candidateAdvisors = FindCandidateAdvisors(); - IList eligibleAdvisors = new ArrayList(); - for (int i = 0; i < candidateAdvisors.Count; i++) - { - IAdvisor candidate = (IAdvisor) candidateAdvisors[i]; - if (AopUtils.CanApply(candidate, type, null)) - { - eligibleAdvisors.Add(candidate); - if (logger.IsInfoEnabled) - { - logger.Info(string.Format("Candidate advisor [{0}] accepted for type [{1}]", candidate, type.ToString())); - } - } - else - { - if (logger.IsInfoEnabled) - { - logger.Info(string.Format("Candidate advisor [{0}] rejected for type [{1}]", candidate, type.ToString())); - } - } - } - return eligibleAdvisors; - } - - - /// - /// Sorts the advisors. - /// - /// The advisors. - /// - protected IList SortAdvisors(IList advisors) - { - if (advisors is ArrayList) - ((ArrayList) advisors).Sort(new OrderComparator()); - else if (advisors is Array) - Array.Sort((Array) advisors, new OrderComparator()); - return advisors; - } - - /// - /// Find all candidate advisors to use in auto-proxying. - /// - /// list of Advisors - protected abstract IList FindCandidateAdvisors(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Aop.Framework.DynamicProxy; +using Spring.Core; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// Abstract IOBjectPostProcessor implementation that creates AOP proxies. + /// This class is completely generic; it contains no special code to handle + /// any particular aspects, such as pooling aspects. + /// + /// + ///

Subclasses must implement the abstract findCandidateAdvisors() method + /// to return a list of Advisors applying to any object. Subclasses can also + /// override the inherited shouldSkip() method to exclude certain objects + /// from autoproxying, but they must be careful to invoke the shouldSkip() + /// method of this class, which tries to avoid circular reference problems + /// and infinite loops.

+ ///

Advisors or advices requiring ordering should implement the Ordered interface. + /// This class sorts advisors by Ordered order value. Advisors that don't implement + /// the Ordered interface will be considered to be unordered, and will appear + /// at the end of the advisor chain in undefined order.

+ ///
+ /// + /// Rod Johnson + /// Adhari C Mahendra (.NET) + public abstract class AbstractAdvisorAutoProxyCreator : AbstractAutoProxyCreator + { + /// + /// We override this method to ensure that all candidate advisors are materialized + /// under a stack trace including this object. Otherwise, the dependencies won't + /// be apparent to the circular-reference prevention strategy in AbstractObjectFactory. + /// + public override IObjectFactory ObjectFactory + { + //TODO investigate override... + set + { + base.ObjectFactory = value; + if (!(value is IConfigurableListableObjectFactory)) + { + throw new InvalidOperationException( + "Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory"); + } + } + get { return base.ObjectFactory; } + } + + /// + /// Return whether the given object is to be proxied, what additional + /// advices (e.g. AOP Alliance interceptors) and advisors to apply. + /// + /// the new object instance + /// the name of the object + /// targetSource returned by TargetSource property: + /// may be ignored. Will be null unless a custom target source is in use. + /// + /// an array of additional interceptors for the particular object; + /// or an empty array if no additional interceptors but just the common ones; + /// or null if no proxy at all, not even with the common interceptors. + /// + /// + ///

The previous name of this method was "GetInterceptorAndAdvisorForObject". + /// It has been renamed in the course of general terminology clarification + /// in Spring 1.1. An AOP Alliance Interceptor is just a special form of + /// Advice, so the generic Advice term is preferred now.

+ ///

The third parameter, customTargetSource, is new in Spring 1.1; + /// add it to existing implementations of this method.

+ ///
+ protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource) + { + IList advisors = FindEligibleAdvisors(objType); + if (advisors.Count == 0) + { + return DO_NOT_PROXY; + } + advisors = SortAdvisors(advisors); + if (advisors is ArrayList) + return ((ArrayList) advisors).ToArray(); + else + { + return advisors as object[]; + } + } + + /// + /// Find all eligible advices and for autoproxying this class. + /// + /// + /// the empty list, not null, if there are no pointcuts or interceptors + protected IList FindEligibleAdvisors(Type type) + { + IList candidateAdvisors = FindCandidateAdvisors(); + IList eligibleAdvisors = new ArrayList(); + for (int i = 0; i < candidateAdvisors.Count; i++) + { + IAdvisor candidate = (IAdvisor) candidateAdvisors[i]; + if (AopUtils.CanApply(candidate, type, null)) + { + eligibleAdvisors.Add(candidate); + if (logger.IsInfoEnabled) + { + logger.Info(string.Format("Candidate advisor [{0}] accepted for type [{1}]", candidate, type.ToString())); + } + } + else + { + if (logger.IsInfoEnabled) + { + logger.Info(string.Format("Candidate advisor [{0}] rejected for type [{1}]", candidate, type.ToString())); + } + } + } + return eligibleAdvisors; + } + + + /// + /// Sorts the advisors. + /// + /// The advisors. + /// + protected IList SortAdvisors(IList advisors) + { + if (advisors is ArrayList) + ((ArrayList) advisors).Sort(new OrderComparator()); + else if (advisors is Array) + Array.Sort((Array) advisors, new OrderComparator()); + return advisors; + } + + /// + /// Find all candidate advisors to use in auto-proxying. + /// + /// list of Advisors + protected abstract IList FindCandidateAdvisors(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs index 1334a10b..2751b8d1 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/AbstractAutoProxyCreator.cs @@ -1,647 +1,646 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.Remoting; -using AopAlliance.Aop; -using Common.Logging; -using Spring.Aop.Framework.Adapter; -using Spring.Aop.Target; -using Spring.Collections; -using Spring.Core; -using Spring.Objects; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.AutoProxy -{ - /// - /// ObjectPostProcessor implementation that wraps a group of objects with AOP proxies - /// that delegate to the given interceptors before invoking the object itself. - /// - /// - ///

This class distinguishes between "common" interceptors: shared for all proxies it - /// creates, and "specific" interceptors: unique per object instance. There need not - /// be any common interceptors. If there are, they are set using the interceptorNames - /// property. As with ProxyFactoryObject, interceptors names in the current factory - /// are used rather than object references to allow correct handling of prototype - /// advisors and interceptors: for example, to support stateful mixins. - /// Any advice type is supported for "interceptorNames" entries.

- ///

Such autoproxying is particularly useful if there's a large number of objects that need - /// to be wrapped with similar proxies, i.e. delegating to the same interceptors. - /// Instead of x repetitive proxy definitions for x target objects, you can register - /// one single such post processor with the object factory to achieve the same effect.

- ///

Subclasses can apply any strategy to decide if a object is to be proxied, - /// e.g. by type, by name, by definition details, etc. They can also return - /// additional interceptors that should just be applied to the specific object - /// instance. The default concrete implementation is ObjectNameAutoProxyCreator, - /// identifying the objects to be proxied via a list of object names.

- ///

Any number of TargetSourceCreator implementations can be used with any subclass, - /// to create a custom target source - for example, to pool prototype objects. - /// Autoproxying will occur even if there is no advice if a TargetSourceCreator specifies - /// a custom TargetSource. If there are no TargetSourceCreators set, or if none matches, - /// a SingletonTargetSource will be used by default to wrap the object to be autoproxied.

- ///
- /// Juergen Hoeller - /// Rod Johnson - /// Adhari C Mahendra (.NET) - /// - /// - /// $Id: AbstractAutoProxyCreator.cs,v 1.15 2008/03/03 09:28:49 bbaia Exp $ - public abstract class AbstractAutoProxyCreator : ProxyConfig, IInstantiationAwareObjectPostProcessor, IObjectFactoryAware, IOrdered - { - #region Protected Fields - - /// - /// The logger for this class hierarchy. - /// - protected readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Convenience constant for subclasses: Return value for "do not proxy". - /// - protected static readonly object[] DO_NOT_PROXY = null; - - /// - /// Convenience constant for subclasses: Return value for - /// "proxy without additional interceptors, just the common ones". - /// - protected static readonly object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new object[0]; - - #endregion - - #region Private Fields - - /// - /// Default value is same as non-ordered - /// - private int order = int.MaxValue; - - /// - /// Default is global AdvisorAdapterRegistry - /// - private IAdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance; - - - /// - /// - /// - private bool freezeProxy = false; - - /// - /// Names of common interceptors. - /// We must use object name rather than object references - /// to handle prototype advisors/interceptors. - /// Default is the empty array: no common interceptors. - /// - private string[] interceptorNames = new string[0]; - - private bool applyCommonInterceptorsFirst = true; - private IList customTargetSourceCreators = new ArrayList(); - private IObjectFactory owningObjectFactory; - - /// - /// Set of object type + name strings, referring to all objects that this auto-proxy - /// creator created a custom TargetSource for. Used to detect own pre-built proxies - /// (from "PostProcessBeforeInstantiation") in the "PostProcessAfterInitialization" method. - /// - private ISet targetSourcedObjects = new SynchronizedSet(new HashedSet()); - - private ISet advisedObjects = new SynchronizedSet(new HashedSet()); - - private ISet nonAdvisedObjects = new SynchronizedSet(new HashedSet()); - - #endregion - - #region Properties - - /// - /// Sets the AdvisorAdapterRegistry to use. - /// - /// - /// Default is the global AdvisorAdapterRegistry. - /// - public IAdvisorAdapterRegistry AdvisorAdapterRegistry - { - set { advisorAdapterRegistry = value; } - } - - /// - /// Sets custom TargetSourceCreators to be applied in this order. - /// - /// - /// - /// If the list is empty, or they all return null, a SingletonTargetSource - /// will be created. - /// - /// - /// TargetSourceCreators can only be invoked if this post processor is used - /// in a IObjectFactory, and its ObjectFactoryAware callback is used. - /// - /// - public IList CustomTargetSourceCreators - { - set { customTargetSourceCreators = value; } - } - - /// - /// Sets the common interceptors, a list of , - /// and introduction object names. - /// - /// - /// - /// If this property isn't set, there will be zero common interceptors. - /// This is perfectly valid, if "specific" interceptors such as - /// matching Advisors are all we want. - /// - /// - /// - /// The list of , - /// and introduction object names. - /// - /// - /// - public string[] InterceptorNames - { - set { interceptorNames = value; } - } - - /// - /// Sets whether the common interceptors should be applied before - /// object-specific ones. - /// - /// - /// Default is true; else, object-specific interceptors will get applied first. - /// - public bool ApplyCommonInterceptorsFirst - { - set { applyCommonInterceptorsFirst = value; } - } - - /// - /// Set whether or not the proxy should be frozen, preventing advice - /// from being added to it once it is created. - /// - /// - ///

Overridden from the super class to prevent the proxy configuration - /// from being frozen before the proxy is created. The default is not frozen. - ///

- ///
- public override bool IsFrozen - { - get { return freezeProxy; } - set { this.freezeProxy = value; } - } - - #endregion - - #region IObjectPostProcessor Members - - /// - /// Create a proxy with the configured interceptors if the object is - /// identified as one to proxy by the subclass. - /// - public virtual object PostProcessAfterInitialization(object obj, string objectName) - { - if (targetSourcedObjects.Contains(objectName)) - { - return obj; - } - - object cacheKey = GetCacheKey(obj.GetType(), objectName); - if (nonAdvisedObjects.Contains(cacheKey)) - { - return obj; - } - if (IsInfrastructureType(obj.GetType(), objectName) || ShouldSkip(obj.GetType(), objectName)) - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format("Did not attempt to autoproxy infrastructure type [{0}]", obj.GetType().ToString())); - } - - #endregion - - nonAdvisedObjects.Add(cacheKey); - return obj; - } - - //ITargetSource targetSource = GetCustomTargetSource(obj.GetType(), objectName); - object[] specificInterceptors; - if (RemotingServices.IsTransparentProxy(obj)) - { - specificInterceptors = GetAdvicesAndAdvisorsForObject(ObjectFactory.GetType(objectName), objectName, null); - } - else - { - specificInterceptors = GetAdvicesAndAdvisorsForObject(obj.GetType(), objectName, null); - } - - - // proxy if we have advice or if a TargetSourceCreator wants to do some - // fancy stuff such as pooling - if (specificInterceptors != DO_NOT_PROXY) - { - advisedObjects.Add(cacheKey); - return CreateProxy(obj.GetType(), objectName, specificInterceptors, new SingletonTargetSource(obj)); - } - nonAdvisedObjects.Add(cacheKey); - return obj; - } - - /// - /// No-op for before initialization. - /// - /// The obj. - /// The name. - /// - public virtual object PostProcessBeforeInitialization(object obj, string name) - { - return obj; - } - - #endregion - - #region IObjectFactoryAware Members - - /// - /// Callback that supplies the owning factory to an object instance. - /// - /// - /// Owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - /// - ///

- /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - ///

- ///
- /// - /// In case of initialization errors. - /// - public virtual IObjectFactory ObjectFactory - { - get { return owningObjectFactory; } - set { owningObjectFactory = value; } - } - - #endregion - - #region IOrdered Members - - /// - /// Propery Order - /// - /// - /// Ordering which will apply to this class's implementation - /// of Ordered, used when applying multiple ObjectPostProcessors. - /// Default value is int.MaxValue, meaning that it's non-ordered. - /// - public virtual int Order - { - get { return order; } - set { order = value; } - } - - #endregion - - #region Protected Methods - - /// - /// Subclasses should override this method to return true if this - /// object should not be considered for autoproxying by this post processor. - /// Sometimes we need to be able to avoid this happening if it will lead to - /// a circular reference. This implementation returns true. - /// - /// the type of the object - /// the name of the object - /// if remarkable to skip - protected virtual bool ShouldSkip(Type objectType, string objectName) - { - return false; - } - - /// - /// Subclasses may choose to implement this: for example, - /// to change the interfaces exposed - /// - /// - /// ProxyFactory that will be used to create the proxy immediably after this method returns. - /// - protected virtual void CustomizeProxyFactory(ProxyFactory pf) - { - // This implementation does nothing - } - - /// - /// Determines whether the object is an infrastructure type, - /// IAdvisor, IAdvice, IAdvisors or AbstractAutoProxyCreator - /// - /// The object type to compare - /// The name of the object - /// - /// true if [is infrastructure type] [the specified obj]; otherwise, false. - /// - protected virtual bool IsInfrastructureType(Type type, String name) - { - return typeof (IAdvisor).IsAssignableFrom(type) - || typeof (IAdvice).IsAssignableFrom(type) - || typeof (IAdvisors).IsAssignableFrom(type) - || typeof (AbstractAutoProxyCreator).IsAssignableFrom(type); - } - - - /// - /// Create a target source for object instances. Uses any - /// TargetSourceCreators if set. Returns null if no Custom TargetSource - /// should be used. - /// This implementation uses the customTargetSourceCreators property. - /// Subclasses can override this method to use a different mechanism. - /// - /// the type of the object to create a TargetSource for - /// the name of the object - /// a TargetSource for this object - protected virtual ITargetSource GetCustomTargetSource(Type objectType, string name) - { - // We can't create fancy target sources for directly registered singletons. - if (customTargetSourceCreators != null && - owningObjectFactory != null && owningObjectFactory.ContainsObject(name)) - { - for (int i = 0; i < customTargetSourceCreators.Count; i++) - { - ITargetSourceCreator tsc = (ITargetSourceCreator) customTargetSourceCreators[i]; - ITargetSource ts = tsc.GetTargetSource(objectType, name, owningObjectFactory); - if (ts != null) - { - // found a match - if (logger.IsInfoEnabled) - { - logger.Info(string.Format("TargetSourceCreator [{0} found custom TargetSource for object with objectName '{1}'", tsc, name)); - } - return ts; - } - } - } - - // no custom TargetSource found - return null; - } - - /// - /// Return whether the given object is to be proxied, what additional - /// advices (e.g. AOP Alliance interceptors) and advisors to apply. - /// - /// - ///

The previous name of this method was "GetInterceptorAndAdvisorForObject". - /// It has been renamed in the course of general terminology clarification - /// in Spring 1.1. An AOP Alliance Interceptor is just a special form of - /// Advice, so the generic Advice term is preferred now.

- ///

The third parameter, customTargetSource, is new in Spring 1.1; - /// add it to existing implementations of this method.

- ///
- /// the new object instance - /// the name of the object - /// targetSource returned by TargetSource property: - /// may be ignored. Will be null unless a custom target source is in use. - /// an array of additional interceptors for the particular object; - /// or an empty array if no additional interceptors but just the common ones; - /// or null if no proxy at all, not even with the common interceptors. - protected abstract object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource); - - /// - /// Create an AOP proxy for the given object. - /// - /// Type of the object. - /// The name of the object. - /// The set of interceptors that is specific to this - /// object (may be empty but not null) - /// The target source for the proxy, already pre-configured to access the object. - /// The AOP Proxy for the object. - protected virtual object CreateProxy(Type objectType, string objectName, object[] specificInterceptors, ITargetSource targetSource) - { - ProxyFactory proxyFactory = CreateProxyFactory(); - // copy our properties (proxyTargetClass) inherited from ProxyConfig - proxyFactory.CopyFrom(this); - - object target = targetSource.GetTarget(); - - - if(!ProxyTargetType) - { - // Must allow for introductions; can't just set interfaces to - // the target's interfaces only. - Type[] targetInterfaceTypes = AopUtils.GetAllInterfaces(target); - foreach (Type interfaceType in targetInterfaceTypes) - { - proxyFactory.AddInterface(interfaceType); - } - } - - - IAdvisor[] advisors = BuildAdvisors(objectName, specificInterceptors); - - foreach (IAdvisor advisor in advisors) - { - if (advisor is IIntroductionAdvisor) - { - proxyFactory.AddIntroduction((IIntroductionAdvisor)advisor); - } - else - { - proxyFactory.AddAdvisor(advisor); - } - } - proxyFactory.TargetSource = targetSource; - CustomizeProxyFactory(proxyFactory); - - proxyFactory.IsFrozen = freezeProxy; - return proxyFactory.GetProxy(); - } - - /// - /// Obtain a new proxy factory instance to be used for proxying a particular object - /// - /// A proxy factory instance for proxying a particular object - protected virtual ProxyFactory CreateProxyFactory() - { - return new ProxyFactory(); - } - - /// - /// Determines the advisors for the given object, including the specific interceptors - /// as well as the common interceptor, all adapted to the Advisor interface. - /// - /// The name of the object. - /// The set of interceptors that is specific to this - /// object (may be empty, but not null) - /// The list of Advisors for the given object - protected virtual IAdvisor[] BuildAdvisors(string objectName, object[] specificInterceptors) - { - // handle prototypes correctly - IAdvisor[] commonInterceptors = ResolveInterceptorNames(); - - ArrayList allInterceptors = new ArrayList(); - if (specificInterceptors != null) - { - allInterceptors.AddRange(specificInterceptors); - if (commonInterceptors != null) - { - if (applyCommonInterceptorsFirst) - { - allInterceptors.InsertRange(0, commonInterceptors); - } - else - { - allInterceptors.AddRange(commonInterceptors); - } - } - } - if (logger.IsInfoEnabled) - { - int nrOfCommonInterceptors = commonInterceptors != null ? commonInterceptors.Length : 0; - int nrOfSpecificInterceptors = specificInterceptors != null ? specificInterceptors.Length : 0; - logger.Info(string.Format("Creating implicit proxy for object '{0}' with {1} common interceptors and {2} specific interceptors", objectName, nrOfCommonInterceptors, nrOfSpecificInterceptors)); - } - - - IAdvisor[] advisors = new IAdvisor[allInterceptors.Count]; - for (int i = 0; i < allInterceptors.Count; i++) - { - advisors[i] = advisorAdapterRegistry.Wrap(allInterceptors[i]); - } - return advisors; - } - - /// - /// Build a cache key for the given object type and object name - /// - /// The object type. - /// The object name. - /// The cache key for the given type and name - protected virtual object GetCacheKey(Type objectType, string objectName) - { - return objectType.FullName + "_" + objectName; - } - - - #endregion - - #region Private Methods - - private IAdvisor[] ResolveInterceptorNames() - { - ArrayList advisors = new ArrayList(); - foreach(string name in interceptorNames) - { - object next = owningObjectFactory.GetObject(name); - if (next is IAdvisors) - { - advisors.AddRange(((IAdvisors)next).Advisors); - } - else - { - advisors.Add(advisorAdapterRegistry.Wrap(next)); - } - } - return (IAdvisor[])advisors.ToArray(typeof(IAdvisor)); - } - - #endregion - - #region IInstantiationAwareObjectPostProcessor Members - - /// - /// Create the proxy if have a custom TargetSource - /// - /// The object type - /// The object name - /// null if not creating a proxy, otherwise return the proxy. - public object PostProcessBeforeInstantiation(Type objectType, string objectName) - { - object cacheKey = GetCacheKey(objectType, objectName); - if (!targetSourcedObjects.Contains(cacheKey)) - { - if (advisedObjects.Contains(cacheKey) || nonAdvisedObjects.Contains(cacheKey)) - { - return null; - } - if (IsInfrastructureType(objectType, objectName) || ShouldSkip(objectType, objectName)) - { - nonAdvisedObjects.Add(cacheKey); - return null; - } - } - // Create proxy here if we have a custom TargetSource. - // Suppresses unnecessary default instantiation of the target object: - // The TargetSource will handle target instances in a custom fashion. - ITargetSource targetSource = GetCustomTargetSource(objectType, objectName); - if (targetSource != null) - { - targetSourcedObjects.Add(objectName); - object[] specificInterceptors = GetAdvicesAndAdvisorsForObject(objectType, objectName, targetSource); - return CreateProxy(objectType, objectName, specificInterceptors, targetSource); - } - return null; - } - - - /// - /// Default behavior, return true and continue processing. - /// - /// The object instance - /// The object name. - /// true - public bool PostProcessAfterInstantiation(object objectInstance, string objectName) - { - return true; - } - - /// - /// Default behavior, return passed in PropertyValues - /// - /// The property values that the factory is about to apply (never null). - /// he relevant property infos for the target object (with ignored - /// dependency types - which the factory handles specifically - already filtered out) - /// The object instance created, but whose properties have not yet - /// been set. - /// Name of the object. - /// The passed in PropertyValues - public IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, - string objectName) - { - return pvs; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.Remoting; +using AopAlliance.Aop; +using Common.Logging; +using Spring.Aop.Framework.Adapter; +using Spring.Aop.Target; +using Spring.Collections; +using Spring.Core; +using Spring.Objects; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// ObjectPostProcessor implementation that wraps a group of objects with AOP proxies + /// that delegate to the given interceptors before invoking the object itself. + /// + /// + ///

This class distinguishes between "common" interceptors: shared for all proxies it + /// creates, and "specific" interceptors: unique per object instance. There need not + /// be any common interceptors. If there are, they are set using the interceptorNames + /// property. As with ProxyFactoryObject, interceptors names in the current factory + /// are used rather than object references to allow correct handling of prototype + /// advisors and interceptors: for example, to support stateful mixins. + /// Any advice type is supported for "interceptorNames" entries.

+ ///

Such autoproxying is particularly useful if there's a large number of objects that need + /// to be wrapped with similar proxies, i.e. delegating to the same interceptors. + /// Instead of x repetitive proxy definitions for x target objects, you can register + /// one single such post processor with the object factory to achieve the same effect.

+ ///

Subclasses can apply any strategy to decide if a object is to be proxied, + /// e.g. by type, by name, by definition details, etc. They can also return + /// additional interceptors that should just be applied to the specific object + /// instance. The default concrete implementation is ObjectNameAutoProxyCreator, + /// identifying the objects to be proxied via a list of object names.

+ ///

Any number of TargetSourceCreator implementations can be used with any subclass, + /// to create a custom target source - for example, to pool prototype objects. + /// Autoproxying will occur even if there is no advice if a TargetSourceCreator specifies + /// a custom TargetSource. If there are no TargetSourceCreators set, or if none matches, + /// a SingletonTargetSource will be used by default to wrap the object to be autoproxied.

+ ///
+ /// Juergen Hoeller + /// Rod Johnson + /// Adhari C Mahendra (.NET) + /// + /// + public abstract class AbstractAutoProxyCreator : ProxyConfig, IInstantiationAwareObjectPostProcessor, IObjectFactoryAware, IOrdered + { + #region Protected Fields + + /// + /// The logger for this class hierarchy. + /// + protected readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Convenience constant for subclasses: Return value for "do not proxy". + /// + protected static readonly object[] DO_NOT_PROXY = null; + + /// + /// Convenience constant for subclasses: Return value for + /// "proxy without additional interceptors, just the common ones". + /// + protected static readonly object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new object[0]; + + #endregion + + #region Private Fields + + /// + /// Default value is same as non-ordered + /// + private int order = int.MaxValue; + + /// + /// Default is global AdvisorAdapterRegistry + /// + private IAdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance; + + + /// + /// + /// + private bool freezeProxy = false; + + /// + /// Names of common interceptors. + /// We must use object name rather than object references + /// to handle prototype advisors/interceptors. + /// Default is the empty array: no common interceptors. + /// + private string[] interceptorNames = new string[0]; + + private bool applyCommonInterceptorsFirst = true; + private IList customTargetSourceCreators = new ArrayList(); + private IObjectFactory owningObjectFactory; + + /// + /// Set of object type + name strings, referring to all objects that this auto-proxy + /// creator created a custom TargetSource for. Used to detect own pre-built proxies + /// (from "PostProcessBeforeInstantiation") in the "PostProcessAfterInitialization" method. + /// + private ISet targetSourcedObjects = new SynchronizedSet(new HashedSet()); + + private ISet advisedObjects = new SynchronizedSet(new HashedSet()); + + private ISet nonAdvisedObjects = new SynchronizedSet(new HashedSet()); + + #endregion + + #region Properties + + /// + /// Sets the AdvisorAdapterRegistry to use. + /// + /// + /// Default is the global AdvisorAdapterRegistry. + /// + public IAdvisorAdapterRegistry AdvisorAdapterRegistry + { + set { advisorAdapterRegistry = value; } + } + + /// + /// Sets custom TargetSourceCreators to be applied in this order. + /// + /// + /// + /// If the list is empty, or they all return null, a SingletonTargetSource + /// will be created. + /// + /// + /// TargetSourceCreators can only be invoked if this post processor is used + /// in a IObjectFactory, and its ObjectFactoryAware callback is used. + /// + /// + public IList CustomTargetSourceCreators + { + set { customTargetSourceCreators = value; } + } + + /// + /// Sets the common interceptors, a list of , + /// and introduction object names. + /// + /// + /// + /// If this property isn't set, there will be zero common interceptors. + /// This is perfectly valid, if "specific" interceptors such as + /// matching Advisors are all we want. + /// + /// + /// + /// The list of , + /// and introduction object names. + /// + /// + /// + public string[] InterceptorNames + { + set { interceptorNames = value; } + } + + /// + /// Sets whether the common interceptors should be applied before + /// object-specific ones. + /// + /// + /// Default is true; else, object-specific interceptors will get applied first. + /// + public bool ApplyCommonInterceptorsFirst + { + set { applyCommonInterceptorsFirst = value; } + } + + /// + /// Set whether or not the proxy should be frozen, preventing advice + /// from being added to it once it is created. + /// + /// + ///

Overridden from the super class to prevent the proxy configuration + /// from being frozen before the proxy is created. The default is not frozen. + ///

+ ///
+ public override bool IsFrozen + { + get { return freezeProxy; } + set { this.freezeProxy = value; } + } + + #endregion + + #region IObjectPostProcessor Members + + /// + /// Create a proxy with the configured interceptors if the object is + /// identified as one to proxy by the subclass. + /// + public virtual object PostProcessAfterInitialization(object obj, string objectName) + { + if (targetSourcedObjects.Contains(objectName)) + { + return obj; + } + + object cacheKey = GetCacheKey(obj.GetType(), objectName); + if (nonAdvisedObjects.Contains(cacheKey)) + { + return obj; + } + if (IsInfrastructureType(obj.GetType(), objectName) || ShouldSkip(obj.GetType(), objectName)) + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format("Did not attempt to autoproxy infrastructure type [{0}]", obj.GetType().ToString())); + } + + #endregion + + nonAdvisedObjects.Add(cacheKey); + return obj; + } + + //ITargetSource targetSource = GetCustomTargetSource(obj.GetType(), objectName); + object[] specificInterceptors; + if (RemotingServices.IsTransparentProxy(obj)) + { + specificInterceptors = GetAdvicesAndAdvisorsForObject(ObjectFactory.GetType(objectName), objectName, null); + } + else + { + specificInterceptors = GetAdvicesAndAdvisorsForObject(obj.GetType(), objectName, null); + } + + + // proxy if we have advice or if a TargetSourceCreator wants to do some + // fancy stuff such as pooling + if (specificInterceptors != DO_NOT_PROXY) + { + advisedObjects.Add(cacheKey); + return CreateProxy(obj.GetType(), objectName, specificInterceptors, new SingletonTargetSource(obj)); + } + nonAdvisedObjects.Add(cacheKey); + return obj; + } + + /// + /// No-op for before initialization. + /// + /// The obj. + /// The name. + /// + public virtual object PostProcessBeforeInitialization(object obj, string name) + { + return obj; + } + + #endregion + + #region IObjectFactoryAware Members + + /// + /// Callback that supplies the owning factory to an object instance. + /// + /// + /// Owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + /// + ///

+ /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + ///

+ ///
+ /// + /// In case of initialization errors. + /// + public virtual IObjectFactory ObjectFactory + { + get { return owningObjectFactory; } + set { owningObjectFactory = value; } + } + + #endregion + + #region IOrdered Members + + /// + /// Propery Order + /// + /// + /// Ordering which will apply to this class's implementation + /// of Ordered, used when applying multiple ObjectPostProcessors. + /// Default value is int.MaxValue, meaning that it's non-ordered. + /// + public virtual int Order + { + get { return order; } + set { order = value; } + } + + #endregion + + #region Protected Methods + + /// + /// Subclasses should override this method to return true if this + /// object should not be considered for autoproxying by this post processor. + /// Sometimes we need to be able to avoid this happening if it will lead to + /// a circular reference. This implementation returns true. + /// + /// the type of the object + /// the name of the object + /// if remarkable to skip + protected virtual bool ShouldSkip(Type objectType, string objectName) + { + return false; + } + + /// + /// Subclasses may choose to implement this: for example, + /// to change the interfaces exposed + /// + /// + /// ProxyFactory that will be used to create the proxy immediably after this method returns. + /// + protected virtual void CustomizeProxyFactory(ProxyFactory pf) + { + // This implementation does nothing + } + + /// + /// Determines whether the object is an infrastructure type, + /// IAdvisor, IAdvice, IAdvisors or AbstractAutoProxyCreator + /// + /// The object type to compare + /// The name of the object + /// + /// true if [is infrastructure type] [the specified obj]; otherwise, false. + /// + protected virtual bool IsInfrastructureType(Type type, String name) + { + return typeof (IAdvisor).IsAssignableFrom(type) + || typeof (IAdvice).IsAssignableFrom(type) + || typeof (IAdvisors).IsAssignableFrom(type) + || typeof (AbstractAutoProxyCreator).IsAssignableFrom(type); + } + + + /// + /// Create a target source for object instances. Uses any + /// TargetSourceCreators if set. Returns null if no Custom TargetSource + /// should be used. + /// This implementation uses the customTargetSourceCreators property. + /// Subclasses can override this method to use a different mechanism. + /// + /// the type of the object to create a TargetSource for + /// the name of the object + /// a TargetSource for this object + protected virtual ITargetSource GetCustomTargetSource(Type objectType, string name) + { + // We can't create fancy target sources for directly registered singletons. + if (customTargetSourceCreators != null && + owningObjectFactory != null && owningObjectFactory.ContainsObject(name)) + { + for (int i = 0; i < customTargetSourceCreators.Count; i++) + { + ITargetSourceCreator tsc = (ITargetSourceCreator) customTargetSourceCreators[i]; + ITargetSource ts = tsc.GetTargetSource(objectType, name, owningObjectFactory); + if (ts != null) + { + // found a match + if (logger.IsInfoEnabled) + { + logger.Info(string.Format("TargetSourceCreator [{0} found custom TargetSource for object with objectName '{1}'", tsc, name)); + } + return ts; + } + } + } + + // no custom TargetSource found + return null; + } + + /// + /// Return whether the given object is to be proxied, what additional + /// advices (e.g. AOP Alliance interceptors) and advisors to apply. + /// + /// + ///

The previous name of this method was "GetInterceptorAndAdvisorForObject". + /// It has been renamed in the course of general terminology clarification + /// in Spring 1.1. An AOP Alliance Interceptor is just a special form of + /// Advice, so the generic Advice term is preferred now.

+ ///

The third parameter, customTargetSource, is new in Spring 1.1; + /// add it to existing implementations of this method.

+ ///
+ /// the new object instance + /// the name of the object + /// targetSource returned by TargetSource property: + /// may be ignored. Will be null unless a custom target source is in use. + /// an array of additional interceptors for the particular object; + /// or an empty array if no additional interceptors but just the common ones; + /// or null if no proxy at all, not even with the common interceptors. + protected abstract object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource); + + /// + /// Create an AOP proxy for the given object. + /// + /// Type of the object. + /// The name of the object. + /// The set of interceptors that is specific to this + /// object (may be empty but not null) + /// The target source for the proxy, already pre-configured to access the object. + /// The AOP Proxy for the object. + protected virtual object CreateProxy(Type objectType, string objectName, object[] specificInterceptors, ITargetSource targetSource) + { + ProxyFactory proxyFactory = CreateProxyFactory(); + // copy our properties (proxyTargetClass) inherited from ProxyConfig + proxyFactory.CopyFrom(this); + + object target = targetSource.GetTarget(); + + + if(!ProxyTargetType) + { + // Must allow for introductions; can't just set interfaces to + // the target's interfaces only. + Type[] targetInterfaceTypes = AopUtils.GetAllInterfaces(target); + foreach (Type interfaceType in targetInterfaceTypes) + { + proxyFactory.AddInterface(interfaceType); + } + } + + + IAdvisor[] advisors = BuildAdvisors(objectName, specificInterceptors); + + foreach (IAdvisor advisor in advisors) + { + if (advisor is IIntroductionAdvisor) + { + proxyFactory.AddIntroduction((IIntroductionAdvisor)advisor); + } + else + { + proxyFactory.AddAdvisor(advisor); + } + } + proxyFactory.TargetSource = targetSource; + CustomizeProxyFactory(proxyFactory); + + proxyFactory.IsFrozen = freezeProxy; + return proxyFactory.GetProxy(); + } + + /// + /// Obtain a new proxy factory instance to be used for proxying a particular object + /// + /// A proxy factory instance for proxying a particular object + protected virtual ProxyFactory CreateProxyFactory() + { + return new ProxyFactory(); + } + + /// + /// Determines the advisors for the given object, including the specific interceptors + /// as well as the common interceptor, all adapted to the Advisor interface. + /// + /// The name of the object. + /// The set of interceptors that is specific to this + /// object (may be empty, but not null) + /// The list of Advisors for the given object + protected virtual IAdvisor[] BuildAdvisors(string objectName, object[] specificInterceptors) + { + // handle prototypes correctly + IAdvisor[] commonInterceptors = ResolveInterceptorNames(); + + ArrayList allInterceptors = new ArrayList(); + if (specificInterceptors != null) + { + allInterceptors.AddRange(specificInterceptors); + if (commonInterceptors != null) + { + if (applyCommonInterceptorsFirst) + { + allInterceptors.InsertRange(0, commonInterceptors); + } + else + { + allInterceptors.AddRange(commonInterceptors); + } + } + } + if (logger.IsInfoEnabled) + { + int nrOfCommonInterceptors = commonInterceptors != null ? commonInterceptors.Length : 0; + int nrOfSpecificInterceptors = specificInterceptors != null ? specificInterceptors.Length : 0; + logger.Info(string.Format("Creating implicit proxy for object '{0}' with {1} common interceptors and {2} specific interceptors", objectName, nrOfCommonInterceptors, nrOfSpecificInterceptors)); + } + + + IAdvisor[] advisors = new IAdvisor[allInterceptors.Count]; + for (int i = 0; i < allInterceptors.Count; i++) + { + advisors[i] = advisorAdapterRegistry.Wrap(allInterceptors[i]); + } + return advisors; + } + + /// + /// Build a cache key for the given object type and object name + /// + /// The object type. + /// The object name. + /// The cache key for the given type and name + protected virtual object GetCacheKey(Type objectType, string objectName) + { + return objectType.FullName + "_" + objectName; + } + + + #endregion + + #region Private Methods + + private IAdvisor[] ResolveInterceptorNames() + { + ArrayList advisors = new ArrayList(); + foreach(string name in interceptorNames) + { + object next = owningObjectFactory.GetObject(name); + if (next is IAdvisors) + { + advisors.AddRange(((IAdvisors)next).Advisors); + } + else + { + advisors.Add(advisorAdapterRegistry.Wrap(next)); + } + } + return (IAdvisor[])advisors.ToArray(typeof(IAdvisor)); + } + + #endregion + + #region IInstantiationAwareObjectPostProcessor Members + + /// + /// Create the proxy if have a custom TargetSource + /// + /// The object type + /// The object name + /// null if not creating a proxy, otherwise return the proxy. + public object PostProcessBeforeInstantiation(Type objectType, string objectName) + { + object cacheKey = GetCacheKey(objectType, objectName); + if (!targetSourcedObjects.Contains(cacheKey)) + { + if (advisedObjects.Contains(cacheKey) || nonAdvisedObjects.Contains(cacheKey)) + { + return null; + } + if (IsInfrastructureType(objectType, objectName) || ShouldSkip(objectType, objectName)) + { + nonAdvisedObjects.Add(cacheKey); + return null; + } + } + // Create proxy here if we have a custom TargetSource. + // Suppresses unnecessary default instantiation of the target object: + // The TargetSource will handle target instances in a custom fashion. + ITargetSource targetSource = GetCustomTargetSource(objectType, objectName); + if (targetSource != null) + { + targetSourcedObjects.Add(objectName); + object[] specificInterceptors = GetAdvicesAndAdvisorsForObject(objectType, objectName, targetSource); + return CreateProxy(objectType, objectName, specificInterceptors, targetSource); + } + return null; + } + + + /// + /// Default behavior, return true and continue processing. + /// + /// The object instance + /// The object name. + /// true + public bool PostProcessAfterInstantiation(object objectInstance, string objectName) + { + return true; + } + + /// + /// Default behavior, return passed in PropertyValues + /// + /// The property values that the factory is about to apply (never null). + /// he relevant property infos for the target object (with ignored + /// dependency types - which the factory handles specifically - already filtered out) + /// The object instance created, but whose properties have not yet + /// been set. + /// Name of the object. + /// The passed in PropertyValues + public IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, + string objectName) + { + return pvs; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs index dfc44061..960a6d1d 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs @@ -1,198 +1,197 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Aop.Framework.AutoProxy -{ - /// - /// ObjectPostProcessor implementation that creates AOP proxies based on all candidate - /// Advisors in the current IObjectFactory. This class is completely generic; it contains - /// no special code to handle any particular aspects, such as pooling aspects. - /// - /// Rod Johnson - /// Adhari C Mahendra (.NET) - /// $Id: DefaultAdvisorAutoProxyCreator.cs,v 1.9 2007/10/08 22:04:51 markpollack Exp $ - public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware, IInitializingObject - { - - /// - /// Separator between prefix and remainder of object name - /// - public static readonly string SEPARATOR = "."; - private bool usePrefix; - private string advisorObjectNamePrefix; - private IList advisors; - - #region Properties - - /// - /// Gets or sets a value indicating whether to exclude - /// advisors with a certain prefix. - /// - /// true if [use prefix]; otherwise, false. - public bool UsePrefix - { - get { return usePrefix; } - set { usePrefix = value; } - } - - /// - /// Set the prefix for object names that will cause them to be included for - /// auto-proxying by this object. This prefix should be set to avoid circular - /// references. Default value is the object name of this object + a dot. - /// - /// The advisor object name prefix. - public string AdvisorObjectNamePrefix - { - get { return advisorObjectNamePrefix; } - set { advisorObjectNamePrefix = value; } - } - - #endregion - /// - /// Find all candidate advices to use in auto proxying. - /// - /// list of Advice - protected override IList FindCandidateAdvisors() - { - if (advisors == null) - { - throw new InvalidOperationException("Must not be called before AfterPropertiesSet()"); - } - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format("returning available advisors")); - } - return advisors; - } - - private IList InstantiateCandidateAdvisors() - { - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format("instantiating available advisors")); - } - - //This is ensured in AbstractAdvisorAutoProxyCreator. Will be more type safe once sync with Spring Java 2.x - IConfigurableListableObjectFactory owningFactory = ObjectFactory as IConfigurableListableObjectFactory; - if (owningFactory == null) - { - throw new InvalidOperationException("Cannot use DefaultAdvisorAutoProxyCreator without a IListableObjectFactory"); - } - - ArrayList candidateAdvisors = new ArrayList(); - - string[] advisorNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( - owningFactory, typeof(IAdvisor), true, false); - for (int i = 0; i < advisorNames.Length; i++) - { - string name = advisorNames[i]; - if ( (!usePrefix || name.StartsWith(advisorObjectNamePrefix)) && !owningFactory.IsCurrentlyInCreation(name)) - { - try - { - IAdvisor advisor = (IAdvisor) owningFactory.GetObject(name); - candidateAdvisors.Add(advisor); - } catch (ObjectCreationException ex) - { - Exception rootEx = ex.GetBaseException(); - - - if (rootEx is ObjectCurrentlyInCreationException) - { - ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException) rootEx; - if (owningFactory.IsCurrentlyInCreation(oce.ObjectName)) - { - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format("Ignoring currently created advisor '{0}': exception message = {1}", - name, ex.Message)); - } - continue; - } - } - throw; - } - } - } - - string[] aspectNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( - owningFactory, typeof(IAdvisors), true, false); - for (int i = 0; i < aspectNames.Length; i++) - { - string name = aspectNames[i]; - if (!usePrefix || name.StartsWith(advisorObjectNamePrefix)) - { - IAdvisors advisors = (IAdvisors)owningFactory.GetObject(name); - candidateAdvisors.AddRange(advisors.Advisors); - } - } - - return candidateAdvisors; - } - - - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - public void AfterPropertiesSet() - { - advisors = InstantiateCandidateAdvisors(); - } - - #region IObjectNameAware Members - - /// - /// Set the name of the object in the object factory that created this object. - /// - /// The name of the object in the factory. - /// - ///

- /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - ///

- ///
- public string ObjectName - { - set - { - // If no infrastructure object name prefix has been set, override it. - if (advisorObjectNamePrefix == null) - { - advisorObjectNamePrefix = value + SEPARATOR; - } - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// ObjectPostProcessor implementation that creates AOP proxies based on all candidate + /// Advisors in the current IObjectFactory. This class is completely generic; it contains + /// no special code to handle any particular aspects, such as pooling aspects. + /// + /// Rod Johnson + /// Adhari C Mahendra (.NET) + public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware, IInitializingObject + { + + /// + /// Separator between prefix and remainder of object name + /// + public static readonly string SEPARATOR = "."; + private bool usePrefix; + private string advisorObjectNamePrefix; + private IList advisors; + + #region Properties + + /// + /// Gets or sets a value indicating whether to exclude + /// advisors with a certain prefix. + /// + /// true if [use prefix]; otherwise, false. + public bool UsePrefix + { + get { return usePrefix; } + set { usePrefix = value; } + } + + /// + /// Set the prefix for object names that will cause them to be included for + /// auto-proxying by this object. This prefix should be set to avoid circular + /// references. Default value is the object name of this object + a dot. + /// + /// The advisor object name prefix. + public string AdvisorObjectNamePrefix + { + get { return advisorObjectNamePrefix; } + set { advisorObjectNamePrefix = value; } + } + + #endregion + /// + /// Find all candidate advices to use in auto proxying. + /// + /// list of Advice + protected override IList FindCandidateAdvisors() + { + if (advisors == null) + { + throw new InvalidOperationException("Must not be called before AfterPropertiesSet()"); + } + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format("returning available advisors")); + } + return advisors; + } + + private IList InstantiateCandidateAdvisors() + { + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format("instantiating available advisors")); + } + + //This is ensured in AbstractAdvisorAutoProxyCreator. Will be more type safe once sync with Spring Java 2.x + IConfigurableListableObjectFactory owningFactory = ObjectFactory as IConfigurableListableObjectFactory; + if (owningFactory == null) + { + throw new InvalidOperationException("Cannot use DefaultAdvisorAutoProxyCreator without a IListableObjectFactory"); + } + + ArrayList candidateAdvisors = new ArrayList(); + + string[] advisorNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( + owningFactory, typeof(IAdvisor), true, false); + for (int i = 0; i < advisorNames.Length; i++) + { + string name = advisorNames[i]; + if ( (!usePrefix || name.StartsWith(advisorObjectNamePrefix)) && !owningFactory.IsCurrentlyInCreation(name)) + { + try + { + IAdvisor advisor = (IAdvisor) owningFactory.GetObject(name); + candidateAdvisors.Add(advisor); + } catch (ObjectCreationException ex) + { + Exception rootEx = ex.GetBaseException(); + + + if (rootEx is ObjectCurrentlyInCreationException) + { + ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException) rootEx; + if (owningFactory.IsCurrentlyInCreation(oce.ObjectName)) + { + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format("Ignoring currently created advisor '{0}': exception message = {1}", + name, ex.Message)); + } + continue; + } + } + throw; + } + } + } + + string[] aspectNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( + owningFactory, typeof(IAdvisors), true, false); + for (int i = 0; i < aspectNames.Length; i++) + { + string name = aspectNames[i]; + if (!usePrefix || name.StartsWith(advisorObjectNamePrefix)) + { + IAdvisors advisors = (IAdvisors)owningFactory.GetObject(name); + candidateAdvisors.AddRange(advisors.Advisors); + } + } + + return candidateAdvisors; + } + + + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + public void AfterPropertiesSet() + { + advisors = InstantiateCandidateAdvisors(); + } + + #region IObjectNameAware Members + + /// + /// Set the name of the object in the object factory that created this object. + /// + /// The name of the object in the factory. + /// + ///

+ /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + ///

+ ///
+ public string ObjectName + { + set + { + // If no infrastructure object name prefix has been set, override it. + if (advisorObjectNamePrefix == null) + { + advisorObjectNamePrefix = value + SEPARATOR; + } + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ITargetSourceCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ITargetSourceCreator.cs index dffa583a..c20c7c8b 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ITargetSourceCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ITargetSourceCreator.cs @@ -1,53 +1,52 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Aop.Framework.AutoProxy -{ - /// - /// Implementations can create special target sources, such as pooling target - /// sources, for particular objects. For example, they may base their choice - /// on attributes, such as a pooling attribute, on the target type. - /// - ///

AbstractAutoProxyCreator can support a number of TargetSourceCreators, - /// which will be applied in order.

- ///
- /// Rod Johnson - /// Adhari C Mahendra (.NET) - /// $Id: ITargetSourceCreator.cs,v 1.3 2007/08/22 08:49:08 markpollack Exp $ - public interface ITargetSourceCreator - { - /// - /// Create a special TargetSource for the given object, if any. - /// - /// The type of the object to create a TargetSource for - /// the name of the object - /// the containing factory - /// a special TargetSource or null if this TargetSourceCreator isn't - /// interested in the particular object - ITargetSource GetTargetSource(Type objectType, string objectName, IObjectFactory factory); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// Implementations can create special target sources, such as pooling target + /// sources, for particular objects. For example, they may base their choice + /// on attributes, such as a pooling attribute, on the target type. + /// + ///

AbstractAutoProxyCreator can support a number of TargetSourceCreators, + /// which will be applied in order.

+ ///
+ /// Rod Johnson + /// Adhari C Mahendra (.NET) + public interface ITargetSourceCreator + { + /// + /// Create a special TargetSource for the given object, if any. + /// + /// The type of the object to create a TargetSource for + /// the name of the object + /// the containing factory + /// a special TargetSource or null if this TargetSourceCreator isn't + /// interested in the particular object + ITargetSource GetTargetSource(Type objectType, string objectName, IObjectFactory factory); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs index 37f16e67..18e00496 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreator.cs @@ -1,112 +1,111 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Objects.Factory; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.AutoProxy -{ - /// - /// Object Auto Proxy Creator - /// - /// - /// - /// Auto proxy creator that identifies objects to proxy via a list of names. - /// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches. - /// - /// In case of a IFactoryObject, only the objects created by the - /// FactoryBean will get proxied. If you intend to proxy a IFactoryObject instance itself - /// specify the object name of the IFactoryObject including - /// the factory-object prefix "&" e.g. "&MyFactoryObject". - /// - /// - /// - /// Juergen Hoeller - /// Adhari C Mahendra (.NET) - /// $Id: ObjectNameAutoProxyCreator.cs,v 1.8 2008/03/03 09:28:49 bbaia Exp $ - public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator - { - private IList objectNames; - - /// - /// Set the names of the objects in IList fashioned way that should automatically - /// get wrapped with proxies. - /// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*" - /// will match the object named "myObject" and all objects whose name start with "tx". - /// - public IList ObjectNames - { - set { objectNames = value; } - } - - /// - /// Identify as object to proxy if the object name is in the configured list of names. - /// - protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource) - { - if (objectNames != null) - { - for (int i = 0; i < objectNames.Count; i++) - { - string mappedName = String.Copy((string) objectNames[i]); - if (typeof (IFactoryObject).IsAssignableFrom(objType)) - { - if (!name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix)) - { - continue; - } - mappedName = mappedName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length); - } - if (IsMatch(name, mappedName)) - { - return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS; - } - } - } - return DO_NOT_PROXY; - - } - - /// - /// Return if the given object name matches the mapped name. - /// - /// - ///

- /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, - /// as well as direct equality. Can be overridden in subclasses. - ///

- ///
- /// the object name to check - /// the name in the configured list of names - /// if the names match - protected virtual bool IsMatch(string objectName, string mappedName) - { - return PatternMatchUtils.SimpleMatch(mappedName, objectName); - } - - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Objects.Factory; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.AutoProxy +{ + /// + /// Object Auto Proxy Creator + /// + /// + /// + /// Auto proxy creator that identifies objects to proxy via a list of names. + /// Checks for direct, "xxx*", "*xxx" and "*xxx*" matches. + /// + /// In case of a IFactoryObject, only the objects created by the + /// FactoryBean will get proxied. If you intend to proxy a IFactoryObject instance itself + /// specify the object name of the IFactoryObject including + /// the factory-object prefix "&" e.g. "&MyFactoryObject". + /// + /// + /// + /// Juergen Hoeller + /// Adhari C Mahendra (.NET) + public class ObjectNameAutoProxyCreator : AbstractAutoProxyCreator + { + private IList objectNames; + + /// + /// Set the names of the objects in IList fashioned way that should automatically + /// get wrapped with proxies. + /// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*" + /// will match the object named "myObject" and all objects whose name start with "tx". + /// + public IList ObjectNames + { + set { objectNames = value; } + } + + /// + /// Identify as object to proxy if the object name is in the configured list of names. + /// + protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource) + { + if (objectNames != null) + { + for (int i = 0; i < objectNames.Count; i++) + { + string mappedName = String.Copy((string) objectNames[i]); + if (typeof (IFactoryObject).IsAssignableFrom(objType)) + { + if (!name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix)) + { + continue; + } + mappedName = mappedName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length); + } + if (IsMatch(name, mappedName)) + { + return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS; + } + } + } + return DO_NOT_PROXY; + + } + + /// + /// Return if the given object name matches the mapped name. + /// + /// + ///

+ /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, + /// as well as direct equality. Can be overridden in subclasses. + ///

+ ///
+ /// the object name to check + /// the name in the configured list of names + /// if the names match + protected virtual bool IsMatch(string objectName, string mappedName) + { + return PatternMatchUtils.SimpleMatch(mappedName, objectName); + } + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/Target/AbstractPrototypeTargetSourceCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/Target/AbstractPrototypeTargetSourceCreator.cs index 55af4478..51cf3618 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/Target/AbstractPrototypeTargetSourceCreator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/Target/AbstractPrototypeTargetSourceCreator.cs @@ -1,107 +1,107 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Common.Logging; -using Spring.Aop.Target; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Aop.Framework.AutoProxy.Target -{ - /// - /// Summary description for AbstractPrototypeBasedTargetSourceCreator. - /// - public abstract class AbstractPrototypeTargetSourceCreator : ITargetSourceCreator - { - /// - /// The logger - /// - protected readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #region ITargetSourceCreator Members - - /// - /// Create a special TargetSource for the given object, if any. - /// - /// the type of the object to create a TargetSource for - /// the name of the object - /// the containing factory - /// - /// a special TargetSource or null if this TargetSourceCreator isn't - /// interested in the particular object - /// - public ITargetSource GetTargetSource(Type objectType, string name, IObjectFactory factory) - { - AbstractPrototypeTargetSource prototypeTargetSource = CreatePrototypeTargetSource(objectType, name, factory); - if (prototypeTargetSource == null) - { - return null; - } - else - { - if (!(factory is IObjectDefinitionRegistry)) - { - if (logger.IsWarnEnabled) - logger.Warn("Cannot do autopooling with a IObjectFactory that doesn't implement IObjectDefinitionRegistry"); - return null; - } - IObjectDefinitionRegistry definitionRegistry = (IObjectDefinitionRegistry) factory; - RootObjectDefinition definition = (RootObjectDefinition) definitionRegistry.GetObjectDefinition(name); - - if (logger.IsInfoEnabled) - logger.Info("Configuring AbstractPrototypeBasedTargetSource..."); - - // Infinite cycle will result if we don't use a different factory, - // because a GetObject() call with this objectName will go through the autoproxy - // infrastructure again. - // We to override just this object definition, as it may reference other objects - // and we're happy to take the parent's definition for those. - DefaultListableObjectFactory objectFactory = new DefaultListableObjectFactory(factory); - - // Override the prototype object - objectFactory.RegisterObjectDefinition(name, definition); - - // Complete configuring the PrototypeTargetSource - prototypeTargetSource.TargetObjectName = name; - prototypeTargetSource.ObjectFactory = objectFactory; - - return prototypeTargetSource; - } - } - - #endregion - - /// - /// Creates the prototype target source. - /// - /// The type of the object to create a target source for. - /// The name. - /// The factory. - /// - protected abstract AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, - IObjectFactory factory); - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Common.Logging; +using Spring.Aop.Target; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Aop.Framework.AutoProxy.Target +{ + /// + /// Summary description for AbstractPrototypeBasedTargetSourceCreator. + /// + public abstract class AbstractPrototypeTargetSourceCreator : ITargetSourceCreator + { + /// + /// The logger + /// + protected readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + #region ITargetSourceCreator Members + + /// + /// Create a special TargetSource for the given object, if any. + /// + /// the type of the object to create a TargetSource for + /// the name of the object + /// the containing factory + /// + /// a special TargetSource or null if this TargetSourceCreator isn't + /// interested in the particular object + /// + public ITargetSource GetTargetSource(Type objectType, string name, IObjectFactory factory) + { + AbstractPrototypeTargetSource prototypeTargetSource = CreatePrototypeTargetSource(objectType, name, factory); + if (prototypeTargetSource == null) + { + return null; + } + else + { + if (!(factory is IObjectDefinitionRegistry)) + { + if (logger.IsWarnEnabled) + logger.Warn("Cannot do autopooling with a IObjectFactory that doesn't implement IObjectDefinitionRegistry"); + return null; + } + IObjectDefinitionRegistry definitionRegistry = (IObjectDefinitionRegistry) factory; + RootObjectDefinition definition = (RootObjectDefinition) definitionRegistry.GetObjectDefinition(name); + + if (logger.IsInfoEnabled) + logger.Info("Configuring AbstractPrototypeBasedTargetSource..."); + + // Infinite cycle will result if we don't use a different factory, + // because a GetObject() call with this objectName will go through the autoproxy + // infrastructure again. + // We to override just this object definition, as it may reference other objects + // and we're happy to take the parent's definition for those. + DefaultListableObjectFactory objectFactory = new DefaultListableObjectFactory(factory); + + // Override the prototype object + objectFactory.RegisterObjectDefinition(name, definition); + + // Complete configuring the PrototypeTargetSource + prototypeTargetSource.TargetObjectName = name; + prototypeTargetSource.ObjectFactory = objectFactory; + + return prototypeTargetSource; + } + } + + #endregion + + /// + /// Creates the prototype target source. + /// + /// The type of the object to create a target source for. + /// The name. + /// The factory. + /// + protected abstract AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, + IObjectFactory factory); + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicMethodInvocation.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicMethodInvocation.cs index 8ce1283b..9021f9ac 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicMethodInvocation.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicMethodInvocation.cs @@ -1,126 +1,125 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -using Spring.Util; -using Spring.Reflection.Dynamic; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Invokes a target method using dynamic reflection. - /// - /// - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: DynamicMethodInvocation.cs,v 1.3 2008/02/06 18:28:52 bbaia Exp $ - [Serializable] - public class DynamicMethodInvocation : AbstractMethodInvocation - { - /// - /// The method invocation that is to be invoked on the proxy. - /// - protected MethodInfo proxyMethod; - - /// - /// Creates a new instance of the - /// class. - /// - /// The AOP proxy. - /// The target object. - /// The target method proxied. - /// The method to invoke on proxy. - /// The target method's arguments. - /// - /// The of the target object. - /// - /// The list of interceptors that are to be applied. May be - /// . - /// - /// - /// If any of the or - /// parameters is . - /// - public DynamicMethodInvocation( - object proxy, object target, MethodInfo method, MethodInfo proxyMethod, - object[] arguments, Type targetType, IList interceptors) - : base(proxy, target, method, arguments, targetType, interceptors) - { - this.proxyMethod = proxyMethod; - } - - /// - /// Invokes the joinpoint using dynamic reflection. - /// - /// - ///

- /// Subclasses can override this to use custom invocation. - ///

- ///
- /// - /// The return value of the invocation of the joinpoint. - /// - /// - /// If invoking the joinpoint resulted in an exception. - /// - /// - protected override object InvokeJoinpoint() - { - IDynamicMethod targetMethod = (this.proxyMethod == null) ? new SafeMethod(method) : new SafeMethod(proxyMethod); - try - { - return targetMethod.Invoke(target, arguments); - } - // Only happens if fallback to standard reflection. - catch (TargetInvocationException ex) - { - throw ReflectionUtils.UnwrapTargetInvocationException(ex); - } - } - - /// - /// Creates a new instance - /// from the specified and - /// increments the interceptor index. - /// - /// - /// The current instance. - /// - /// - /// The new instance to use. - /// - protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation) - { - DynamicMethodInvocation rmi = new DynamicMethodInvocation( - this.proxy, this.target, this.method, this.proxyMethod, this.arguments, this.targetType, this.interceptors); - rmi.currentInterceptorIndex = this.currentInterceptorIndex + 1; - - return rmi; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +using Spring.Util; +using Spring.Reflection.Dynamic; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Invokes a target method using dynamic reflection. + /// + /// + /// Aleksandar Seovic + /// Bruno Baia + [Serializable] + public class DynamicMethodInvocation : AbstractMethodInvocation + { + /// + /// The method invocation that is to be invoked on the proxy. + /// + protected MethodInfo proxyMethod; + + /// + /// Creates a new instance of the + /// class. + /// + /// The AOP proxy. + /// The target object. + /// The target method proxied. + /// The method to invoke on proxy. + /// The target method's arguments. + /// + /// The of the target object. + /// + /// The list of interceptors that are to be applied. May be + /// . + /// + /// + /// If any of the or + /// parameters is . + /// + public DynamicMethodInvocation( + object proxy, object target, MethodInfo method, MethodInfo proxyMethod, + object[] arguments, Type targetType, IList interceptors) + : base(proxy, target, method, arguments, targetType, interceptors) + { + this.proxyMethod = proxyMethod; + } + + /// + /// Invokes the joinpoint using dynamic reflection. + /// + /// + ///

+ /// Subclasses can override this to use custom invocation. + ///

+ ///
+ /// + /// The return value of the invocation of the joinpoint. + /// + /// + /// If invoking the joinpoint resulted in an exception. + /// + /// + protected override object InvokeJoinpoint() + { + IDynamicMethod targetMethod = (this.proxyMethod == null) ? new SafeMethod(method) : new SafeMethod(proxyMethod); + try + { + return targetMethod.Invoke(target, arguments); + } + // Only happens if fallback to standard reflection. + catch (TargetInvocationException ex) + { + throw ReflectionUtils.UnwrapTargetInvocationException(ex); + } + } + + /// + /// Creates a new instance + /// from the specified and + /// increments the interceptor index. + /// + /// + /// The current instance. + /// + /// + /// The new instance to use. + /// + protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation) + { + DynamicMethodInvocation rmi = new DynamicMethodInvocation( + this.proxy, this.target, this.method, this.proxyMethod, this.arguments, this.targetType, this.interceptors); + rmi.currentInterceptorIndex = this.currentInterceptorIndex + 1; + + return rmi; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyMethodBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyMethodBuilder.cs index 247ab977..e2d05ce2 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyMethodBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyMethodBuilder.cs @@ -1,788 +1,787 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.Serialization; - -using Spring.Proxy; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Base class for AOP method builders that contains common functionalities. - /// - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: AbstractAopProxyMethodBuilder.cs,v 1.10 2008/05/21 08:04:34 bbaia Exp $ - public abstract class AbstractAopProxyMethodBuilder : AbstractProxyMethodBuilder - { - #region Fields - - /// - /// The implementation to use. - /// - protected IAopProxyTypeGenerator aopProxyGenerator; - - /// - /// The dictionary to cache the list of target - /// s. - /// - protected IDictionary targetMethods; - - /// - /// The dictionary to cache the list of target - /// s defined on the proxy. - /// - protected IDictionary onProxyTargetMethods; - - // variables - - /// - /// The local variable to store the list of method interceptors. - /// - protected LocalBuilder interceptors; - - /// - /// The local variable to store the target type being proxied. - /// - protected LocalBuilder targetType; - - /// - /// The local variable to store method arguments. - /// - protected LocalBuilder arguments; - - /// - /// The local variable to store the return value. - /// - protected LocalBuilder returnValue; - -#if NET_2_0 - /// - /// The local variable to store the closed generic method - /// when the target method is generic. - /// - protected LocalBuilder genericTargetMethod; - - /// - /// The local variable to store the closed generic method - /// when the target method defined on the proxy is generic. - /// - protected LocalBuilder genericOnProxyTargetMethod; -#endif - /// - /// The field to cache the target . - /// - protected FieldBuilder targetMethodCacheField; - - /// - /// The field to cache the target - /// defined on the proxy. - /// - protected FieldBuilder onProxyTargetMethodCacheField; - - // convinience fields - - /// - /// Indicates if the method returns a value. - /// - protected bool methodReturnsValue; - - // private fields - - private static IDictionary ldindOpCodes; - - #endregion - - #region Constructor(s) / Destructor - - static AbstractAopProxyMethodBuilder() - { - ldindOpCodes = new Hashtable(); - ldindOpCodes[typeof(sbyte)] = OpCodes.Ldind_I1; - ldindOpCodes[typeof(short)] = OpCodes.Ldind_I2; - ldindOpCodes[typeof(int)] = OpCodes.Ldind_I4; - ldindOpCodes[typeof(long)] = OpCodes.Ldind_I8; - ldindOpCodes[typeof(byte)] = OpCodes.Ldind_U1; - ldindOpCodes[typeof(ushort)] = OpCodes.Ldind_U2; - ldindOpCodes[typeof(uint)] = OpCodes.Ldind_U4; - ldindOpCodes[typeof(ulong)] = OpCodes.Ldind_I8; - ldindOpCodes[typeof(float)] = OpCodes.Ldind_R4; - ldindOpCodes[typeof(double)] = OpCodes.Ldind_R8; - ldindOpCodes[typeof(char)] = OpCodes.Ldind_U2; - ldindOpCodes[typeof(bool)] = OpCodes.Ldind_I1; - } - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - /// - /// if the interface is to be - /// implemented explicitly; otherwise . - /// - /// - /// The dictionary to cache the list of target - /// s. - /// - protected AbstractAopProxyMethodBuilder( - TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, - bool explicitImplementation, IDictionary targetMethods) - : this(typeBuilder, aopProxyGenerator, explicitImplementation, targetMethods, new Hashtable()) - { - } - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - /// - /// if the interface is to be - /// implemented explicitly; otherwise . - /// - /// - /// The dictionary to cache the list of target - /// s. - /// - /// - /// The dictionary to cache the list of target - /// s defined on the proxy. - /// - protected AbstractAopProxyMethodBuilder( - TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, - bool explicitImplementation, IDictionary targetMethods, IDictionary onProxyTargetMethods) - : base(typeBuilder, aopProxyGenerator, explicitImplementation) - { - this.aopProxyGenerator = aopProxyGenerator; - this.targetMethods = targetMethods; - this.onProxyTargetMethods = onProxyTargetMethods; - } - - #endregion - - #region Protected Members - - /// - /// Generates the proxy method. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected override void GenerateMethod( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - methodReturnsValue = (method.ReturnType != typeof(void)); - - DeclareLocals(il, method); - - GenerateTargetMethodCacheField(il, method); - GenerateOnProxyTargetMethodCacheField(il, method); - - BeginMethod(il, method); - GenerateMethodLogic(il, method, interfaceMethod); - EndMethod(il, method); - } - - /// - /// Generates unique method id for the cache field. - /// - /// The target method. - /// An unique method name. - protected virtual string GenerateMethodCacheFieldId(MethodInfo method) - { - return "_m" + Guid.NewGuid().ToString("N"); - } - - /// - /// Create static field that will cache target method. - /// - /// The IL generator to use. - /// The target method. - protected virtual void GenerateTargetMethodCacheField( - ILGenerator il, MethodInfo method) - { - string methodId = GenerateMethodCacheFieldId(method); - targetMethods.Add(methodId, method); - - targetMethodCacheField = typeBuilder.DefineField(methodId, typeof(MethodInfo), - FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly); - -#if NET_2_0 - MakeGenericMethod(il, method, targetMethodCacheField, genericTargetMethod); -#endif - } - - /// - /// Create static field that will cache target method when defined on the proxy. - /// - /// The IL generator to use. - /// The target method. - protected virtual void GenerateOnProxyTargetMethodCacheField( - ILGenerator il, MethodInfo method) - { - } - -#if NET_2_0 - /// - /// Create a closed generic method for the current call - /// if target method is a generic definition. - /// - /// The IL generator to use. - /// The target method. - /// - /// The field that contains the method generic definition - /// - /// - /// The local variable to store the closed generic method. - /// - protected void MakeGenericMethod(ILGenerator il, MethodInfo method, - FieldBuilder methodCacheField, LocalBuilder localMethod) - { - // if target method is a generic definition, - // create a closed generic method for the current call. - if (method.IsGenericMethodDefinition) - { - Type[] genericArgs = method.GetGenericArguments(); - - LocalBuilder typeArgs = il.DeclareLocal(typeof(Type[])); - - il.Emit(OpCodes.Ldsfld, methodCacheField); - - // specify array size and create an array - il.Emit(OpCodes.Ldc_I4, genericArgs.Length); - il.Emit(OpCodes.Newarr, typeof(Type)); - il.Emit(OpCodes.Stloc, typeArgs); - - // populate array with type arguments - for (int i = 0; i < genericArgs.Length; i++) - { - il.Emit(OpCodes.Ldloc, typeArgs); - il.Emit(OpCodes.Ldc_I4, i); - il.Emit(OpCodes.Ldtoken, genericArgs[i]); - il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null); - il.Emit(OpCodes.Stelem_Ref); - } - - il.Emit(OpCodes.Ldloc, typeArgs); - il.Emit(OpCodes.Callvirt, References.MakeGenericMethod); - il.Emit(OpCodes.Stloc, localMethod); - } - } -#endif - - /// - /// Generates the IL instructions that pushes - /// the target type on stack. - /// - /// The IL generator to use. - protected virtual void PushTargetType(ILGenerator il) - { - aopProxyGenerator.PushAdvisedProxy(il); - il.Emit(OpCodes.Ldfld, References.TargetTypeField); - } - - /// - /// Generates the IL instructions that pushes - /// the current - /// instance on stack. - /// - /// The IL generator to use. - protected virtual void PushAdvisedProxy(ILGenerator il) - { - aopProxyGenerator.PushAdvisedProxy(il); - } - - /// - /// Pushes the target to stack. - /// - /// The IL generator to use. - /// The method to proxy. - protected virtual void PushTargetMethodInfo(ILGenerator il, MethodInfo method) - { -#if NET_2_0 - if (method.IsGenericMethodDefinition) - { - il.Emit(OpCodes.Ldloc, genericTargetMethod); - return; - } -#endif - il.Emit(OpCodes.Ldsfld, targetMethodCacheField); - } - - /// - /// Pushes the target defined on the proxy to stack. - /// - /// The IL generator to use. - /// The method to proxy. - protected virtual void PushOnProxyTargetMethodInfo(ILGenerator il, MethodInfo method) - { - if (onProxyTargetMethodCacheField != null) - { -#if NET_2_0 - if (method.IsGenericMethodDefinition) - { - il.Emit(OpCodes.Ldloc, genericOnProxyTargetMethod); - return; - } -#endif - il.Emit(OpCodes.Ldsfld, onProxyTargetMethodCacheField); - } - else - { - il.Emit(OpCodes.Ldnull); - } - } - - /// - /// Creates local variable declarations. - /// - /// The IL generator to use. - /// The method to proxy. - protected virtual void DeclareLocals(ILGenerator il, MethodInfo method) - { - interceptors = il.DeclareLocal(typeof(IList)); - targetType = il.DeclareLocal(typeof(Type)); - arguments = il.DeclareLocal(typeof(Object[])); - -#if NET_2_0 - if (method.IsGenericMethodDefinition) - { - genericTargetMethod = il.DeclareLocal(typeof(MethodInfo)); - genericOnProxyTargetMethod = il.DeclareLocal(typeof(MethodInfo)); - } -#endif - if (methodReturnsValue) - { - returnValue = il.DeclareLocal(method.ReturnType); - } - -#if DEBUG - interceptors.SetLocalSymInfo("interceptors"); - targetType.SetLocalSymInfo("targetType"); - arguments.SetLocalSymInfo("arguments"); -#if NET_2_0 - if (method.IsGenericMethodDefinition) - { - genericTargetMethod.SetLocalSymInfo("genericTargetMethod"); - genericOnProxyTargetMethod.SetLocalSymInfo("genericOnProxyTargetMethod"); - } -#endif - if (methodReturnsValue) - { - returnValue.SetLocalSymInfo("returnValue"); - } -#endif - } - - /// - /// Initializes local variables - /// - /// The IL generator to use. - /// The method to proxy. - protected virtual void BeginMethod(ILGenerator il, MethodInfo method) - { - Label jmpProxyNotExposed = il.DefineLabel(); - - // set current proxy to this object - PushAdvisedProxy(il); - il.Emit(OpCodes.Ldfld, References.AdvisedField); - il.EmitCall(OpCodes.Callvirt, References.ExposeProxyProperty, null); - il.Emit(OpCodes.Brfalse_S, jmpProxyNotExposed); - il.Emit(OpCodes.Ldarg_0); - il.EmitCall(OpCodes.Call, References.PushProxyMethod, null); - - il.MarkLabel(jmpProxyNotExposed); - - // initialize targetType - PushTargetType(il); - il.Emit(OpCodes.Stloc, targetType); - - // initialize interceptors - PushAdvisedProxy(il); - il.Emit(OpCodes.Ldloc, targetType); - PushTargetMethodInfo(il, method); - il.EmitCall(OpCodes.Call, References.GetInterceptorsMethod, null); - il.Emit(OpCodes.Stloc, interceptors); - } - - /// - /// Generates method logic. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected virtual void GenerateMethodLogic( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - Label jmpDirectCall = il.DefineLabel(); - Label jmpEndIf = il.DefineLabel(); - - // check if there are any interceptors - il.Emit(OpCodes.Ldloc, interceptors); - il.EmitCall(OpCodes.Callvirt, References.CountProperty, null); - il.Emit(OpCodes.Ldc_I4_0); - - // if not jump to direct call - il.Emit(OpCodes.Ble, jmpDirectCall); - - // otherwise call Invoke and jump to method end - CallInvoke(il, method); - il.Emit(OpCodes.Br, jmpEndIf); - - // call method directly - il.MarkLabel(jmpDirectCall); - CallDirectProxiedMethod(il, method, interfaceMethod); - if (methodReturnsValue) - { - // store return value, unboxing is not necessary because we called method directly - il.Emit(OpCodes.Stloc, returnValue); - } - - il.MarkLabel(jmpEndIf); - - if (methodReturnsValue) - { - if (!method.ReturnType.IsValueType) - { - ProcessReturnValue(il, returnValue); - } - } - } - - /// - /// Calls method using Invoke - /// - /// The IL generator to use. - /// The method to proxy. - protected virtual void CallInvoke(ILGenerator il, MethodInfo method) - { - ParameterInfo[] parameters = method.GetParameters(); - - SetupMethodArguments(il, method, parameters); - - PushAdvisedProxy(il); - - // setup parameters for call - il.Emit(OpCodes.Ldarg_0); // proxy - PushTarget(il); // target - il.Emit(OpCodes.Ldloc, targetType); // target type - PushTargetMethodInfo(il, method); // method - PushOnProxyTargetMethodInfo(il, method); // method defined on proxy - il.Emit(OpCodes.Ldloc, arguments); // args - il.Emit(OpCodes.Ldloc, interceptors); // interceptors - - // call Invoke - il.EmitCall(OpCodes.Call, References.InvokeMethod, null); - - // process return value - if (methodReturnsValue) - { - EmitUnboxIfNeeded(il, method.ReturnType); - il.Emit(OpCodes.Stloc, returnValue); - } - else - { - il.Emit(OpCodes.Pop); - } - - // process byRef arguments - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i].ParameterType.IsByRef) - { - il.Emit(OpCodes.Ldarg_S, i + 1); - il.Emit(OpCodes.Ldloc, arguments); - il.Emit(OpCodes.Ldc_I4_S, i); - il.Emit(OpCodes.Ldelem_Ref); - Type type = parameters[i].ParameterType.GetElementType(); - EmitUnboxIfNeeded(il, type); - EmitStoreValueIndirect(il, type); - } - } - } - - /// - /// Setup proxied method arguments. - /// - /// The IL generator to use. - /// The method to proxy. - /// The method's parameters. - protected void SetupMethodArguments( - ILGenerator il, MethodInfo method, ParameterInfo[] parameters) - { - if (parameters.Length > 0) - { - // specify array size and create an array - il.Emit(OpCodes.Ldc_I4, parameters.Length); - il.Emit(OpCodes.Newarr, typeof(Object)); - il.Emit(OpCodes.Stloc, arguments); - - // populate array with params - for (int i = 0; i < parameters.Length; i++) - { - Type type = parameters[i].ParameterType; - - il.Emit(OpCodes.Ldloc, arguments); - il.Emit(OpCodes.Ldc_I4, i); - il.Emit(OpCodes.Ldarg_S, i + 1); - - // setup byRef arguments - if (type.IsByRef) - { - type = type.GetElementType(); - EmitLoadValueIndirect(il, type); - } - -#if NET_2_0 - if (type.IsValueType || type.IsGenericParameter) -#else - if (type.IsValueType) -#endif - { - il.Emit(OpCodes.Box, type); - } - - il.Emit(OpCodes.Stelem_Ref); - } - } - else - { - il.Emit(OpCodes.Ldnull); - il.Emit(OpCodes.Stloc, arguments); - } - } - - /// - /// Calls proxied method directly. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected abstract void CallDirectProxiedMethod( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod); - - /// - /// Ends method by returning return value if appropriate. - /// - /// The IL generator to use. - /// The method to proxy. - protected virtual void EndMethod(ILGenerator il, MethodInfo method) - { - Label jmpProxyNotExposed = il.DefineLabel(); - - // reset current proxy to old value - PushAdvisedProxy(il); - il.Emit(OpCodes.Ldfld, References.AdvisedField); - il.EmitCall(OpCodes.Callvirt, References.ExposeProxyProperty, null); - il.Emit(OpCodes.Brfalse_S, jmpProxyNotExposed); - il.EmitCall(OpCodes.Call, References.PopProxyMethod, null); - - il.MarkLabel(jmpProxyNotExposed); - - if (methodReturnsValue) - { - il.Emit(OpCodes.Ldloc, returnValue); - } - } - - #endregion - - #region Reflection.Emit utility methods - - /// - /// Emits MSIL instructions to load a value of the specified - /// onto the evaluation stack indirectly. - /// - /// The IL generator to use. - /// The type of the value. - protected static void EmitLoadValueIndirect(ILGenerator il, Type type) - { - if (type.IsValueType) - { - if (type == typeof(int)) il.Emit(OpCodes.Ldind_I4); - else if (type == typeof(uint)) il.Emit(OpCodes.Ldind_U4); - else if (type == typeof(char)) il.Emit(OpCodes.Ldind_I2); - else if (type == typeof(bool)) il.Emit(OpCodes.Ldind_I1); - else if (type == typeof(float)) il.Emit(OpCodes.Ldind_R4); - else if (type == typeof(double)) il.Emit(OpCodes.Ldind_R8); - else if (type == typeof(short)) il.Emit(OpCodes.Ldind_I2); - else if (type == typeof(ushort)) il.Emit(OpCodes.Ldind_U2); - else if (type == typeof(long) || type == typeof(ulong)) il.Emit(OpCodes.Ldind_I8); - else il.Emit(OpCodes.Ldobj, type); - } - else - { - il.Emit(OpCodes.Ldind_Ref); - } - } - - /// - /// Emit MSIL instructions to store a value of the specified - /// at a supplied address. - /// - /// The IL generator to use. - /// The type of the value. - protected static void EmitStoreValueIndirect(ILGenerator il, Type type) - { - if (type.IsValueType) - { - if (type.IsEnum) EmitStoreValueIndirect(il, Enum.GetUnderlyingType(type)); - else if (type == typeof(int)) il.Emit(OpCodes.Stind_I4); - else if (type == typeof(short)) il.Emit(OpCodes.Stind_I2); - else if (type == typeof(long) || type == typeof(ulong)) il.Emit(OpCodes.Stind_I8); - else if (type == typeof(char)) il.Emit(OpCodes.Stind_I2); - else if (type == typeof(bool)) il.Emit(OpCodes.Stind_I1); - else if (type == typeof(float)) il.Emit(OpCodes.Stind_R4); - else if (type == typeof(double)) il.Emit(OpCodes.Stind_R8); - else il.Emit(OpCodes.Stobj, type); - } - else - { - il.Emit(OpCodes.Stind_Ref); - } - } - - /// - /// Emits MSIL instructions to convert the boxed representation - /// of the supplied to its unboxed form. - /// - /// The IL generator to use. - /// The type specified in the instruction. - protected static void EmitUnboxIfNeeded(ILGenerator il, Type type) - { -#if NET_2_0 - if (type.IsValueType || type.IsGenericParameter) - { - il.Emit(OpCodes.Unbox_Any, type); - } -#else - if (type.IsValueType) - { - il.Emit(OpCodes.Unbox, type); - il.Emit(OpCodes.Ldobj, type); - } -#endif - } - - #endregion - } - - #region References helper class definition - - internal struct References - { - // fields - public static readonly FieldInfo AdvisedField = - typeof(AdvisedProxy).GetField("m_advised", BindingFlags.Instance | BindingFlags.Public); - - public static readonly FieldInfo TargetTypeField = - typeof(AdvisedProxy).GetField("m_targetType", BindingFlags.Instance | BindingFlags.Public); - - public static readonly FieldInfo IntroductionsField = - typeof(AdvisedProxy).GetField("m_introductions", BindingFlags.Instance | BindingFlags.Public); - - public static readonly FieldInfo TargetSourceWrapperField = - typeof(AdvisedProxy).GetField("m_targetSourceWrapper", BindingFlags.Instance | BindingFlags.Public); - - // constructors - public static readonly ConstructorInfo BaseCompositionAopProxyConstructor = - typeof(BaseCompositionAopProxy).GetConstructor(new Type[] { typeof(IAdvised) }); - - public static readonly ConstructorInfo BaseCompositionAopProxySerializationConstructor = - typeof(BaseCompositionAopProxy).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, - new Type[] {typeof(SerializationInfo), typeof(StreamingContext)}, - null); - - public static readonly ConstructorInfo AdvisedProxyConstructor = - typeof(AdvisedProxy).GetConstructor(new Type[] { typeof(IAdvised), typeof(IAopProxy) }); - - public static readonly ConstructorInfo AdvisedProxySerializationConstructor = - typeof(AdvisedProxy).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, - new Type[] {typeof (SerializationInfo), typeof (StreamingContext)}, - null); - public static readonly ConstructorInfo ObjectConstructor = - typeof(Object).GetConstructor(Type.EmptyTypes); - - // methods - public static readonly MethodInfo PushProxyMethod = - typeof(AopContext).GetMethod("PushProxy", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(Object) }, null); - - public static readonly MethodInfo PopProxyMethod = - typeof(AopContext).GetMethod("PopProxy", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null); - - public static readonly MethodInfo InvokeMethod = - typeof(AdvisedProxy).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(Object), typeof(Object), typeof(Type), typeof(MethodInfo), typeof(MethodInfo), typeof(Object[]), typeof(IList) }, null); - - public static readonly MethodInfo GetInterceptorsMethod = - typeof(AdvisedProxy).GetMethod("GetInterceptors", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(Type), typeof(MethodInfo) }, null); - - public static readonly MethodInfo GetTargetMethod = - typeof(ITargetSourceWrapper).GetMethod("GetTarget", Type.EmptyTypes); - - public static readonly MethodInfo GetTypeMethod = - typeof(Object).GetMethod("GetType", Type.EmptyTypes); - - public static readonly MethodInfo GetTypeFromHandle = - typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }); - -#if NET_2_0 - public static readonly MethodInfo MakeGenericMethod = - typeof(MethodInfo).GetMethod("MakeGenericMethod", new Type[] { typeof(Type[]) }); -#endif - - public static readonly MethodInfo DisposeMethod = - typeof(IDisposable).GetMethod("Dispose", Type.EmptyTypes); - - public static readonly MethodInfo AddSerializationValue = - typeof(SerializationInfo).GetMethod("AddValue", new Type[] { typeof(string), typeof(object) }); - - public static readonly MethodInfo GetSerializationValue = - typeof(SerializationInfo).GetMethod("GetValue", new Type[] { typeof(string), typeof(Type) }); - - // properties - public static readonly MethodInfo ExposeProxyProperty = - typeof(IAdvised).GetProperty("ExposeProxy", typeof(Boolean)).GetGetMethod(); - - public static readonly MethodInfo CountProperty = - typeof(ICollection).GetProperty("Count", typeof(Int32)).GetGetMethod(); - } - - #endregion -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; + +using Spring.Proxy; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Base class for AOP method builders that contains common functionalities. + /// + /// Aleksandar Seovic + /// Bruno Baia + public abstract class AbstractAopProxyMethodBuilder : AbstractProxyMethodBuilder + { + #region Fields + + /// + /// The implementation to use. + /// + protected IAopProxyTypeGenerator aopProxyGenerator; + + /// + /// The dictionary to cache the list of target + /// s. + /// + protected IDictionary targetMethods; + + /// + /// The dictionary to cache the list of target + /// s defined on the proxy. + /// + protected IDictionary onProxyTargetMethods; + + // variables + + /// + /// The local variable to store the list of method interceptors. + /// + protected LocalBuilder interceptors; + + /// + /// The local variable to store the target type being proxied. + /// + protected LocalBuilder targetType; + + /// + /// The local variable to store method arguments. + /// + protected LocalBuilder arguments; + + /// + /// The local variable to store the return value. + /// + protected LocalBuilder returnValue; + +#if NET_2_0 + /// + /// The local variable to store the closed generic method + /// when the target method is generic. + /// + protected LocalBuilder genericTargetMethod; + + /// + /// The local variable to store the closed generic method + /// when the target method defined on the proxy is generic. + /// + protected LocalBuilder genericOnProxyTargetMethod; +#endif + /// + /// The field to cache the target . + /// + protected FieldBuilder targetMethodCacheField; + + /// + /// The field to cache the target + /// defined on the proxy. + /// + protected FieldBuilder onProxyTargetMethodCacheField; + + // convinience fields + + /// + /// Indicates if the method returns a value. + /// + protected bool methodReturnsValue; + + // private fields + + private static IDictionary ldindOpCodes; + + #endregion + + #region Constructor(s) / Destructor + + static AbstractAopProxyMethodBuilder() + { + ldindOpCodes = new Hashtable(); + ldindOpCodes[typeof(sbyte)] = OpCodes.Ldind_I1; + ldindOpCodes[typeof(short)] = OpCodes.Ldind_I2; + ldindOpCodes[typeof(int)] = OpCodes.Ldind_I4; + ldindOpCodes[typeof(long)] = OpCodes.Ldind_I8; + ldindOpCodes[typeof(byte)] = OpCodes.Ldind_U1; + ldindOpCodes[typeof(ushort)] = OpCodes.Ldind_U2; + ldindOpCodes[typeof(uint)] = OpCodes.Ldind_U4; + ldindOpCodes[typeof(ulong)] = OpCodes.Ldind_I8; + ldindOpCodes[typeof(float)] = OpCodes.Ldind_R4; + ldindOpCodes[typeof(double)] = OpCodes.Ldind_R8; + ldindOpCodes[typeof(char)] = OpCodes.Ldind_U2; + ldindOpCodes[typeof(bool)] = OpCodes.Ldind_I1; + } + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + /// + /// if the interface is to be + /// implemented explicitly; otherwise . + /// + /// + /// The dictionary to cache the list of target + /// s. + /// + protected AbstractAopProxyMethodBuilder( + TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, + bool explicitImplementation, IDictionary targetMethods) + : this(typeBuilder, aopProxyGenerator, explicitImplementation, targetMethods, new Hashtable()) + { + } + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + /// + /// if the interface is to be + /// implemented explicitly; otherwise . + /// + /// + /// The dictionary to cache the list of target + /// s. + /// + /// + /// The dictionary to cache the list of target + /// s defined on the proxy. + /// + protected AbstractAopProxyMethodBuilder( + TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, + bool explicitImplementation, IDictionary targetMethods, IDictionary onProxyTargetMethods) + : base(typeBuilder, aopProxyGenerator, explicitImplementation) + { + this.aopProxyGenerator = aopProxyGenerator; + this.targetMethods = targetMethods; + this.onProxyTargetMethods = onProxyTargetMethods; + } + + #endregion + + #region Protected Members + + /// + /// Generates the proxy method. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected override void GenerateMethod( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + methodReturnsValue = (method.ReturnType != typeof(void)); + + DeclareLocals(il, method); + + GenerateTargetMethodCacheField(il, method); + GenerateOnProxyTargetMethodCacheField(il, method); + + BeginMethod(il, method); + GenerateMethodLogic(il, method, interfaceMethod); + EndMethod(il, method); + } + + /// + /// Generates unique method id for the cache field. + /// + /// The target method. + /// An unique method name. + protected virtual string GenerateMethodCacheFieldId(MethodInfo method) + { + return "_m" + Guid.NewGuid().ToString("N"); + } + + /// + /// Create static field that will cache target method. + /// + /// The IL generator to use. + /// The target method. + protected virtual void GenerateTargetMethodCacheField( + ILGenerator il, MethodInfo method) + { + string methodId = GenerateMethodCacheFieldId(method); + targetMethods.Add(methodId, method); + + targetMethodCacheField = typeBuilder.DefineField(methodId, typeof(MethodInfo), + FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly); + +#if NET_2_0 + MakeGenericMethod(il, method, targetMethodCacheField, genericTargetMethod); +#endif + } + + /// + /// Create static field that will cache target method when defined on the proxy. + /// + /// The IL generator to use. + /// The target method. + protected virtual void GenerateOnProxyTargetMethodCacheField( + ILGenerator il, MethodInfo method) + { + } + +#if NET_2_0 + /// + /// Create a closed generic method for the current call + /// if target method is a generic definition. + /// + /// The IL generator to use. + /// The target method. + /// + /// The field that contains the method generic definition + /// + /// + /// The local variable to store the closed generic method. + /// + protected void MakeGenericMethod(ILGenerator il, MethodInfo method, + FieldBuilder methodCacheField, LocalBuilder localMethod) + { + // if target method is a generic definition, + // create a closed generic method for the current call. + if (method.IsGenericMethodDefinition) + { + Type[] genericArgs = method.GetGenericArguments(); + + LocalBuilder typeArgs = il.DeclareLocal(typeof(Type[])); + + il.Emit(OpCodes.Ldsfld, methodCacheField); + + // specify array size and create an array + il.Emit(OpCodes.Ldc_I4, genericArgs.Length); + il.Emit(OpCodes.Newarr, typeof(Type)); + il.Emit(OpCodes.Stloc, typeArgs); + + // populate array with type arguments + for (int i = 0; i < genericArgs.Length; i++) + { + il.Emit(OpCodes.Ldloc, typeArgs); + il.Emit(OpCodes.Ldc_I4, i); + il.Emit(OpCodes.Ldtoken, genericArgs[i]); + il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null); + il.Emit(OpCodes.Stelem_Ref); + } + + il.Emit(OpCodes.Ldloc, typeArgs); + il.Emit(OpCodes.Callvirt, References.MakeGenericMethod); + il.Emit(OpCodes.Stloc, localMethod); + } + } +#endif + + /// + /// Generates the IL instructions that pushes + /// the target type on stack. + /// + /// The IL generator to use. + protected virtual void PushTargetType(ILGenerator il) + { + aopProxyGenerator.PushAdvisedProxy(il); + il.Emit(OpCodes.Ldfld, References.TargetTypeField); + } + + /// + /// Generates the IL instructions that pushes + /// the current + /// instance on stack. + /// + /// The IL generator to use. + protected virtual void PushAdvisedProxy(ILGenerator il) + { + aopProxyGenerator.PushAdvisedProxy(il); + } + + /// + /// Pushes the target to stack. + /// + /// The IL generator to use. + /// The method to proxy. + protected virtual void PushTargetMethodInfo(ILGenerator il, MethodInfo method) + { +#if NET_2_0 + if (method.IsGenericMethodDefinition) + { + il.Emit(OpCodes.Ldloc, genericTargetMethod); + return; + } +#endif + il.Emit(OpCodes.Ldsfld, targetMethodCacheField); + } + + /// + /// Pushes the target defined on the proxy to stack. + /// + /// The IL generator to use. + /// The method to proxy. + protected virtual void PushOnProxyTargetMethodInfo(ILGenerator il, MethodInfo method) + { + if (onProxyTargetMethodCacheField != null) + { +#if NET_2_0 + if (method.IsGenericMethodDefinition) + { + il.Emit(OpCodes.Ldloc, genericOnProxyTargetMethod); + return; + } +#endif + il.Emit(OpCodes.Ldsfld, onProxyTargetMethodCacheField); + } + else + { + il.Emit(OpCodes.Ldnull); + } + } + + /// + /// Creates local variable declarations. + /// + /// The IL generator to use. + /// The method to proxy. + protected virtual void DeclareLocals(ILGenerator il, MethodInfo method) + { + interceptors = il.DeclareLocal(typeof(IList)); + targetType = il.DeclareLocal(typeof(Type)); + arguments = il.DeclareLocal(typeof(Object[])); + +#if NET_2_0 + if (method.IsGenericMethodDefinition) + { + genericTargetMethod = il.DeclareLocal(typeof(MethodInfo)); + genericOnProxyTargetMethod = il.DeclareLocal(typeof(MethodInfo)); + } +#endif + if (methodReturnsValue) + { + returnValue = il.DeclareLocal(method.ReturnType); + } + +#if DEBUG + interceptors.SetLocalSymInfo("interceptors"); + targetType.SetLocalSymInfo("targetType"); + arguments.SetLocalSymInfo("arguments"); +#if NET_2_0 + if (method.IsGenericMethodDefinition) + { + genericTargetMethod.SetLocalSymInfo("genericTargetMethod"); + genericOnProxyTargetMethod.SetLocalSymInfo("genericOnProxyTargetMethod"); + } +#endif + if (methodReturnsValue) + { + returnValue.SetLocalSymInfo("returnValue"); + } +#endif + } + + /// + /// Initializes local variables + /// + /// The IL generator to use. + /// The method to proxy. + protected virtual void BeginMethod(ILGenerator il, MethodInfo method) + { + Label jmpProxyNotExposed = il.DefineLabel(); + + // set current proxy to this object + PushAdvisedProxy(il); + il.Emit(OpCodes.Ldfld, References.AdvisedField); + il.EmitCall(OpCodes.Callvirt, References.ExposeProxyProperty, null); + il.Emit(OpCodes.Brfalse_S, jmpProxyNotExposed); + il.Emit(OpCodes.Ldarg_0); + il.EmitCall(OpCodes.Call, References.PushProxyMethod, null); + + il.MarkLabel(jmpProxyNotExposed); + + // initialize targetType + PushTargetType(il); + il.Emit(OpCodes.Stloc, targetType); + + // initialize interceptors + PushAdvisedProxy(il); + il.Emit(OpCodes.Ldloc, targetType); + PushTargetMethodInfo(il, method); + il.EmitCall(OpCodes.Call, References.GetInterceptorsMethod, null); + il.Emit(OpCodes.Stloc, interceptors); + } + + /// + /// Generates method logic. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected virtual void GenerateMethodLogic( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + Label jmpDirectCall = il.DefineLabel(); + Label jmpEndIf = il.DefineLabel(); + + // check if there are any interceptors + il.Emit(OpCodes.Ldloc, interceptors); + il.EmitCall(OpCodes.Callvirt, References.CountProperty, null); + il.Emit(OpCodes.Ldc_I4_0); + + // if not jump to direct call + il.Emit(OpCodes.Ble, jmpDirectCall); + + // otherwise call Invoke and jump to method end + CallInvoke(il, method); + il.Emit(OpCodes.Br, jmpEndIf); + + // call method directly + il.MarkLabel(jmpDirectCall); + CallDirectProxiedMethod(il, method, interfaceMethod); + if (methodReturnsValue) + { + // store return value, unboxing is not necessary because we called method directly + il.Emit(OpCodes.Stloc, returnValue); + } + + il.MarkLabel(jmpEndIf); + + if (methodReturnsValue) + { + if (!method.ReturnType.IsValueType) + { + ProcessReturnValue(il, returnValue); + } + } + } + + /// + /// Calls method using Invoke + /// + /// The IL generator to use. + /// The method to proxy. + protected virtual void CallInvoke(ILGenerator il, MethodInfo method) + { + ParameterInfo[] parameters = method.GetParameters(); + + SetupMethodArguments(il, method, parameters); + + PushAdvisedProxy(il); + + // setup parameters for call + il.Emit(OpCodes.Ldarg_0); // proxy + PushTarget(il); // target + il.Emit(OpCodes.Ldloc, targetType); // target type + PushTargetMethodInfo(il, method); // method + PushOnProxyTargetMethodInfo(il, method); // method defined on proxy + il.Emit(OpCodes.Ldloc, arguments); // args + il.Emit(OpCodes.Ldloc, interceptors); // interceptors + + // call Invoke + il.EmitCall(OpCodes.Call, References.InvokeMethod, null); + + // process return value + if (methodReturnsValue) + { + EmitUnboxIfNeeded(il, method.ReturnType); + il.Emit(OpCodes.Stloc, returnValue); + } + else + { + il.Emit(OpCodes.Pop); + } + + // process byRef arguments + for (int i = 0; i < parameters.Length; i++) + { + if (parameters[i].ParameterType.IsByRef) + { + il.Emit(OpCodes.Ldarg_S, i + 1); + il.Emit(OpCodes.Ldloc, arguments); + il.Emit(OpCodes.Ldc_I4_S, i); + il.Emit(OpCodes.Ldelem_Ref); + Type type = parameters[i].ParameterType.GetElementType(); + EmitUnboxIfNeeded(il, type); + EmitStoreValueIndirect(il, type); + } + } + } + + /// + /// Setup proxied method arguments. + /// + /// The IL generator to use. + /// The method to proxy. + /// The method's parameters. + protected void SetupMethodArguments( + ILGenerator il, MethodInfo method, ParameterInfo[] parameters) + { + if (parameters.Length > 0) + { + // specify array size and create an array + il.Emit(OpCodes.Ldc_I4, parameters.Length); + il.Emit(OpCodes.Newarr, typeof(Object)); + il.Emit(OpCodes.Stloc, arguments); + + // populate array with params + for (int i = 0; i < parameters.Length; i++) + { + Type type = parameters[i].ParameterType; + + il.Emit(OpCodes.Ldloc, arguments); + il.Emit(OpCodes.Ldc_I4, i); + il.Emit(OpCodes.Ldarg_S, i + 1); + + // setup byRef arguments + if (type.IsByRef) + { + type = type.GetElementType(); + EmitLoadValueIndirect(il, type); + } + +#if NET_2_0 + if (type.IsValueType || type.IsGenericParameter) +#else + if (type.IsValueType) +#endif + { + il.Emit(OpCodes.Box, type); + } + + il.Emit(OpCodes.Stelem_Ref); + } + } + else + { + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stloc, arguments); + } + } + + /// + /// Calls proxied method directly. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected abstract void CallDirectProxiedMethod( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod); + + /// + /// Ends method by returning return value if appropriate. + /// + /// The IL generator to use. + /// The method to proxy. + protected virtual void EndMethod(ILGenerator il, MethodInfo method) + { + Label jmpProxyNotExposed = il.DefineLabel(); + + // reset current proxy to old value + PushAdvisedProxy(il); + il.Emit(OpCodes.Ldfld, References.AdvisedField); + il.EmitCall(OpCodes.Callvirt, References.ExposeProxyProperty, null); + il.Emit(OpCodes.Brfalse_S, jmpProxyNotExposed); + il.EmitCall(OpCodes.Call, References.PopProxyMethod, null); + + il.MarkLabel(jmpProxyNotExposed); + + if (methodReturnsValue) + { + il.Emit(OpCodes.Ldloc, returnValue); + } + } + + #endregion + + #region Reflection.Emit utility methods + + /// + /// Emits MSIL instructions to load a value of the specified + /// onto the evaluation stack indirectly. + /// + /// The IL generator to use. + /// The type of the value. + protected static void EmitLoadValueIndirect(ILGenerator il, Type type) + { + if (type.IsValueType) + { + if (type == typeof(int)) il.Emit(OpCodes.Ldind_I4); + else if (type == typeof(uint)) il.Emit(OpCodes.Ldind_U4); + else if (type == typeof(char)) il.Emit(OpCodes.Ldind_I2); + else if (type == typeof(bool)) il.Emit(OpCodes.Ldind_I1); + else if (type == typeof(float)) il.Emit(OpCodes.Ldind_R4); + else if (type == typeof(double)) il.Emit(OpCodes.Ldind_R8); + else if (type == typeof(short)) il.Emit(OpCodes.Ldind_I2); + else if (type == typeof(ushort)) il.Emit(OpCodes.Ldind_U2); + else if (type == typeof(long) || type == typeof(ulong)) il.Emit(OpCodes.Ldind_I8); + else il.Emit(OpCodes.Ldobj, type); + } + else + { + il.Emit(OpCodes.Ldind_Ref); + } + } + + /// + /// Emit MSIL instructions to store a value of the specified + /// at a supplied address. + /// + /// The IL generator to use. + /// The type of the value. + protected static void EmitStoreValueIndirect(ILGenerator il, Type type) + { + if (type.IsValueType) + { + if (type.IsEnum) EmitStoreValueIndirect(il, Enum.GetUnderlyingType(type)); + else if (type == typeof(int)) il.Emit(OpCodes.Stind_I4); + else if (type == typeof(short)) il.Emit(OpCodes.Stind_I2); + else if (type == typeof(long) || type == typeof(ulong)) il.Emit(OpCodes.Stind_I8); + else if (type == typeof(char)) il.Emit(OpCodes.Stind_I2); + else if (type == typeof(bool)) il.Emit(OpCodes.Stind_I1); + else if (type == typeof(float)) il.Emit(OpCodes.Stind_R4); + else if (type == typeof(double)) il.Emit(OpCodes.Stind_R8); + else il.Emit(OpCodes.Stobj, type); + } + else + { + il.Emit(OpCodes.Stind_Ref); + } + } + + /// + /// Emits MSIL instructions to convert the boxed representation + /// of the supplied to its unboxed form. + /// + /// The IL generator to use. + /// The type specified in the instruction. + protected static void EmitUnboxIfNeeded(ILGenerator il, Type type) + { +#if NET_2_0 + if (type.IsValueType || type.IsGenericParameter) + { + il.Emit(OpCodes.Unbox_Any, type); + } +#else + if (type.IsValueType) + { + il.Emit(OpCodes.Unbox, type); + il.Emit(OpCodes.Ldobj, type); + } +#endif + } + + #endregion + } + + #region References helper class definition + + internal struct References + { + // fields + public static readonly FieldInfo AdvisedField = + typeof(AdvisedProxy).GetField("m_advised", BindingFlags.Instance | BindingFlags.Public); + + public static readonly FieldInfo TargetTypeField = + typeof(AdvisedProxy).GetField("m_targetType", BindingFlags.Instance | BindingFlags.Public); + + public static readonly FieldInfo IntroductionsField = + typeof(AdvisedProxy).GetField("m_introductions", BindingFlags.Instance | BindingFlags.Public); + + public static readonly FieldInfo TargetSourceWrapperField = + typeof(AdvisedProxy).GetField("m_targetSourceWrapper", BindingFlags.Instance | BindingFlags.Public); + + // constructors + public static readonly ConstructorInfo BaseCompositionAopProxyConstructor = + typeof(BaseCompositionAopProxy).GetConstructor(new Type[] { typeof(IAdvised) }); + + public static readonly ConstructorInfo BaseCompositionAopProxySerializationConstructor = + typeof(BaseCompositionAopProxy).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, + new Type[] {typeof(SerializationInfo), typeof(StreamingContext)}, + null); + + public static readonly ConstructorInfo AdvisedProxyConstructor = + typeof(AdvisedProxy).GetConstructor(new Type[] { typeof(IAdvised), typeof(IAopProxy) }); + + public static readonly ConstructorInfo AdvisedProxySerializationConstructor = + typeof(AdvisedProxy).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, + new Type[] {typeof (SerializationInfo), typeof (StreamingContext)}, + null); + public static readonly ConstructorInfo ObjectConstructor = + typeof(Object).GetConstructor(Type.EmptyTypes); + + // methods + public static readonly MethodInfo PushProxyMethod = + typeof(AopContext).GetMethod("PushProxy", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(Object) }, null); + + public static readonly MethodInfo PopProxyMethod = + typeof(AopContext).GetMethod("PopProxy", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null); + + public static readonly MethodInfo InvokeMethod = + typeof(AdvisedProxy).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(Object), typeof(Object), typeof(Type), typeof(MethodInfo), typeof(MethodInfo), typeof(Object[]), typeof(IList) }, null); + + public static readonly MethodInfo GetInterceptorsMethod = + typeof(AdvisedProxy).GetMethod("GetInterceptors", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(Type), typeof(MethodInfo) }, null); + + public static readonly MethodInfo GetTargetMethod = + typeof(ITargetSourceWrapper).GetMethod("GetTarget", Type.EmptyTypes); + + public static readonly MethodInfo GetTypeMethod = + typeof(Object).GetMethod("GetType", Type.EmptyTypes); + + public static readonly MethodInfo GetTypeFromHandle = + typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }); + +#if NET_2_0 + public static readonly MethodInfo MakeGenericMethod = + typeof(MethodInfo).GetMethod("MakeGenericMethod", new Type[] { typeof(Type[]) }); +#endif + + public static readonly MethodInfo DisposeMethod = + typeof(IDisposable).GetMethod("Dispose", Type.EmptyTypes); + + public static readonly MethodInfo AddSerializationValue = + typeof(SerializationInfo).GetMethod("AddValue", new Type[] { typeof(string), typeof(object) }); + + public static readonly MethodInfo GetSerializationValue = + typeof(SerializationInfo).GetMethod("GetValue", new Type[] { typeof(string), typeof(Type) }); + + // properties + public static readonly MethodInfo ExposeProxyProperty = + typeof(IAdvised).GetProperty("ExposeProxy", typeof(Boolean)).GetGetMethod(); + + public static readonly MethodInfo CountProperty = + typeof(ICollection).GetProperty("Count", typeof(Int32)).GetGetMethod(); + } + + #endregion +} diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyTypeBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyTypeBuilder.cs index 785afe97..a8125901 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyTypeBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AbstractAopProxyTypeBuilder.cs @@ -1,106 +1,105 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection.Emit; - -using Spring.Proxy; - - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Base class for proxy builders that can be used - /// to create an AOP proxy for any object. - /// - /// Bruno Baia - /// $Id: AbstractAopProxyTypeBuilder.cs,v 1.5 2007/12/03 09:06:58 bbaia Exp $ - public abstract class AbstractAopProxyTypeBuilder : - AbstractProxyTypeBuilder, IAopProxyTypeGenerator - { - #region IProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the target instance on which calls should be delegated to. - /// - /// The IL generator to use. - public override void PushTarget(ILGenerator il) - { - PushAdvisedProxy(il); - il.Emit(OpCodes.Ldfld, References.TargetSourceWrapperField); - il.EmitCall(OpCodes.Callvirt, References.GetTargetMethod, null); - } - - #endregion - - #region IAopProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the current - /// instance on stack. - /// - /// The IL generator to use. - public abstract void PushAdvisedProxy(ILGenerator il); - - #endregion - - #region Protected Methods - - /// - /// Calculates and returns the list of attributes that apply to the - /// specified type. - /// - /// - /// Removes from the list. - /// - /// The type to find attributes for. - /// - /// A list of custom attributes that should be applied to type. - /// - protected override IList GetTypeAttributes(Type type) - { - IList attrs = base.GetTypeAttributes(type); - int i = 0; - while (i < attrs.Count) - { - if (IsAttributeMatchingType(attrs[i], typeof(SerializableAttribute))) - { - attrs.RemoveAt(i); - } - else - { - i++; - } - } - - return attrs; - } - - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection.Emit; + +using Spring.Proxy; + + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Base class for proxy builders that can be used + /// to create an AOP proxy for any object. + /// + /// Bruno Baia + public abstract class AbstractAopProxyTypeBuilder : + AbstractProxyTypeBuilder, IAopProxyTypeGenerator + { + #region IProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the target instance on which calls should be delegated to. + /// + /// The IL generator to use. + public override void PushTarget(ILGenerator il) + { + PushAdvisedProxy(il); + il.Emit(OpCodes.Ldfld, References.TargetSourceWrapperField); + il.EmitCall(OpCodes.Callvirt, References.GetTargetMethod, null); + } + + #endregion + + #region IAopProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the current + /// instance on stack. + /// + /// The IL generator to use. + public abstract void PushAdvisedProxy(ILGenerator il); + + #endregion + + #region Protected Methods + + /// + /// Calculates and returns the list of attributes that apply to the + /// specified type. + /// + /// + /// Removes from the list. + /// + /// The type to find attributes for. + /// + /// A list of custom attributes that should be applied to type. + /// + protected override IList GetTypeAttributes(Type type) + { + IList attrs = base.GetTypeAttributes(type); + int i = 0; + while (i < attrs.Count) + { + if (IsAttributeMatchingType(attrs[i], typeof(SerializableAttribute))) + { + attrs.RemoveAt(i); + } + else + { + i++; + } + } + + return attrs; + } + + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs index af4d7e42..9ef9b3ea 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/AdvisedProxy.cs @@ -1,432 +1,431 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Reflection; -using System.Runtime.Serialization; -using System.Security.Permissions; - -using AopAlliance.Aop; -using AopAlliance.Intercept; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Represents the AOP configuration data built-in with the proxy. - /// - /// Bruno Baia - /// $Id: AdvisedProxy.cs,v 1.10 2008/02/06 18:28:52 bbaia Exp $ - [Serializable] - public class AdvisedProxy : IAdvised //, ISerializable - { - #region Fields - - /// - /// Should we use dynamic reflection for method invocation ? - /// - public static bool UseDynamicReflection; - - /// - /// Optimization fields - /// - private static IList EmptyList = ArrayList.ReadOnly(new ArrayList()); - - /// - /// IAdvised delegate - /// - public IAdvised m_advised; - - /// - /// Array of introduction delegates - /// - public IAdvice[] m_introductions; - - /// - /// Target source wrapper - /// - public ITargetSourceWrapper m_targetSourceWrapper; - - /// - /// Type of target object. - /// - public Type m_targetType; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the class. - /// - static AdvisedProxy() - { - string appSettingsKey = typeof(AdvisedProxy).FullName + ".UseDynamicReflection"; - NameValueCollection appSettings = - ConfigurationUtils.GetSection("appSettings") as NameValueCollection; - - if (appSettings != null && StringUtils.HasLength(appSettings[appSettingsKey])) - { - UseDynamicReflection = bool.Parse(appSettings[appSettingsKey]); - } - else - { - UseDynamicReflection = true; - } - } - - /// - /// Creates a new instance of the class. - /// - public AdvisedProxy() - {} - - /// - /// Creates a new instance of the class. - /// - /// The proxy configuration. - protected AdvisedProxy(IAdvised advised) - { - m_advised = advised; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The proxy configuration. - /// The proxy. - public AdvisedProxy(IAdvised advised, IAopProxy proxy) - { - Initialize(advised, proxy); - } - - /// - /// Deserialization constructor. - /// - /// Serialization data. - /// Serialization context. - protected AdvisedProxy(SerializationInfo info, StreamingContext context) - { - m_advised = (IAdvised) info.GetValue("advised", typeof(IAdvised)); - m_introductions = (IAdvice[]) info.GetValue("introductions", typeof(IAdvice[])); - m_targetSourceWrapper = (ITargetSourceWrapper) info.GetValue("tsWrapper", typeof(ITargetSourceWrapper)); - m_targetType = (Type) info.GetValue("targetType", typeof(Type)); - } - - /// - /// Serializes this instance. - /// - /// Serialization data. - /// Serialization context. - [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("advised", m_advised); - info.AddValue("introductions", m_introductions); - info.AddValue("tsWrapper", m_targetSourceWrapper); - info.AddValue("targetType", m_targetType); - } - - #endregion - - #region Protected Methods - - /// - /// Initialization method. - /// - /// The proxy configuration. - /// - /// The current implementation. - /// - protected void Initialize(IAdvised advised, IAopProxy proxy) - { - this.m_advised = advised; - this.m_targetType = advised.TargetSource.TargetType; - - // initialize target - if (advised.TargetSource.IsStatic) - { - this.m_targetSourceWrapper = new StaticTargetSourceWrapper(advised.TargetSource); - } - else - { - this.m_targetSourceWrapper = new DynamicTargetSourceWrapper(advised.TargetSource); - } - - // initialize introduction advice - this.m_introductions = new IAdvice[advised.Introductions.Length]; - for (int i = 0; i < advised.Introductions.Length; i++) - { - this.m_introductions[i] = advised.Introductions[i].Advice; - - // set target proxy on introduction instance if it implements ITargetAware - if (this.m_introductions[i] is ITargetAware) - { - ((ITargetAware) this.m_introductions[i]).TargetProxy = proxy; - } - } - } - - #endregion - - #region Public Methods - - /// - /// Invokes intercepted methods using reflection - /// - /// proxy object - /// target object to invoke method on - /// target type - /// taget method to invoke - /// The method to invoke on proxy. - /// method arguments - /// interceptor chain - /// value returned by invocation chain - public object Invoke(object proxy, object target, Type targetType, - MethodInfo targetMethod, MethodInfo proxyMethod, object[] args, IList interceptors) - { - IMethodInvocation invocation = null; - if (UseDynamicReflection) - { - invocation = new DynamicMethodInvocation( - proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); - } - else - { - invocation = new ReflectiveMethodInvocation( - proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); - } - return invocation.Proceed(); - } - - /// - /// Returns a list of method interceptors - /// - /// target type - /// target method - /// list of inteceptors for the specified method - public IList GetInterceptors(Type targetType, MethodInfo method) - { - if (m_advised.Advisors.Length == 0) - { - return EmptyList; - } - else - { - return m_advised.AdvisorChainFactory.GetInterceptors(m_advised, this, method, targetType); - } - } - - #endregion - - #region IAdvised Members - - bool IAdvised.ExposeProxy - { - get { return m_advised.ExposeProxy; } - } - - IAdvisorChainFactory IAdvised.AdvisorChainFactory - { - get { return m_advised.AdvisorChainFactory; } - } - - bool IAdvised.ProxyTargetType - { - get { return m_advised.ProxyTargetType; } - } - - bool IAdvised.ProxyTargetAttributes - { - get { return m_advised.ProxyTargetAttributes; } - } - - IAdvisor[] IAdvised.Advisors - { - get { return m_advised.Advisors; } - } - - IIntroductionAdvisor[] IAdvised.Introductions - { - get { return m_advised.Introductions; } - } - - Type[] IAdvised.Interfaces - { - get { return m_advised.Interfaces; } - } - - IDictionary IAdvised.InterfaceMap - { - get { return m_advised.InterfaceMap; } - } - - bool IAdvised.IsFrozen - { - get { return m_advised.IsFrozen; } - } - - ITargetSource IAdvised.TargetSource - { - get { return m_advised.TargetSource; } - } - - bool IAdvised.IsSerializable - { - get { return m_advised.IsSerializable; } - } - - /// - /// Adds the supplied to the end (or tail) - /// of the advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// - public void AddAdvice(IAdvice advice) - { - this.m_advised.AddAdvice(advice); - } - - /// - /// Adds the supplied to the supplied - /// in the advice (interceptor) chain. - /// - /// - /// The zero (0) indexed position (from the head) at which the - /// supplied is to be inserted into the - /// advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// - public void AddAdvice(int position, IAdvice advice) - { - this.m_advised.AddAdvice(position, advice); - } - - bool IAdvised.IsInterfaceProxied(Type intf) - { - return m_advised.IsInterfaceProxied(intf); - } - - void IAdvised.AddAdvisors(IAdvisors advisors) - { - m_advised.AddAdvisors(advisors); - } - - void IAdvised.AddAdvisor(IAdvisor advisor) - { - m_advised.AddAdvisor(advisor); - } - - void IAdvised.AddAdvisor(int pos, IAdvisor advisor) - { - m_advised.AddAdvisor(pos, advisor); - } - - void IAdvised.AddIntroduction(IIntroductionAdvisor advisor) - { - m_advised.AddIntroduction(advisor); - } - - void IAdvised.AddIntroduction(int pos, IIntroductionAdvisor advisor) - { - m_advised.AddIntroduction(pos, advisor); - } - - int IAdvised.IndexOf(IAdvisor advisor) - { - return m_advised.IndexOf(advisor); - } - - int IAdvised.IndexOf(IIntroductionAdvisor advisor) - { - return m_advised.IndexOf(advisor); - } - - bool IAdvised.RemoveAdvisor(IAdvisor advisor) - { - return m_advised.RemoveAdvisor(advisor); - } - - void IAdvised.RemoveAdvisor(int index) - { - m_advised.RemoveAdvisor(index); - } - - bool IAdvised.RemoveAdvice(IAdvice advice) - { - return m_advised.RemoveAdvice(advice); - } - - bool IAdvised.RemoveIntroduction(IIntroductionAdvisor advisor) - { - return m_advised.RemoveIntroduction(advisor); - } - - void IAdvised.RemoveIntroduction(int index) - { - m_advised.RemoveIntroduction(index); - } - - void IAdvised.ReplaceIntroduction(int index, IIntroductionAdvisor advisor) - { - m_advised.ReplaceIntroduction(index, advisor); - } - - bool IAdvised.ReplaceAdvisor(IAdvisor a, IAdvisor b) - { - return m_advised.ReplaceAdvisor(a, b); - } - - string IAdvised.ToProxyConfigString() - { - return m_advised.ToProxyConfigString(); - } - - #endregion - - #region ITargetTypeAware implementation - - /// - /// Gets the target type behind the implementing object. - /// Ttypically a proxy configuration or an actual proxy. - /// - /// The type of the target or null if not known. - public Type TargetType - { - get { return m_targetType; } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Reflection; +using System.Runtime.Serialization; +using System.Security.Permissions; + +using AopAlliance.Aop; +using AopAlliance.Intercept; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Represents the AOP configuration data built-in with the proxy. + /// + /// Bruno Baia + [Serializable] + public class AdvisedProxy : IAdvised //, ISerializable + { + #region Fields + + /// + /// Should we use dynamic reflection for method invocation ? + /// + public static bool UseDynamicReflection; + + /// + /// Optimization fields + /// + private static IList EmptyList = ArrayList.ReadOnly(new ArrayList()); + + /// + /// IAdvised delegate + /// + public IAdvised m_advised; + + /// + /// Array of introduction delegates + /// + public IAdvice[] m_introductions; + + /// + /// Target source wrapper + /// + public ITargetSourceWrapper m_targetSourceWrapper; + + /// + /// Type of target object. + /// + public Type m_targetType; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the class. + /// + static AdvisedProxy() + { + string appSettingsKey = typeof(AdvisedProxy).FullName + ".UseDynamicReflection"; + NameValueCollection appSettings = + ConfigurationUtils.GetSection("appSettings") as NameValueCollection; + + if (appSettings != null && StringUtils.HasLength(appSettings[appSettingsKey])) + { + UseDynamicReflection = bool.Parse(appSettings[appSettingsKey]); + } + else + { + UseDynamicReflection = true; + } + } + + /// + /// Creates a new instance of the class. + /// + public AdvisedProxy() + {} + + /// + /// Creates a new instance of the class. + /// + /// The proxy configuration. + protected AdvisedProxy(IAdvised advised) + { + m_advised = advised; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The proxy configuration. + /// The proxy. + public AdvisedProxy(IAdvised advised, IAopProxy proxy) + { + Initialize(advised, proxy); + } + + /// + /// Deserialization constructor. + /// + /// Serialization data. + /// Serialization context. + protected AdvisedProxy(SerializationInfo info, StreamingContext context) + { + m_advised = (IAdvised) info.GetValue("advised", typeof(IAdvised)); + m_introductions = (IAdvice[]) info.GetValue("introductions", typeof(IAdvice[])); + m_targetSourceWrapper = (ITargetSourceWrapper) info.GetValue("tsWrapper", typeof(ITargetSourceWrapper)); + m_targetType = (Type) info.GetValue("targetType", typeof(Type)); + } + + /// + /// Serializes this instance. + /// + /// Serialization data. + /// Serialization context. + [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("advised", m_advised); + info.AddValue("introductions", m_introductions); + info.AddValue("tsWrapper", m_targetSourceWrapper); + info.AddValue("targetType", m_targetType); + } + + #endregion + + #region Protected Methods + + /// + /// Initialization method. + /// + /// The proxy configuration. + /// + /// The current implementation. + /// + protected void Initialize(IAdvised advised, IAopProxy proxy) + { + this.m_advised = advised; + this.m_targetType = advised.TargetSource.TargetType; + + // initialize target + if (advised.TargetSource.IsStatic) + { + this.m_targetSourceWrapper = new StaticTargetSourceWrapper(advised.TargetSource); + } + else + { + this.m_targetSourceWrapper = new DynamicTargetSourceWrapper(advised.TargetSource); + } + + // initialize introduction advice + this.m_introductions = new IAdvice[advised.Introductions.Length]; + for (int i = 0; i < advised.Introductions.Length; i++) + { + this.m_introductions[i] = advised.Introductions[i].Advice; + + // set target proxy on introduction instance if it implements ITargetAware + if (this.m_introductions[i] is ITargetAware) + { + ((ITargetAware) this.m_introductions[i]).TargetProxy = proxy; + } + } + } + + #endregion + + #region Public Methods + + /// + /// Invokes intercepted methods using reflection + /// + /// proxy object + /// target object to invoke method on + /// target type + /// taget method to invoke + /// The method to invoke on proxy. + /// method arguments + /// interceptor chain + /// value returned by invocation chain + public object Invoke(object proxy, object target, Type targetType, + MethodInfo targetMethod, MethodInfo proxyMethod, object[] args, IList interceptors) + { + IMethodInvocation invocation = null; + if (UseDynamicReflection) + { + invocation = new DynamicMethodInvocation( + proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); + } + else + { + invocation = new ReflectiveMethodInvocation( + proxy, target, targetMethod, proxyMethod, args, targetType, interceptors); + } + return invocation.Proceed(); + } + + /// + /// Returns a list of method interceptors + /// + /// target type + /// target method + /// list of inteceptors for the specified method + public IList GetInterceptors(Type targetType, MethodInfo method) + { + if (m_advised.Advisors.Length == 0) + { + return EmptyList; + } + else + { + return m_advised.AdvisorChainFactory.GetInterceptors(m_advised, this, method, targetType); + } + } + + #endregion + + #region IAdvised Members + + bool IAdvised.ExposeProxy + { + get { return m_advised.ExposeProxy; } + } + + IAdvisorChainFactory IAdvised.AdvisorChainFactory + { + get { return m_advised.AdvisorChainFactory; } + } + + bool IAdvised.ProxyTargetType + { + get { return m_advised.ProxyTargetType; } + } + + bool IAdvised.ProxyTargetAttributes + { + get { return m_advised.ProxyTargetAttributes; } + } + + IAdvisor[] IAdvised.Advisors + { + get { return m_advised.Advisors; } + } + + IIntroductionAdvisor[] IAdvised.Introductions + { + get { return m_advised.Introductions; } + } + + Type[] IAdvised.Interfaces + { + get { return m_advised.Interfaces; } + } + + IDictionary IAdvised.InterfaceMap + { + get { return m_advised.InterfaceMap; } + } + + bool IAdvised.IsFrozen + { + get { return m_advised.IsFrozen; } + } + + ITargetSource IAdvised.TargetSource + { + get { return m_advised.TargetSource; } + } + + bool IAdvised.IsSerializable + { + get { return m_advised.IsSerializable; } + } + + /// + /// Adds the supplied to the end (or tail) + /// of the advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// + public void AddAdvice(IAdvice advice) + { + this.m_advised.AddAdvice(advice); + } + + /// + /// Adds the supplied to the supplied + /// in the advice (interceptor) chain. + /// + /// + /// The zero (0) indexed position (from the head) at which the + /// supplied is to be inserted into the + /// advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// + public void AddAdvice(int position, IAdvice advice) + { + this.m_advised.AddAdvice(position, advice); + } + + bool IAdvised.IsInterfaceProxied(Type intf) + { + return m_advised.IsInterfaceProxied(intf); + } + + void IAdvised.AddAdvisors(IAdvisors advisors) + { + m_advised.AddAdvisors(advisors); + } + + void IAdvised.AddAdvisor(IAdvisor advisor) + { + m_advised.AddAdvisor(advisor); + } + + void IAdvised.AddAdvisor(int pos, IAdvisor advisor) + { + m_advised.AddAdvisor(pos, advisor); + } + + void IAdvised.AddIntroduction(IIntroductionAdvisor advisor) + { + m_advised.AddIntroduction(advisor); + } + + void IAdvised.AddIntroduction(int pos, IIntroductionAdvisor advisor) + { + m_advised.AddIntroduction(pos, advisor); + } + + int IAdvised.IndexOf(IAdvisor advisor) + { + return m_advised.IndexOf(advisor); + } + + int IAdvised.IndexOf(IIntroductionAdvisor advisor) + { + return m_advised.IndexOf(advisor); + } + + bool IAdvised.RemoveAdvisor(IAdvisor advisor) + { + return m_advised.RemoveAdvisor(advisor); + } + + void IAdvised.RemoveAdvisor(int index) + { + m_advised.RemoveAdvisor(index); + } + + bool IAdvised.RemoveAdvice(IAdvice advice) + { + return m_advised.RemoveAdvice(advice); + } + + bool IAdvised.RemoveIntroduction(IIntroductionAdvisor advisor) + { + return m_advised.RemoveIntroduction(advisor); + } + + void IAdvised.RemoveIntroduction(int index) + { + m_advised.RemoveIntroduction(index); + } + + void IAdvised.ReplaceIntroduction(int index, IIntroductionAdvisor advisor) + { + m_advised.ReplaceIntroduction(index, advisor); + } + + bool IAdvised.ReplaceAdvisor(IAdvisor a, IAdvisor b) + { + return m_advised.ReplaceAdvisor(a, b); + } + + string IAdvised.ToProxyConfigString() + { + return m_advised.ToProxyConfigString(); + } + + #endregion + + #region ITargetTypeAware implementation + + /// + /// Gets the target type behind the implementing object. + /// Ttypically a proxy configuration or an actual proxy. + /// + /// The type of the target or null if not known. + public Type TargetType + { + get { return m_targetType; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseAopProxyMethodBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseAopProxyMethodBuilder.cs index 99234cfa..876af5c3 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseAopProxyMethodBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseAopProxyMethodBuilder.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// implementation - /// that delegates method calls to the base method. - /// - /// Bruno Baia - /// $Id: BaseAopProxyMethodBuilder.cs,v 1.1 2008/02/06 18:28:52 bbaia Exp $ - public class BaseAopProxyMethodBuilder : AbstractAopProxyMethodBuilder - { - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - /// - /// The dictionary to cache the list of target - /// s. - /// - /// - /// The dictionary to cache the list of target - /// s defined on the proxy. - /// - public BaseAopProxyMethodBuilder( - TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, - IDictionary targetMethods, IDictionary onProxyTargetMethods) - : base(typeBuilder, aopProxyGenerator, false, targetMethods, onProxyTargetMethods) - { - } - - #endregion - - #region Protected Methods - - /// - /// Create static field that will cache target method when defined on the proxy. - /// - /// The IL generator to use. - /// The target method. - protected override void GenerateOnProxyTargetMethodCacheField( - ILGenerator il, MethodInfo method) - { - if (method.IsVirtual && !method.IsFinal) - { - // generate proxy method - MethodBuilder baseMethod = typeBuilder.DefineMethod("proxy_" + method.Name, - MethodAttributes.Public | MethodAttributes.HideBySig, - CallingConventions.Standard, - method.ReturnType, ReflectionUtils.GetParameterTypes(method)); - -#if NET_2_0 - DefineGenericParameters(baseMethod, method); -#endif - DefineParameters(baseMethod, method); - - ILGenerator localIL = baseMethod.GetILGenerator(); - - localIL.Emit(OpCodes.Ldarg_0); - // setup parameters for call - for (int i = 0; i < method.GetParameters().Length; i++) - { - localIL.Emit(OpCodes.Ldarg_S, i + 1); - } - localIL.EmitCall(OpCodes.Call, method, null); - localIL.Emit(OpCodes.Ret); - - // create static field that will cache proxy method - string methodId = GenerateMethodCacheFieldId(method); - onProxyTargetMethods.Add(methodId, method); - - onProxyTargetMethodCacheField = typeBuilder.DefineField( - methodId, typeof(MethodInfo), FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly); - -#if NET_2_0 - MakeGenericMethod(il, method, onProxyTargetMethodCacheField, genericOnProxyTargetMethod); -#endif - } - } - - /// - /// Calls target method directly. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected override void CallDirectProxiedMethod( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - CallDirectBaseMethod(il, method); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// implementation + /// that delegates method calls to the base method. + /// + /// Bruno Baia + public class BaseAopProxyMethodBuilder : AbstractAopProxyMethodBuilder + { + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + /// + /// The dictionary to cache the list of target + /// s. + /// + /// + /// The dictionary to cache the list of target + /// s defined on the proxy. + /// + public BaseAopProxyMethodBuilder( + TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, + IDictionary targetMethods, IDictionary onProxyTargetMethods) + : base(typeBuilder, aopProxyGenerator, false, targetMethods, onProxyTargetMethods) + { + } + + #endregion + + #region Protected Methods + + /// + /// Create static field that will cache target method when defined on the proxy. + /// + /// The IL generator to use. + /// The target method. + protected override void GenerateOnProxyTargetMethodCacheField( + ILGenerator il, MethodInfo method) + { + if (method.IsVirtual && !method.IsFinal) + { + // generate proxy method + MethodBuilder baseMethod = typeBuilder.DefineMethod("proxy_" + method.Name, + MethodAttributes.Public | MethodAttributes.HideBySig, + CallingConventions.Standard, + method.ReturnType, ReflectionUtils.GetParameterTypes(method)); + +#if NET_2_0 + DefineGenericParameters(baseMethod, method); +#endif + DefineParameters(baseMethod, method); + + ILGenerator localIL = baseMethod.GetILGenerator(); + + localIL.Emit(OpCodes.Ldarg_0); + // setup parameters for call + for (int i = 0; i < method.GetParameters().Length; i++) + { + localIL.Emit(OpCodes.Ldarg_S, i + 1); + } + localIL.EmitCall(OpCodes.Call, method, null); + localIL.Emit(OpCodes.Ret); + + // create static field that will cache proxy method + string methodId = GenerateMethodCacheFieldId(method); + onProxyTargetMethods.Add(methodId, method); + + onProxyTargetMethodCacheField = typeBuilder.DefineField( + methodId, typeof(MethodInfo), FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly); + +#if NET_2_0 + MakeGenericMethod(il, method, onProxyTargetMethodCacheField, genericOnProxyTargetMethod); +#endif + } + } + + /// + /// Calls target method directly. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected override void CallDirectProxiedMethod( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + CallDirectBaseMethod(il, method); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseCompositionAopProxy.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseCompositionAopProxy.cs index 5ebe7421..2ce944f0 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseCompositionAopProxy.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/BaseCompositionAopProxy.cs @@ -1,122 +1,121 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Base class that each dynamic composition proxy has to extend. - /// - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: BaseCompositionAopProxy.cs,v 1.2 2007/03/16 04:01:22 aseovic Exp $ - [Serializable] - public abstract class BaseCompositionAopProxy : AdvisedProxy, IAopProxy, ISerializable - { - #region Constructor (s) / Destructor - - /// - /// Default constructor. - /// - public BaseCompositionAopProxy() - {} - - /// - /// Creates a new instance of the - /// class. - /// - /// The proxy configuration. - public BaseCompositionAopProxy(IAdvised advised) : base(advised) - { - base.Initialize(advised, this); - } - - /// - /// Deserialization constructor. - /// - /// Serialization data. - /// Serialization context. - protected BaseCompositionAopProxy(SerializationInfo info, StreamingContext context) : base(info, context) - {} - - #endregion - - #region IAopProxy Members - - /// - /// Returns this proxy instance - /// - /// - object IAopProxy.GetProxy() - { - return this; - } - - #endregion - - #region Equal, HashCode and ToString overrides - - /// - /// Delegate to target object handling of equals method. - /// - /// The object to compare with the current target object - /// true if the specified Object is equal to the current target object; otherwise, false - public override bool Equals(object obj) - { - using (m_targetSourceWrapper) - { - return m_targetSourceWrapper.GetTarget().Equals(obj); - } - } - - /// - /// Delgate to the target object generation of the hash code. - /// - /// A hash code for the target object. - public override int GetHashCode() - { - using (m_targetSourceWrapper) - { - return m_targetSourceWrapper.GetTarget().GetHashCode(); - } - } - - /// - /// Returns a String the represents the target object. - /// - /// A String that represents the target object - public override string ToString() - { - using (m_targetSourceWrapper) - { - return m_targetSourceWrapper.GetTarget().ToString(); - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Base class that each dynamic composition proxy has to extend. + /// + /// Aleksandar Seovic + /// Bruno Baia + [Serializable] + public abstract class BaseCompositionAopProxy : AdvisedProxy, IAopProxy, ISerializable + { + #region Constructor (s) / Destructor + + /// + /// Default constructor. + /// + public BaseCompositionAopProxy() + {} + + /// + /// Creates a new instance of the + /// class. + /// + /// The proxy configuration. + public BaseCompositionAopProxy(IAdvised advised) : base(advised) + { + base.Initialize(advised, this); + } + + /// + /// Deserialization constructor. + /// + /// Serialization data. + /// Serialization context. + protected BaseCompositionAopProxy(SerializationInfo info, StreamingContext context) : base(info, context) + {} + + #endregion + + #region IAopProxy Members + + /// + /// Returns this proxy instance + /// + /// + object IAopProxy.GetProxy() + { + return this; + } + + #endregion + + #region Equal, HashCode and ToString overrides + + /// + /// Delegate to target object handling of equals method. + /// + /// The object to compare with the current target object + /// true if the specified Object is equal to the current target object; otherwise, false + public override bool Equals(object obj) + { + using (m_targetSourceWrapper) + { + return m_targetSourceWrapper.GetTarget().Equals(obj); + } + } + + /// + /// Delgate to the target object generation of the hash code. + /// + /// A hash code for the target object. + public override int GetHashCode() + { + using (m_targetSourceWrapper) + { + return m_targetSourceWrapper.GetTarget().GetHashCode(); + } + } + + /// + /// Returns a String the represents the target object. + /// + /// A String that represents the target object + public override string ToString() + { + using (m_targetSourceWrapper) + { + return m_targetSourceWrapper.GetTarget().ToString(); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs index aa5e6a86..0fc210f4 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CachedAopProxyFactory.cs @@ -1,184 +1,183 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text; -using System.Collections; - -using Common.Logging; -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Implementation of the - /// interface that caches the AOP proxy instance. - /// - /// - ///

- /// Caches against a key based on : - /// - the base type - /// - the target type - /// - the interfaces to proxy - ///

- ///
- /// Bruno Baia - /// Erich Eichinger - /// - /// - /// $Id: CachedAopProxyFactory.cs,v 1.1 2007/08/02 04:15:21 markpollack Exp $ - [Serializable] - public class CachedAopProxyFactory : DefaultAopProxyFactory - { - /// - /// The shared instance for this class. - /// - private static readonly ILog logger = LogManager.GetLogger(typeof(CachedAopProxyFactory)); - - private static Hashtable typeCache = new Hashtable(); - - /// - /// Generates the proxy type and caches the - /// instance against the base type and the interfaces to proxy. - /// - /// - /// The to use - /// - /// The generated or cached proxy class. - protected override Type BuildProxyType(IProxyTypeBuilder typeBuilder) - { - ProxyTypeCacheKey cacheKey = new ProxyTypeCacheKey( - typeBuilder.BaseType, typeBuilder.TargetType, typeBuilder.Interfaces); - Type proxyType = null; - lock (typeCache) - { - proxyType = typeCache[cacheKey] as Type; - if (proxyType == null) - { - proxyType = typeBuilder.BuildProxyType(); - typeCache[cacheKey] = proxyType; - } - else - { - #region Instrumentation - - if (logger.IsInfoEnabled) - { - logger.Info(String.Format( - "AOP proxy type found in cache for '{0}'.", cacheKey)); - } - - #endregion - } - } - return proxyType; - } - - #region ProxyTypeCacheKey inner class implementation - - /// - /// Uniquely identifies a proxytype in the cache - /// - private sealed class ProxyTypeCacheKey - { - private sealed class HashCodeComparer : IComparer - { - public int Compare(object x, object y) - { - return x.GetHashCode().CompareTo(y.GetHashCode()); - } - } - - private static IComparer interfaceComparer = new HashCodeComparer(); - - private Type baseType; - private Type targetType; - private Type[] interfaceTypes; - - public ProxyTypeCacheKey(Type baseType, Type targetType, Type[] interfaceTypes) - { - this.baseType = baseType; - this.targetType = targetType; - Array.Sort(interfaceTypes, interfaceComparer); // sort by GetHashcode()? to have a defined order - this.interfaceTypes = interfaceTypes; - } - - public override bool Equals(object obj) - { - if (this == obj) - { - return true; - } - ProxyTypeCacheKey proxyTypeCacheKey = obj as ProxyTypeCacheKey; - if (proxyTypeCacheKey == null) - { - return false; - } - if (!Equals(targetType, proxyTypeCacheKey.targetType)) - { - return false; - } - if (!Equals(baseType, proxyTypeCacheKey.baseType)) - { - return false; - } - for (int i = 0; i < interfaceTypes.Length; i++) - { - if (!Equals(interfaceTypes[i], proxyTypeCacheKey.interfaceTypes[i])) - { - return false; - } - } - return true; - } - - public override int GetHashCode() - { - int result = baseType.GetHashCode(); - result = 29*result + targetType.GetHashCode(); - for (int i = 0; i < interfaceTypes.Length; i++) - { - result = 29 * result + interfaceTypes[i].GetHashCode(); - } - return result; - } - - public override string ToString() - { - StringBuilder buffer = new StringBuilder(); - buffer.Append("baseType=" + baseType + "; "); - buffer.Append("targetType=" + targetType + "; "); - buffer.Append("interfaceTypes=["); - foreach (Type intf in interfaceTypes) - { - buffer.Append(intf + ";"); - } - buffer.Append("]; "); - return buffer.ToString(); - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text; +using System.Collections; + +using Common.Logging; +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Implementation of the + /// interface that caches the AOP proxy instance. + /// + /// + ///

+ /// Caches against a key based on : + /// - the base type + /// - the target type + /// - the interfaces to proxy + ///

+ ///
+ /// Bruno Baia + /// Erich Eichinger + /// + /// + [Serializable] + public class CachedAopProxyFactory : DefaultAopProxyFactory + { + /// + /// The shared instance for this class. + /// + private static readonly ILog logger = LogManager.GetLogger(typeof(CachedAopProxyFactory)); + + private static Hashtable typeCache = new Hashtable(); + + /// + /// Generates the proxy type and caches the + /// instance against the base type and the interfaces to proxy. + /// + /// + /// The to use + /// + /// The generated or cached proxy class. + protected override Type BuildProxyType(IProxyTypeBuilder typeBuilder) + { + ProxyTypeCacheKey cacheKey = new ProxyTypeCacheKey( + typeBuilder.BaseType, typeBuilder.TargetType, typeBuilder.Interfaces); + Type proxyType = null; + lock (typeCache) + { + proxyType = typeCache[cacheKey] as Type; + if (proxyType == null) + { + proxyType = typeBuilder.BuildProxyType(); + typeCache[cacheKey] = proxyType; + } + else + { + #region Instrumentation + + if (logger.IsInfoEnabled) + { + logger.Info(String.Format( + "AOP proxy type found in cache for '{0}'.", cacheKey)); + } + + #endregion + } + } + return proxyType; + } + + #region ProxyTypeCacheKey inner class implementation + + /// + /// Uniquely identifies a proxytype in the cache + /// + private sealed class ProxyTypeCacheKey + { + private sealed class HashCodeComparer : IComparer + { + public int Compare(object x, object y) + { + return x.GetHashCode().CompareTo(y.GetHashCode()); + } + } + + private static IComparer interfaceComparer = new HashCodeComparer(); + + private Type baseType; + private Type targetType; + private Type[] interfaceTypes; + + public ProxyTypeCacheKey(Type baseType, Type targetType, Type[] interfaceTypes) + { + this.baseType = baseType; + this.targetType = targetType; + Array.Sort(interfaceTypes, interfaceComparer); // sort by GetHashcode()? to have a defined order + this.interfaceTypes = interfaceTypes; + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + ProxyTypeCacheKey proxyTypeCacheKey = obj as ProxyTypeCacheKey; + if (proxyTypeCacheKey == null) + { + return false; + } + if (!Equals(targetType, proxyTypeCacheKey.targetType)) + { + return false; + } + if (!Equals(baseType, proxyTypeCacheKey.baseType)) + { + return false; + } + for (int i = 0; i < interfaceTypes.Length; i++) + { + if (!Equals(interfaceTypes[i], proxyTypeCacheKey.interfaceTypes[i])) + { + return false; + } + } + return true; + } + + public override int GetHashCode() + { + int result = baseType.GetHashCode(); + result = 29*result + targetType.GetHashCode(); + for (int i = 0; i < interfaceTypes.Length; i++) + { + result = 29 * result + interfaceTypes[i].GetHashCode(); + } + return result; + } + + public override string ToString() + { + StringBuilder buffer = new StringBuilder(); + buffer.Append("baseType=" + baseType + "; "); + buffer.Append("targetType=" + targetType + "; "); + buffer.Append("interfaceTypes=["); + foreach (Type intf in interfaceTypes) + { + buffer.Append(intf + ";"); + } + buffer.Append("]; "); + return buffer.ToString(); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CompositionAopProxyTypeBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CompositionAopProxyTypeBuilder.cs index 2f2256f8..90de5483 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CompositionAopProxyTypeBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/CompositionAopProxyTypeBuilder.cs @@ -1,213 +1,212 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.Serialization; - -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Builds an AOP proxy type using composition. - /// - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: CompositionAopProxyTypeBuilder.cs,v 1.15 2007/12/07 17:58:56 bbaia Exp $ - public class CompositionAopProxyTypeBuilder : AbstractAopProxyTypeBuilder - { - #region Fields - - private const string PROXY_TYPE_NAME = "CompositionAopProxy"; - - private IAdvised advised; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// The proxy configuration. - public CompositionAopProxyTypeBuilder(IAdvised advised) - { - this.advised = advised; - - Name = PROXY_TYPE_NAME; - BaseType = typeof(BaseCompositionAopProxy); - TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType; - Interfaces = GetProxiableInterfaces(advised.Interfaces); - ProxyTargetAttributes = advised.ProxyTargetAttributes; - } - - #endregion - - #region IProxyTypeBuilder Members - - /// - /// Creates the proxy type. - /// - /// The generated proxy type. - public override Type BuildProxyType() - { - IDictionary targetMethods = new Hashtable(); - - TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); - - // apply custom attributes to the proxy type. - ApplyTypeAttributes(typeBuilder, TargetType); - - if (advised.IsSerializable) - { - typeBuilder.SetCustomAttribute( - ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute))); - ImplementSerializationConstructor(typeBuilder); - } - - // create constructors - ImplementConstructors(typeBuilder); - - // implement interfaces - IDictionary interfaceMap = advised.InterfaceMap; - foreach (Type intf in Interfaces) - { - object target = interfaceMap[intf]; - if (target == null) - { - // implement interface - ImplementInterface(typeBuilder, - new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods), - intf, TargetType); - } - else if (target is IIntroductionAdvisor) - { - // implement introduction - ImplementInterface(typeBuilder, - new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor) target)), - intf, TargetType); - } - } - - Type proxyType; - proxyType = typeBuilder.CreateType(); - - // set target method references - foreach (DictionaryEntry entry in targetMethods) - { - FieldInfo field = proxyType.GetField((string) entry.Key, BindingFlags.NonPublic | BindingFlags.Static); - field.SetValue(proxyType, (MethodInfo) entry.Value); - } - - return proxyType; - } - - #endregion - - #region IAopProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the current - /// instance on stack. - /// - /// The IL generator to use. - public override void PushAdvisedProxy(ILGenerator il) - { - il.Emit(OpCodes.Ldarg_0); - } - - #endregion - - #region Protected Methods - - /// - /// Implements serialization constructor. - /// - /// Type builder to use. - private void ImplementSerializationConstructor(TypeBuilder typeBuilder) - { - ConstructorBuilder cb = - typeBuilder.DefineConstructor(MethodAttributes.Family, - CallingConventions.Standard, - new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); - - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldarg_2); - il.Emit(OpCodes.Call, References.BaseCompositionAopProxySerializationConstructor); - il.Emit(OpCodes.Ret); - } - - /// - /// Implements constructors for the proxy class. - /// - /// - ///

- /// This implementation calls the base constructor. - ///

- ///
- /// - /// The builder to use. - /// - protected override void ImplementConstructors(TypeBuilder typeBuilder) - { - ConstructorBuilder cb = - typeBuilder.DefineConstructor(References.BaseCompositionAopProxyConstructor.Attributes, - References.BaseCompositionAopProxyConstructor.CallingConvention, - new Type[] { typeof(IAdvised) }); - - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Call, References.BaseCompositionAopProxyConstructor); - il.Emit(OpCodes.Ret); - } - - #endregion - - #region Public Methods - - /// - /// Determines if the specified - /// is one of those generated by this builder. - /// - /// The type to check. - /// - /// if the type is a composition-based proxy; - /// otherwise . - /// - public static bool IsCompositionProxy(Type type) - { - return type.FullName.StartsWith(PROXY_TYPE_NAME); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; + +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Builds an AOP proxy type using composition. + /// + /// Aleksandar Seovic + /// Bruno Baia + public class CompositionAopProxyTypeBuilder : AbstractAopProxyTypeBuilder + { + #region Fields + + private const string PROXY_TYPE_NAME = "CompositionAopProxy"; + + private IAdvised advised; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// The proxy configuration. + public CompositionAopProxyTypeBuilder(IAdvised advised) + { + this.advised = advised; + + Name = PROXY_TYPE_NAME; + BaseType = typeof(BaseCompositionAopProxy); + TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType; + Interfaces = GetProxiableInterfaces(advised.Interfaces); + ProxyTargetAttributes = advised.ProxyTargetAttributes; + } + + #endregion + + #region IProxyTypeBuilder Members + + /// + /// Creates the proxy type. + /// + /// The generated proxy type. + public override Type BuildProxyType() + { + IDictionary targetMethods = new Hashtable(); + + TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); + + // apply custom attributes to the proxy type. + ApplyTypeAttributes(typeBuilder, TargetType); + + if (advised.IsSerializable) + { + typeBuilder.SetCustomAttribute( + ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute))); + ImplementSerializationConstructor(typeBuilder); + } + + // create constructors + ImplementConstructors(typeBuilder); + + // implement interfaces + IDictionary interfaceMap = advised.InterfaceMap; + foreach (Type intf in Interfaces) + { + object target = interfaceMap[intf]; + if (target == null) + { + // implement interface + ImplementInterface(typeBuilder, + new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods), + intf, TargetType); + } + else if (target is IIntroductionAdvisor) + { + // implement introduction + ImplementInterface(typeBuilder, + new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor) target)), + intf, TargetType); + } + } + + Type proxyType; + proxyType = typeBuilder.CreateType(); + + // set target method references + foreach (DictionaryEntry entry in targetMethods) + { + FieldInfo field = proxyType.GetField((string) entry.Key, BindingFlags.NonPublic | BindingFlags.Static); + field.SetValue(proxyType, (MethodInfo) entry.Value); + } + + return proxyType; + } + + #endregion + + #region IAopProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the current + /// instance on stack. + /// + /// The IL generator to use. + public override void PushAdvisedProxy(ILGenerator il) + { + il.Emit(OpCodes.Ldarg_0); + } + + #endregion + + #region Protected Methods + + /// + /// Implements serialization constructor. + /// + /// Type builder to use. + private void ImplementSerializationConstructor(TypeBuilder typeBuilder) + { + ConstructorBuilder cb = + typeBuilder.DefineConstructor(MethodAttributes.Family, + CallingConventions.Standard, + new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); + + ILGenerator il = cb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Call, References.BaseCompositionAopProxySerializationConstructor); + il.Emit(OpCodes.Ret); + } + + /// + /// Implements constructors for the proxy class. + /// + /// + ///

+ /// This implementation calls the base constructor. + ///

+ ///
+ /// + /// The builder to use. + /// + protected override void ImplementConstructors(TypeBuilder typeBuilder) + { + ConstructorBuilder cb = + typeBuilder.DefineConstructor(References.BaseCompositionAopProxyConstructor.Attributes, + References.BaseCompositionAopProxyConstructor.CallingConvention, + new Type[] { typeof(IAdvised) }); + + ILGenerator il = cb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Call, References.BaseCompositionAopProxyConstructor); + il.Emit(OpCodes.Ret); + } + + #endregion + + #region Public Methods + + /// + /// Determines if the specified + /// is one of those generated by this builder. + /// + /// The type to check. + /// + /// if the type is a composition-based proxy; + /// otherwise . + /// + public static bool IsCompositionProxy(Type type) + { + return type.FullName.StartsWith(PROXY_TYPE_NAME); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DecoratorAopProxyTypeBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DecoratorAopProxyTypeBuilder.cs index 1f76c7f5..21084de1 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DecoratorAopProxyTypeBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DecoratorAopProxyTypeBuilder.cs @@ -1,317 +1,316 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.Serialization; - -using Spring.Util; -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Builds an AOP proxy type using the decorator pattern. - /// - /// Bruno Baia - /// $Id: DecoratorAopProxyTypeBuilder.cs,v 1.17 2007/12/07 17:58:56 bbaia Exp $ - public class DecoratorAopProxyTypeBuilder : AbstractAopProxyTypeBuilder - { - #region Fields - - private const string PROXY_TYPE_NAME = "DecoratorAopProxy"; - - private IAdvised advised; - - /// - /// AdvisedProxy instance calls should be delegated to. - /// - protected FieldBuilder advisedProxyField; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// The proxy configuration. - public DecoratorAopProxyTypeBuilder(IAdvised advised) - { - if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME)) - { - throw new AopConfigException(String.Format( - "Cannot create decorator-based IAopProxy for a non visible class [{0}]", - advised.TargetSource.TargetType.FullName)); - } - if (advised.TargetSource.TargetType.IsSealed) - { - throw new AopConfigException(String.Format( - "Cannot create decorator-based IAopProxy for a sealed class [{0}]", - advised.TargetSource.TargetType.FullName)); - } - this.advised = advised; - - Name = PROXY_TYPE_NAME; - TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType; - BaseType = TargetType; - Interfaces = GetProxiableInterfaces(advised.Interfaces); - ProxyTargetAttributes = advised.ProxyTargetAttributes; - } - - #endregion - - #region IProxyTypeBuilder Members - - /// - /// Creates the proxy type. - /// - /// The generated proxy class. - public override Type BuildProxyType() - { - IDictionary targetMethods = new Hashtable(); - - TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); - - // apply custom attributes to the proxy type. - ApplyTypeAttributes(typeBuilder, TargetType); - - // declare fields - DeclareAdvisedProxyInstanceField(typeBuilder); - - // implement ISerializable if possible - if (advised.IsSerializable) - { - typeBuilder.SetCustomAttribute( - ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute))); - ImplementSerializationConstructor(typeBuilder); - ImplementGetObjectDataMethod(typeBuilder); - } - - // create constructors - ImplementConstructors(typeBuilder); - - // implement interfaces - IDictionary interfaceMap = advised.InterfaceMap; - foreach (Type intf in Interfaces) - { - object target = interfaceMap[intf]; - if (target == null) - { - // implement interface (proxy only final methods) - ImplementInterface(typeBuilder, - new TargetAopProxyMethodBuilder(typeBuilder, this, true, targetMethods), - intf, TargetType, false); - } - else if (target is IIntroductionAdvisor) - { - // implement introduction - ImplementInterface(typeBuilder, - new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor)target)), - intf, TargetType); - } - } - - // inherit from target type - InheritType(typeBuilder, - new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods), - TargetType); - - // implement IAdvised interface - ImplementInterface(typeBuilder, - new IAdvisedProxyMethodBuilder(typeBuilder, this), - typeof(IAdvised), TargetType); - - // implement IAopProxy interface - ImplementIAopProxy(typeBuilder); - - Type proxyType; - proxyType = typeBuilder.CreateType(); - - // set target method references - foreach (DictionaryEntry entry in targetMethods) - { - FieldInfo field = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static); - field.SetValue(proxyType, (MethodInfo)entry.Value); - } - - return proxyType; - } - - #endregion - - #region IAopProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the current - /// instance on stack. - /// - /// The IL generator to use. - public override void PushAdvisedProxy(ILGenerator il) - { - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, advisedProxyField); - } - - #endregion - - #region Protected Methods - - /// - /// Declares field that holds the - /// instance used by the proxy. - /// - /// - /// The builder to use for code generation. - /// - protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder) - { - advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private); - } - - /// - /// Implements serialization method. - /// - /// - private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder) - { - typeBuilder.AddInterfaceImplementation(typeof(ISerializable)); - - MethodBuilder mb = - typeBuilder.DefineMethod("GetObjectData", - MethodAttributes.Public | MethodAttributes.HideBySig | - MethodAttributes.NewSlot | MethodAttributes.Virtual, - typeof (void), - new Type[] {typeof (SerializationInfo), typeof (StreamingContext)}); - - ILGenerator il = mb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldstr, "advisedProxy"); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, advisedProxyField); - il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null); - il.Emit(OpCodes.Ret); - - typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData")); - } - - - /// - /// Implements serialization constructor. - /// - /// Type builder to use. - private void ImplementSerializationConstructor(TypeBuilder typeBuilder) - { - ConstructorBuilder cb = - typeBuilder.DefineConstructor(MethodAttributes.Family, - CallingConventions.Standard, - new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); - - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldstr, "advisedProxy"); - il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy)); - il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null); - il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null); - il.Emit(OpCodes.Castclass, typeof(AdvisedProxy)); - il.Emit(OpCodes.Stfld, advisedProxyField); - il.Emit(OpCodes.Ret); - } - - /// - /// Implements constructors for the proxy class. - /// - /// - ///

- /// This implementation creates a new instance - /// of the class. - ///

- ///
- /// - /// The builder to use. - /// - protected override void ImplementConstructors(TypeBuilder typeBuilder) - { - ConstructorBuilder cb = - typeBuilder.DefineConstructor(References.ObjectConstructor.Attributes, - References.ObjectConstructor.CallingConvention, - new Type[] { typeof(IAdvised) }); - - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor); - il.Emit(OpCodes.Stfld, advisedProxyField); - il.Emit(OpCodes.Ret); - } - - /// - /// Implements interface. - /// - /// The type builder to use. - protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder) - { - Type intf = typeof(IAopProxy); - MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes); - - typeBuilder.AddInterfaceImplementation(intf); - - MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name, - MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, - getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes); - - ILGenerator il = mb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ret); - - typeBuilder.DefineMethodOverride(mb, getProxyMethod); - } - - #endregion - - #region Public Methods - - /// - /// Determines if the specified - /// is one of those generated by this builder. - /// - /// The type to check. - /// - /// if the type is a decorator-based proxy; - /// otherwise . - /// - public static bool IsDecoratorProxy(Type type) - { - return type.FullName.StartsWith(PROXY_TYPE_NAME); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; + +using Spring.Util; +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Builds an AOP proxy type using the decorator pattern. + /// + /// Bruno Baia + public class DecoratorAopProxyTypeBuilder : AbstractAopProxyTypeBuilder + { + #region Fields + + private const string PROXY_TYPE_NAME = "DecoratorAopProxy"; + + private IAdvised advised; + + /// + /// AdvisedProxy instance calls should be delegated to. + /// + protected FieldBuilder advisedProxyField; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// The proxy configuration. + public DecoratorAopProxyTypeBuilder(IAdvised advised) + { + if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME)) + { + throw new AopConfigException(String.Format( + "Cannot create decorator-based IAopProxy for a non visible class [{0}]", + advised.TargetSource.TargetType.FullName)); + } + if (advised.TargetSource.TargetType.IsSealed) + { + throw new AopConfigException(String.Format( + "Cannot create decorator-based IAopProxy for a sealed class [{0}]", + advised.TargetSource.TargetType.FullName)); + } + this.advised = advised; + + Name = PROXY_TYPE_NAME; + TargetType = advised.TargetSource.TargetType.IsInterface ? typeof(object) : advised.TargetSource.TargetType; + BaseType = TargetType; + Interfaces = GetProxiableInterfaces(advised.Interfaces); + ProxyTargetAttributes = advised.ProxyTargetAttributes; + } + + #endregion + + #region IProxyTypeBuilder Members + + /// + /// Creates the proxy type. + /// + /// The generated proxy class. + public override Type BuildProxyType() + { + IDictionary targetMethods = new Hashtable(); + + TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); + + // apply custom attributes to the proxy type. + ApplyTypeAttributes(typeBuilder, TargetType); + + // declare fields + DeclareAdvisedProxyInstanceField(typeBuilder); + + // implement ISerializable if possible + if (advised.IsSerializable) + { + typeBuilder.SetCustomAttribute( + ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute))); + ImplementSerializationConstructor(typeBuilder); + ImplementGetObjectDataMethod(typeBuilder); + } + + // create constructors + ImplementConstructors(typeBuilder); + + // implement interfaces + IDictionary interfaceMap = advised.InterfaceMap; + foreach (Type intf in Interfaces) + { + object target = interfaceMap[intf]; + if (target == null) + { + // implement interface (proxy only final methods) + ImplementInterface(typeBuilder, + new TargetAopProxyMethodBuilder(typeBuilder, this, true, targetMethods), + intf, TargetType, false); + } + else if (target is IIntroductionAdvisor) + { + // implement introduction + ImplementInterface(typeBuilder, + new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor)target)), + intf, TargetType); + } + } + + // inherit from target type + InheritType(typeBuilder, + new TargetAopProxyMethodBuilder(typeBuilder, this, false, targetMethods), + TargetType); + + // implement IAdvised interface + ImplementInterface(typeBuilder, + new IAdvisedProxyMethodBuilder(typeBuilder, this), + typeof(IAdvised), TargetType); + + // implement IAopProxy interface + ImplementIAopProxy(typeBuilder); + + Type proxyType; + proxyType = typeBuilder.CreateType(); + + // set target method references + foreach (DictionaryEntry entry in targetMethods) + { + FieldInfo field = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static); + field.SetValue(proxyType, (MethodInfo)entry.Value); + } + + return proxyType; + } + + #endregion + + #region IAopProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the current + /// instance on stack. + /// + /// The IL generator to use. + public override void PushAdvisedProxy(ILGenerator il) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, advisedProxyField); + } + + #endregion + + #region Protected Methods + + /// + /// Declares field that holds the + /// instance used by the proxy. + /// + /// + /// The builder to use for code generation. + /// + protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder) + { + advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private); + } + + /// + /// Implements serialization method. + /// + /// + private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder) + { + typeBuilder.AddInterfaceImplementation(typeof(ISerializable)); + + MethodBuilder mb = + typeBuilder.DefineMethod("GetObjectData", + MethodAttributes.Public | MethodAttributes.HideBySig | + MethodAttributes.NewSlot | MethodAttributes.Virtual, + typeof (void), + new Type[] {typeof (SerializationInfo), typeof (StreamingContext)}); + + ILGenerator il = mb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldstr, "advisedProxy"); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, advisedProxyField); + il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null); + il.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData")); + } + + + /// + /// Implements serialization constructor. + /// + /// Type builder to use. + private void ImplementSerializationConstructor(TypeBuilder typeBuilder) + { + ConstructorBuilder cb = + typeBuilder.DefineConstructor(MethodAttributes.Family, + CallingConventions.Standard, + new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); + + ILGenerator il = cb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldstr, "advisedProxy"); + il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy)); + il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null); + il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null); + il.Emit(OpCodes.Castclass, typeof(AdvisedProxy)); + il.Emit(OpCodes.Stfld, advisedProxyField); + il.Emit(OpCodes.Ret); + } + + /// + /// Implements constructors for the proxy class. + /// + /// + ///

+ /// This implementation creates a new instance + /// of the class. + ///

+ ///
+ /// + /// The builder to use. + /// + protected override void ImplementConstructors(TypeBuilder typeBuilder) + { + ConstructorBuilder cb = + typeBuilder.DefineConstructor(References.ObjectConstructor.Attributes, + References.ObjectConstructor.CallingConvention, + new Type[] { typeof(IAdvised) }); + + ILGenerator il = cb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor); + il.Emit(OpCodes.Stfld, advisedProxyField); + il.Emit(OpCodes.Ret); + } + + /// + /// Implements interface. + /// + /// The type builder to use. + protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder) + { + Type intf = typeof(IAopProxy); + MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes); + + typeBuilder.AddInterfaceImplementation(intf); + + MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name, + MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, + getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes); + + ILGenerator il = mb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(mb, getProxyMethod); + } + + #endregion + + #region Public Methods + + /// + /// Determines if the specified + /// is one of those generated by this builder. + /// + /// The type to check. + /// + /// if the type is a decorator-based proxy; + /// otherwise . + /// + public static bool IsDecoratorProxy(Type type) + { + return type.FullName.StartsWith(PROXY_TYPE_NAME); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DefaultAopProxyFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DefaultAopProxyFactory.cs index 8f509519..64aa17d9 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DefaultAopProxyFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/DefaultAopProxyFactory.cs @@ -1,110 +1,109 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Proxy; -using Spring.Aop.Target; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Default implementation of the - /// interface, - /// either creating a decorator-based dynamic proxy or - /// a composition-based dynamic proxy. - /// - /// - ///

- /// Creates a decorator-base proxy if one the following is true : - /// - the "ProxyTargetType" property is set - /// - no interfaces have been specified - ///

- ///

- /// In general, specify "ProxyTargetType" to enforce a decorator-based proxy, - /// or specify one or more interfaces to use a composition-based proxy. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// Bruno Baia (.NET) - /// - /// $Id: DefaultAopProxyFactory.cs,v 1.2 2007/08/02 16:28:29 bbaia Exp $ - [Serializable] - public class DefaultAopProxyFactory : IAopProxyFactory - { - - /// - /// Creates an for the - /// supplied configuration. - /// - /// The AOP configuration. - /// An . - /// - /// If the supplied configuration is - /// invalid. - /// - /// - public virtual IAopProxy CreateAopProxy(AdvisedSupport advisedSupport) - { - if (advisedSupport == null) - { - throw new AopConfigException("Cannot create IAopProxy with null ProxyConfig"); - } - if (advisedSupport.Advisors.Length == 0 && advisedSupport.TargetSource == EmptyTargetSource.Empty) - { - throw new AopConfigException("Cannot create IAopProxy with no advisors and no target source"); - } - if (advisedSupport.ProxyType == null) - { - IProxyTypeBuilder typeBuilder; - if ((advisedSupport.ProxyTargetType) || - (advisedSupport.Interfaces.Length == 0)) - { - typeBuilder = new DecoratorAopProxyTypeBuilder(advisedSupport); - } - else - { - typeBuilder = new CompositionAopProxyTypeBuilder(advisedSupport); - } - advisedSupport.ProxyType = BuildProxyType(typeBuilder); - advisedSupport.ProxyConstructor = advisedSupport.ProxyType.GetConstructor(new Type[] { typeof(IAdvised) }); - } - - return (IAopProxy)advisedSupport.ProxyConstructor.Invoke(new object[] { advisedSupport }); - } - - /// - /// Generates the proxy type. - /// - /// - /// The to use - /// - /// The generated proxy class. - protected virtual Type BuildProxyType(IProxyTypeBuilder typeBuilder) - { - return typeBuilder.BuildProxyType(); - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Proxy; +using Spring.Aop.Target; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Default implementation of the + /// interface, + /// either creating a decorator-based dynamic proxy or + /// a composition-based dynamic proxy. + /// + /// + ///

+ /// Creates a decorator-base proxy if one the following is true : + /// - the "ProxyTargetType" property is set + /// - no interfaces have been specified + ///

+ ///

+ /// In general, specify "ProxyTargetType" to enforce a decorator-based proxy, + /// or specify one or more interfaces to use a composition-based proxy. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// Bruno Baia (.NET) + /// + [Serializable] + public class DefaultAopProxyFactory : IAopProxyFactory + { + + /// + /// Creates an for the + /// supplied configuration. + /// + /// The AOP configuration. + /// An . + /// + /// If the supplied configuration is + /// invalid. + /// + /// + public virtual IAopProxy CreateAopProxy(AdvisedSupport advisedSupport) + { + if (advisedSupport == null) + { + throw new AopConfigException("Cannot create IAopProxy with null ProxyConfig"); + } + if (advisedSupport.Advisors.Length == 0 && advisedSupport.TargetSource == EmptyTargetSource.Empty) + { + throw new AopConfigException("Cannot create IAopProxy with no advisors and no target source"); + } + if (advisedSupport.ProxyType == null) + { + IProxyTypeBuilder typeBuilder; + if ((advisedSupport.ProxyTargetType) || + (advisedSupport.Interfaces.Length == 0)) + { + typeBuilder = new DecoratorAopProxyTypeBuilder(advisedSupport); + } + else + { + typeBuilder = new CompositionAopProxyTypeBuilder(advisedSupport); + } + advisedSupport.ProxyType = BuildProxyType(typeBuilder); + advisedSupport.ProxyConstructor = advisedSupport.ProxyType.GetConstructor(new Type[] { typeof(IAdvised) }); + } + + return (IAopProxy)advisedSupport.ProxyConstructor.Invoke(new object[] { advisedSupport }); + } + + /// + /// Generates the proxy type. + /// + /// + /// The to use + /// + /// The generated proxy class. + protected virtual Type BuildProxyType(IProxyTypeBuilder typeBuilder) + { + return typeBuilder.BuildProxyType(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAdvisedProxyMethodBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAdvisedProxyMethodBuilder.cs index 5c21830b..4c263b92 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAdvisedProxyMethodBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAdvisedProxyMethodBuilder.cs @@ -1,83 +1,82 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Util; -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// implementation that delegates - /// method calls to an instance. - /// - /// Bruno Baia - /// $Id: IAdvisedProxyMethodBuilder.cs,v 1.3 2006/11/12 01:37:47 bbaia Exp $ - public class IAdvisedProxyMethodBuilder : TargetProxyMethodBuilder - { - #region Fields - - /// - /// The implementation to use. - /// - private IAopProxyTypeGenerator _aopProxyGenerator; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - public IAdvisedProxyMethodBuilder( - TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator) - : base(typeBuilder, aopProxyGenerator, true) - { - this._aopProxyGenerator = aopProxyGenerator; - } - - #endregion - - #region Protected Methods - - /// - /// Generates the IL instructions that pushes - /// the target instance on which calls should be delegated to. - /// - /// The IL generator to use. - protected override void PushTarget(ILGenerator il) - { - _aopProxyGenerator.PushAdvisedProxy(il); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Util; +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// implementation that delegates + /// method calls to an instance. + /// + /// Bruno Baia + public class IAdvisedProxyMethodBuilder : TargetProxyMethodBuilder + { + #region Fields + + /// + /// The implementation to use. + /// + private IAopProxyTypeGenerator _aopProxyGenerator; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + public IAdvisedProxyMethodBuilder( + TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator) + : base(typeBuilder, aopProxyGenerator, true) + { + this._aopProxyGenerator = aopProxyGenerator; + } + + #endregion + + #region Protected Methods + + /// + /// Generates the IL instructions that pushes + /// the target instance on which calls should be delegated to. + /// + /// The IL generator to use. + protected override void PushTarget(ILGenerator il) + { + _aopProxyGenerator.PushAdvisedProxy(il); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAopProxyTypeGenerator.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAopProxyTypeGenerator.cs index 5aaa2eb8..c9bde607 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAopProxyTypeGenerator.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IAopProxyTypeGenerator.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection.Emit; - -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Describes the operations that generates IL instructions - /// used to build the Aop proxy type. - /// - /// Bruno Baia - /// $Id: IAopProxyTypeGenerator.cs,v 1.2 2006/11/05 20:36:59 bbaia Exp $ - public interface IAopProxyTypeGenerator : IProxyTypeGenerator - { - /// - /// Generates the IL instructions that pushes - /// the current - /// instance on stack. - /// - /// The IL generator to use. - void PushAdvisedProxy(ILGenerator il); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection.Emit; + +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Describes the operations that generates IL instructions + /// used to build the Aop proxy type. + /// + /// Bruno Baia + public interface IAopProxyTypeGenerator : IProxyTypeGenerator + { + /// + /// Generates the IL instructions that pushes + /// the current + /// instance on stack. + /// + /// The IL generator to use. + void PushAdvisedProxy(ILGenerator il); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs index b1fc1654..7818d6c6 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs @@ -1,397 +1,396 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Runtime.Serialization; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Core; -using Spring.Proxy; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// Builds an AOP proxy type using inheritance. - /// - /// Bruno Baia - /// $Id: InheritanceAopProxyTypeBuilder.cs,v 1.2 2008/03/03 09:28:50 bbaia Exp $ - public class InheritanceAopProxyTypeBuilder : AbstractAopProxyTypeBuilder - { - #region Fields - - private const string PROXY_TYPE_NAME = "InheritanceAopProxy"; - - private IAdvised advised; - private bool proxyDeclaredMembersOnly = true; - - /// - /// AdvisedProxy instance calls should be delegated to. - /// - protected FieldBuilder advisedProxyField; - - #endregion - - #region Properties - - /// - /// Gets or sets a value indicating whether inherited members should be proxied. - /// - /// - /// if inherited members should be proxied; - /// otherwise, . - /// - public bool ProxyDeclaredMembersOnly - { - get { return proxyDeclaredMembersOnly; } - set { proxyDeclaredMembersOnly = value; } - } - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// The proxy configuration. - public InheritanceAopProxyTypeBuilder(IAdvised advised) - { - if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME)) - { - throw new AopConfigException(String.Format( - "Cannot create inheritance-based IAopProxy for a non visible class [{0}]", - advised.TargetSource.TargetType.FullName)); - } - if (advised.TargetSource.TargetType.IsSealed) - { - throw new AopConfigException(String.Format( - "Cannot create inheritance-based IAopProxy for a sealed class [{0}]", - advised.TargetSource.TargetType.FullName)); - } - this.advised = advised; - - Name = PROXY_TYPE_NAME; - TargetType = advised.TargetSource.TargetType; - BaseType = TargetType; - Interfaces = GetProxiableInterfaces(advised.Interfaces); - ProxyTargetAttributes = advised.ProxyTargetAttributes; - } - - #endregion - - #region IProxyTypeBuilder Members - - /// - /// Creates the proxy type. - /// - /// The generated proxy class. - public override Type BuildProxyType() - { - IDictionary targetMethods = new Hashtable(); - IDictionary proxyMethods = new Hashtable(); - - TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); - - // apply custom attributes to the proxy type. - ApplyTypeAttributes(typeBuilder, TargetType); - - // declare fields - DeclareAdvisedProxyInstanceField(typeBuilder); - - // implement ISerializable if possible - if (advised.IsSerializable) - { - typeBuilder.SetCustomAttribute( - ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute))); - ImplementSerializationConstructor(typeBuilder); - ImplementGetObjectDataMethod(typeBuilder); - } - - // create constructors - ImplementConstructors(typeBuilder); - - // implement interfaces - IDictionary interfaceMap = advised.InterfaceMap; - foreach (Type intf in Interfaces) - { - object target = interfaceMap[intf]; - if (target == null) - { - // implement interface (proxy only final methods) - ImplementInterface(typeBuilder, - new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods), - intf, TargetType, false); - } - else if (target is IIntroductionAdvisor) - { - // implement introduction - ImplementInterface(typeBuilder, - new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor)target)), - intf, TargetType); - } - } - - // inherit from target type - InheritType(typeBuilder, - new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods), - TargetType, ProxyDeclaredMembersOnly); - - // implement IAdvised interface - ImplementInterface(typeBuilder, - new IAdvisedProxyMethodBuilder(typeBuilder, this), - typeof(IAdvised), TargetType); - - // implement IAopProxy interface - ImplementIAopProxy(typeBuilder); - - Type proxyType; - proxyType = typeBuilder.CreateType(); - - // set target method references - foreach (DictionaryEntry entry in targetMethods) - { - FieldInfo field = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static); - field.SetValue(proxyType, (MethodInfo)entry.Value); - } - - // set proxy method references - foreach (DictionaryEntry entry in proxyMethods) - { - FieldInfo field = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static); - field.SetValue(proxyType, FindProxyMethod(proxyType, (MethodInfo)entry.Value)); - } - - return proxyType; - } - - private MethodInfo FindProxyMethod(Type targetType, MethodInfo method) - { - ComposedCriteria searchCriteria = new ComposedCriteria(); - searchCriteria.Add(new MethodNameMatchCriteria("proxy_" + method.Name)); - searchCriteria.Add(new MethodParametersCountCriteria(method.GetParameters().Length)); -#if NET_2_0 - searchCriteria.Add(new MethodGenericArgumentsCountCriteria( - method.GetGenericArguments().Length)); -#endif - searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(method))); - - MemberInfo[] matchingMethods = targetType.FindMembers( - MemberTypes.Method, - BindingFlags.Instance | BindingFlags.Public, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - searchCriteria); - - if (matchingMethods != null && matchingMethods.Length == 1) - { - return matchingMethods[0] as MethodInfo; - } - else - { - throw new AmbiguousMatchException(); - } - } - - #endregion - - #region IAopProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the target instance on which calls should be delegated to. - /// - /// The IL generator to use. - public override void PushTarget(ILGenerator il) - { - il.Emit(OpCodes.Ldarg_0); - } - - /// - /// Generates the IL instructions that pushes - /// the current - /// instance on stack. - /// - /// The IL generator to use. - public override void PushAdvisedProxy(ILGenerator il) - { - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, advisedProxyField); - } - - #endregion - - #region Protected Methods - - /// - /// Declares field that holds the - /// instance used by the proxy. - /// - /// - /// The builder to use for code generation. - /// - protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder) - { - advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private); - } - - /// - /// Implements serialization method. - /// - /// - private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder) - { - typeBuilder.AddInterfaceImplementation(typeof(ISerializable)); - - MethodBuilder mb = - typeBuilder.DefineMethod("GetObjectData", - MethodAttributes.Public | MethodAttributes.HideBySig | - MethodAttributes.NewSlot | MethodAttributes.Virtual, - typeof(void), - new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); - - ILGenerator il = mb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldstr, "advisedProxy"); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, advisedProxyField); - il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null); - il.Emit(OpCodes.Ret); - - typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData")); - } - - /// - /// Implements serialization constructor. - /// - /// Type builder to use. - private void ImplementSerializationConstructor(TypeBuilder typeBuilder) - { - ConstructorBuilder cb = - typeBuilder.DefineConstructor(MethodAttributes.Family, - CallingConventions.Standard, - new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); - - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldstr, "advisedProxy"); - il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy)); - il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null); - il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null); - il.Emit(OpCodes.Castclass, typeof(AdvisedProxy)); - il.Emit(OpCodes.Stfld, advisedProxyField); - il.Emit(OpCodes.Ret); - } - - /// - /// Defines the types of the parameters for the specified constructor. - /// - /// The constructor to use. - /// The types for constructor's parameters. - protected override Type[] DefineConstructorParameters(ConstructorInfo constructor) - { - Type[] currentParams = ReflectionUtils.GetParameterTypes(constructor.GetParameters()); - Type[] newParams = new Type[currentParams.Length + 1]; - - newParams[currentParams.Length] = typeof(IAdvised); - currentParams.CopyTo(newParams, 0); - - return newParams; - } - - /// - /// Generates the proxy constructor. - /// - /// - ///

- /// This implementation creates instance of the AdvisedProxy object. - ///

- ///
- /// The constructor builder to use. - /// The IL generator to use. - /// The constructor to delegate the creation to. - protected override void GenerateConstructor( - ConstructorBuilder builder, ILGenerator il, ConstructorInfo constructor) - { - int paramCount = constructor.GetParameters().Length; - il.Emit(OpCodes.Ldarg_0); - for (int i = 0; i < paramCount; i++) - { - il.Emit(OpCodes.Ldarg_S, i + 1); - } - il.Emit(OpCodes.Call, constructor); - - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_S, paramCount + 1); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor); - il.Emit(OpCodes.Stfld, advisedProxyField); - } - - /// - /// Implements interface. - /// - /// The type builder to use. - protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder) - { - Type intf = typeof(IAopProxy); - MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes); - - typeBuilder.AddInterfaceImplementation(intf); - - MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name, - MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, - getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes); - - ILGenerator il = mb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ret); - - typeBuilder.DefineMethodOverride(mb, getProxyMethod); - } - - #endregion - - #region Public Methods - - /// - /// Determines if the specified - /// is one of those generated by this builder. - /// - /// The type to check. - /// - /// if the type is a inheritance-based proxy; - /// otherwise . - /// - public static bool IsInheritanceProxy(Type type) - { - return type.FullName.StartsWith(PROXY_TYPE_NAME); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Runtime.Serialization; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Core; +using Spring.Proxy; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// Builds an AOP proxy type using inheritance. + /// + /// Bruno Baia + public class InheritanceAopProxyTypeBuilder : AbstractAopProxyTypeBuilder + { + #region Fields + + private const string PROXY_TYPE_NAME = "InheritanceAopProxy"; + + private IAdvised advised; + private bool proxyDeclaredMembersOnly = true; + + /// + /// AdvisedProxy instance calls should be delegated to. + /// + protected FieldBuilder advisedProxyField; + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether inherited members should be proxied. + /// + /// + /// if inherited members should be proxied; + /// otherwise, . + /// + public bool ProxyDeclaredMembersOnly + { + get { return proxyDeclaredMembersOnly; } + set { proxyDeclaredMembersOnly = value; } + } + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// The proxy configuration. + public InheritanceAopProxyTypeBuilder(IAdvised advised) + { + if (!ReflectionUtils.IsTypeVisible(advised.TargetSource.TargetType, DynamicProxyManager.ASSEMBLY_NAME)) + { + throw new AopConfigException(String.Format( + "Cannot create inheritance-based IAopProxy for a non visible class [{0}]", + advised.TargetSource.TargetType.FullName)); + } + if (advised.TargetSource.TargetType.IsSealed) + { + throw new AopConfigException(String.Format( + "Cannot create inheritance-based IAopProxy for a sealed class [{0}]", + advised.TargetSource.TargetType.FullName)); + } + this.advised = advised; + + Name = PROXY_TYPE_NAME; + TargetType = advised.TargetSource.TargetType; + BaseType = TargetType; + Interfaces = GetProxiableInterfaces(advised.Interfaces); + ProxyTargetAttributes = advised.ProxyTargetAttributes; + } + + #endregion + + #region IProxyTypeBuilder Members + + /// + /// Creates the proxy type. + /// + /// The generated proxy class. + public override Type BuildProxyType() + { + IDictionary targetMethods = new Hashtable(); + IDictionary proxyMethods = new Hashtable(); + + TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); + + // apply custom attributes to the proxy type. + ApplyTypeAttributes(typeBuilder, TargetType); + + // declare fields + DeclareAdvisedProxyInstanceField(typeBuilder); + + // implement ISerializable if possible + if (advised.IsSerializable) + { + typeBuilder.SetCustomAttribute( + ReflectionUtils.CreateCustomAttribute(typeof(SerializableAttribute))); + ImplementSerializationConstructor(typeBuilder); + ImplementGetObjectDataMethod(typeBuilder); + } + + // create constructors + ImplementConstructors(typeBuilder); + + // implement interfaces + IDictionary interfaceMap = advised.InterfaceMap; + foreach (Type intf in Interfaces) + { + object target = interfaceMap[intf]; + if (target == null) + { + // implement interface (proxy only final methods) + ImplementInterface(typeBuilder, + new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods), + intf, TargetType, false); + } + else if (target is IIntroductionAdvisor) + { + // implement introduction + ImplementInterface(typeBuilder, + new IntroductionProxyMethodBuilder(typeBuilder, this, targetMethods, advised.IndexOf((IIntroductionAdvisor)target)), + intf, TargetType); + } + } + + // inherit from target type + InheritType(typeBuilder, + new BaseAopProxyMethodBuilder(typeBuilder, this, targetMethods, proxyMethods), + TargetType, ProxyDeclaredMembersOnly); + + // implement IAdvised interface + ImplementInterface(typeBuilder, + new IAdvisedProxyMethodBuilder(typeBuilder, this), + typeof(IAdvised), TargetType); + + // implement IAopProxy interface + ImplementIAopProxy(typeBuilder); + + Type proxyType; + proxyType = typeBuilder.CreateType(); + + // set target method references + foreach (DictionaryEntry entry in targetMethods) + { + FieldInfo field = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static); + field.SetValue(proxyType, (MethodInfo)entry.Value); + } + + // set proxy method references + foreach (DictionaryEntry entry in proxyMethods) + { + FieldInfo field = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static); + field.SetValue(proxyType, FindProxyMethod(proxyType, (MethodInfo)entry.Value)); + } + + return proxyType; + } + + private MethodInfo FindProxyMethod(Type targetType, MethodInfo method) + { + ComposedCriteria searchCriteria = new ComposedCriteria(); + searchCriteria.Add(new MethodNameMatchCriteria("proxy_" + method.Name)); + searchCriteria.Add(new MethodParametersCountCriteria(method.GetParameters().Length)); +#if NET_2_0 + searchCriteria.Add(new MethodGenericArgumentsCountCriteria( + method.GetGenericArguments().Length)); +#endif + searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(method))); + + MemberInfo[] matchingMethods = targetType.FindMembers( + MemberTypes.Method, + BindingFlags.Instance | BindingFlags.Public, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + searchCriteria); + + if (matchingMethods != null && matchingMethods.Length == 1) + { + return matchingMethods[0] as MethodInfo; + } + else + { + throw new AmbiguousMatchException(); + } + } + + #endregion + + #region IAopProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the target instance on which calls should be delegated to. + /// + /// The IL generator to use. + public override void PushTarget(ILGenerator il) + { + il.Emit(OpCodes.Ldarg_0); + } + + /// + /// Generates the IL instructions that pushes + /// the current + /// instance on stack. + /// + /// The IL generator to use. + public override void PushAdvisedProxy(ILGenerator il) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, advisedProxyField); + } + + #endregion + + #region Protected Methods + + /// + /// Declares field that holds the + /// instance used by the proxy. + /// + /// + /// The builder to use for code generation. + /// + protected virtual void DeclareAdvisedProxyInstanceField(TypeBuilder builder) + { + advisedProxyField = builder.DefineField("__advisedProxy", typeof(AdvisedProxy), FieldAttributes.Private); + } + + /// + /// Implements serialization method. + /// + /// + private void ImplementGetObjectDataMethod(TypeBuilder typeBuilder) + { + typeBuilder.AddInterfaceImplementation(typeof(ISerializable)); + + MethodBuilder mb = + typeBuilder.DefineMethod("GetObjectData", + MethodAttributes.Public | MethodAttributes.HideBySig | + MethodAttributes.NewSlot | MethodAttributes.Virtual, + typeof(void), + new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); + + ILGenerator il = mb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldstr, "advisedProxy"); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, advisedProxyField); + il.EmitCall(OpCodes.Callvirt, References.AddSerializationValue, null); + il.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(mb, typeof(ISerializable).GetMethod("GetObjectData")); + } + + /// + /// Implements serialization constructor. + /// + /// Type builder to use. + private void ImplementSerializationConstructor(TypeBuilder typeBuilder) + { + ConstructorBuilder cb = + typeBuilder.DefineConstructor(MethodAttributes.Family, + CallingConventions.Standard, + new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }); + + ILGenerator il = cb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldstr, "advisedProxy"); + il.Emit(OpCodes.Ldtoken, typeof(AdvisedProxy)); + il.EmitCall(OpCodes.Call, References.GetTypeFromHandle, null); + il.EmitCall(OpCodes.Callvirt, References.GetSerializationValue, null); + il.Emit(OpCodes.Castclass, typeof(AdvisedProxy)); + il.Emit(OpCodes.Stfld, advisedProxyField); + il.Emit(OpCodes.Ret); + } + + /// + /// Defines the types of the parameters for the specified constructor. + /// + /// The constructor to use. + /// The types for constructor's parameters. + protected override Type[] DefineConstructorParameters(ConstructorInfo constructor) + { + Type[] currentParams = ReflectionUtils.GetParameterTypes(constructor.GetParameters()); + Type[] newParams = new Type[currentParams.Length + 1]; + + newParams[currentParams.Length] = typeof(IAdvised); + currentParams.CopyTo(newParams, 0); + + return newParams; + } + + /// + /// Generates the proxy constructor. + /// + /// + ///

+ /// This implementation creates instance of the AdvisedProxy object. + ///

+ ///
+ /// The constructor builder to use. + /// The IL generator to use. + /// The constructor to delegate the creation to. + protected override void GenerateConstructor( + ConstructorBuilder builder, ILGenerator il, ConstructorInfo constructor) + { + int paramCount = constructor.GetParameters().Length; + il.Emit(OpCodes.Ldarg_0); + for (int i = 0; i < paramCount; i++) + { + il.Emit(OpCodes.Ldarg_S, i + 1); + } + il.Emit(OpCodes.Call, constructor); + + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_S, paramCount + 1); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Newobj, References.AdvisedProxyConstructor); + il.Emit(OpCodes.Stfld, advisedProxyField); + } + + /// + /// Implements interface. + /// + /// The type builder to use. + protected virtual void ImplementIAopProxy(TypeBuilder typeBuilder) + { + Type intf = typeof(IAopProxy); + MethodInfo getProxyMethod = intf.GetMethod("GetProxy", Type.EmptyTypes); + + typeBuilder.AddInterfaceImplementation(intf); + + MethodBuilder mb = typeBuilder.DefineMethod(typeof(IAdvised).FullName + "." + getProxyMethod.Name, + MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, + getProxyMethod.CallingConvention, getProxyMethod.ReturnType, Type.EmptyTypes); + + ILGenerator il = mb.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ret); + + typeBuilder.DefineMethodOverride(mb, getProxyMethod); + } + + #endregion + + #region Public Methods + + /// + /// Determines if the specified + /// is one of those generated by this builder. + /// + /// The type to check. + /// + /// if the type is a inheritance-based proxy; + /// otherwise . + /// + public static bool IsInheritanceProxy(Type type) + { + return type.FullName.StartsWith(PROXY_TYPE_NAME); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IntroductionProxyMethodBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IntroductionProxyMethodBuilder.cs index b58f1829..9ff2b3ec 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IntroductionProxyMethodBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/IntroductionProxyMethodBuilder.cs @@ -1,117 +1,116 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// implementation - /// that delegates method calls to introduction object. - /// - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: IntroductionProxyMethodBuilder.cs,v 1.5 2006/11/05 20:36:59 bbaia Exp $ - public class IntroductionProxyMethodBuilder : AbstractAopProxyMethodBuilder - { - #region Fields - - /// - /// The index of the introduction to delegate call to. - /// - protected int index; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - /// - /// - /// - /// index of the introduction to delegate call to - public IntroductionProxyMethodBuilder( - TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, - IDictionary targetMethods, int index) - : base(typeBuilder, aopProxyGenerator, true, targetMethods) - { - this.index = index; - } - - #endregion - - #region Protected Methods - - /// - /// Generates the IL instructions that pushes - /// the introduction type on stack. - /// - /// The IL generator to use. - protected override void PushTargetType(ILGenerator il) - { - PushTarget(il); - il.EmitCall(OpCodes.Call, References.GetTypeMethod, null); - } - - /// - /// Generates the IL instructions that pushes - /// the introduction instance on stack. - /// - /// The IL generator to use. - protected override void PushTarget(ILGenerator il) - { - PushAdvisedProxy(il); - il.Emit(OpCodes.Ldfld, References.IntroductionsField); - il.Emit(OpCodes.Ldc_I4, index); - il.Emit(OpCodes.Ldelem_Ref); - } - - /// - /// Calls proxied method directly. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected override void CallDirectProxiedMethod( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - CallDirectTargetMethod(il, interfaceMethod); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// implementation + /// that delegates method calls to introduction object. + /// + /// Aleksandar Seovic + /// Bruno Baia + public class IntroductionProxyMethodBuilder : AbstractAopProxyMethodBuilder + { + #region Fields + + /// + /// The index of the introduction to delegate call to. + /// + protected int index; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + /// + /// + /// + /// index of the introduction to delegate call to + public IntroductionProxyMethodBuilder( + TypeBuilder typeBuilder, IAopProxyTypeGenerator aopProxyGenerator, + IDictionary targetMethods, int index) + : base(typeBuilder, aopProxyGenerator, true, targetMethods) + { + this.index = index; + } + + #endregion + + #region Protected Methods + + /// + /// Generates the IL instructions that pushes + /// the introduction type on stack. + /// + /// The IL generator to use. + protected override void PushTargetType(ILGenerator il) + { + PushTarget(il); + il.EmitCall(OpCodes.Call, References.GetTypeMethod, null); + } + + /// + /// Generates the IL instructions that pushes + /// the introduction instance on stack. + /// + /// The IL generator to use. + protected override void PushTarget(ILGenerator il) + { + PushAdvisedProxy(il); + il.Emit(OpCodes.Ldfld, References.IntroductionsField); + il.Emit(OpCodes.Ldc_I4, index); + il.Emit(OpCodes.Ldelem_Ref); + } + + /// + /// Calls proxied method directly. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected override void CallDirectProxiedMethod( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + CallDirectTargetMethod(il, interfaceMethod); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/TargetAopProxyMethodBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/TargetAopProxyMethodBuilder.cs index ac3190dc..4f32f260 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/TargetAopProxyMethodBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/TargetAopProxyMethodBuilder.cs @@ -1,152 +1,151 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework.DynamicProxy -{ - /// - /// implementation - /// that delegates method calls to target object. - /// - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: TargetAopProxyMethodBuilder.cs,v 1.3 2008/01/29 18:24:50 markpollack Exp $ - public class TargetAopProxyMethodBuilder : AbstractAopProxyMethodBuilder - { - #region Fields - - /// - /// The local variable to store - /// the instance. - /// - protected LocalBuilder targetSource; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - /// - /// if the interface is to be - /// implemented explicitly; otherwise . - /// - /// - /// The dictionary to cache the list of target - /// s. - /// - public TargetAopProxyMethodBuilder(TypeBuilder typeBuilder, - IAopProxyTypeGenerator aopProxyGenerator, bool explicitImplementation, IDictionary targetMethods) - : base(typeBuilder, aopProxyGenerator, explicitImplementation, targetMethods) - { - } - - #endregion - - #region Protected Methods - - /// - /// Creates local variable declarations. - /// - /// The IL generator to use. - /// The method to proxy. - protected override void DeclareLocals(ILGenerator il, MethodInfo method) - { - base.DeclareLocals(il, method); - targetSource = il.DeclareLocal(typeof(ITargetSourceWrapper)); - -#if DEBUG - targetSource.SetLocalSymInfo("targetSource"); -#endif - } - - /// - /// Generates method logic. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected override void GenerateMethodLogic( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - Label jmpEndFinally = il.DefineLabel(); - - // save target source so we can call Dispose later - PushAdvisedProxy(il); - il.Emit(OpCodes.Ldfld, References.TargetSourceWrapperField); - il.Emit(OpCodes.Stloc, targetSource); - - // open try/finally block - il.BeginExceptionBlock(); - - base.GenerateMethodLogic(il, method, interfaceMethod); - - // open finally block - il.BeginFinallyBlock(); - - // call Dispose on target source - il.Emit(OpCodes.Ldloc, targetSource); - il.Emit(OpCodes.Brfalse, jmpEndFinally); - il.Emit(OpCodes.Ldloc, targetSource); - il.EmitCall(OpCodes.Callvirt, References.DisposeMethod, null); - - il.MarkLabel(jmpEndFinally); - - // close try/finally block - il.EndExceptionBlock(); - } - - /// - /// Calls proxied method directly. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected override void CallDirectProxiedMethod( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - if (interfaceMethod != null) - CallDirectTargetMethod(il, interfaceMethod); - else - CallDirectTargetMethod(il, method); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework.DynamicProxy +{ + /// + /// implementation + /// that delegates method calls to target object. + /// + /// Aleksandar Seovic + /// Bruno Baia + public class TargetAopProxyMethodBuilder : AbstractAopProxyMethodBuilder + { + #region Fields + + /// + /// The local variable to store + /// the instance. + /// + protected LocalBuilder targetSource; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + /// + /// if the interface is to be + /// implemented explicitly; otherwise . + /// + /// + /// The dictionary to cache the list of target + /// s. + /// + public TargetAopProxyMethodBuilder(TypeBuilder typeBuilder, + IAopProxyTypeGenerator aopProxyGenerator, bool explicitImplementation, IDictionary targetMethods) + : base(typeBuilder, aopProxyGenerator, explicitImplementation, targetMethods) + { + } + + #endregion + + #region Protected Methods + + /// + /// Creates local variable declarations. + /// + /// The IL generator to use. + /// The method to proxy. + protected override void DeclareLocals(ILGenerator il, MethodInfo method) + { + base.DeclareLocals(il, method); + targetSource = il.DeclareLocal(typeof(ITargetSourceWrapper)); + +#if DEBUG + targetSource.SetLocalSymInfo("targetSource"); +#endif + } + + /// + /// Generates method logic. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected override void GenerateMethodLogic( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + Label jmpEndFinally = il.DefineLabel(); + + // save target source so we can call Dispose later + PushAdvisedProxy(il); + il.Emit(OpCodes.Ldfld, References.TargetSourceWrapperField); + il.Emit(OpCodes.Stloc, targetSource); + + // open try/finally block + il.BeginExceptionBlock(); + + base.GenerateMethodLogic(il, method, interfaceMethod); + + // open finally block + il.BeginFinallyBlock(); + + // call Dispose on target source + il.Emit(OpCodes.Ldloc, targetSource); + il.Emit(OpCodes.Brfalse, jmpEndFinally); + il.Emit(OpCodes.Ldloc, targetSource); + il.EmitCall(OpCodes.Callvirt, References.DisposeMethod, null); + + il.MarkLabel(jmpEndFinally); + + // close try/finally block + il.EndExceptionBlock(); + } + + /// + /// Calls proxied method directly. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected override void CallDirectProxiedMethod( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + if (interfaceMethod != null) + CallDirectTargetMethod(il, interfaceMethod); + else + CallDirectTargetMethod(il, method); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicTargetSourceWrapper.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicTargetSourceWrapper.cs index d7f51989..d7e191ae 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicTargetSourceWrapper.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicTargetSourceWrapper.cs @@ -1,98 +1,97 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Decorates a target source with the - /// interface. - /// - /// - ///

- /// This implementation will release the target object when said object - /// is disposed. - ///

- ///
- /// Aleksandar Seovic - /// $Id: DynamicTargetSourceWrapper.cs,v 1.4 2007/03/16 04:01:17 aseovic Exp $ - [Serializable] - public sealed class DynamicTargetSourceWrapper : ITargetSourceWrapper - { - private ITargetSource targetSource; - private object target; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The target object that proxy methods will be delegated to. - /// - /// - /// If the supplied is - /// . - /// - internal DynamicTargetSourceWrapper(ITargetSource targetSource) - { - AssertUtils.ArgumentNotNull(targetSource, "targetSource"); - this.targetSource = targetSource; - } - - /// - /// Returns the target object that proxy methods will be delegated to. - /// - /// The target object. - public object GetTarget() - { - if (this.target == null) - { - this.target = targetSource.GetTarget(); - } - - return this.target; - } - - /// - /// Releases the dynamic target when this object is disposed. - /// - public void Dispose() - { - GC.SuppressFinalize(this); - Dispose(true); - } - - private void Dispose(bool disposing) - { - if (disposing && this.target != null) - { - this.targetSource.ReleaseTarget(this.target); - this.target = null; - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Decorates a target source with the + /// interface. + /// + /// + ///

+ /// This implementation will release the target object when said object + /// is disposed. + ///

+ ///
+ /// Aleksandar Seovic + [Serializable] + public sealed class DynamicTargetSourceWrapper : ITargetSourceWrapper + { + private ITargetSource targetSource; + private object target; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The target object that proxy methods will be delegated to. + /// + /// + /// If the supplied is + /// . + /// + internal DynamicTargetSourceWrapper(ITargetSource targetSource) + { + AssertUtils.ArgumentNotNull(targetSource, "targetSource"); + this.targetSource = targetSource; + } + + /// + /// Returns the target object that proxy methods will be delegated to. + /// + /// The target object. + public object GetTarget() + { + if (this.target == null) + { + this.target = targetSource.GetTarget(); + } + + return this.target; + } + + /// + /// Releases the dynamic target when this object is disposed. + /// + public void Dispose() + { + GC.SuppressFinalize(this); + Dispose(true); + } + + private void Dispose(bool disposing) + { + if (disposing && this.target != null) + { + this.targetSource.ReleaseTarget(this.target); + this.target = null; + } + } + } +} diff --git a/src/Spring/Spring.Aop/Aop/Framework/HashtableCachingAdvisorChainFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/HashtableCachingAdvisorChainFactory.cs index ca75241a..1714ed8b 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/HashtableCachingAdvisorChainFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/HashtableCachingAdvisorChainFactory.cs @@ -1,104 +1,103 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// implementation - /// that caches advisor chains on a per-advised-method basis. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: HashtableCachingAdvisorChainFactory.cs,v 1.9 2007/03/16 04:01:18 aseovic Exp $ - [Serializable] - public sealed class HashtableCachingAdvisorChainFactory : IAdvisorChainFactory - { - private IDictionary methodCache = new Hashtable(); - - /// - /// Gets the list of and - /// - /// instances for the supplied . - /// - /// The proxy configuration object. - /// The object proxy. - /// - /// The method for which the interceptors are to be evaluated. - /// - /// - /// The of the target object. - /// - /// - /// The list of and - /// - /// instances for the supplied . - /// - public IList GetInterceptors(IAdvised advised, object proxy, MethodInfo method, Type targetType) - { - IList cached = (IList) this.methodCache[method]; - if (cached == null) - { - // recalculate... - cached = AdvisorChainFactoryUtils.CalculateInterceptors(advised, proxy, method, targetType); - this.methodCache[method] = cached; - } - return cached; - } - - /// - /// Invoked when the first proxy is created. - /// - /// - /// The relevant source. - /// - public void Activated(AdvisedSupport source) - { - } - - /// - /// Invoked when advice is changed after a proxy is created. - /// - /// - /// The relevant source. - /// - public void AdviceChanged(AdvisedSupport source) - { - methodCache.Clear(); - } - - /// - /// Invoked when interfaces are changed after a proxy is created. - /// - /// - /// The relevant source. - /// - public void InterfacesChanged(AdvisedSupport source) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// implementation + /// that caches advisor chains on a per-advised-method basis. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class HashtableCachingAdvisorChainFactory : IAdvisorChainFactory + { + private IDictionary methodCache = new Hashtable(); + + /// + /// Gets the list of and + /// + /// instances for the supplied . + /// + /// The proxy configuration object. + /// The object proxy. + /// + /// The method for which the interceptors are to be evaluated. + /// + /// + /// The of the target object. + /// + /// + /// The list of and + /// + /// instances for the supplied . + /// + public IList GetInterceptors(IAdvised advised, object proxy, MethodInfo method, Type targetType) + { + IList cached = (IList) this.methodCache[method]; + if (cached == null) + { + // recalculate... + cached = AdvisorChainFactoryUtils.CalculateInterceptors(advised, proxy, method, targetType); + this.methodCache[method] = cached; + } + return cached; + } + + /// + /// Invoked when the first proxy is created. + /// + /// + /// The relevant source. + /// + public void Activated(AdvisedSupport source) + { + } + + /// + /// Invoked when advice is changed after a proxy is created. + /// + /// + /// The relevant source. + /// + public void AdviceChanged(AdvisedSupport source) + { + methodCache.Clear(); + } + + /// + /// Invoked when interfaces are changed after a proxy is created. + /// + /// + /// The relevant source. + /// + public void InterfacesChanged(AdvisedSupport source) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/IAdvised.cs b/src/Spring/Spring.Aop/Aop/Framework/IAdvised.cs index 7fe13cfa..c12dffdf 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/IAdvised.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/IAdvised.cs @@ -1,500 +1,499 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -using AopAlliance.Aop; -using Spring.Aop; -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Configuration data for an AOP proxy factory. - /// - /// - ///

- /// This configuration includes the - /// s, - /// s, and (any) proxied interfaces. - ///

- ///

- /// Any AOP proxy obtained from Spring.NET can be cast to this interface to - /// allow the manipulation of said proxy's AOP advice. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAdvised.cs,v 1.15 2007/10/10 18:07:38 markpollack Exp $ - /// - [ProxyIgnore] - public interface IAdvised - { - /// - /// Should proxies obtained from this configuration expose - /// the AOP proxy to the - /// class? - /// - /// - ///

- /// This is useful if an advised object needs to call another advised - /// method on itself. (If it uses the this reference (Me - /// in Visual Basic.NET), the invocation will not be advised). - ///

- ///
- bool ExposeProxy { get; } - - /// - /// Gets the - /// - /// implementation that will be used to get the interceptor - /// chains for the advised - /// . - /// - /// - /// The - /// implementation that will be used to get the interceptor - /// chains for the advised - /// . - /// - IAdvisorChainFactory AdvisorChainFactory { get; } - - /// - /// Is the target to be proxied in addition - /// to any interfaces declared on the proxied ? - /// - bool ProxyTargetType { get; } - - /// - /// Is target type attributes, method attributes, method's return type attributes - /// and method's parameter attributes to be proxied in addition - /// to any interfaces declared on the proxied ? - /// - bool ProxyTargetAttributes { get; } - - /// - /// Returns the collection of - /// instances that have been applied to this proxy. - /// - /// - ///

- /// Will never return , but may return an - /// empty array (in the case where no - /// instances have been applied to - /// this proxy). - ///

- ///
- /// - /// The collection of - /// instances that have been applied to this proxy. - /// - IAdvisor[] Advisors { get; } - - /// - /// Returns the collection of - /// instances that have been applied to this proxy. - /// - /// - ///

- /// Will never return , but may return an - /// empty array (in the case where no - /// instances have been - /// applied to this proxy). - ///

- ///
- /// - /// The collection of - /// instances that have been applied to this proxy. - /// - IIntroductionAdvisor[] Introductions { get; } - - /// - /// Returns the collection of interface s - /// to be (or that are being) proxied by this proxy. - /// - /// - /// The collection of interface s - /// to be (or that are being) proxied by this proxy. - /// - Type[] Interfaces { get; } - - /// - /// Returns the mapping of the proxied interface - /// s to their delegates. - /// - /// - /// The mapping of the proxied interface - /// s to their delegates. - /// - IDictionary InterfaceMap { get; } - - /// - /// Is this configuration frozen? - /// - /// - ///

- /// When a config is frozen, no advice changes can be made. This is - /// useful for optimization, and useful when we don't want callers - /// to be able to manipulate configuration after casting to - /// . - ///

- ///
- bool IsFrozen { get; } - - /// - /// Returns the used by this - /// object. - /// - /// - /// The used by this - /// object. - /// - ITargetSource TargetSource { get; } - - /// - /// Returns a boolean specifying if this - /// instance can be serialized. - /// - /// - /// true if this instance can be serialized, false otherwise. - /// - bool IsSerializable { get; } - - /// - /// Adds the supplied to the end (or tail) - /// of the advice (interceptor) chain. - /// - /// - ///

- /// Please be aware that Spring.NET's AOP implementation only supports - /// method advice (as encapsulated by the - /// interface). - ///

- ///
- /// - /// The to be added. - /// - /// - /// - void AddAdvice(IAdvice advice); - - /// - /// Adds the supplied to the supplied - /// in the advice (interceptor) chain. - /// - /// - ///

- /// Please be aware that Spring.NET's AOP implementation only supports - /// method advice (as encapsulated by the - /// interface). - ///

- ///
- /// - /// The zero (0) indexed position (from the head) at which the - /// supplied is to be inserted into the - /// advice (interceptor) chain. - /// - /// - /// The to be added. - /// - /// - /// - void AddAdvice(int position, IAdvice advice); - - /// - /// Is the supplied (interface) - /// proxied? - /// - /// - /// The interface to test. - /// - /// - /// if the supplied - /// (interface) is proxied; - /// if not or the supplied - /// is . - /// - bool IsInterfaceProxied(Type intf); - - /// - /// Adds the advisors from the supplied - /// to the list of . - /// - /// - /// The to add advisors from. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - void AddAdvisors(IAdvisors advisors); - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - void AddAdvisor(IAdvisor advisor); - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The index in the - /// list at which the supplied - /// is to be inserted. - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - void AddAdvisor(int index, IAdvisor advisor); - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - void AddIntroduction(IIntroductionAdvisor introductionAdvisor); - - /// - /// Adds the supplied to the list - /// of . - /// - /// - /// The index in the - /// list at which the supplied - /// is to be inserted. - /// - /// - /// The to add. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be added. - /// - void AddIntroduction(int index, IIntroductionAdvisor introductionAdvisor); - - /// - /// Return the index (0 based) of the supplied - /// in the interceptor - /// (advice) chain for this proxy. - /// - /// - ///

- /// The return value of this method can be used to index into - /// the - /// list. - ///

- ///
- /// - /// The to search for. - /// - /// - /// The zero (0) based index of this advisor, or -1 if the - /// supplied is not an advisor for this - /// proxy. - /// - int IndexOf(IAdvisor advisor); - - /// - /// Return the index (0 based) of the supplied - /// in the introductions - /// for this proxy. - /// - /// - ///

- /// The return value of this method can be used to index into - /// the - /// list. - ///

- ///
- /// - /// The to search for. - /// - /// - /// The zero (0) based index of this advisor, or -1 if the - /// supplied is not an introduction advisor - /// for this proxy. - /// - int IndexOf(IIntroductionAdvisor advisor); - - /// - /// Removes the supplied the list of advisors - /// for this proxy. - /// - /// The advisor to remove. - /// - /// if advisor was found in the list of - /// for this - /// proxy and was successfully removed; if not - /// or if the supplied is . - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be removed. - /// - bool RemoveAdvisor(IAdvisor advisor); - - /// - /// Removes the at the supplied - /// in the - /// list - /// from the list of - /// for this proxy. - /// - /// - /// The index of the to remove. - /// - /// - /// If this proxy configuration is frozen and the - /// at the supplied - /// cannot be removed; or if the supplied is out of - /// range. - /// - void RemoveAdvisor(int index); - - /// - /// Removes the supplied from the list - /// of . - /// - /// - /// The to remove. - /// - /// - /// if the supplied was - /// found in the list of - /// and successfully removed. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be removed. - /// - bool RemoveAdvice(IAdvice advice); - - /// - /// Removes the supplied from the list - /// of . - /// - /// - /// The to remove. - /// - /// - /// if the supplied was - /// found in the list of - /// and successfully removed. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be removed. - /// - bool RemoveIntroduction(IIntroductionAdvisor introduction); - - /// - /// Removes the at the supplied - /// in the list of - /// for this proxy. - /// - /// The index of the advisor to remove. - /// - /// - /// If this proxy configuration is frozen and the - /// at the supplied - /// cannot be removed; or if the supplied - /// is out of range. - /// - void RemoveIntroduction(int index); - - /// - /// Replaces the that - /// exists at the supplied in the list of - /// - /// with the supplied . - /// - /// - /// The index of the - /// in the list of - /// - /// that is to be replaced. - /// - /// - /// The new (replacement) . - /// - /// - /// If the supplied is out of range. - /// - void ReplaceIntroduction(int index, IIntroductionAdvisor introduction); - - /// - /// Replaces the with the - /// . - /// - /// - /// The original (old) advisor to be replaced. - /// - /// - /// The new advisor to replace the with. - /// - /// - /// if the was - /// replaced; if the was not found in the - /// advisors collection, this method returns - /// and (effectively) does nothing. - /// - /// - /// If this proxy configuration is frozen and the - /// cannot be replaced. - /// - /// - bool ReplaceAdvisor(IAdvisor oldAdvisor, IAdvisor newAdvisor); - - /// - /// As will normally be passed - /// straight through to the advised target, this method returns the - /// equivalent for the AOP - /// proxy itself. - /// - /// - /// A description of the proxy configuration. - /// - string ToProxyConfigString(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +using AopAlliance.Aop; +using Spring.Aop; +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Configuration data for an AOP proxy factory. + /// + /// + ///

+ /// This configuration includes the + /// s, + /// s, and (any) proxied interfaces. + ///

+ ///

+ /// Any AOP proxy obtained from Spring.NET can be cast to this interface to + /// allow the manipulation of said proxy's AOP advice. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + [ProxyIgnore] + public interface IAdvised + { + /// + /// Should proxies obtained from this configuration expose + /// the AOP proxy to the + /// class? + /// + /// + ///

+ /// This is useful if an advised object needs to call another advised + /// method on itself. (If it uses the this reference (Me + /// in Visual Basic.NET), the invocation will not be advised). + ///

+ ///
+ bool ExposeProxy { get; } + + /// + /// Gets the + /// + /// implementation that will be used to get the interceptor + /// chains for the advised + /// . + /// + /// + /// The + /// implementation that will be used to get the interceptor + /// chains for the advised + /// . + /// + IAdvisorChainFactory AdvisorChainFactory { get; } + + /// + /// Is the target to be proxied in addition + /// to any interfaces declared on the proxied ? + /// + bool ProxyTargetType { get; } + + /// + /// Is target type attributes, method attributes, method's return type attributes + /// and method's parameter attributes to be proxied in addition + /// to any interfaces declared on the proxied ? + /// + bool ProxyTargetAttributes { get; } + + /// + /// Returns the collection of + /// instances that have been applied to this proxy. + /// + /// + ///

+ /// Will never return , but may return an + /// empty array (in the case where no + /// instances have been applied to + /// this proxy). + ///

+ ///
+ /// + /// The collection of + /// instances that have been applied to this proxy. + /// + IAdvisor[] Advisors { get; } + + /// + /// Returns the collection of + /// instances that have been applied to this proxy. + /// + /// + ///

+ /// Will never return , but may return an + /// empty array (in the case where no + /// instances have been + /// applied to this proxy). + ///

+ ///
+ /// + /// The collection of + /// instances that have been applied to this proxy. + /// + IIntroductionAdvisor[] Introductions { get; } + + /// + /// Returns the collection of interface s + /// to be (or that are being) proxied by this proxy. + /// + /// + /// The collection of interface s + /// to be (or that are being) proxied by this proxy. + /// + Type[] Interfaces { get; } + + /// + /// Returns the mapping of the proxied interface + /// s to their delegates. + /// + /// + /// The mapping of the proxied interface + /// s to their delegates. + /// + IDictionary InterfaceMap { get; } + + /// + /// Is this configuration frozen? + /// + /// + ///

+ /// When a config is frozen, no advice changes can be made. This is + /// useful for optimization, and useful when we don't want callers + /// to be able to manipulate configuration after casting to + /// . + ///

+ ///
+ bool IsFrozen { get; } + + /// + /// Returns the used by this + /// object. + /// + /// + /// The used by this + /// object. + /// + ITargetSource TargetSource { get; } + + /// + /// Returns a boolean specifying if this + /// instance can be serialized. + /// + /// + /// true if this instance can be serialized, false otherwise. + /// + bool IsSerializable { get; } + + /// + /// Adds the supplied to the end (or tail) + /// of the advice (interceptor) chain. + /// + /// + ///

+ /// Please be aware that Spring.NET's AOP implementation only supports + /// method advice (as encapsulated by the + /// interface). + ///

+ ///
+ /// + /// The to be added. + /// + /// + /// + void AddAdvice(IAdvice advice); + + /// + /// Adds the supplied to the supplied + /// in the advice (interceptor) chain. + /// + /// + ///

+ /// Please be aware that Spring.NET's AOP implementation only supports + /// method advice (as encapsulated by the + /// interface). + ///

+ ///
+ /// + /// The zero (0) indexed position (from the head) at which the + /// supplied is to be inserted into the + /// advice (interceptor) chain. + /// + /// + /// The to be added. + /// + /// + /// + void AddAdvice(int position, IAdvice advice); + + /// + /// Is the supplied (interface) + /// proxied? + /// + /// + /// The interface to test. + /// + /// + /// if the supplied + /// (interface) is proxied; + /// if not or the supplied + /// is . + /// + bool IsInterfaceProxied(Type intf); + + /// + /// Adds the advisors from the supplied + /// to the list of . + /// + /// + /// The to add advisors from. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + void AddAdvisors(IAdvisors advisors); + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + void AddAdvisor(IAdvisor advisor); + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The index in the + /// list at which the supplied + /// is to be inserted. + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + void AddAdvisor(int index, IAdvisor advisor); + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + void AddIntroduction(IIntroductionAdvisor introductionAdvisor); + + /// + /// Adds the supplied to the list + /// of . + /// + /// + /// The index in the + /// list at which the supplied + /// is to be inserted. + /// + /// + /// The to add. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be added. + /// + void AddIntroduction(int index, IIntroductionAdvisor introductionAdvisor); + + /// + /// Return the index (0 based) of the supplied + /// in the interceptor + /// (advice) chain for this proxy. + /// + /// + ///

+ /// The return value of this method can be used to index into + /// the + /// list. + ///

+ ///
+ /// + /// The to search for. + /// + /// + /// The zero (0) based index of this advisor, or -1 if the + /// supplied is not an advisor for this + /// proxy. + /// + int IndexOf(IAdvisor advisor); + + /// + /// Return the index (0 based) of the supplied + /// in the introductions + /// for this proxy. + /// + /// + ///

+ /// The return value of this method can be used to index into + /// the + /// list. + ///

+ ///
+ /// + /// The to search for. + /// + /// + /// The zero (0) based index of this advisor, or -1 if the + /// supplied is not an introduction advisor + /// for this proxy. + /// + int IndexOf(IIntroductionAdvisor advisor); + + /// + /// Removes the supplied the list of advisors + /// for this proxy. + /// + /// The advisor to remove. + /// + /// if advisor was found in the list of + /// for this + /// proxy and was successfully removed; if not + /// or if the supplied is . + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be removed. + /// + bool RemoveAdvisor(IAdvisor advisor); + + /// + /// Removes the at the supplied + /// in the + /// list + /// from the list of + /// for this proxy. + /// + /// + /// The index of the to remove. + /// + /// + /// If this proxy configuration is frozen and the + /// at the supplied + /// cannot be removed; or if the supplied is out of + /// range. + /// + void RemoveAdvisor(int index); + + /// + /// Removes the supplied from the list + /// of . + /// + /// + /// The to remove. + /// + /// + /// if the supplied was + /// found in the list of + /// and successfully removed. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be removed. + /// + bool RemoveAdvice(IAdvice advice); + + /// + /// Removes the supplied from the list + /// of . + /// + /// + /// The to remove. + /// + /// + /// if the supplied was + /// found in the list of + /// and successfully removed. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be removed. + /// + bool RemoveIntroduction(IIntroductionAdvisor introduction); + + /// + /// Removes the at the supplied + /// in the list of + /// for this proxy. + /// + /// The index of the advisor to remove. + /// + /// + /// If this proxy configuration is frozen and the + /// at the supplied + /// cannot be removed; or if the supplied + /// is out of range. + /// + void RemoveIntroduction(int index); + + /// + /// Replaces the that + /// exists at the supplied in the list of + /// + /// with the supplied . + /// + /// + /// The index of the + /// in the list of + /// + /// that is to be replaced. + /// + /// + /// The new (replacement) . + /// + /// + /// If the supplied is out of range. + /// + void ReplaceIntroduction(int index, IIntroductionAdvisor introduction); + + /// + /// Replaces the with the + /// . + /// + /// + /// The original (old) advisor to be replaced. + /// + /// + /// The new advisor to replace the with. + /// + /// + /// if the was + /// replaced; if the was not found in the + /// advisors collection, this method returns + /// and (effectively) does nothing. + /// + /// + /// If this proxy configuration is frozen and the + /// cannot be replaced. + /// + /// + bool ReplaceAdvisor(IAdvisor oldAdvisor, IAdvisor newAdvisor); + + /// + /// As will normally be passed + /// straight through to the advised target, this method returns the + /// equivalent for the AOP + /// proxy itself. + /// + /// + /// A description of the proxy configuration. + /// + string ToProxyConfigString(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/IAdvisedSupportListener.cs b/src/Spring/Spring.Aop/Aop/Framework/IAdvisedSupportListener.cs index 4085ceba..83904437 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/IAdvisedSupportListener.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/IAdvisedSupportListener.cs @@ -1,66 +1,65 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Aop.Framework -{ - /// - /// Callback interface for - /// listeners. - /// - /// - ///

- /// Allows - /// implementations to be notified of notable lifecycle events relating - /// to the creation of a proxy, and changes to the configuration data of a - /// proxy. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAdvisedSupportListener.cs,v 1.5 2006/04/09 07:18:35 markpollack Exp $ - public interface IAdvisedSupportListener - { - /// - /// Invoked when the first proxy is created. - /// - /// - /// The relevant source. - /// - void Activated(AdvisedSupport source); - - /// - /// Invoked when advice is changed after a proxy is created. - /// - /// - /// The relevant source. - /// - void AdviceChanged(AdvisedSupport source); - - /// - /// Invoked when interfaces are changed after a proxy is created. - /// - /// - /// The relevant source. - /// - void InterfacesChanged(AdvisedSupport source); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Aop.Framework +{ + /// + /// Callback interface for + /// listeners. + /// + /// + ///

+ /// Allows + /// implementations to be notified of notable lifecycle events relating + /// to the creation of a proxy, and changes to the configuration data of a + /// proxy. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IAdvisedSupportListener + { + /// + /// Invoked when the first proxy is created. + /// + /// + /// The relevant source. + /// + void Activated(AdvisedSupport source); + + /// + /// Invoked when advice is changed after a proxy is created. + /// + /// + /// The relevant source. + /// + void AdviceChanged(AdvisedSupport source); + + /// + /// Invoked when interfaces are changed after a proxy is created. + /// + /// + /// The relevant source. + /// + void InterfacesChanged(AdvisedSupport source); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/IAdvisorChainFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/IAdvisorChainFactory.cs index f1965d4d..348f446a 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/IAdvisorChainFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/IAdvisorChainFactory.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Factory interface for advisor chains. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAdvisorChainFactory.cs,v 1.8 2006/09/14 21:05:23 bbaia Exp $ - public interface IAdvisorChainFactory : IAdvisedSupportListener - { - /// - /// Gets the list of and - /// - /// instances for the supplied . - /// - /// The proxy configuration object. - /// The object proxy. - /// - /// The method for which the interceptors are to be evaluated. - /// - /// - /// The of the target object. - /// - /// - /// The list of and - /// - /// instances for the supplied . - /// - IList GetInterceptors( - IAdvised advised, object proxy, MethodInfo method, Type targetType); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Factory interface for advisor chains. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IAdvisorChainFactory : IAdvisedSupportListener + { + /// + /// Gets the list of and + /// + /// instances for the supplied . + /// + /// The proxy configuration object. + /// The object proxy. + /// + /// The method for which the interceptors are to be evaluated. + /// + /// + /// The of the target object. + /// + /// + /// The list of and + /// + /// instances for the supplied . + /// + IList GetInterceptors( + IAdvised advised, object proxy, MethodInfo method, Type targetType); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/IAopProxy.cs b/src/Spring/Spring.Aop/Aop/Framework/IAopProxy.cs index 55238299..0e764269 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/IAopProxy.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/IAopProxy.cs @@ -1,45 +1,44 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Proxy; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// The central interface for Spring.NET based AOP proxies. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAopProxy.cs,v 1.4 2006/11/16 02:30:49 bbaia Exp $ - [ProxyIgnore] - public interface IAopProxy - { - /// - /// Creates a new proxy object. - /// - object GetProxy(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Proxy; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// The central interface for Spring.NET based AOP proxies. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [ProxyIgnore] + public interface IAopProxy + { + /// + /// Creates a new proxy object. + /// + object GetProxy(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/IAopProxyFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/IAopProxyFactory.cs index e03900e9..40c4c82a 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/IAopProxyFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/IAopProxyFactory.cs @@ -1,47 +1,46 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Aop.Framework -{ - /// - /// Factory interface for the creation of AOP proxies based on - /// configuration - /// objects. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IAopProxyFactory.cs,v 1.3 2006/04/09 07:18:35 markpollack Exp $ - public interface IAopProxyFactory - { - /// - /// Creates an for the - /// supplied configuration. - /// - /// The AOP configuration. - /// An . - /// - /// If the supplied configuration is - /// invalid. - /// - IAopProxy CreateAopProxy(AdvisedSupport advisedSupport); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Aop.Framework +{ + /// + /// Factory interface for the creation of AOP proxies based on + /// configuration + /// objects. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IAopProxyFactory + { + /// + /// Creates an for the + /// supplied configuration. + /// + /// The AOP configuration. + /// An . + /// + /// If the supplied configuration is + /// invalid. + /// + IAopProxy CreateAopProxy(AdvisedSupport advisedSupport); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/ITargetAware.cs b/src/Spring/Spring.Aop/Aop/Framework/ITargetAware.cs index 864345cc..e401104d 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/ITargetAware.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/ITargetAware.cs @@ -1,46 +1,45 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Aop.Framework -{ - /// - /// Provides access to the target object of an AOP proxy. - /// - /// - ///

- /// To be implemented by introduction aspects in order to obtain access to - /// the target object. - ///

- ///
- /// Aleksandar Seovic - /// $Id: ITargetAware.cs,v 1.3 2006/04/09 07:18:35 markpollack Exp $ - public interface ITargetAware - { - /// - /// Sets the target object. - /// - IAopProxy TargetProxy - { - set; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Aop.Framework +{ + /// + /// Provides access to the target object of an AOP proxy. + /// + /// + ///

+ /// To be implemented by introduction aspects in order to obtain access to + /// the target object. + ///

+ ///
+ /// Aleksandar Seovic + public interface ITargetAware + { + /// + /// Sets the target object. + /// + IAopProxy TargetProxy + { + set; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/ITargetSourceWrapper.cs b/src/Spring/Spring.Aop/Aop/Framework/ITargetSourceWrapper.cs index 373cdb98..58dceaaf 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/ITargetSourceWrapper.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/ITargetSourceWrapper.cs @@ -1,39 +1,38 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Aop.Framework -{ - /// - /// Decorates a target source with the - /// interface. - /// - /// Aleksandar Seovic - /// $Id: ITargetSourceWrapper.cs,v 1.1 2006/08/10 18:45:52 bbaia Exp $ - public interface ITargetSourceWrapper : IDisposable - { - /// - /// Returns the target object that proxy methods will be delegated to. - /// - /// The target object. - object GetTarget(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Aop.Framework +{ + /// + /// Decorates a target source with the + /// interface. + /// + /// Aleksandar Seovic + public interface ITargetSourceWrapper : IDisposable + { + /// + /// Returns the target object that proxy methods will be delegated to. + /// + /// The target object. + object GetTarget(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/InterceptorAndDynamicMethodMatcher.cs b/src/Spring/Spring.Aop/Aop/Framework/InterceptorAndDynamicMethodMatcher.cs index 73853ce5..fed01f1c 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/InterceptorAndDynamicMethodMatcher.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/InterceptorAndDynamicMethodMatcher.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using AopAlliance.Intercept; -using Spring.Aop; - -namespace Spring.Aop.Framework -{ - - /// Internal framework class. - /// This class is required because if we put an interceptor that implements IInterceptionAdvice - /// in the interceptor list passed to MethodInvocation, it may be mistaken for an - /// advice that requires dynamic method matching. - /// - /// Rod Johnson - /// Aleksandar Seovic (.Net) - /// $Id: InterceptorAndDynamicMethodMatcher.cs,v 1.3 2007/03/16 04:01:18 aseovic Exp $ - [Serializable] - internal class InterceptorAndDynamicMethodMatcher - { - internal IMethodMatcher MethodMatcher; - internal IMethodInterceptor Interceptor; - - public InterceptorAndDynamicMethodMatcher(IMethodInterceptor interceptor, IMethodMatcher methodMatcher) - { - this.Interceptor = interceptor; - this.MethodMatcher = methodMatcher; - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using AopAlliance.Intercept; +using Spring.Aop; + +namespace Spring.Aop.Framework +{ + + /// Internal framework class. + /// This class is required because if we put an interceptor that implements IInterceptionAdvice + /// in the interceptor list passed to MethodInvocation, it may be mistaken for an + /// advice that requires dynamic method matching. + /// + /// Rod Johnson + /// Aleksandar Seovic (.Net) + [Serializable] + internal class InterceptorAndDynamicMethodMatcher + { + internal IMethodMatcher MethodMatcher; + internal IMethodInterceptor Interceptor; + + public InterceptorAndDynamicMethodMatcher(IMethodInterceptor interceptor, IMethodMatcher methodMatcher) + { + this.Interceptor = interceptor; + this.MethodMatcher = methodMatcher; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/ProxyConfig.cs b/src/Spring/Spring.Aop/Aop/Framework/ProxyConfig.cs index c019aef6..0a145c4a 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/ProxyConfig.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/ProxyConfig.cs @@ -1,222 +1,221 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text; -using Spring.Aop.Framework.DynamicProxy; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Convenience superclass for configuration used in creating proxies, - /// to ensure that all proxy creators have consistent properties. - /// - /// - ///

- /// Note that it is no longer possible to configure subclasses to - /// expose the . - /// Interceptors should normally manage their own thread locals if they - /// need to make resources available to advised objects. If it is - /// absolutely necessary to expose the - /// , use an - /// interceptor to do so. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: ProxyConfig.cs,v 1.13 2007/09/07 01:51:49 markpollack Exp $ - [Serializable] - public class ProxyConfig - { - #region Fields - private bool proxyTargetType; - private bool proxyTargetAttributes = true; - private bool optimize; - private bool frozen; - - private IAopProxyFactory aopProxyFactory = - ObjectUtils.InstantiateType( typeof(ProxyConfig).Assembly, "Spring.Aop.Framework.DynamicProxy.CachedAopProxyFactory") as IAopProxyFactory; - private bool exposeProxy; - private object syncRoot = new object(); - #endregion - - #region Properites - - /// - /// Use to synchronize access to this ProxyConfig instance - /// - public object SyncRoot - { - get { return syncRoot; } - } - - /// - /// Is the target to be proxied in addition - /// to any interfaces declared on the proxied ? - /// - public virtual bool ProxyTargetType - { - get { return this.proxyTargetType; } - set { this.proxyTargetType = value; } - } - - /// - /// Is target type attributes, method attributes, method's return type attributes - /// and method's parameter attributes to be proxied in addition - /// to any interfaces declared on the proxied ? - /// - public virtual bool ProxyTargetAttributes - { - get { return this.proxyTargetAttributes; } - set { this.proxyTargetAttributes = value; } - } - - /// - /// Are any agressive optimizations to be performed? - /// - /// - ///

- /// The exact meaning of agressive optimizations will differ - /// between proxies, but there is usually some tradeoff. - ///

- ///

- /// For example, optimization will usually mean that advice changes - /// won't take effect after a proxy has been created. For this reason, - /// optimization is disabled by default. An optimize value of - /// may be ignored if other settings preclude - /// optimization: for example, if the - /// property - /// is set to and such a value is not compatible - /// with the optimization. - ///

- ///

- /// The default is . - ///

- ///
- public virtual bool Optimize - { - get { return this.optimize; } - set { this.optimize = value; } - } - - /// - /// Should proxies obtained from this configuration expose - /// the AOP proxy to the - /// class? - /// - /// - ///

- /// The default is , as enabling this property - /// may impair performance. - ///

- ///
- public bool ExposeProxy - { - get { return this.exposeProxy; } - set { this.exposeProxy = value; } - } - - /// - /// Gets and set the factory to be used to create AOP proxies. - /// - /// - ///

- /// This obviously allows one to customise the - /// implementation, - /// allowing different strategies to be dropped in without changing the - /// core framework. For example, an - /// implementation - /// could return an - /// using remoting proxies, Reflection.Emit or a code generation - /// strategy. - ///

- ///
- public virtual IAopProxyFactory AopProxyFactory - { - get { return this.aopProxyFactory; } - set { this.aopProxyFactory = value; } - } - - /// - /// Is this configuration frozen? - /// - /// - ///

- /// The default is not frozen. - ///

- ///
- public virtual bool IsFrozen - { - get { return frozen; } - set { this.frozen = value; } - } - - #endregion - - /// - /// Copies the configuration from the supplied - /// into this instance. - /// - /// - /// The configuration to be copied. - /// - /// - /// If the supplied is - /// . - /// - public virtual void CopyFrom(ProxyConfig otherConfiguration) - { - AssertUtils.ArgumentNotNull(otherConfiguration, "otherConfiguration"); - - this.optimize = otherConfiguration.optimize; - this.proxyTargetType = otherConfiguration.proxyTargetType; - this.proxyTargetAttributes = otherConfiguration.proxyTargetAttributes; - this.exposeProxy = otherConfiguration.exposeProxy; - this.frozen = otherConfiguration.frozen; - this.aopProxyFactory = otherConfiguration.aopProxyFactory; - } - - /// - /// A that represents the current - /// configuration. - /// - /// - /// A that represents the current - /// configuration. - /// - public override string ToString() - { - StringBuilder buffer = new StringBuilder(); - buffer.Append("proxyTargetType=" + ProxyTargetType + "; "); - buffer.Append("proxyTargetAttributes=" + ProxyTargetAttributes + "; "); - buffer.Append("exposeProxy=" + ExposeProxy + "; "); - buffer.Append("isFrozen=" + IsFrozen + "; "); - buffer.Append("optimize=" + Optimize + "; "); - buffer.Append("aopProxyFactory=" + AopProxyFactory.GetType().FullName + "; "); - return buffer.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text; +using Spring.Aop.Framework.DynamicProxy; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Convenience superclass for configuration used in creating proxies, + /// to ensure that all proxy creators have consistent properties. + /// + /// + ///

+ /// Note that it is no longer possible to configure subclasses to + /// expose the . + /// Interceptors should normally manage their own thread locals if they + /// need to make resources available to advised objects. If it is + /// absolutely necessary to expose the + /// , use an + /// interceptor to do so. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class ProxyConfig + { + #region Fields + private bool proxyTargetType; + private bool proxyTargetAttributes = true; + private bool optimize; + private bool frozen; + + private IAopProxyFactory aopProxyFactory = + ObjectUtils.InstantiateType( typeof(ProxyConfig).Assembly, "Spring.Aop.Framework.DynamicProxy.CachedAopProxyFactory") as IAopProxyFactory; + private bool exposeProxy; + private object syncRoot = new object(); + #endregion + + #region Properites + + /// + /// Use to synchronize access to this ProxyConfig instance + /// + public object SyncRoot + { + get { return syncRoot; } + } + + /// + /// Is the target to be proxied in addition + /// to any interfaces declared on the proxied ? + /// + public virtual bool ProxyTargetType + { + get { return this.proxyTargetType; } + set { this.proxyTargetType = value; } + } + + /// + /// Is target type attributes, method attributes, method's return type attributes + /// and method's parameter attributes to be proxied in addition + /// to any interfaces declared on the proxied ? + /// + public virtual bool ProxyTargetAttributes + { + get { return this.proxyTargetAttributes; } + set { this.proxyTargetAttributes = value; } + } + + /// + /// Are any agressive optimizations to be performed? + /// + /// + ///

+ /// The exact meaning of agressive optimizations will differ + /// between proxies, but there is usually some tradeoff. + ///

+ ///

+ /// For example, optimization will usually mean that advice changes + /// won't take effect after a proxy has been created. For this reason, + /// optimization is disabled by default. An optimize value of + /// may be ignored if other settings preclude + /// optimization: for example, if the + /// property + /// is set to and such a value is not compatible + /// with the optimization. + ///

+ ///

+ /// The default is . + ///

+ ///
+ public virtual bool Optimize + { + get { return this.optimize; } + set { this.optimize = value; } + } + + /// + /// Should proxies obtained from this configuration expose + /// the AOP proxy to the + /// class? + /// + /// + ///

+ /// The default is , as enabling this property + /// may impair performance. + ///

+ ///
+ public bool ExposeProxy + { + get { return this.exposeProxy; } + set { this.exposeProxy = value; } + } + + /// + /// Gets and set the factory to be used to create AOP proxies. + /// + /// + ///

+ /// This obviously allows one to customise the + /// implementation, + /// allowing different strategies to be dropped in without changing the + /// core framework. For example, an + /// implementation + /// could return an + /// using remoting proxies, Reflection.Emit or a code generation + /// strategy. + ///

+ ///
+ public virtual IAopProxyFactory AopProxyFactory + { + get { return this.aopProxyFactory; } + set { this.aopProxyFactory = value; } + } + + /// + /// Is this configuration frozen? + /// + /// + ///

+ /// The default is not frozen. + ///

+ ///
+ public virtual bool IsFrozen + { + get { return frozen; } + set { this.frozen = value; } + } + + #endregion + + /// + /// Copies the configuration from the supplied + /// into this instance. + /// + /// + /// The configuration to be copied. + /// + /// + /// If the supplied is + /// . + /// + public virtual void CopyFrom(ProxyConfig otherConfiguration) + { + AssertUtils.ArgumentNotNull(otherConfiguration, "otherConfiguration"); + + this.optimize = otherConfiguration.optimize; + this.proxyTargetType = otherConfiguration.proxyTargetType; + this.proxyTargetAttributes = otherConfiguration.proxyTargetAttributes; + this.exposeProxy = otherConfiguration.exposeProxy; + this.frozen = otherConfiguration.frozen; + this.aopProxyFactory = otherConfiguration.aopProxyFactory; + } + + /// + /// A that represents the current + /// configuration. + /// + /// + /// A that represents the current + /// configuration. + /// + public override string ToString() + { + StringBuilder buffer = new StringBuilder(); + buffer.Append("proxyTargetType=" + ProxyTargetType + "; "); + buffer.Append("proxyTargetAttributes=" + ProxyTargetAttributes + "; "); + buffer.Append("exposeProxy=" + ExposeProxy + "; "); + buffer.Append("isFrozen=" + IsFrozen + "; "); + buffer.Append("optimize=" + Optimize + "; "); + buffer.Append("aopProxyFactory=" + AopProxyFactory.GetType().FullName + "; "); + return buffer.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/ProxyFactory.cs b/src/Spring/Spring.Aop/Aop/Framework/ProxyFactory.cs index e562143a..0dc56014 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/ProxyFactory.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/ProxyFactory.cs @@ -1,129 +1,128 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Factory for AOP proxies for programmatic use, rather than via a - /// Spring.NET IoC container. - /// - /// - ///

- /// This class provides a simple way of obtaining and configuring AOP - /// proxies in code. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: ProxyFactory.cs,v 1.8 2007/03/16 04:01:19 aseovic Exp $ - [Serializable] - public class ProxyFactory : AdvisedSupport - { - /// - /// Creates a new instance of the - /// class. - /// - public ProxyFactory() - { - } - - /// - /// Creates a new instance of the - /// class that proxys all of the interfaces exposed by the supplied - /// . - /// - /// The object to proxy. - /// - /// If the is . - /// - public ProxyFactory(object target) : base(GetInterfaces(target)) - { - Target = target; - } - - /// - /// Creates a new instance of the - /// class that has no target object, only interfaces. - /// - /// - ///

- /// Interceptors must be added if this factory is to do anything useful. - ///

- ///
- /// The interfaces to implement. - public ProxyFactory(Type[] interfaces) : base(interfaces) {} - - /// - /// Creates a new proxy according to the settings in this factory. - /// - /// - ///

- /// Can be called repeatedly; the effect of repeated invocations will - /// (of course) vary if interfaces have been added or removed. - ///

- ///
- /// An AOP proxy for target object. - public virtual object GetProxy() - { - IAopProxy proxy = CreateAopProxy(); - return proxy.GetProxy(); - } - - #region Convenience Methods (Static) For Proxy Creation - - /// - /// Creates a new proxy for the supplied - /// and . - /// - /// - ///

- /// This is a convenience method for creating a proxy for a single - /// interceptor. - ///

- ///
- /// - /// The interface that the proxy must implement. - /// - /// - /// The interceptor that the proxy must invoke. - /// - /// - /// A new AOP proxy for the supplied - /// and . - /// - public static object GetProxy(Type proxyInterface, IInterceptor interceptor) - { - ProxyFactory proxyFactory = new ProxyFactory(); - proxyFactory.AddInterface(proxyInterface); - proxyFactory.AddAdvice(interceptor); - return proxyFactory.GetProxy(); - } - - #endregion - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Factory for AOP proxies for programmatic use, rather than via a + /// Spring.NET IoC container. + /// + /// + ///

+ /// This class provides a simple way of obtaining and configuring AOP + /// proxies in code. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class ProxyFactory : AdvisedSupport + { + /// + /// Creates a new instance of the + /// class. + /// + public ProxyFactory() + { + } + + /// + /// Creates a new instance of the + /// class that proxys all of the interfaces exposed by the supplied + /// . + /// + /// The object to proxy. + /// + /// If the is . + /// + public ProxyFactory(object target) : base(GetInterfaces(target)) + { + Target = target; + } + + /// + /// Creates a new instance of the + /// class that has no target object, only interfaces. + /// + /// + ///

+ /// Interceptors must be added if this factory is to do anything useful. + ///

+ ///
+ /// The interfaces to implement. + public ProxyFactory(Type[] interfaces) : base(interfaces) {} + + /// + /// Creates a new proxy according to the settings in this factory. + /// + /// + ///

+ /// Can be called repeatedly; the effect of repeated invocations will + /// (of course) vary if interfaces have been added or removed. + ///

+ ///
+ /// An AOP proxy for target object. + public virtual object GetProxy() + { + IAopProxy proxy = CreateAopProxy(); + return proxy.GetProxy(); + } + + #region Convenience Methods (Static) For Proxy Creation + + /// + /// Creates a new proxy for the supplied + /// and . + /// + /// + ///

+ /// This is a convenience method for creating a proxy for a single + /// interceptor. + ///

+ ///
+ /// + /// The interface that the proxy must implement. + /// + /// + /// The interceptor that the proxy must invoke. + /// + /// + /// A new AOP proxy for the supplied + /// and . + /// + public static object GetProxy(Type proxyInterface, IInterceptor interceptor) + { + ProxyFactory proxyFactory = new ProxyFactory(); + proxyFactory.AddInterface(proxyInterface); + proxyFactory.AddAdvice(interceptor); + return proxyFactory.GetProxy(); + } + + #endregion + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/ProxyFactoryObject.cs b/src/Spring/Spring.Aop/Aop/Framework/ProxyFactoryObject.cs index a45de17a..7b3738c5 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/ProxyFactoryObject.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/ProxyFactoryObject.cs @@ -1,918 +1,917 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -using AopAlliance.Aop; -using AopAlliance.Intercept; -using Common.Logging; -using Spring.Aop.Framework.Adapter; -using Spring.Aop.Support; -using Spring.Aop.Target; -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Objects.Factory; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// implementation to - /// source AOP proxies from a Spring.NET IoC container (an - /// ). - /// - /// - ///

- /// s and - /// s are identified by a list of object - /// names in the current container.

- ///

- /// Global interceptors and advisors can be added at the factory level - /// (that is, outside the context of a - /// definition). The - /// specified interceptors and advisors are expanded in an interceptor list - /// (see - /// ) - /// where an 'xxx*' wildcard-style entry is included in the list, - /// matching the given prefix with the object names. For example, - /// 'global*' would match both 'globalObject1' and - /// 'globalObjectBar', and '*' would match all defined - /// interceptors. The matching interceptors get applied according to their - /// returned order value, if they implement the - /// interface. An interceptor name list - /// may not conclude with a global 'xxx*' pattern, as global - /// interceptors cannot invoke targets. - ///

- ///

- /// It is possible to cast a proxy obtained from this factory to an - /// reference, or to obtain the - /// reference and - /// programmatically manipulate it. This won't work for existing prototype - /// references, which are independent... however, it will work for prototypes - /// subsequently obtained from the factory. Changes to interception will - /// work immediately on singletons (including existing references). - /// However, to change interfaces or the target it is necessary to obtain a - /// new instance from the surrounding container. This means that singleton - /// instances obtained from the factory do not have the same object - /// identity... however, they do have the same interceptors and target, and - /// changing any reference will change all objects. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Federico Spinazzi (.NET) - /// Choy Rim (.NET) - /// Mark Pollack (.NET) - /// Aleksandar Seovic (.NET) - /// $Id: ProxyFactoryObject.cs,v 1.26 2007/08/03 14:38:30 markpollack Exp $ - /// - /// - /// - /// - /// - [Serializable] - public class ProxyFactoryObject - : AdvisedSupport, IFactoryObject, IObjectFactoryAware, IAdvisedSupportListener - { - #region Fields - - /// - /// The shared instance for this class. - /// - private static readonly ILog logger = LogManager.GetLogger(typeof (ProxyFactoryObject)); - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - private bool singleton = true; - - /// - /// This suffix in a value in an interceptor list indicates to expand globals. - /// - public const string GlobalInterceptorSuffix = "*"; - - /// - /// The cached instance if this proxy factory object is a singleton. - /// - private object singletonInstance; - - /// - /// The owning object factory (which cannot be changed after this object is initialized). - /// - private IObjectFactory objectFactory; - - /// - /// The mapping from an or interceptor - /// to an object name (or ), depending on where it was - /// sourced from. - /// - /// - ///

- /// If it's sourced from object name, it will need to be - /// refreshed each time a new prototype instance is created. - ///

- ///
- private IDictionary sourceDictionary = new Hashtable(); - - /// - /// Names of interceptors and pointcut objects in the factory. - /// - /// - ///

- /// Default is for globals expansion only. - ///

- ///
- private string[] interceptorNames = null; - - /// - /// Names of introductions and pointcut objects in the factory. - /// - /// - ///

- /// Default is for globals expansion only. - ///

- ///
- private string[] introductionNames = null; - - /// - /// The name of the target object(in the enclosing - /// ). - /// - private string targetName = null; - - #endregion - - #region Properties - - /// - /// Sets the names of the interfaces that are to be implemented by the proxy. - /// - /// - /// The names of the interfaces that are to be implemented by the proxy. - /// - /// - /// If the supplied value (or any of its elements) is ; - /// or if any of the element values is not the (assembly qualified) name of - /// an interface type. - /// - public virtual string[] ProxyInterfaces - { - set - { - try - { - Interfaces = TypeResolutionUtils.ResolveInterfaceArray(value); - } - catch (Exception ex) - { - throw new AopConfigException("Bad value passed to the ProxyInterfaces property (see inner exception).", ex); - } - } - } - - /// - /// Sets the name of the target object being proxied. - /// - /// - ///

- /// Only works when the - /// - /// property is set; it is a logic error on the part of the programmer - /// if this value is set and the accompanying - /// is not also set. - ///

- ///
- /// - /// The name of the target object being proxied. - /// - public virtual string TargetName - { - set { this.targetName = value; } - } - - /// - /// Sets the list of and - /// object names. - /// - /// - ///

- /// This property must always be set (configured) when using a - /// in an - /// context. - ///

- ///
- /// - /// The list of and - /// object names. - /// - /// - /// - /// - /// - public virtual string[] InterceptorNames - { - set { this.interceptorNames = value; } - } - - /// - /// Sets the list of introduction object names. - /// - /// - ///

- /// Only works when the - /// - /// property is set; it is a logic error on the part of the programmer - /// if this value is set and the accompanying - /// is not supplied. - ///

- ///
- /// - /// The list of introduction object names. . - /// - public virtual string[] IntroductionNames - { - set { this.introductionNames = value; } - } - - #endregion - - #region IFactoryObjectAware implementation - - /// - /// Callback that supplies the owning factory to an object instance. - /// - /// - /// Owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - /// - /// In case of initialization errors. - /// - /// - /// - public virtual IObjectFactory ObjectFactory - { - set - { - this.objectFactory = value; - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Setting IObjectFactory. Will configure target, interceptors and introductions..."); - } - - #endregion - - ConfigureAdvisorChain(); - ConfigureIntroductions(); - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("ProxyFactoryObject config: " + this); - } - - #endregion - - if (IsSingleton) - { - if (this.targetName != null) - { - TargetSource = NamedObjectToTargetSource(this.objectFactory.GetObject(this.targetName)); - } - - // eagerly initialize the shared singleton instance... - this.singletonInstance = CreateAopProxy().GetProxy(); - - // must listen to superclass advice and interface change - // events to recache singleton instance if necessary... - AddListener(this); - } - } - } - - #endregion - - #region IFactoryObject implementation - - /// - /// Creates an instance of the AOP proxy to be returned by this factory - /// - /// - ///

- /// Invoked when clients obtain objects from this factory object. The - /// (proxy) instance will be cached for a singleton, and created on each - /// call to - /// for a prototype. - ///

- ///
- /// - /// A fresh AOP proxy reflecting the current state of this factory. - /// - /// - public virtual object GetObject() - { - lock(this.SyncRoot) - { - return (this.IsSingleton ? GetSingletonInstance() : NewPrototypeInstance()); - } - } - - /// - /// Return the of the proxy. - /// - /// - /// Will check the singleton instance if already created, - /// else fall back to the proxy interface (if a single one), - /// the target bean type, or the TargetSource's target class. - /// - /// Return the of object that this - /// creates, or - /// if not known in advance. - public virtual Type ObjectType - { - get - { - if (this.singletonInstance != null) - { - return this.singletonInstance.GetType(); - } - else if (Interfaces.Length == 1) - { - return Interfaces[0]; - } - else if (this.targetName != null && this.objectFactory != null) - { - return this.objectFactory.GetType(this.targetName); - } - else - { - return TargetSource.TargetType; - } - } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - public virtual bool IsSingleton - { - get { return this.singleton; } - set { this.singleton = value; } - } - - #endregion - - #region Private Methods - - private object NewPrototypeInstance() - { - RefreshAdvisorChain(); - RefreshTarget(); - RefreshIntroductions(); - - // in the case of a prototype, we need to give the proxy - // an independent instance of the configuration... - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Creating copy of prototype ProxyFactoryObject config: " + this); - } - - #endregion - - AdvisedSupport copy = new AdvisedSupport(); - copy.CopyConfigurationFrom(this); - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Copy has config: " + copy); - } - - #endregion - - object generatedProxy = copy.CreateAopProxy().GetProxy(); - this.ProxyType = copy.ProxyType; - this.ProxyConstructor = copy.ProxyConstructor; - return generatedProxy; - } - - /// Create the advisor (interceptor) chain. - /// - /// The advisors that are sourced from an ObjectFactory will be refreshed each time - /// a new prototype instance is added. Interceptors added programmatically through - /// the factory API are unaffected by such changes. - /// - private void ConfigureAdvisorChain() - { - if (this.interceptorNames == null || this.interceptorNames.Length == 0) - { - return; - } - - // materialize interceptor chain from object names... - for (int i = 0; i < this.interceptorNames.Length; ++i) - { - string name = this.interceptorNames[i]; - - if(name == null) - { - throw new AopConfigException("Found null interceptor name value in the InterceptorNames list; check your configuration."); - } - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Configuring interceptor '" + name + "'"); - } - - #endregion - - if (name.EndsWith(GlobalInterceptorSuffix)) - { - IListableObjectFactory lof = this.objectFactory as IListableObjectFactory; - if (lof == null) - { - // TODO : test this... - throw new AopConfigException( - "Can only use global advisors or interceptors in conjunction with an IListableObjectFactory."); - } - else - { - AddGlobalAdvisor((IListableObjectFactory) this.objectFactory, - name.Substring(0, (name.Length - GlobalInterceptorSuffix.Length))); - continue; - } - } - - else if (i == this.interceptorNames.Length - 1 && - this.targetName == null && - this.m_targetSource == EmptyTargetSource.Empty) - { - // the last name in the chain may be an IAdvisor/IAdvice or a target/ITargetSource; - // unfortunately we don't know; we must look at type of the object... - if (!IsNamedObjectAnAdvisorOrAdvice(name)) - { - this.targetName = name; - continue; - } - } - - object advice = null; - if(this.IsSingleton || - this.objectFactory.IsSingleton(name)) - { - advice = this.objectFactory.GetObject(name); - } - else - { - advice = this.objectFactory.GetObject(name); - } - if (advice is IAdvisors) - { - IAdvisors advisors = (IAdvisors)advice; - foreach (object advisor in advisors.Advisors) - { - AddAdvisor(advisor, name); - } - } - else - { - AddAdvisor(advice, name); - } - } - } - - - private bool IsNamedObjectAnAdvisorOrAdvice(string name) - { - Type namedObjectType = this.objectFactory.GetType(name); - if (namedObjectType != null) - { - return typeof(IAdvisors).IsAssignableFrom(namedObjectType) - || typeof(IAdvisor).IsAssignableFrom(namedObjectType) - || typeof(IAdvice).IsAssignableFrom(namedObjectType); - } - // treat it as an IAdvisor if we can't tell... - return true; - } - - - /// - /// Configures introductions for this proxy. - /// - private void ConfigureIntroductions() - { - if (this.introductionNames == null || this.introductionNames.Length == 0) - { - return; - } - - // Materialize introductions from object names... - for (int i = 0; i < this.introductionNames.Length; ++i) - { - string name = this.introductionNames[i]; - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Configuring introduction '" + name + "'"); - } - - #endregion - - if (name.EndsWith(GlobalInterceptorSuffix)) - { - if (!(this.objectFactory is IListableObjectFactory)) - { - throw new AopConfigException("Can only use global introductions with a ListableObjectFactory"); - } - else - { - AddGlobalIntroduction((IListableObjectFactory) this.objectFactory, - name.Substring(0, (name.Length - GlobalInterceptorSuffix.Length))); - } - } - else - { - // add a named introduction - object introduction = this.objectFactory.GetObject(this.introductionNames[i]); - AddIntroduction(introduction, this.introductionNames[i]); - } - } - } - - /// Add all global interceptors and pointcuts. - private void AddGlobalAdvisor(IListableObjectFactory objectFactory, string prefix) - { - string[] globalAspectNames = - ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisors)); - string[] globalAdvisorNames = - ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisor)); - string[] globalInterceptorNames = - ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IInterceptor)); - IList objects = new ArrayList(); - IDictionary names = new Hashtable(); - - for (int i = 0; i < globalAspectNames.Length; i++) - { - string name = globalAspectNames[i]; - if (name.StartsWith(prefix)) - { - IAdvisors advisors = (IAdvisors) objectFactory.GetObject(name); - foreach (object advisor in advisors.Advisors) - { - // exclude introduction advisors from interceptor list - if (!(advisor is IIntroductionAdvisor)) - { - objects.Add(advisor); - names[advisor] = name; - } - } - } - } - for (int i = 0; i < globalAdvisorNames.Length; i++) - { - string name = globalAdvisorNames[i]; - if (name.StartsWith(prefix)) - { - object obj = objectFactory.GetObject(name); - // exclude introduction advisors from interceptor list - if (!(obj is IIntroductionAdvisor)) - { - objects.Add(obj); - names[obj] = name; - } - } - } - for (int i = 0; i < globalInterceptorNames.Length; i++) - { - string name = globalInterceptorNames[i]; - if (name.StartsWith(prefix)) - { - object obj = objectFactory.GetObject(name); - objects.Add(obj); - names[obj] = name; - } - } - ((ArrayList) objects).Sort(new OrderComparator()); - foreach (object obj in objects) - { - string name = (string) names[obj]; - AddAdvisor(obj, name); - } - } - - /// Add all global introductions. - private void AddGlobalIntroduction(IListableObjectFactory objectFactory, string prefix) - { - string[] globalAspectNames = - ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisors)); - string[] globalAdvisorNames = - ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof (IAdvisor)); - string[] globalIntroductionNames = - ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof (IAdvice)); - IList objects = new ArrayList(); - IDictionary names = new Hashtable(); - - for (int i = 0; i < globalAspectNames.Length; i++) - { - string name = globalAspectNames[i]; - if (name.StartsWith(prefix)) - { - IAdvisors advisors = (IAdvisors)objectFactory.GetObject(name); - foreach (object advisor in advisors.Advisors) - { - // only include introduction advisors - if (advisor is IIntroductionAdvisor) - { - objects.Add(advisor); - names[advisor] = name; - } - } - } - } - for (int i = 0; i < globalAdvisorNames.Length; i++) - { - string name = globalAdvisorNames[i]; - if (name.StartsWith(prefix)) - { - object obj = objectFactory.GetObject(name); - // only include introduction advisors - if (obj is IIntroductionAdvisor) - { - objects.Add(obj); - names[obj] = name; - } - } - } - for (int i = 0; i < globalIntroductionNames.Length; i++) - { - string name = globalIntroductionNames[i]; - if (name.StartsWith(prefix)) - { - object obj = objectFactory.GetObject(name); - // exclude other advice types - if (!(obj is IInterceptor || obj is IBeforeAdvice || obj is IAfterReturningAdvice)) - { - objects.Add(obj); - names[obj] = name; - } - } - } - ((ArrayList) objects).Sort(new OrderComparator()); - foreach (object obj in objects) - { - string name = (string) names[obj]; - AddIntroduction(obj, name); - } - } - - /// Add the given interceptor or pointcut to the interceptor list. - /// interceptor or pointcut to add - /// object name from which we obtained this object in our owning object factory - private void AddAdvisor(object next, string name) - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Adding advisor with name '" + name + "'."); - } - - #endregion - - IAdvisor advisor = NamedObjectToAdvisor(next); - AddAdvisor(advisor); - - // Record the pointcut as descended from the given object name. - // This allows us to refresh the interceptor list, which we'll need to - // do if we have to create a new prototype instance. Otherwise the new - // prototype instance wouldn't be truly independent, because it might - // reference the original instances of prototype interceptors. - this.sourceDictionary[advisor] = name; - } - - /// Add the introduction to the introduction list. - /// - /// If specified parameter is IIntroducionAdvisor it is added directly, otherwise it is wrapped - /// with DefaultIntroductionAdvisor first. - /// - /// introducion to add - /// object name from which we obtained this object in our owning object factory - private void AddIntroduction(object introduction, string name) - { - logger.Debug("Adding introduction with name [" + name + "]"); - IIntroductionAdvisor advisor = NamedObjectToIntroduction(introduction); - AddIntroduction(advisor); - - // Record the introduction as descended from the given object name. - // This allows us to refresh the introduction list, which we'll need to - // do if we have to create a new prototype instance. Otherwise the new - // prototype instance wouldn't be truly independent, because it might - // reference the original instances of prototype introductions. - this.sourceDictionary[advisor] = name; - } - - /// Refresh named objects from the interceptor chain. - /// We need to do this every time a new prototype instance is returned, - /// to return distinct instances of prototype interfaces and pointcuts. - /// - private void RefreshAdvisorChain() - { - IAdvisor[] advisors = Advisors; - for (int i = 0; i < advisors.Length; ++i) - { - string objectName = (string) this.sourceDictionary[advisors[i]]; - if (objectName != null) - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Refreshing object named '" + objectName + "'"); - } - - #endregion - - IAdvisor refreshedAdvisor - = NamedObjectToAdvisor(this.objectFactory.GetObject(objectName)); - ReplaceAdvisor(advisors[i], refreshedAdvisor); - this.sourceDictionary.Remove(advisors[i]); - // keep name mapping up to date... - this.sourceDictionary[refreshedAdvisor] = objectName; - } - else - { - // We can't throw an exception here, as the user may have added additional - // pointcuts programmatically we don't know about - logger.Info( - "Cannot find object name for Advisor [" + advisors[i] + "] when refreshing advisor chain"); - } - } - } - - /// - /// Refreshes target object for prototype instances. - /// - private void RefreshTarget() - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Refreshing target with name '" + this.targetName + "'"); - } - - #endregion - - if (StringUtils.IsNullOrEmpty(this.targetName)) - { - // TODO test... - throw new AopConfigException("Target name cannot be null (or composed wholly of whitespace) for prototype factory."); - } - object target = this.objectFactory.GetObject(this.targetName); - TargetSource = NamedObjectToTargetSource(target); - } - - /// Refresh named objects from the interceptor chain. - /// We need to do this every time a new prototype instance is returned, - /// to return distinct instances of prototype interfaces and pointcuts. - /// - private void RefreshIntroductions() - { - IIntroductionAdvisor[] introductions = Introductions; - for (int i = 0; i < introductions.Length; i++) - { - string objectName = (string) this.sourceDictionary[introductions[i]]; - if (objectName != null) - { - logger.Info("Refreshing introduction named '" + objectName + "'"); - object obj = this.objectFactory.GetObject(objectName); - IIntroductionAdvisor refreshedIntroduction = NamedObjectToIntroduction(obj); - - ReplaceIntroduction(i, refreshedIntroduction); - this.sourceDictionary.Remove(introductions[i]); - this.sourceDictionary[refreshedIntroduction] = objectName; - } - else - { - // We can't throw an exception here, as the user may have added additional - // introductions programmatically we don't know about - logger.Info( - "Cannot find object name for Introduction [" + introductions[i] + - "] when refreshing introduction list"); - } - } - } - - /// Wraps pointcut or interceptor with appropriate advisor - /// pointcut or interceptor that needs to be wrapped with advisor - /// Advisor - private IAdvisor NamedObjectToAdvisor(object next) - { - return GlobalAdvisorAdapterRegistry.Instance.Wrap(next); - } - - /// Wraps target with SingletonTargetSource if necessary - /// target or target source object - /// target source passed or target wrapped with SingletonTargetSource - private ITargetSource NamedObjectToTargetSource(object target) - { - if (target is ITargetSource) - { - return (ITargetSource) target; - } - else - { - // It's an object that needs target source around it. - return new SingletonTargetSource(target); - } - } - - /// Wraps introduction with IIntroductionAdvisor if necessary - /// object to wrap - /// Introduction advisor - private IIntroductionAdvisor NamedObjectToIntroduction(object introduction) - { - if (introduction is IIntroductionAdvisor) - { - return (IIntroductionAdvisor) introduction; - } - else - { - return new DefaultIntroductionAdvisor((IAdvice) introduction); - } - } - - private object GetSingletonInstance() - { - if (this.singletonInstance == null) - { - this.singletonInstance = CreateAopProxy().GetProxy(); - } - return this.singletonInstance; - } - - #endregion - - #region IAdvisedSupportListener implementation - - /// - /// - public virtual void Activated(AdvisedSupport advisedSupport) - { - } - - /// No need to do anything when advice change, proxy can handle those changes by itself. - /// - /// - public virtual void AdviceChanged(AdvisedSupport advisedSupport) - { - } - - /// Implementation of listener for AdvisedSupport.InterfacesChanged event - /// event source - public virtual void InterfacesChanged(AdvisedSupport advisedSupport) - { - logger.Info("Implemented interfaces have changed; reseting singleton instance"); - this.singletonInstance = null; - this.ProxyType = null; - this.ProxyConstructor = null; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +using AopAlliance.Aop; +using AopAlliance.Intercept; +using Common.Logging; +using Spring.Aop.Framework.Adapter; +using Spring.Aop.Support; +using Spring.Aop.Target; +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Objects.Factory; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// implementation to + /// source AOP proxies from a Spring.NET IoC container (an + /// ). + /// + /// + ///

+ /// s and + /// s are identified by a list of object + /// names in the current container.

+ ///

+ /// Global interceptors and advisors can be added at the factory level + /// (that is, outside the context of a + /// definition). The + /// specified interceptors and advisors are expanded in an interceptor list + /// (see + /// ) + /// where an 'xxx*' wildcard-style entry is included in the list, + /// matching the given prefix with the object names. For example, + /// 'global*' would match both 'globalObject1' and + /// 'globalObjectBar', and '*' would match all defined + /// interceptors. The matching interceptors get applied according to their + /// returned order value, if they implement the + /// interface. An interceptor name list + /// may not conclude with a global 'xxx*' pattern, as global + /// interceptors cannot invoke targets. + ///

+ ///

+ /// It is possible to cast a proxy obtained from this factory to an + /// reference, or to obtain the + /// reference and + /// programmatically manipulate it. This won't work for existing prototype + /// references, which are independent... however, it will work for prototypes + /// subsequently obtained from the factory. Changes to interception will + /// work immediately on singletons (including existing references). + /// However, to change interfaces or the target it is necessary to obtain a + /// new instance from the surrounding container. This means that singleton + /// instances obtained from the factory do not have the same object + /// identity... however, they do have the same interceptors and target, and + /// changing any reference will change all objects. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Federico Spinazzi (.NET) + /// Choy Rim (.NET) + /// Mark Pollack (.NET) + /// Aleksandar Seovic (.NET) + /// + /// + /// + /// + /// + [Serializable] + public class ProxyFactoryObject + : AdvisedSupport, IFactoryObject, IObjectFactoryAware, IAdvisedSupportListener + { + #region Fields + + /// + /// The shared instance for this class. + /// + private static readonly ILog logger = LogManager.GetLogger(typeof (ProxyFactoryObject)); + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + private bool singleton = true; + + /// + /// This suffix in a value in an interceptor list indicates to expand globals. + /// + public const string GlobalInterceptorSuffix = "*"; + + /// + /// The cached instance if this proxy factory object is a singleton. + /// + private object singletonInstance; + + /// + /// The owning object factory (which cannot be changed after this object is initialized). + /// + private IObjectFactory objectFactory; + + /// + /// The mapping from an or interceptor + /// to an object name (or ), depending on where it was + /// sourced from. + /// + /// + ///

+ /// If it's sourced from object name, it will need to be + /// refreshed each time a new prototype instance is created. + ///

+ ///
+ private IDictionary sourceDictionary = new Hashtable(); + + /// + /// Names of interceptors and pointcut objects in the factory. + /// + /// + ///

+ /// Default is for globals expansion only. + ///

+ ///
+ private string[] interceptorNames = null; + + /// + /// Names of introductions and pointcut objects in the factory. + /// + /// + ///

+ /// Default is for globals expansion only. + ///

+ ///
+ private string[] introductionNames = null; + + /// + /// The name of the target object(in the enclosing + /// ). + /// + private string targetName = null; + + #endregion + + #region Properties + + /// + /// Sets the names of the interfaces that are to be implemented by the proxy. + /// + /// + /// The names of the interfaces that are to be implemented by the proxy. + /// + /// + /// If the supplied value (or any of its elements) is ; + /// or if any of the element values is not the (assembly qualified) name of + /// an interface type. + /// + public virtual string[] ProxyInterfaces + { + set + { + try + { + Interfaces = TypeResolutionUtils.ResolveInterfaceArray(value); + } + catch (Exception ex) + { + throw new AopConfigException("Bad value passed to the ProxyInterfaces property (see inner exception).", ex); + } + } + } + + /// + /// Sets the name of the target object being proxied. + /// + /// + ///

+ /// Only works when the + /// + /// property is set; it is a logic error on the part of the programmer + /// if this value is set and the accompanying + /// is not also set. + ///

+ ///
+ /// + /// The name of the target object being proxied. + /// + public virtual string TargetName + { + set { this.targetName = value; } + } + + /// + /// Sets the list of and + /// object names. + /// + /// + ///

+ /// This property must always be set (configured) when using a + /// in an + /// context. + ///

+ ///
+ /// + /// The list of and + /// object names. + /// + /// + /// + /// + /// + public virtual string[] InterceptorNames + { + set { this.interceptorNames = value; } + } + + /// + /// Sets the list of introduction object names. + /// + /// + ///

+ /// Only works when the + /// + /// property is set; it is a logic error on the part of the programmer + /// if this value is set and the accompanying + /// is not supplied. + ///

+ ///
+ /// + /// The list of introduction object names. . + /// + public virtual string[] IntroductionNames + { + set { this.introductionNames = value; } + } + + #endregion + + #region IFactoryObjectAware implementation + + /// + /// Callback that supplies the owning factory to an object instance. + /// + /// + /// Owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + /// + /// In case of initialization errors. + /// + /// + /// + public virtual IObjectFactory ObjectFactory + { + set + { + this.objectFactory = value; + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Setting IObjectFactory. Will configure target, interceptors and introductions..."); + } + + #endregion + + ConfigureAdvisorChain(); + ConfigureIntroductions(); + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("ProxyFactoryObject config: " + this); + } + + #endregion + + if (IsSingleton) + { + if (this.targetName != null) + { + TargetSource = NamedObjectToTargetSource(this.objectFactory.GetObject(this.targetName)); + } + + // eagerly initialize the shared singleton instance... + this.singletonInstance = CreateAopProxy().GetProxy(); + + // must listen to superclass advice and interface change + // events to recache singleton instance if necessary... + AddListener(this); + } + } + } + + #endregion + + #region IFactoryObject implementation + + /// + /// Creates an instance of the AOP proxy to be returned by this factory + /// + /// + ///

+ /// Invoked when clients obtain objects from this factory object. The + /// (proxy) instance will be cached for a singleton, and created on each + /// call to + /// for a prototype. + ///

+ ///
+ /// + /// A fresh AOP proxy reflecting the current state of this factory. + /// + /// + public virtual object GetObject() + { + lock(this.SyncRoot) + { + return (this.IsSingleton ? GetSingletonInstance() : NewPrototypeInstance()); + } + } + + /// + /// Return the of the proxy. + /// + /// + /// Will check the singleton instance if already created, + /// else fall back to the proxy interface (if a single one), + /// the target bean type, or the TargetSource's target class. + /// + /// Return the of object that this + /// creates, or + /// if not known in advance. + public virtual Type ObjectType + { + get + { + if (this.singletonInstance != null) + { + return this.singletonInstance.GetType(); + } + else if (Interfaces.Length == 1) + { + return Interfaces[0]; + } + else if (this.targetName != null && this.objectFactory != null) + { + return this.objectFactory.GetType(this.targetName); + } + else + { + return TargetSource.TargetType; + } + } + } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + public virtual bool IsSingleton + { + get { return this.singleton; } + set { this.singleton = value; } + } + + #endregion + + #region Private Methods + + private object NewPrototypeInstance() + { + RefreshAdvisorChain(); + RefreshTarget(); + RefreshIntroductions(); + + // in the case of a prototype, we need to give the proxy + // an independent instance of the configuration... + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Creating copy of prototype ProxyFactoryObject config: " + this); + } + + #endregion + + AdvisedSupport copy = new AdvisedSupport(); + copy.CopyConfigurationFrom(this); + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Copy has config: " + copy); + } + + #endregion + + object generatedProxy = copy.CreateAopProxy().GetProxy(); + this.ProxyType = copy.ProxyType; + this.ProxyConstructor = copy.ProxyConstructor; + return generatedProxy; + } + + /// Create the advisor (interceptor) chain. + /// + /// The advisors that are sourced from an ObjectFactory will be refreshed each time + /// a new prototype instance is added. Interceptors added programmatically through + /// the factory API are unaffected by such changes. + /// + private void ConfigureAdvisorChain() + { + if (this.interceptorNames == null || this.interceptorNames.Length == 0) + { + return; + } + + // materialize interceptor chain from object names... + for (int i = 0; i < this.interceptorNames.Length; ++i) + { + string name = this.interceptorNames[i]; + + if(name == null) + { + throw new AopConfigException("Found null interceptor name value in the InterceptorNames list; check your configuration."); + } + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Configuring interceptor '" + name + "'"); + } + + #endregion + + if (name.EndsWith(GlobalInterceptorSuffix)) + { + IListableObjectFactory lof = this.objectFactory as IListableObjectFactory; + if (lof == null) + { + // TODO : test this... + throw new AopConfigException( + "Can only use global advisors or interceptors in conjunction with an IListableObjectFactory."); + } + else + { + AddGlobalAdvisor((IListableObjectFactory) this.objectFactory, + name.Substring(0, (name.Length - GlobalInterceptorSuffix.Length))); + continue; + } + } + + else if (i == this.interceptorNames.Length - 1 && + this.targetName == null && + this.m_targetSource == EmptyTargetSource.Empty) + { + // the last name in the chain may be an IAdvisor/IAdvice or a target/ITargetSource; + // unfortunately we don't know; we must look at type of the object... + if (!IsNamedObjectAnAdvisorOrAdvice(name)) + { + this.targetName = name; + continue; + } + } + + object advice = null; + if(this.IsSingleton || + this.objectFactory.IsSingleton(name)) + { + advice = this.objectFactory.GetObject(name); + } + else + { + advice = this.objectFactory.GetObject(name); + } + if (advice is IAdvisors) + { + IAdvisors advisors = (IAdvisors)advice; + foreach (object advisor in advisors.Advisors) + { + AddAdvisor(advisor, name); + } + } + else + { + AddAdvisor(advice, name); + } + } + } + + + private bool IsNamedObjectAnAdvisorOrAdvice(string name) + { + Type namedObjectType = this.objectFactory.GetType(name); + if (namedObjectType != null) + { + return typeof(IAdvisors).IsAssignableFrom(namedObjectType) + || typeof(IAdvisor).IsAssignableFrom(namedObjectType) + || typeof(IAdvice).IsAssignableFrom(namedObjectType); + } + // treat it as an IAdvisor if we can't tell... + return true; + } + + + /// + /// Configures introductions for this proxy. + /// + private void ConfigureIntroductions() + { + if (this.introductionNames == null || this.introductionNames.Length == 0) + { + return; + } + + // Materialize introductions from object names... + for (int i = 0; i < this.introductionNames.Length; ++i) + { + string name = this.introductionNames[i]; + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Configuring introduction '" + name + "'"); + } + + #endregion + + if (name.EndsWith(GlobalInterceptorSuffix)) + { + if (!(this.objectFactory is IListableObjectFactory)) + { + throw new AopConfigException("Can only use global introductions with a ListableObjectFactory"); + } + else + { + AddGlobalIntroduction((IListableObjectFactory) this.objectFactory, + name.Substring(0, (name.Length - GlobalInterceptorSuffix.Length))); + } + } + else + { + // add a named introduction + object introduction = this.objectFactory.GetObject(this.introductionNames[i]); + AddIntroduction(introduction, this.introductionNames[i]); + } + } + } + + /// Add all global interceptors and pointcuts. + private void AddGlobalAdvisor(IListableObjectFactory objectFactory, string prefix) + { + string[] globalAspectNames = + ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisors)); + string[] globalAdvisorNames = + ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisor)); + string[] globalInterceptorNames = + ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IInterceptor)); + IList objects = new ArrayList(); + IDictionary names = new Hashtable(); + + for (int i = 0; i < globalAspectNames.Length; i++) + { + string name = globalAspectNames[i]; + if (name.StartsWith(prefix)) + { + IAdvisors advisors = (IAdvisors) objectFactory.GetObject(name); + foreach (object advisor in advisors.Advisors) + { + // exclude introduction advisors from interceptor list + if (!(advisor is IIntroductionAdvisor)) + { + objects.Add(advisor); + names[advisor] = name; + } + } + } + } + for (int i = 0; i < globalAdvisorNames.Length; i++) + { + string name = globalAdvisorNames[i]; + if (name.StartsWith(prefix)) + { + object obj = objectFactory.GetObject(name); + // exclude introduction advisors from interceptor list + if (!(obj is IIntroductionAdvisor)) + { + objects.Add(obj); + names[obj] = name; + } + } + } + for (int i = 0; i < globalInterceptorNames.Length; i++) + { + string name = globalInterceptorNames[i]; + if (name.StartsWith(prefix)) + { + object obj = objectFactory.GetObject(name); + objects.Add(obj); + names[obj] = name; + } + } + ((ArrayList) objects).Sort(new OrderComparator()); + foreach (object obj in objects) + { + string name = (string) names[obj]; + AddAdvisor(obj, name); + } + } + + /// Add all global introductions. + private void AddGlobalIntroduction(IListableObjectFactory objectFactory, string prefix) + { + string[] globalAspectNames = + ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisors)); + string[] globalAdvisorNames = + ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof (IAdvisor)); + string[] globalIntroductionNames = + ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof (IAdvice)); + IList objects = new ArrayList(); + IDictionary names = new Hashtable(); + + for (int i = 0; i < globalAspectNames.Length; i++) + { + string name = globalAspectNames[i]; + if (name.StartsWith(prefix)) + { + IAdvisors advisors = (IAdvisors)objectFactory.GetObject(name); + foreach (object advisor in advisors.Advisors) + { + // only include introduction advisors + if (advisor is IIntroductionAdvisor) + { + objects.Add(advisor); + names[advisor] = name; + } + } + } + } + for (int i = 0; i < globalAdvisorNames.Length; i++) + { + string name = globalAdvisorNames[i]; + if (name.StartsWith(prefix)) + { + object obj = objectFactory.GetObject(name); + // only include introduction advisors + if (obj is IIntroductionAdvisor) + { + objects.Add(obj); + names[obj] = name; + } + } + } + for (int i = 0; i < globalIntroductionNames.Length; i++) + { + string name = globalIntroductionNames[i]; + if (name.StartsWith(prefix)) + { + object obj = objectFactory.GetObject(name); + // exclude other advice types + if (!(obj is IInterceptor || obj is IBeforeAdvice || obj is IAfterReturningAdvice)) + { + objects.Add(obj); + names[obj] = name; + } + } + } + ((ArrayList) objects).Sort(new OrderComparator()); + foreach (object obj in objects) + { + string name = (string) names[obj]; + AddIntroduction(obj, name); + } + } + + /// Add the given interceptor or pointcut to the interceptor list. + /// interceptor or pointcut to add + /// object name from which we obtained this object in our owning object factory + private void AddAdvisor(object next, string name) + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Adding advisor with name '" + name + "'."); + } + + #endregion + + IAdvisor advisor = NamedObjectToAdvisor(next); + AddAdvisor(advisor); + + // Record the pointcut as descended from the given object name. + // This allows us to refresh the interceptor list, which we'll need to + // do if we have to create a new prototype instance. Otherwise the new + // prototype instance wouldn't be truly independent, because it might + // reference the original instances of prototype interceptors. + this.sourceDictionary[advisor] = name; + } + + /// Add the introduction to the introduction list. + /// + /// If specified parameter is IIntroducionAdvisor it is added directly, otherwise it is wrapped + /// with DefaultIntroductionAdvisor first. + /// + /// introducion to add + /// object name from which we obtained this object in our owning object factory + private void AddIntroduction(object introduction, string name) + { + logger.Debug("Adding introduction with name [" + name + "]"); + IIntroductionAdvisor advisor = NamedObjectToIntroduction(introduction); + AddIntroduction(advisor); + + // Record the introduction as descended from the given object name. + // This allows us to refresh the introduction list, which we'll need to + // do if we have to create a new prototype instance. Otherwise the new + // prototype instance wouldn't be truly independent, because it might + // reference the original instances of prototype introductions. + this.sourceDictionary[advisor] = name; + } + + /// Refresh named objects from the interceptor chain. + /// We need to do this every time a new prototype instance is returned, + /// to return distinct instances of prototype interfaces and pointcuts. + /// + private void RefreshAdvisorChain() + { + IAdvisor[] advisors = Advisors; + for (int i = 0; i < advisors.Length; ++i) + { + string objectName = (string) this.sourceDictionary[advisors[i]]; + if (objectName != null) + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Refreshing object named '" + objectName + "'"); + } + + #endregion + + IAdvisor refreshedAdvisor + = NamedObjectToAdvisor(this.objectFactory.GetObject(objectName)); + ReplaceAdvisor(advisors[i], refreshedAdvisor); + this.sourceDictionary.Remove(advisors[i]); + // keep name mapping up to date... + this.sourceDictionary[refreshedAdvisor] = objectName; + } + else + { + // We can't throw an exception here, as the user may have added additional + // pointcuts programmatically we don't know about + logger.Info( + "Cannot find object name for Advisor [" + advisors[i] + "] when refreshing advisor chain"); + } + } + } + + /// + /// Refreshes target object for prototype instances. + /// + private void RefreshTarget() + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Refreshing target with name '" + this.targetName + "'"); + } + + #endregion + + if (StringUtils.IsNullOrEmpty(this.targetName)) + { + // TODO test... + throw new AopConfigException("Target name cannot be null (or composed wholly of whitespace) for prototype factory."); + } + object target = this.objectFactory.GetObject(this.targetName); + TargetSource = NamedObjectToTargetSource(target); + } + + /// Refresh named objects from the interceptor chain. + /// We need to do this every time a new prototype instance is returned, + /// to return distinct instances of prototype interfaces and pointcuts. + /// + private void RefreshIntroductions() + { + IIntroductionAdvisor[] introductions = Introductions; + for (int i = 0; i < introductions.Length; i++) + { + string objectName = (string) this.sourceDictionary[introductions[i]]; + if (objectName != null) + { + logger.Info("Refreshing introduction named '" + objectName + "'"); + object obj = this.objectFactory.GetObject(objectName); + IIntroductionAdvisor refreshedIntroduction = NamedObjectToIntroduction(obj); + + ReplaceIntroduction(i, refreshedIntroduction); + this.sourceDictionary.Remove(introductions[i]); + this.sourceDictionary[refreshedIntroduction] = objectName; + } + else + { + // We can't throw an exception here, as the user may have added additional + // introductions programmatically we don't know about + logger.Info( + "Cannot find object name for Introduction [" + introductions[i] + + "] when refreshing introduction list"); + } + } + } + + /// Wraps pointcut or interceptor with appropriate advisor + /// pointcut or interceptor that needs to be wrapped with advisor + /// Advisor + private IAdvisor NamedObjectToAdvisor(object next) + { + return GlobalAdvisorAdapterRegistry.Instance.Wrap(next); + } + + /// Wraps target with SingletonTargetSource if necessary + /// target or target source object + /// target source passed or target wrapped with SingletonTargetSource + private ITargetSource NamedObjectToTargetSource(object target) + { + if (target is ITargetSource) + { + return (ITargetSource) target; + } + else + { + // It's an object that needs target source around it. + return new SingletonTargetSource(target); + } + } + + /// Wraps introduction with IIntroductionAdvisor if necessary + /// object to wrap + /// Introduction advisor + private IIntroductionAdvisor NamedObjectToIntroduction(object introduction) + { + if (introduction is IIntroductionAdvisor) + { + return (IIntroductionAdvisor) introduction; + } + else + { + return new DefaultIntroductionAdvisor((IAdvice) introduction); + } + } + + private object GetSingletonInstance() + { + if (this.singletonInstance == null) + { + this.singletonInstance = CreateAopProxy().GetProxy(); + } + return this.singletonInstance; + } + + #endregion + + #region IAdvisedSupportListener implementation + + /// + /// + public virtual void Activated(AdvisedSupport advisedSupport) + { + } + + /// No need to do anything when advice change, proxy can handle those changes by itself. + /// + /// + public virtual void AdviceChanged(AdvisedSupport advisedSupport) + { + } + + /// Implementation of listener for AdvisedSupport.InterfacesChanged event + /// event source + public virtual void InterfacesChanged(AdvisedSupport advisedSupport) + { + logger.Info("Implemented interfaces have changed; reseting singleton instance"); + this.singletonInstance = null; + this.ProxyType = null; + this.ProxyConstructor = null; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/ReflectiveMethodInvocation.cs b/src/Spring/Spring.Aop/Aop/Framework/ReflectiveMethodInvocation.cs index 0901bbc0..152359f3 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/ReflectiveMethodInvocation.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/ReflectiveMethodInvocation.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -using Spring.Util; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Invokes a target method using standard reflection. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// Rick Evans (.NET) - /// Bruno Baia (.NET) - /// $Id: ReflectiveMethodInvocation.cs,v 1.18 2008/02/06 18:28:52 bbaia Exp $ - [Serializable] - public class ReflectiveMethodInvocation : AbstractMethodInvocation - { - /// - /// The method invocation that is to be invoked on the proxy. - /// - protected MethodInfo proxyMethod; - - /// - /// Creates a new instance of the - /// class. - /// - /// The AOP proxy. - /// The target object. - /// The target method proxied. - /// The method to invoke on proxy. - /// The target method's arguments. - /// - /// The of the target object. - /// - /// The list of interceptors that are to be applied. May be - /// . - /// - /// - /// If any of the or - /// parameters is . - /// - public ReflectiveMethodInvocation( - object proxy, object target, MethodInfo method, MethodInfo proxyMethod, - object[] arguments, Type targetType, IList interceptors) - : base(proxy, target, method, arguments, targetType, interceptors) - { - this.proxyMethod = proxyMethod; - } - - /// - /// Invokes the joinpoint using standard reflection. - /// - /// - ///

- /// Subclasses can override this to use custom invocation. - ///

- ///
- /// - /// The return value of the invocation of the joinpoint. - /// - /// - /// If invoking the joinpoint resulted in an exception. - /// - /// - protected override object InvokeJoinpoint() - { - try - { - if (proxyMethod == null) - { - return method.Invoke(target, arguments); - } - else - { - return proxyMethod.Invoke(target, arguments); - } - } - catch (TargetInvocationException ex) - { - throw ReflectionUtils.UnwrapTargetInvocationException(ex); - } - } - - /// - /// Creates a new instance - /// from the specified and - /// increments the interceptor index. - /// - /// - /// The current instance. - /// - /// - /// The new instance to use. - /// - protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation) - { - ReflectiveMethodInvocation rmi = new ReflectiveMethodInvocation( - this.proxy, this.target, this.method, this.proxyMethod, this.arguments, this.targetType, this.interceptors); - rmi.currentInterceptorIndex = this.currentInterceptorIndex + 1; - - return rmi; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +using Spring.Util; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Invokes a target method using standard reflection. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// Rick Evans (.NET) + /// Bruno Baia (.NET) + [Serializable] + public class ReflectiveMethodInvocation : AbstractMethodInvocation + { + /// + /// The method invocation that is to be invoked on the proxy. + /// + protected MethodInfo proxyMethod; + + /// + /// Creates a new instance of the + /// class. + /// + /// The AOP proxy. + /// The target object. + /// The target method proxied. + /// The method to invoke on proxy. + /// The target method's arguments. + /// + /// The of the target object. + /// + /// The list of interceptors that are to be applied. May be + /// . + /// + /// + /// If any of the or + /// parameters is . + /// + public ReflectiveMethodInvocation( + object proxy, object target, MethodInfo method, MethodInfo proxyMethod, + object[] arguments, Type targetType, IList interceptors) + : base(proxy, target, method, arguments, targetType, interceptors) + { + this.proxyMethod = proxyMethod; + } + + /// + /// Invokes the joinpoint using standard reflection. + /// + /// + ///

+ /// Subclasses can override this to use custom invocation. + ///

+ ///
+ /// + /// The return value of the invocation of the joinpoint. + /// + /// + /// If invoking the joinpoint resulted in an exception. + /// + /// + protected override object InvokeJoinpoint() + { + try + { + if (proxyMethod == null) + { + return method.Invoke(target, arguments); + } + else + { + return proxyMethod.Invoke(target, arguments); + } + } + catch (TargetInvocationException ex) + { + throw ReflectionUtils.UnwrapTargetInvocationException(ex); + } + } + + /// + /// Creates a new instance + /// from the specified and + /// increments the interceptor index. + /// + /// + /// The current instance. + /// + /// + /// The new instance to use. + /// + protected override IMethodInvocation PrepareMethodInvocationForProceed(IMethodInvocation invocation) + { + ReflectiveMethodInvocation rmi = new ReflectiveMethodInvocation( + this.proxy, this.target, this.method, this.proxyMethod, this.arguments, this.targetType, this.interceptors); + rmi.currentInterceptorIndex = this.currentInterceptorIndex + 1; + + return rmi; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Framework/StaticTargetSourceWrapper.cs b/src/Spring/Spring.Aop/Aop/Framework/StaticTargetSourceWrapper.cs index 8ee45180..65df4d14 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/StaticTargetSourceWrapper.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/StaticTargetSourceWrapper.cs @@ -1,88 +1,87 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Framework -{ - /// - /// Decorates a target source with the - /// interface. - /// - /// - ///

- /// Because the target source is static, the target object can be cached - /// and simply returned as is. - ///

- ///
- /// Aleksandar Seovic - /// $Id: StaticTargetSourceWrapper.cs,v 1.3 2007/03/16 04:01:20 aseovic Exp $ - [Serializable] - public sealed class StaticTargetSourceWrapper : ITargetSourceWrapper - { - private object target; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The target object that proxy methods will be delegated to. - /// - /// - /// If the supplied is - /// . - /// - internal StaticTargetSourceWrapper(ITargetSource targetSource) - { - AssertUtils.ArgumentNotNull(targetSource, "targetSource"); - this.target = targetSource.GetTarget(); - } - - /// - /// Returns the target object that proxy methods will be delegated to. - /// - /// The target object. - public object GetTarget() - { - return this.target; - } - - /// - /// Performs application-defined tasks associated with freeing, - /// releasing, or resetting unmanaged resources. - /// - /// - /// - /// This is a no-op operation in this implementation. - /// - /// - public void Dispose() - { - // do nothing, this is static target source wrapper... - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Framework +{ + /// + /// Decorates a target source with the + /// interface. + /// + /// + ///

+ /// Because the target source is static, the target object can be cached + /// and simply returned as is. + ///

+ ///
+ /// Aleksandar Seovic + [Serializable] + public sealed class StaticTargetSourceWrapper : ITargetSourceWrapper + { + private object target; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The target object that proxy methods will be delegated to. + /// + /// + /// If the supplied is + /// . + /// + internal StaticTargetSourceWrapper(ITargetSource targetSource) + { + AssertUtils.ArgumentNotNull(targetSource, "targetSource"); + this.target = targetSource.GetTarget(); + } + + /// + /// Returns the target object that proxy methods will be delegated to. + /// + /// The target object. + public object GetTarget() + { + return this.target; + } + + /// + /// Performs application-defined tasks associated with freeing, + /// releasing, or resetting unmanaged resources. + /// + /// + /// + /// This is a no-op operation in this implementation. + /// + /// + public void Dispose() + { + // do nothing, this is static target source wrapper... + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IAdvisor.cs b/src/Spring/Spring.Aop/Aop/IAdvisor.cs index c28b0294..b48f6d65 100644 --- a/src/Spring/Spring.Aop/Aop/IAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/IAdvisor.cs @@ -1,96 +1,95 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; - -#endregion - -namespace Spring.Aop -{ - /// - /// Base interface holding AOP advice and a filter determining the - /// applicability of the advice (such as a pointcut). - /// - /// - /// - /// This interface is not for use by Spring.NET users, but exists rather to - /// allow for commonality in the support for different types of advice - /// within the framework. - /// - ///

- /// Spring.NET AOP is centered on around advice delivered via method - /// interception, compliant with the AOP Alliance interception API. - /// The interface allows support for - /// different types of advice, such as before and after - /// advice, which need not be implemented using interception. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// - /// - /// - /// $Id: IAdvisor.cs,v 1.7 2006/04/09 07:18:36 markpollack Exp $ - public interface IAdvisor - { - /// - /// Is this advice associated with a particular instance? - /// - /// - ///

- /// An advisor that was creating a mixin would be a per instance - /// operation and would thus return . If the - /// advisor is not per instance, it is shared with all instances of the - /// advised class obtained from the same Spring.NET IoC container. - ///

- ///

- /// Use singleton and prototype object definitions or - /// appropriate programmatic proxy creation to ensure that - /// s have the correct lifecycle model. - ///

- /// - /// This method is not currently used by the framework. - /// - ///
- /// - /// if this advice is associated with a - /// particular instance. - /// - bool IsPerInstance { get; } - - /// - /// Return the advice part of this aspect. - /// - /// - ///

- /// An advice may be an interceptor, a throws advice, before advice, - /// introduction etc. - ///

- ///
- /// - /// The advice that should apply if the pointcut matches. - /// - IAdvice Advice { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; + +#endregion + +namespace Spring.Aop +{ + /// + /// Base interface holding AOP advice and a filter determining the + /// applicability of the advice (such as a pointcut). + /// + /// + /// + /// This interface is not for use by Spring.NET users, but exists rather to + /// allow for commonality in the support for different types of advice + /// within the framework. + /// + ///

+ /// Spring.NET AOP is centered on around advice delivered via method + /// interception, compliant with the AOP Alliance interception API. + /// The interface allows support for + /// different types of advice, such as before and after + /// advice, which need not be implemented using interception. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + /// + /// + /// + public interface IAdvisor + { + /// + /// Is this advice associated with a particular instance? + /// + /// + ///

+ /// An advisor that was creating a mixin would be a per instance + /// operation and would thus return . If the + /// advisor is not per instance, it is shared with all instances of the + /// advised class obtained from the same Spring.NET IoC container. + ///

+ ///

+ /// Use singleton and prototype object definitions or + /// appropriate programmatic proxy creation to ensure that + /// s have the correct lifecycle model. + ///

+ /// + /// This method is not currently used by the framework. + /// + ///
+ /// + /// if this advice is associated with a + /// particular instance. + /// + bool IsPerInstance { get; } + + /// + /// Return the advice part of this aspect. + /// + /// + ///

+ /// An advice may be an interceptor, a throws advice, before advice, + /// introduction etc. + ///

+ ///
+ /// + /// The advice that should apply if the pointcut matches. + /// + IAdvice Advice { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IAdvisors.cs b/src/Spring/Spring.Aop/Aop/IAdvisors.cs index 530f85a8..7e2f74f3 100644 --- a/src/Spring/Spring.Aop/Aop/IAdvisors.cs +++ b/src/Spring/Spring.Aop/Aop/IAdvisors.cs @@ -1,47 +1,46 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using AopAlliance.Aop; - -#endregion - -namespace Spring.Aop -{ - /// - /// AOP Aspect abstraction, holding a list of s - /// - /// - /// Aleksandar Seovic (.NET) - /// $Id: IAdvisors.cs,v 1.1 2007/08/03 14:38:30 markpollack Exp $ - public interface IAdvisors - { - /// - /// Gets or sets a list of advisors. - /// - /// - /// A list of advisors. - /// - IList Advisors { get; set; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using AopAlliance.Aop; + +#endregion + +namespace Spring.Aop +{ + /// + /// AOP Aspect abstraction, holding a list of s + /// + /// + /// Aleksandar Seovic (.NET) + public interface IAdvisors + { + /// + /// Gets or sets a list of advisors. + /// + /// + /// A list of advisors. + /// + IList Advisors { get; set; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IAfterReturningAdvice.cs b/src/Spring/Spring.Aop/Aop/IAfterReturningAdvice.cs index f2fc9cfd..d4be52e8 100644 --- a/src/Spring/Spring.Aop/Aop/IAfterReturningAdvice.cs +++ b/src/Spring/Spring.Aop/Aop/IAfterReturningAdvice.cs @@ -1,78 +1,77 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using AopAlliance.Aop; - -#endregion - -namespace Spring.Aop -{ - /// - /// Advice that executes after a method returns successfully. - /// - /// - ///

- /// After returning advice is invoked only on a normal method - /// return, but not if an exception is thrown. Such advice can see - /// the return value of the advised method invocation, but cannot change it. - ///

- ///

- /// Possible uses for this type of advice would include performing access - /// control checks on the return value of an advised method invocation, the - /// ubiquitous logging of method invocation return values (useful during - /// development), etc. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// - /// - /// $Id: IAfterReturningAdvice.cs,v 1.6 2006/04/09 07:18:36 markpollack Exp $ - public interface IAfterReturningAdvice : IAdvice - { - /// - /// Executes after - /// returns successfully. - /// - /// - ///

- /// Note that the supplied cannot - /// be changed by this type of advice... use the around advice type - /// () if you - /// need to change the return value of an advised method invocation. - /// The data encapsulated by the supplied - /// can of course be modified though. - ///

- ///
- /// - /// The value returned by the . - /// - /// The intecepted method. - /// The intercepted method's arguments. - /// The target object. - /// - void AfterReturning(object returnValue, MethodInfo method, object[] args, object target); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using AopAlliance.Aop; + +#endregion + +namespace Spring.Aop +{ + /// + /// Advice that executes after a method returns successfully. + /// + /// + ///

+ /// After returning advice is invoked only on a normal method + /// return, but not if an exception is thrown. Such advice can see + /// the return value of the advised method invocation, but cannot change it. + ///

+ ///

+ /// Possible uses for this type of advice would include performing access + /// control checks on the return value of an advised method invocation, the + /// ubiquitous logging of method invocation return values (useful during + /// development), etc. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + /// + /// + public interface IAfterReturningAdvice : IAdvice + { + /// + /// Executes after + /// returns successfully. + /// + /// + ///

+ /// Note that the supplied cannot + /// be changed by this type of advice... use the around advice type + /// () if you + /// need to change the return value of an advised method invocation. + /// The data encapsulated by the supplied + /// can of course be modified though. + ///

+ ///
+ /// + /// The value returned by the . + /// + /// The intecepted method. + /// The intercepted method's arguments. + /// The target object. + /// + void AfterReturning(object returnValue, MethodInfo method, object[] args, object target); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IBeforeAdvice.cs b/src/Spring/Spring.Aop/Aop/IBeforeAdvice.cs index 70d84389..fddc1b72 100644 --- a/src/Spring/Spring.Aop/Aop/IBeforeAdvice.cs +++ b/src/Spring/Spring.Aop/Aop/IBeforeAdvice.cs @@ -1,55 +1,54 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; - -#endregion - -namespace Spring.Aop -{ - /// - /// Superinterface for all before advice. - /// - /// - ///

- /// Before advice is advice that executes before a joinpoint, but - /// which does not have the ability to prevent execution flow proceeding to - /// the joinpoint (unless it throws an ). - ///

- ///

- /// Spring.NET only supports method before advice. Although this - /// is unlikely to change, this API is designed to allow field - /// before advice in future if desired. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// - /// - /// - /// $Id: IBeforeAdvice.cs,v 1.4 2006/04/09 07:18:36 markpollack Exp $ - public interface IBeforeAdvice : IAdvice - { - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; + +#endregion + +namespace Spring.Aop +{ + /// + /// Superinterface for all before advice. + /// + /// + ///

+ /// Before advice is advice that executes before a joinpoint, but + /// which does not have the ability to prevent execution flow proceeding to + /// the joinpoint (unless it throws an ). + ///

+ ///

+ /// Spring.NET only supports method before advice. Although this + /// is unlikely to change, this API is designed to allow field + /// before advice in future if desired. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + /// + /// + /// + public interface IBeforeAdvice : IAdvice + { + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IIntroductionAdvisor.cs b/src/Spring/Spring.Aop/Aop/IIntroductionAdvisor.cs index 0c238edc..744a2ab6 100644 --- a/src/Spring/Spring.Aop/Aop/IIntroductionAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/IIntroductionAdvisor.cs @@ -1,93 +1,92 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop -{ - /// - /// Superinterface for advisors that perform one or more AOP - /// introductions. - /// - /// - ///

- /// This interface cannot be implemented directly; subinterfaces must - /// provide the advice type implementing the introduction. - ///

- ///

- /// Introduction is the implementation of additional interfaces (not - /// implemented by a target) via AOP advice. - ///

- ///
- /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IIntroductionAdvisor.cs,v 1.8 2006/04/09 07:18:36 markpollack Exp $ - public interface IIntroductionAdvisor : IAdvisor - { - /// - /// Returns the filter determining which target classes this - /// introduction should apply to. - /// - /// - ///

- /// This is the part of a pointcut. - /// Be advised that method matching doesn't make sense in the context - /// of introductions. - ///

- ///
- /// - /// The filter determining which target classes this introduction - /// should apply to. - /// - ITypeFilter TypeFilter { get; } - - /// - /// Gets the interfaces introduced by this - /// . - /// - /// - /// The interfaces introduced by this - /// . - /// - Type[] Interfaces { get; } - - /// - /// Can the advised interfaces be implemented by the introduction - /// advice? - /// - /// - ///

- /// Invoked before adding an - /// . - ///

- ///
- /// - /// If the advised interfaces cannot be implemented by the introduction - /// advice. - /// - /// - void ValidateInterfaces(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop +{ + /// + /// Superinterface for advisors that perform one or more AOP + /// introductions. + /// + /// + ///

+ /// This interface cannot be implemented directly; subinterfaces must + /// provide the advice type implementing the introduction. + ///

+ ///

+ /// Introduction is the implementation of additional interfaces (not + /// implemented by a target) via AOP advice. + ///

+ ///
+ /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IIntroductionAdvisor : IAdvisor + { + /// + /// Returns the filter determining which target classes this + /// introduction should apply to. + /// + /// + ///

+ /// This is the part of a pointcut. + /// Be advised that method matching doesn't make sense in the context + /// of introductions. + ///

+ ///
+ /// + /// The filter determining which target classes this introduction + /// should apply to. + /// + ITypeFilter TypeFilter { get; } + + /// + /// Gets the interfaces introduced by this + /// . + /// + /// + /// The interfaces introduced by this + /// . + /// + Type[] Interfaces { get; } + + /// + /// Can the advised interfaces be implemented by the introduction + /// advice? + /// + /// + ///

+ /// Invoked before adding an + /// . + ///

+ ///
+ /// + /// If the advised interfaces cannot be implemented by the introduction + /// advice. + /// + /// + void ValidateInterfaces(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IIntroductionInterceptor.cs b/src/Spring/Spring.Aop/Aop/IIntroductionInterceptor.cs index c7d00885..4e500b49 100644 --- a/src/Spring/Spring.Aop/Aop/IIntroductionInterceptor.cs +++ b/src/Spring/Spring.Aop/Aop/IIntroductionInterceptor.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop -{ - /// - /// Subinterface of the AOP Alliance - /// interface that - /// allows additional interfaces to be implemented by the interceptor, and - /// available via a proxy using that interceptor. - /// - /// - ///

- /// This is a fundamental AOP concept called introduction. - ///

- ///

- /// Introductions are often mixins, enabling the building of composite - /// objects that can achieve many of the goals of multiple inheritance. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IIntroductionInterceptor.cs,v 1.3 2006/04/09 07:18:36 markpollack Exp $ - public interface IIntroductionInterceptor : IMethodInterceptor - { - /// - /// Does this - /// implement the given interface? - /// - /// The interface to check. - /// - /// if this - /// - /// implements the given interface. - /// - bool ImplementsInterface(Type intf); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop +{ + /// + /// Subinterface of the AOP Alliance + /// interface that + /// allows additional interfaces to be implemented by the interceptor, and + /// available via a proxy using that interceptor. + /// + /// + ///

+ /// This is a fundamental AOP concept called introduction. + ///

+ ///

+ /// Introductions are often mixins, enabling the building of composite + /// objects that can achieve many of the goals of multiple inheritance. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IIntroductionInterceptor : IMethodInterceptor + { + /// + /// Does this + /// implement the given interface? + /// + /// The interface to check. + /// + /// if this + /// + /// implements the given interface. + /// + bool ImplementsInterface(Type intf); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IMethodBeforeAdvice.cs b/src/Spring/Spring.Aop/Aop/IMethodBeforeAdvice.cs index 171ac9a8..8a6dca6d 100644 --- a/src/Spring/Spring.Aop/Aop/IMethodBeforeAdvice.cs +++ b/src/Spring/Spring.Aop/Aop/IMethodBeforeAdvice.cs @@ -1,73 +1,72 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop -{ - /// - /// Advice executed before a method is invoked. - /// - /// - ///

- /// Such advice cannot prevent the method call proceeding, short of - /// throwing an . - ///

- ///

- /// The main advantage of before advice is that there is no - /// possibility of inadvertently failing to proceed down the interceptor - /// chain, since there is no need (and indeed means) to invoke the next - /// interceptor in the call chain. - ///

- ///

- /// Possible uses for this type of advice would include performing class - /// invariant checks prior to the actual method invocation, the ubiquitous - /// logging of method invocations (useful during development), etc. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// - /// - /// - /// $Id: IMethodBeforeAdvice.cs,v 1.6 2006/04/09 07:18:36 markpollack Exp $ - public interface IMethodBeforeAdvice : IBeforeAdvice - { - /// - /// The callback before a given method is invoked. - /// - /// The method being invoked. - /// The arguments to the method. - /// - /// The target of the method invocation. May be . - /// - /// - /// Thrown when and if this object wishes to abort the call. Any - /// exception so thrown will be propagated to the caller. - /// - void Before(MethodInfo method, object[] args, object target); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop +{ + /// + /// Advice executed before a method is invoked. + /// + /// + ///

+ /// Such advice cannot prevent the method call proceeding, short of + /// throwing an . + ///

+ ///

+ /// The main advantage of before advice is that there is no + /// possibility of inadvertently failing to proceed down the interceptor + /// chain, since there is no need (and indeed means) to invoke the next + /// interceptor in the call chain. + ///

+ ///

+ /// Possible uses for this type of advice would include performing class + /// invariant checks prior to the actual method invocation, the ubiquitous + /// logging of method invocations (useful during development), etc. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + /// + /// + /// + public interface IMethodBeforeAdvice : IBeforeAdvice + { + /// + /// The callback before a given method is invoked. + /// + /// The method being invoked. + /// The arguments to the method. + /// + /// The target of the method invocation. May be . + /// + /// + /// Thrown when and if this object wishes to abort the call. Any + /// exception so thrown will be propagated to the caller. + /// + void Before(MethodInfo method, object[] args, object target); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IMethodMatcher.cs b/src/Spring/Spring.Aop/Aop/IMethodMatcher.cs index 9383073a..72537865 100644 --- a/src/Spring/Spring.Aop/Aop/IMethodMatcher.cs +++ b/src/Spring/Spring.Aop/Aop/IMethodMatcher.cs @@ -1,151 +1,150 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop -{ - /// - /// That part of an that checks whether a - /// target method is eligible for advice. - /// - /// - ///

- /// An may be evaluated - /// statically or at runtime (dynamically). Static - /// matching involves only the method signature and (possibly) any - /// s that have been applied to a method. - /// Dynamic matching additionally takes into account the actual argument - /// values passed to a method invocation. - ///

- ///

- /// If the value of the - /// property of an implementation instance returns , - /// evaluation can be performed statically, and the result will be the same - /// for all invocations of this method, whatever their arguments. This - /// means that if the value of the - /// is - /// , the three argument - /// - /// method will never be invoked for the lifetime of the - /// . - ///

- ///

- /// If an implementation returns in its two argument - /// - /// method, and the value of it's - /// property is - /// , the three argument - /// - /// method will be invoked immediately before each and every potential - /// execution of the related advice, to decide whether the advice - /// should run. All previous advice, such as earlier interceptors in an - /// interceptor chain, will have run, so any state changes they have - /// produced in parameters or thread local storage, will be available at - /// the time of evaluation. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IMethodMatcher.cs,v 1.9 2006/04/09 07:18:36 markpollack Exp $ - /// - public interface IMethodMatcher - { - /// - /// Is this dynamic? - /// - /// - ///

- /// If , the three argument - /// - /// method will be invoked if the two argument - /// - /// method returns . - ///

- ///

- /// Note that this property can be checked when an AOP proxy is created, - /// and implementations need not check the value of this property again - /// before each method invocation. - ///

- ///
- /// - /// if this - /// is dynamic. - /// - bool IsRuntime { get; } - - /// - /// Does the supplied satisfy this matcher? - /// - /// - ///

- /// This is a static check. If this method invocation returns - /// ,or if the - /// property is - /// , then no runtime check will be made. - ///

- ///
- /// The candidate method. - /// - /// The target (may be , - /// in which case the candidate must be taken - /// to be the 's declaring class). - /// - /// - /// if this this method matches statically. - /// - bool Matches(MethodInfo method, Type targetType); - - /// - /// Is there a runtime (dynamic) match for the supplied - /// ? - /// - /// - ///

- /// In order for this method to have even been invoked, the supplied - /// must have matched - /// statically. This method is invoked only if the two argument - /// - /// method returns for the supplied - /// and , and - /// if the property - /// is . - ///

- ///

- /// Invoked immediately before any potential running of the - /// advice, and after any advice earlier in the advice chain has - /// run. - ///

- ///
- /// The candidate method. - /// - /// The target . - /// - /// The arguments to the method - /// - /// if there is a runtime match. - bool Matches(MethodInfo method, Type targetType, object[] args); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop +{ + /// + /// That part of an that checks whether a + /// target method is eligible for advice. + /// + /// + ///

+ /// An may be evaluated + /// statically or at runtime (dynamically). Static + /// matching involves only the method signature and (possibly) any + /// s that have been applied to a method. + /// Dynamic matching additionally takes into account the actual argument + /// values passed to a method invocation. + ///

+ ///

+ /// If the value of the + /// property of an implementation instance returns , + /// evaluation can be performed statically, and the result will be the same + /// for all invocations of this method, whatever their arguments. This + /// means that if the value of the + /// is + /// , the three argument + /// + /// method will never be invoked for the lifetime of the + /// . + ///

+ ///

+ /// If an implementation returns in its two argument + /// + /// method, and the value of it's + /// property is + /// , the three argument + /// + /// method will be invoked immediately before each and every potential + /// execution of the related advice, to decide whether the advice + /// should run. All previous advice, such as earlier interceptors in an + /// interceptor chain, will have run, so any state changes they have + /// produced in parameters or thread local storage, will be available at + /// the time of evaluation. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + public interface IMethodMatcher + { + /// + /// Is this dynamic? + /// + /// + ///

+ /// If , the three argument + /// + /// method will be invoked if the two argument + /// + /// method returns . + ///

+ ///

+ /// Note that this property can be checked when an AOP proxy is created, + /// and implementations need not check the value of this property again + /// before each method invocation. + ///

+ ///
+ /// + /// if this + /// is dynamic. + /// + bool IsRuntime { get; } + + /// + /// Does the supplied satisfy this matcher? + /// + /// + ///

+ /// This is a static check. If this method invocation returns + /// ,or if the + /// property is + /// , then no runtime check will be made. + ///

+ ///
+ /// The candidate method. + /// + /// The target (may be , + /// in which case the candidate must be taken + /// to be the 's declaring class). + /// + /// + /// if this this method matches statically. + /// + bool Matches(MethodInfo method, Type targetType); + + /// + /// Is there a runtime (dynamic) match for the supplied + /// ? + /// + /// + ///

+ /// In order for this method to have even been invoked, the supplied + /// must have matched + /// statically. This method is invoked only if the two argument + /// + /// method returns for the supplied + /// and , and + /// if the property + /// is . + ///

+ ///

+ /// Invoked immediately before any potential running of the + /// advice, and after any advice earlier in the advice chain has + /// run. + ///

+ ///
+ /// The candidate method. + /// + /// The target . + /// + /// The arguments to the method + /// + /// if there is a runtime match. + bool Matches(MethodInfo method, Type targetType, object[] args); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IPointcut.cs b/src/Spring/Spring.Aop/Aop/IPointcut.cs index 362b8550..9f8e183c 100644 --- a/src/Spring/Spring.Aop/Aop/IPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/IPointcut.cs @@ -1,61 +1,60 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop -{ - /// - /// Spring.NET's core pointcut abstraction. - /// - /// - ///

- /// A pointcut is composed of s and - /// s. Both these basic terms and an - /// itself can be combined to build up - /// sophisticated combinations. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: IPointcut.cs,v 1.9 2006/04/09 07:18:36 markpollack Exp $ - public interface IPointcut - { - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - ITypeFilter TypeFilter { get; } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - IMethodMatcher MethodMatcher { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop +{ + /// + /// Spring.NET's core pointcut abstraction. + /// + /// + ///

+ /// A pointcut is composed of s and + /// s. Both these basic terms and an + /// itself can be combined to build up + /// sophisticated combinations. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface IPointcut + { + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + ITypeFilter TypeFilter { get; } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + IMethodMatcher MethodMatcher { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/IPointcutAdvisor.cs index 13418271..30814175 100644 --- a/src/Spring/Spring.Aop/Aop/IPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/IPointcutAdvisor.cs @@ -1,50 +1,49 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop -{ - /// - /// Superinterface for all s that are - /// driven by a pointcut. - /// - /// - ///

- /// This covers nearly all advisors except introduction advisors, for which - /// method-level matching does not apply. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// $Id: IPointcutAdvisor.cs,v 1.3 2006/04/09 07:18:36 markpollack Exp $ - public interface IPointcutAdvisor : IAdvisor - { - /// - /// The that drives this advisor. - /// - IPointcut Pointcut { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop +{ + /// + /// Superinterface for all s that are + /// driven by a pointcut. + /// + /// + ///

+ /// This covers nearly all advisors except introduction advisors, for which + /// method-level matching does not apply. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + public interface IPointcutAdvisor : IAdvisor + { + /// + /// The that drives this advisor. + /// + IPointcut Pointcut { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/ITargetSource.cs b/src/Spring/Spring.Aop/Aop/ITargetSource.cs index 2a50f8c8..0fc86905 100644 --- a/src/Spring/Spring.Aop/Aop/ITargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/ITargetSource.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop -{ - /// - /// Used to obtain the current "target" of an AOP invocation - /// - /// - ///

- /// This target will be invoked via reflection if no around advice chooses - /// to end the interceptor chain itself. - ///

- ///

- /// If an is "static", it - /// will always return the same target, allowing optimizations in the AOP - /// framework. Dynamic target sources can support pooling, hot swapping etc. - ///

- ///

- /// Application developers don't usually need to work with target sources - /// directly: this is an AOP framework interface. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: ITargetSource.cs,v 1.9 2007/10/10 18:07:38 markpollack Exp $ - public interface ITargetSource - { - /// - /// The of the target object. - /// - Type TargetType { get; } - - /// - /// Is the target source static? - /// - /// - /// if the target source is static. - /// - bool IsStatic { get; } - - /// - /// Returns the target object. - /// - /// The target object. - /// - /// If unable to obtain the target object. - /// - object GetTarget(); - - /// - /// Releases the target object. - /// - /// The target object to release. - void ReleaseTarget(object target); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop +{ + /// + /// Used to obtain the current "target" of an AOP invocation + /// + /// + ///

+ /// This target will be invoked via reflection if no around advice chooses + /// to end the interceptor chain itself. + ///

+ ///

+ /// If an is "static", it + /// will always return the same target, allowing optimizations in the AOP + /// framework. Dynamic target sources can support pooling, hot swapping etc. + ///

+ ///

+ /// Application developers don't usually need to work with target sources + /// directly: this is an AOP framework interface. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface ITargetSource + { + /// + /// The of the target object. + /// + Type TargetType { get; } + + /// + /// Is the target source static? + /// + /// + /// if the target source is static. + /// + bool IsStatic { get; } + + /// + /// Returns the target object. + /// + /// The target object. + /// + /// If unable to obtain the target object. + /// + object GetTarget(); + + /// + /// Releases the target object. + /// + /// The target object to release. + void ReleaseTarget(object target); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/IThrowsAdvice.cs b/src/Spring/Spring.Aop/Aop/IThrowsAdvice.cs index dde6e761..65cca7e8 100644 --- a/src/Spring/Spring.Aop/Aop/IThrowsAdvice.cs +++ b/src/Spring/Spring.Aop/Aop/IThrowsAdvice.cs @@ -1,61 +1,60 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; - -#endregion - -namespace Spring.Aop -{ - /// - /// Simple marker interface for throws advice. - /// - /// - ///

- /// There are no methods on this interface, as methods are discovered and - /// invoked via reflection. Please do see read the API documentation for the - /// class; - /// said documention describes in detail the signature of the methods that - /// implementations of the interface - /// must adhere to in the specific case of Spring.NET's implementation of - /// throws advice. - ///

- ///

- /// There are any number of possible uses for this type of advice. Some - /// examples would include the ubiquitous logging of any such exceptions, - /// monitoring the number and type of exceptions and sending emails to - /// a support desk once certain criteria have been met, wrapping generic - /// exceptions such as in - /// exceptions that are more meaningful to your business logic, etc. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// - /// - /// $Id: IThrowsAdvice.cs,v 1.5 2006/04/09 07:18:36 markpollack Exp $ - public interface IThrowsAdvice : IAdvice - { - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; + +#endregion + +namespace Spring.Aop +{ + /// + /// Simple marker interface for throws advice. + /// + /// + ///

+ /// There are no methods on this interface, as methods are discovered and + /// invoked via reflection. Please do see read the API documentation for the + /// class; + /// said documention describes in detail the signature of the methods that + /// implementations of the interface + /// must adhere to in the specific case of Spring.NET's implementation of + /// throws advice. + ///

+ ///

+ /// There are any number of possible uses for this type of advice. Some + /// examples would include the ubiquitous logging of any such exceptions, + /// monitoring the number and type of exceptions and sending emails to + /// a support desk once certain criteria have been met, wrapping generic + /// exceptions such as in + /// exceptions that are more meaningful to your business logic, etc. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + /// + /// + public interface IThrowsAdvice : IAdvice + { + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/ITypeFilter.cs b/src/Spring/Spring.Aop/Aop/ITypeFilter.cs index 6ca69514..974ff812 100644 --- a/src/Spring/Spring.Aop/Aop/ITypeFilter.cs +++ b/src/Spring/Spring.Aop/Aop/ITypeFilter.cs @@ -1,59 +1,58 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop -{ - /// - /// A filter that restricts the matching of a pointcut or introduction to - /// a given set of target types. - /// - /// - ///

- /// Can be used as part of a pointcut, or for the entire targeting of an - /// introduction. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// - /// - /// $Id: ITypeFilter.cs,v 1.2 2006/04/09 07:18:36 markpollack Exp $ - public interface ITypeFilter - { - /// - /// Should the pointcut apply to the supplied - /// ? - /// - /// - /// The candidate . - /// - /// - /// if the advice should apply to the supplied - /// - /// - bool Matches(Type type); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop +{ + /// + /// A filter that restricts the matching of a pointcut or introduction to + /// a given set of target types. + /// + /// + ///

+ /// Can be used as part of a pointcut, or for the entire targeting of an + /// introduction. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// + /// + public interface ITypeFilter + { + /// + /// Should the pointcut apply to the supplied + /// ? + /// + /// + /// The candidate . + /// + /// + /// if the advice should apply to the supplied + /// + /// + bool Matches(Type type); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/AbstractGenericPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/AbstractGenericPointcutAdvisor.cs index 3b7a1905..bbaf9b2a 100644 --- a/src/Spring/Spring.Aop/Aop/Support/AbstractGenericPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/AbstractGenericPointcutAdvisor.cs @@ -1,64 +1,63 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using AopAlliance.Aop; - -namespace Spring.Aop.Support -{ - /// - /// Abstract PointcutAdvisor that allows for any Advice to be configured. - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: AbstractGenericPointcutAdvisor.cs,v 1.2 2007/08/10 17:39:44 bbaia Exp $ - [Serializable] - public abstract class AbstractGenericPointcutAdvisor : AbstractPointcutAdvisor - { - private IAdvice advice; - - - /// - /// Return the advice part of this advisor. - /// - /// - /// The advice that should apply if the pointcut matches. - /// - /// - public override IAdvice Advice - { - get { return this.advice; } - set { this.advice = value; } - } - - - /// - /// Returns a that represents the current - /// . - /// - /// - /// A representation of this advisor. - /// - public override string ToString() - { - return GetType().Name + ": advice=[" + Advice + "]"; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using AopAlliance.Aop; + +namespace Spring.Aop.Support +{ + /// + /// Abstract PointcutAdvisor that allows for any Advice to be configured. + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + [Serializable] + public abstract class AbstractGenericPointcutAdvisor : AbstractPointcutAdvisor + { + private IAdvice advice; + + + /// + /// Return the advice part of this advisor. + /// + /// + /// The advice that should apply if the pointcut matches. + /// + /// + public override IAdvice Advice + { + get { return this.advice; } + set { this.advice = value; } + } + + + /// + /// Returns a that represents the current + /// . + /// + /// + /// A representation of this advisor. + /// + public override string ToString() + { + return GetType().Name + ": advice=[" + Advice + "]"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/AbstractObjectFactoryPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/AbstractObjectFactoryPointcutAdvisor.cs index f4805a8b..a295ccc0 100644 --- a/src/Spring/Spring.Aop/Aop/Support/AbstractObjectFactoryPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/AbstractObjectFactoryPointcutAdvisor.cs @@ -1,137 +1,136 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using AopAlliance.Aop; -using Spring.Objects.Factory; -using Spring.Util; - -namespace Spring.Aop.Support -{ - /// - /// Abstract ObjectFactory-based IPointcutAdvisor that allows for any Advice to be - /// configured as reference to an Advice object in an ObjectFactory. - /// - /// - /// specifying the name of an advice object instead of the advice object itself - /// (if running within an ObjectFactory/ApplicationContext increses loose coupling - /// at initialization time, in order not to initialize the advice object until the - /// pointcut actually matches. - /// - /// Juergen Hoeller - /// Mark Pollack - /// $Id: AbstractObjectFactoryPointcutAdvisor.cs,v 1.2 2007/08/10 17:39:44 bbaia Exp $ - public abstract class AbstractObjectFactoryPointcutAdvisor : AbstractPointcutAdvisor, IObjectFactoryAware - { - private string adviceObjectName; - - private IObjectFactory objectFactory; - - private IAdvice advice; - - private object adviceMonitor = new object(); - - - /// - /// Gets or sets the name of the advice object that this advisor should refer to. - /// - /// An instance of the specified object will be obtained on first access of - /// this advisor's advice. This advisor will only ever obtain at most one - /// single instance of the advice object, caching the instance for the lifetime of - /// the advisor. - /// The name of the advice object. - public string AdviceObjectName - { - get { return adviceObjectName; } - set { adviceObjectName = value; } - } - - #region IObjectFactoryAware Members - - /// - /// Callback that supplies the owning factory to an object instance. - /// - /// - /// Owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - /// - ///

- /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - ///

- ///
- /// - /// In case of initialization errors. - /// - public IObjectFactory ObjectFactory - { - set { objectFactory = value; } - } - - #endregion - - /// - /// Return the advice part of this aspect. - /// - /// - ///

- /// An advice may be an interceptor, a throws advice, before advice, - /// introduction etc. - ///

- ///
- /// - /// The advice that should apply if the pointcut matches. - /// - public override IAdvice Advice - { - get - { - lock (adviceMonitor) - { - if (advice == null && adviceObjectName != null) - { - AssertUtils.State(objectFactory != null, - "ObjectFactory must be set to resolve 'adviceObjectName'"); - advice = objectFactory.GetObject(adviceObjectName, typeof (IAdvice)) as IAdvice; - } - } - return advice; - } - set - { - advice = value; - } - } - - /// - /// Describe this Advisor, showing name of advice object. - /// - /// - /// Type name and advice object name. - /// - public override string ToString() - { - return GetType().Name + ": advice object '" + AdviceObjectName + "'"; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using AopAlliance.Aop; +using Spring.Objects.Factory; +using Spring.Util; + +namespace Spring.Aop.Support +{ + /// + /// Abstract ObjectFactory-based IPointcutAdvisor that allows for any Advice to be + /// configured as reference to an Advice object in an ObjectFactory. + /// + /// + /// specifying the name of an advice object instead of the advice object itself + /// (if running within an ObjectFactory/ApplicationContext increses loose coupling + /// at initialization time, in order not to initialize the advice object until the + /// pointcut actually matches. + /// + /// Juergen Hoeller + /// Mark Pollack + public abstract class AbstractObjectFactoryPointcutAdvisor : AbstractPointcutAdvisor, IObjectFactoryAware + { + private string adviceObjectName; + + private IObjectFactory objectFactory; + + private IAdvice advice; + + private object adviceMonitor = new object(); + + + /// + /// Gets or sets the name of the advice object that this advisor should refer to. + /// + /// An instance of the specified object will be obtained on first access of + /// this advisor's advice. This advisor will only ever obtain at most one + /// single instance of the advice object, caching the instance for the lifetime of + /// the advisor. + /// The name of the advice object. + public string AdviceObjectName + { + get { return adviceObjectName; } + set { adviceObjectName = value; } + } + + #region IObjectFactoryAware Members + + /// + /// Callback that supplies the owning factory to an object instance. + /// + /// + /// Owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + /// + ///

+ /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + ///

+ ///
+ /// + /// In case of initialization errors. + /// + public IObjectFactory ObjectFactory + { + set { objectFactory = value; } + } + + #endregion + + /// + /// Return the advice part of this aspect. + /// + /// + ///

+ /// An advice may be an interceptor, a throws advice, before advice, + /// introduction etc. + ///

+ ///
+ /// + /// The advice that should apply if the pointcut matches. + /// + public override IAdvice Advice + { + get + { + lock (adviceMonitor) + { + if (advice == null && adviceObjectName != null) + { + AssertUtils.State(objectFactory != null, + "ObjectFactory must be set to resolve 'adviceObjectName'"); + advice = objectFactory.GetObject(adviceObjectName, typeof (IAdvice)) as IAdvice; + } + } + return advice; + } + set + { + advice = value; + } + } + + /// + /// Describe this Advisor, showing name of advice object. + /// + /// + /// Type name and advice object name. + /// + public override string ToString() + { + return GetType().Name + ": advice object '" + AdviceObjectName + "'"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/AbstractPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/AbstractPointcutAdvisor.cs index 2c90ff85..1997c7ae 100644 --- a/src/Spring/Spring.Aop/Aop/Support/AbstractPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/AbstractPointcutAdvisor.cs @@ -1,166 +1,165 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using AopAlliance.Aop; -using Spring.Core; - -namespace Spring.Aop.Support -{ - /// - /// Abstract base class for implementations. - /// - /// - /// Can be subclassed for returning a specific pointcut/advice or a freely configurable pointcut/advice. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: AbstractPointcutAdvisor.cs,v 1.2 2008/01/14 20:49:47 oakinger Exp $ - [Serializable] - public abstract class AbstractPointcutAdvisor : IPointcutAdvisor, IOrdered - { - #region Fields - - private int _order = Int32.MaxValue; - - #endregion - - #region IOrdered Members - - /// - /// Returns this s order in the - /// interception chain. - /// - /// - /// This s order in the - /// interception chain. - /// - public virtual int Order - { - get { return this._order; } - set { this._order = value; } - } - - #endregion - - #region IAdvisor Members - - /// - /// Return the advice part of this aspect. - /// - /// - ///

- /// An advice may be an interceptor, a throws advice, before advice, - /// introduction etc. - ///

- ///
- /// - /// The advice that should apply if the pointcut matches. - /// - public abstract IAdvice Advice { get; set; } - - /// - /// Is this advice associated with a particular instance? - /// - /// - ///

- /// Not supported for dynamic advisors. - ///

- ///
- /// - /// if this advice is associated with a - /// particular instance. - /// - /// Always. - /// - public virtual bool IsPerInstance - { - get - { - throw new NotSupportedException( - "The 'IsPerInstance' property of the IAdvisor interface " + - "is not yet supported in Spring.NET."); - } - } - - #endregion - - #region IPointcutAdvisor Members - - /// - /// The that drives this advisor. - /// - public abstract IPointcut Pointcut { get; set; } - - #endregion - - #region Methods - /// - /// Determines whether the specified - /// is equal to the current . - /// - /// The advisor to compare with. - /// - /// if this instance is equal to the - /// specified . - /// - public override bool Equals(object o) - { - if (!(o is AbstractPointcutAdvisor)) - { - return false; - } - IPointcutAdvisor otherAdvisor = (IPointcutAdvisor)o; - if (otherAdvisor.Advice == null && otherAdvisor.Pointcut == null) - { - return (this.Advice == null && this.Pointcut == null); - } - else if (otherAdvisor.Advice == null) - { - return (Advice == null && otherAdvisor.Pointcut.Equals(this.Pointcut)); - } - else if (otherAdvisor.Pointcut == null) - { - return (this.Pointcut == null && otherAdvisor.Advice.Equals(this.Advice)); - } - else - { - return otherAdvisor.Advice.Equals(this.Advice) && otherAdvisor.Pointcut.Equals(this.Pointcut); - } - } - - /// - /// Serves as a hash function for a particular type, suitable for use - /// in hashing algorithms and data structures like a hash table. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return 0 // (SPRNET-847) base.GetHashCode() - + 13 * (Pointcut == null ? 0 : Pointcut.GetHashCode()) - + 27 * (Advice == null ? 0 : Advice.GetHashCode()); - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using AopAlliance.Aop; +using Spring.Core; + +namespace Spring.Aop.Support +{ + /// + /// Abstract base class for implementations. + /// + /// + /// Can be subclassed for returning a specific pointcut/advice or a freely configurable pointcut/advice. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + [Serializable] + public abstract class AbstractPointcutAdvisor : IPointcutAdvisor, IOrdered + { + #region Fields + + private int _order = Int32.MaxValue; + + #endregion + + #region IOrdered Members + + /// + /// Returns this s order in the + /// interception chain. + /// + /// + /// This s order in the + /// interception chain. + /// + public virtual int Order + { + get { return this._order; } + set { this._order = value; } + } + + #endregion + + #region IAdvisor Members + + /// + /// Return the advice part of this aspect. + /// + /// + ///

+ /// An advice may be an interceptor, a throws advice, before advice, + /// introduction etc. + ///

+ ///
+ /// + /// The advice that should apply if the pointcut matches. + /// + public abstract IAdvice Advice { get; set; } + + /// + /// Is this advice associated with a particular instance? + /// + /// + ///

+ /// Not supported for dynamic advisors. + ///

+ ///
+ /// + /// if this advice is associated with a + /// particular instance. + /// + /// Always. + /// + public virtual bool IsPerInstance + { + get + { + throw new NotSupportedException( + "The 'IsPerInstance' property of the IAdvisor interface " + + "is not yet supported in Spring.NET."); + } + } + + #endregion + + #region IPointcutAdvisor Members + + /// + /// The that drives this advisor. + /// + public abstract IPointcut Pointcut { get; set; } + + #endregion + + #region Methods + /// + /// Determines whether the specified + /// is equal to the current . + /// + /// The advisor to compare with. + /// + /// if this instance is equal to the + /// specified . + /// + public override bool Equals(object o) + { + if (!(o is AbstractPointcutAdvisor)) + { + return false; + } + IPointcutAdvisor otherAdvisor = (IPointcutAdvisor)o; + if (otherAdvisor.Advice == null && otherAdvisor.Pointcut == null) + { + return (this.Advice == null && this.Pointcut == null); + } + else if (otherAdvisor.Advice == null) + { + return (Advice == null && otherAdvisor.Pointcut.Equals(this.Pointcut)); + } + else if (otherAdvisor.Pointcut == null) + { + return (this.Pointcut == null && otherAdvisor.Advice.Equals(this.Advice)); + } + else + { + return otherAdvisor.Advice.Equals(this.Advice) && otherAdvisor.Pointcut.Equals(this.Pointcut); + } + } + + /// + /// Serves as a hash function for a particular type, suitable for use + /// in hashing algorithms and data structures like a hash table. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return 0 // (SPRNET-847) base.GetHashCode() + + 13 * (Pointcut == null ? 0 : Pointcut.GetHashCode()) + + 27 * (Advice == null ? 0 : Advice.GetHashCode()); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/AbstractRegularExpressionMethodPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/AbstractRegularExpressionMethodPointcut.cs index b6840af2..b11d4d37 100644 --- a/src/Spring/Spring.Aop/Aop/Support/AbstractRegularExpressionMethodPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/AbstractRegularExpressionMethodPointcut.cs @@ -1,275 +1,275 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Runtime.Serialization; -using System.Security.Permissions; -using AopAlliance.Aop; -using Spring.Core; -using Spring.Objects; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Abstract base regular expression pointcut object. - /// - /// - ///

- /// The regular expressions must be a match. For example, the - /// .*Get.* pattern will match Com.Mycom.Foo.GetBar(), and - /// Get.* will not. - ///

- ///

- /// This base class is serializable. Subclasses should decorate all - /// fields with the - the - /// - /// method in this class will be invoked again on the client side on deserialization. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Simon White (.NET) - [Serializable] - public abstract class AbstractRegularExpressionMethodPointcut - : StaticMethodMatcherPointcut, ITypeFilter, ISerializable - { - [NonSerialized] - private object[] _patterns = ObjectUtils.EmptyObjects; - - #region Constructors - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- protected AbstractRegularExpressionMethodPointcut() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - /// - /// If an error was encountered during the deserialization process. - /// - protected AbstractRegularExpressionMethodPointcut( - SerializationInfo info, StreamingContext context) - { - _patterns = (object[]) info.GetValue("Patterns", typeof(object[])); - try - { - InitPatternRepresentation(_patterns); - } - catch (Exception ex) - { - throw new AspectException( - "Failed to deserialize AOP regular expression pointcut: " + ex.Message); - } - } - - #endregion - - #region Properties - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public override ITypeFilter TypeFilter - { - get { return this; } - } - - /// - /// Convenience property for setting a single pattern. - /// - /// - /// Use this property or Patterns, not both. - /// - public virtual object Pattern - { - get { return (_patterns.Length > 0 ? _patterns[0] : null); } - set - { - AssertUtils.ArgumentNotNull(value, "Pattern"); - this.Patterns = new object[] {value}; - } - } - - /// - /// The regular expressions defining methods to match. - /// - /// - /// Matching will be the union of all these; if any match, - /// the pointcut matches. - /// - public virtual object[] Patterns - { - get { return _patterns; } - set - { - AssertUtils.ArgumentNotNull(value, "Patterns"); - this._patterns = value; - InitPatternRepresentation(this.Patterns); - } - } - - #endregion - - #region Methods - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("Patterns", _patterns); - } - - /// - /// Subclasses must implement this to initialize regular expression pointcuts. - /// - /// - ///

- /// Can be invoked multiple times. - ///

- ///

- /// This method will be invoked from the property, - /// and also on deserialization. - ///

- ///
- /// - /// The patterns to initialize. - /// - /// - /// In the case of an invalid pattern. - /// - protected abstract void InitPatternRepresentation(object[] patterns); - - /// - /// Does the pattern at the supplied - /// match this ? - /// - /// The pattern to match - /// The index of pattern. - /// - /// if there is a match. - /// - protected abstract bool Matches(string pattern, int patternIndex); - - /// - /// Does the supplied satisfy this matcher? - /// - /// - ///

- /// Try to match the regular expression against the fully qualified name - /// of the method's declaring , plus the name of - /// the supplied . - ///

- ///

- /// Note that the declaring is that - /// that originally declared - /// the method, not necessarily the that is - /// currently exposing it. For example, - /// matches any subclass of 's - /// method. - ///

- ///
- /// The candidate method. - /// - /// The target (may be , - /// in which case the candidate must be taken - /// to be the 's declaring class). - /// - /// - /// if this this method matches statically. - /// - public override bool Matches(MethodInfo method, Type targetType) - { - string patt = method.DeclaringType.FullName + "." + method.Name; - for (int i = 0; i < this.Patterns.Length; ++i) - { - bool matched = Matches(patt, i); - if (matched) - { - return true; - } - } - return false; - } - - /// - /// Should the pointcut apply to the supplied - /// ? - /// - /// - ///

- /// In this instance, simply returns . - ///

- ///
- /// - /// The candidate . - /// - /// - /// if the advice should apply to the supplied - /// - /// - public bool Matches(Type type) - { - return true; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Runtime.Serialization; +using System.Security.Permissions; +using AopAlliance.Aop; +using Spring.Core; +using Spring.Objects; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Abstract base regular expression pointcut object. + /// + /// + ///

+ /// The regular expressions must be a match. For example, the + /// .*Get.* pattern will match Com.Mycom.Foo.GetBar(), and + /// Get.* will not. + ///

+ ///

+ /// This base class is serializable. Subclasses should decorate all + /// fields with the - the + /// + /// method in this class will be invoked again on the client side on deserialization. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Simon White (.NET) + [Serializable] + public abstract class AbstractRegularExpressionMethodPointcut + : StaticMethodMatcherPointcut, ITypeFilter, ISerializable + { + [NonSerialized] + private object[] _patterns = ObjectUtils.EmptyObjects; + + #region Constructors + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ protected AbstractRegularExpressionMethodPointcut() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + /// + /// If an error was encountered during the deserialization process. + /// + protected AbstractRegularExpressionMethodPointcut( + SerializationInfo info, StreamingContext context) + { + _patterns = (object[]) info.GetValue("Patterns", typeof(object[])); + try + { + InitPatternRepresentation(_patterns); + } + catch (Exception ex) + { + throw new AspectException( + "Failed to deserialize AOP regular expression pointcut: " + ex.Message); + } + } + + #endregion + + #region Properties + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public override ITypeFilter TypeFilter + { + get { return this; } + } + + /// + /// Convenience property for setting a single pattern. + /// + /// + /// Use this property or Patterns, not both. + /// + public virtual object Pattern + { + get { return (_patterns.Length > 0 ? _patterns[0] : null); } + set + { + AssertUtils.ArgumentNotNull(value, "Pattern"); + this.Patterns = new object[] {value}; + } + } + + /// + /// The regular expressions defining methods to match. + /// + /// + /// Matching will be the union of all these; if any match, + /// the pointcut matches. + /// + public virtual object[] Patterns + { + get { return _patterns; } + set + { + AssertUtils.ArgumentNotNull(value, "Patterns"); + this._patterns = value; + InitPatternRepresentation(this.Patterns); + } + } + + #endregion + + #region Methods + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("Patterns", _patterns); + } + + /// + /// Subclasses must implement this to initialize regular expression pointcuts. + /// + /// + ///

+ /// Can be invoked multiple times. + ///

+ ///

+ /// This method will be invoked from the property, + /// and also on deserialization. + ///

+ ///
+ /// + /// The patterns to initialize. + /// + /// + /// In the case of an invalid pattern. + /// + protected abstract void InitPatternRepresentation(object[] patterns); + + /// + /// Does the pattern at the supplied + /// match this ? + /// + /// The pattern to match + /// The index of pattern. + /// + /// if there is a match. + /// + protected abstract bool Matches(string pattern, int patternIndex); + + /// + /// Does the supplied satisfy this matcher? + /// + /// + ///

+ /// Try to match the regular expression against the fully qualified name + /// of the method's declaring , plus the name of + /// the supplied . + ///

+ ///

+ /// Note that the declaring is that + /// that originally declared + /// the method, not necessarily the that is + /// currently exposing it. For example, + /// matches any subclass of 's + /// method. + ///

+ ///
+ /// The candidate method. + /// + /// The target (may be , + /// in which case the candidate must be taken + /// to be the 's declaring class). + /// + /// + /// if this this method matches statically. + /// + public override bool Matches(MethodInfo method, Type targetType) + { + string patt = method.DeclaringType.FullName + "." + method.Name; + for (int i = 0; i < this.Patterns.Length; ++i) + { + bool matched = Matches(patt, i); + if (matched) + { + return true; + } + } + return false; + } + + /// + /// Should the pointcut apply to the supplied + /// ? + /// + /// + ///

+ /// In this instance, simply returns . + ///

+ ///
+ /// + /// The candidate . + /// + /// + /// if the advice should apply to the supplied + /// + /// + public bool Matches(Type type) + { + return true; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs index 70decf3e..254bb009 100644 --- a/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs @@ -1,204 +1,203 @@ -#region License - -/* -* Copyright 2002-2004 the original author or authors. -* -* 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. -*/ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// implementation that matches methods - /// that have been decorated with a specified . - /// - /// Aleksandar Seovic - /// Ronald Wildenberg - /// $Id: AttributeMatchMethodPointcut.cs,v 1.8 2007/05/21 16:43:45 bbaia Exp $ - [Serializable] - public class AttributeMatchMethodPointcut : StaticMethodMatcherPointcut - { - private Type _attribute; - private bool _inherit = true; - private bool _checkInterfaces = false; - - /// - /// Creates a new instance of the - /// class. - /// - public AttributeMatchMethodPointcut() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The to match. - /// - public AttributeMatchMethodPointcut(Type attribute) - : this(attribute, true, false) - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The to match. - /// - /// - /// Flag that controls whether or not the inheritance tree of the - /// method to be included in the search for the ? - /// - public AttributeMatchMethodPointcut(Type attribute, bool inherit) - : this(attribute, inherit, false) - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The to match. - /// - /// - /// Flag that controls whether or not the inheritance tree of the - /// method to be included in the search for the ? - /// - /// - /// Flag that controls whether or not interfaces attributes of the - /// method to be included in the search for the ? - /// - public AttributeMatchMethodPointcut(Type attribute, bool inherit, bool checkInterfaces) - { - Attribute = attribute; - Inherit = inherit; - CheckInterfaces = checkInterfaces; - } - - /// - /// The to match. - /// - /// - /// If the supplied value is not a that - /// derives from the class. - /// - public virtual Type Attribute - { - get { return _attribute; } - set - { - if (value != null) - { - if (!typeof (Attribute).IsAssignableFrom(value)) - { - throw new ArgumentException( - string.Format( - "The [{0}] Type must be derived from the [System.Attribute] class.", - value)); - } - } - _attribute = value; - } - } - - /// - /// Is the inheritance tree of the method to be included in the search for the - /// ? - /// - /// - ///

- /// The default is . - ///

- ///
- public virtual bool Inherit - { - get { return _inherit; } - set { _inherit = value; } - } - - /// - /// Is the interfaces attributes of the method to be included in the search for the - /// ? - /// - /// - ///

- /// The default is . - ///

- ///
- public virtual bool CheckInterfaces - { - get { return _checkInterfaces; } - set { _checkInterfaces = value; } - } - - /// - /// Does the supplied satisfy this matcher? - /// - /// The candidate method. - /// - /// The target (may be , - /// in which case the candidate must be taken - /// to be the 's declaring class). - /// - /// - /// if this this method matches statically. - /// - public override bool Matches(MethodInfo method, Type targetType) - { - if (method.IsDefined(Attribute, Inherit)) - { - // Checks whether the attribute is defined on the method or a super definition of the method - // but does not check attributes on implemented interfaces. - return true; - } - else - { - if (CheckInterfaces) - { - Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method); - - // Also check whether the attribute is defined on a method implemented from an interface. - // First find all interfaces for the type that contains the method. - // Next, check each interface for the presence of the attribute on the corresponding - // method from the interface. - foreach (Type interfaceType in method.DeclaringType.GetInterfaces()) - { - MethodInfo intfMethod = interfaceType.GetMethod(method.Name, parameterTypes); - if (intfMethod != null && intfMethod.IsDefined(Attribute, Inherit)) - { - return true; - } - } - } - return false; - } - } - } +#region License + +/* +* Copyright 2002-2004 the original author or authors. +* +* 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. +*/ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// implementation that matches methods + /// that have been decorated with a specified . + /// + /// Aleksandar Seovic + /// Ronald Wildenberg + [Serializable] + public class AttributeMatchMethodPointcut : StaticMethodMatcherPointcut + { + private Type _attribute; + private bool _inherit = true; + private bool _checkInterfaces = false; + + /// + /// Creates a new instance of the + /// class. + /// + public AttributeMatchMethodPointcut() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The to match. + /// + public AttributeMatchMethodPointcut(Type attribute) + : this(attribute, true, false) + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The to match. + /// + /// + /// Flag that controls whether or not the inheritance tree of the + /// method to be included in the search for the ? + /// + public AttributeMatchMethodPointcut(Type attribute, bool inherit) + : this(attribute, inherit, false) + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The to match. + /// + /// + /// Flag that controls whether or not the inheritance tree of the + /// method to be included in the search for the ? + /// + /// + /// Flag that controls whether or not interfaces attributes of the + /// method to be included in the search for the ? + /// + public AttributeMatchMethodPointcut(Type attribute, bool inherit, bool checkInterfaces) + { + Attribute = attribute; + Inherit = inherit; + CheckInterfaces = checkInterfaces; + } + + /// + /// The to match. + /// + /// + /// If the supplied value is not a that + /// derives from the class. + /// + public virtual Type Attribute + { + get { return _attribute; } + set + { + if (value != null) + { + if (!typeof (Attribute).IsAssignableFrom(value)) + { + throw new ArgumentException( + string.Format( + "The [{0}] Type must be derived from the [System.Attribute] class.", + value)); + } + } + _attribute = value; + } + } + + /// + /// Is the inheritance tree of the method to be included in the search for the + /// ? + /// + /// + ///

+ /// The default is . + ///

+ ///
+ public virtual bool Inherit + { + get { return _inherit; } + set { _inherit = value; } + } + + /// + /// Is the interfaces attributes of the method to be included in the search for the + /// ? + /// + /// + ///

+ /// The default is . + ///

+ ///
+ public virtual bool CheckInterfaces + { + get { return _checkInterfaces; } + set { _checkInterfaces = value; } + } + + /// + /// Does the supplied satisfy this matcher? + /// + /// The candidate method. + /// + /// The target (may be , + /// in which case the candidate must be taken + /// to be the 's declaring class). + /// + /// + /// if this this method matches statically. + /// + public override bool Matches(MethodInfo method, Type targetType) + { + if (method.IsDefined(Attribute, Inherit)) + { + // Checks whether the attribute is defined on the method or a super definition of the method + // but does not check attributes on implemented interfaces. + return true; + } + else + { + if (CheckInterfaces) + { + Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method); + + // Also check whether the attribute is defined on a method implemented from an interface. + // First find all interfaces for the type that contains the method. + // Next, check each interface for the presence of the attribute on the corresponding + // method from the interface. + foreach (Type interfaceType in method.DeclaringType.GetInterfaces()) + { + MethodInfo intfMethod = interfaceType.GetMethod(method.Name, parameterTypes); + if (intfMethod != null && intfMethod.IsDefined(Attribute, Inherit)) + { + return true; + } + } + } + return false; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcutAdvisor.cs index 3e1d80d4..d72f960c 100644 --- a/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcutAdvisor.cs @@ -1,118 +1,117 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Core; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient class for attribute-match method pointcuts that hold an Interceptor, - /// making them an Advisor. - /// - /// Bruno Baia - /// $Id: AttributeMatchMethodPointcutAdvisor.cs,v 1.3 2007/03/16 04:01:23 aseovic Exp $ - [Serializable] - public class AttributeMatchMethodPointcutAdvisor - : AttributeMatchMethodPointcut, IPointcutAdvisor, IOrdered - { - private int _order = Int32.MaxValue; - private IAdvice _advice; - - /// - /// Creates a new instance of the - /// class. - /// - public AttributeMatchMethodPointcutAdvisor() - { - } - - /// - /// Creates a new instance of the - /// class - /// for the supplied . - /// - /// - public AttributeMatchMethodPointcutAdvisor(IAdvice advice) - { - this._advice = advice; - } - - /// - /// Is this advice associated with a particular instance? - /// - /// - /// if this advice is associated with a - /// particular instance. - /// - /// - /// Always; this property is not yet supported. - /// - public virtual bool IsPerInstance - { - get - { - throw new NotSupportedException( - "The 'IsPerInstance' property of the IAdvisor interface is " + - "not yet supported in Spring.NET."); - } - } - - /// - /// Returns this s order in the - /// interception chain. - /// - /// - /// This s order in the - /// interception chain. - /// - public virtual int Order - { - get { return this._order; } - set { this._order = value; } - } - - /// - /// Return the advice part of this advisor. - /// - /// - /// The advice that should apply if the pointcut matches. - /// - /// - public virtual IAdvice Advice - { - get { return this._advice; } - set { this._advice = value; } - } - - /// - /// The that drives this advisor. - /// - public virtual IPointcut Pointcut - { - get { return this; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Core; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient class for attribute-match method pointcuts that hold an Interceptor, + /// making them an Advisor. + /// + /// Bruno Baia + [Serializable] + public class AttributeMatchMethodPointcutAdvisor + : AttributeMatchMethodPointcut, IPointcutAdvisor, IOrdered + { + private int _order = Int32.MaxValue; + private IAdvice _advice; + + /// + /// Creates a new instance of the + /// class. + /// + public AttributeMatchMethodPointcutAdvisor() + { + } + + /// + /// Creates a new instance of the + /// class + /// for the supplied . + /// + /// + public AttributeMatchMethodPointcutAdvisor(IAdvice advice) + { + this._advice = advice; + } + + /// + /// Is this advice associated with a particular instance? + /// + /// + /// if this advice is associated with a + /// particular instance. + /// + /// + /// Always; this property is not yet supported. + /// + public virtual bool IsPerInstance + { + get + { + throw new NotSupportedException( + "The 'IsPerInstance' property of the IAdvisor interface is " + + "not yet supported in Spring.NET."); + } + } + + /// + /// Returns this s order in the + /// interception chain. + /// + /// + /// This s order in the + /// interception chain. + /// + public virtual int Order + { + get { return this._order; } + set { this._order = value; } + } + + /// + /// Return the advice part of this advisor. + /// + /// + /// The advice that should apply if the pointcut matches. + /// + /// + public virtual IAdvice Advice + { + get { return this._advice; } + set { this._advice = value; } + } + + /// + /// The that drives this advisor. + /// + public virtual IPointcut Pointcut + { + get { return this; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/ComposablePointcut.cs b/src/Spring/Spring.Aop/Aop/Support/ComposablePointcut.cs index c8f7d885..3acaca1f 100644 --- a/src/Spring/Spring.Aop/Aop/Support/ComposablePointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/ComposablePointcut.cs @@ -1,176 +1,175 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient class for building up pointcuts. - /// - /// - ///

- /// All methods return a - /// instance, which facilitates the following concise usage pattern... - ///

- /// - /// IPointcut pointcut = new ComposablePointcut() - /// .Union(typeFilter) - /// .Intersection(methodMatcher) - /// .Intersection(pointcut); - /// - ///

- /// There is no Union() method on this class. Use the - /// method for such functionality. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: ComposablePointcut.cs,v 1.7 2007/03/16 04:01:23 aseovic Exp $ - [Serializable] - public class ComposablePointcut : IPointcut - { - private ITypeFilter _typeFilter; - private IMethodMatcher _methodMatcher; - - /// - /// Creates a new instance of the - /// class - /// that matches all the methods on all s. - /// - public ComposablePointcut() - { - _typeFilter = TrueTypeFilter.True; - _methodMatcher = TrueMethodMatcher.True; - } - - /// - /// Creates a new instance of the - /// class - /// that uses the supplied and - /// . - /// - /// - /// The type filter to use. - /// - /// - /// The method matcher to use. - /// - public ComposablePointcut(ITypeFilter typeFilter, IMethodMatcher methodMatcher) - { - _typeFilter = typeFilter; - _methodMatcher = methodMatcher; - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public virtual ITypeFilter TypeFilter - { - get { return _typeFilter; } - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public virtual IMethodMatcher MethodMatcher - { - get { return _methodMatcher; } - } - - /// - /// Changes the current type filter to be the union of the existing filter and the - /// supplied . - /// - /// The filter to union with. - /// - /// The union of the existing filter and the supplied . - /// - public virtual ComposablePointcut Union(ITypeFilter filter) - { - _typeFilter = TypeFilters.Union(_typeFilter, filter); - return this; - } - - /// - /// Changes the current type filter to be the intersection of the existing filter - /// and the supplied . - /// - /// The filter to diff against. - /// - /// The intersection of the existing filter and the supplied . - /// - public virtual ComposablePointcut Intersection(ITypeFilter filter) - { - _typeFilter = TypeFilters.Intersection(_typeFilter, filter); - return this; - } - - /// - /// Changes the current method matcher to be the union of the existing matcher and the - /// supplied . - /// - /// The matcher to union with. - /// - /// The union of the existing matcher and the supplied . - /// - public virtual ComposablePointcut Union(IMethodMatcher matcher) - { - _methodMatcher = MethodMatchers.Union(_methodMatcher, matcher); - return this; - } - - /// - /// Changes the current method matcher to be the intersection of the existing matcher - /// and the supplied . - /// - /// The matcher to diff against. - /// - /// The intersection of the existing matcher and the supplied . - /// - public virtual ComposablePointcut Intersection(IMethodMatcher matcher) - { - _methodMatcher = MethodMatchers.Intersection(_methodMatcher, matcher); - return this; - } - - /// - /// Changes current pointcut to intersection of the current and supplied pointcut - /// - /// pointcut to diff against - /// updated pointcut - public virtual ComposablePointcut Intersection(IPointcut other) - { - _typeFilter = TypeFilters.Intersection(_typeFilter, other.TypeFilter); - _methodMatcher = MethodMatchers.Intersection(_methodMatcher, other.MethodMatcher); - return this; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient class for building up pointcuts. + /// + /// + ///

+ /// All methods return a + /// instance, which facilitates the following concise usage pattern... + ///

+ /// + /// IPointcut pointcut = new ComposablePointcut() + /// .Union(typeFilter) + /// .Intersection(methodMatcher) + /// .Intersection(pointcut); + /// + ///

+ /// There is no Union() method on this class. Use the + /// method for such functionality. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class ComposablePointcut : IPointcut + { + private ITypeFilter _typeFilter; + private IMethodMatcher _methodMatcher; + + /// + /// Creates a new instance of the + /// class + /// that matches all the methods on all s. + /// + public ComposablePointcut() + { + _typeFilter = TrueTypeFilter.True; + _methodMatcher = TrueMethodMatcher.True; + } + + /// + /// Creates a new instance of the + /// class + /// that uses the supplied and + /// . + /// + /// + /// The type filter to use. + /// + /// + /// The method matcher to use. + /// + public ComposablePointcut(ITypeFilter typeFilter, IMethodMatcher methodMatcher) + { + _typeFilter = typeFilter; + _methodMatcher = methodMatcher; + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public virtual ITypeFilter TypeFilter + { + get { return _typeFilter; } + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public virtual IMethodMatcher MethodMatcher + { + get { return _methodMatcher; } + } + + /// + /// Changes the current type filter to be the union of the existing filter and the + /// supplied . + /// + /// The filter to union with. + /// + /// The union of the existing filter and the supplied . + /// + public virtual ComposablePointcut Union(ITypeFilter filter) + { + _typeFilter = TypeFilters.Union(_typeFilter, filter); + return this; + } + + /// + /// Changes the current type filter to be the intersection of the existing filter + /// and the supplied . + /// + /// The filter to diff against. + /// + /// The intersection of the existing filter and the supplied . + /// + public virtual ComposablePointcut Intersection(ITypeFilter filter) + { + _typeFilter = TypeFilters.Intersection(_typeFilter, filter); + return this; + } + + /// + /// Changes the current method matcher to be the union of the existing matcher and the + /// supplied . + /// + /// The matcher to union with. + /// + /// The union of the existing matcher and the supplied . + /// + public virtual ComposablePointcut Union(IMethodMatcher matcher) + { + _methodMatcher = MethodMatchers.Union(_methodMatcher, matcher); + return this; + } + + /// + /// Changes the current method matcher to be the intersection of the existing matcher + /// and the supplied . + /// + /// The matcher to diff against. + /// + /// The intersection of the existing matcher and the supplied . + /// + public virtual ComposablePointcut Intersection(IMethodMatcher matcher) + { + _methodMatcher = MethodMatchers.Intersection(_methodMatcher, matcher); + return this; + } + + /// + /// Changes current pointcut to intersection of the current and supplied pointcut + /// + /// pointcut to diff against + /// updated pointcut + public virtual ComposablePointcut Intersection(IPointcut other) + { + _typeFilter = TypeFilters.Intersection(_typeFilter, other.TypeFilter); + _methodMatcher = MethodMatchers.Intersection(_methodMatcher, other.MethodMatcher); + return this; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/ControlFlowPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/ControlFlowPointcut.cs index 2fd163f9..d691cd7a 100644 --- a/src/Spring/Spring.Aop/Aop/Support/ControlFlowPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/ControlFlowPointcut.cs @@ -1,244 +1,243 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Core; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Pointcut and method matcher for use in simple cflow-style - /// pointcuts. - /// - /// - ///

- /// Evaluating such pointcuts is slower than evaluating normal pointcuts, - /// but can nevertheless be useful in some cases. Of course, your mileage - /// may vary as to what 'slower' actually means. - ///

- ///
- /// Rod Johnson - /// Simon White (.NET) - /// $Id: ControlFlowPointcut.cs,v 1.6 2006/04/09 07:18:37 markpollack Exp $ - [Serializable] - public class ControlFlowPointcut : IPointcut, ITypeFilter, IMethodMatcher - { - #region Fields - - private Type _type; - private string _methodName; - private int _evaluationCount; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The class under which all control flows are to be matched. - /// - public ControlFlowPointcut(Type type) : this(type, null) - { - } - - /// - /// Construct a new pointcut that matches all calls below the - /// given method in the given class. - /// - /// - ///

- /// If the supplied is - /// , all control flows below the given - /// class will be successfully matched. - ///

- ///
- /// - /// The class under which all control flows are to be matched. - /// - /// - /// The method name under which all control flows are to be matched. - /// - public ControlFlowPointcut(Type type, string methodName) - { - _type = type; - _methodName = methodName; - } - - #endregion - - #region Properties - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public ITypeFilter TypeFilter - { - get { return this; } - } - - /// - /// Gets the number of times this pointcut has been evaluated. - /// - /// - ///

- /// Useful as a debugging aid. - ///

- ///

- /// Note that this value is distinct from the number of times that this - /// pointcut sucessfully matches a target method, in that a - /// may be evaluated many times but - /// never actually match even once. - ///

- ///
- /// - /// The number of times this pointcut has been evaluated. - /// - public int EvaluationCount - { - get { return _evaluationCount; } - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public IMethodMatcher MethodMatcher - { - get { return this; } - } - - /// - /// Is this a runtime pointcut? - /// - /// - ///

- /// This implementation is a runtime pointcut, and so always returns - /// . - ///

- ///
- /// - /// if this is a runtime pointcut. - /// - /// - public bool IsRuntime - { - get { return true; } - } - - #endregion - - #region Methods - - /// - /// Should the pointcut apply to the supplied ? - /// - /// - ///

- /// Subclasses are encouraged to override this method for greater - /// filtering (and performance). - ///

- ///

- /// This, the default, implementation always matches (returns - /// ). - ///

- ///
- /// The candidate target class. - /// - /// if the advice should apply to the supplied - /// - /// - public virtual bool Matches(Type type) - { - return true; - } - - /// - /// Does the supplied satisfy this matcher? - /// Perform static checking. If this returns false, or if the isRuntime() method - /// returns false, no runtime check will be made. - /// - /// - ///

- /// Subclasses are encouraged to override this method if it is possible - /// to filter out some candidate classes. - ///

- ///

- /// This, the default, implementation always matches (returns - /// ). This means that the three argument - /// - /// method will always be invoked. - ///

- ///
- /// The candidate method. - /// - /// The target class (may be , in which case the - /// candidate class must be taken to be the 's - /// declaring class). - /// - /// - /// if this this method matches statically. - /// - /// - public virtual bool Matches(MethodInfo method, Type targetType) - { - return true; - } - - /// - /// Is there a runtime (dynamic) match for the supplied - /// ? - /// - /// - ///

- /// Subclasses are encouraged to override this method if it is possible - /// to filter out some candidate classes. - ///

- ///
- /// The candidate method. - /// The target class. - /// The arguments to the method - /// - /// if there is a runtime match. - /// - public virtual bool Matches(MethodInfo method, Type targetType, object[] args) - { - ++_evaluationCount; - IControlFlow cflow = ControlFlowFactory.CreateControlFlow(); - return (_methodName != null) - ? cflow.Under(_type, _methodName) - : cflow.Under(_type); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Core; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Pointcut and method matcher for use in simple cflow-style + /// pointcuts. + /// + /// + ///

+ /// Evaluating such pointcuts is slower than evaluating normal pointcuts, + /// but can nevertheless be useful in some cases. Of course, your mileage + /// may vary as to what 'slower' actually means. + ///

+ ///
+ /// Rod Johnson + /// Simon White (.NET) + [Serializable] + public class ControlFlowPointcut : IPointcut, ITypeFilter, IMethodMatcher + { + #region Fields + + private Type _type; + private string _methodName; + private int _evaluationCount; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The class under which all control flows are to be matched. + /// + public ControlFlowPointcut(Type type) : this(type, null) + { + } + + /// + /// Construct a new pointcut that matches all calls below the + /// given method in the given class. + /// + /// + ///

+ /// If the supplied is + /// , all control flows below the given + /// class will be successfully matched. + ///

+ ///
+ /// + /// The class under which all control flows are to be matched. + /// + /// + /// The method name under which all control flows are to be matched. + /// + public ControlFlowPointcut(Type type, string methodName) + { + _type = type; + _methodName = methodName; + } + + #endregion + + #region Properties + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public ITypeFilter TypeFilter + { + get { return this; } + } + + /// + /// Gets the number of times this pointcut has been evaluated. + /// + /// + ///

+ /// Useful as a debugging aid. + ///

+ ///

+ /// Note that this value is distinct from the number of times that this + /// pointcut sucessfully matches a target method, in that a + /// may be evaluated many times but + /// never actually match even once. + ///

+ ///
+ /// + /// The number of times this pointcut has been evaluated. + /// + public int EvaluationCount + { + get { return _evaluationCount; } + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public IMethodMatcher MethodMatcher + { + get { return this; } + } + + /// + /// Is this a runtime pointcut? + /// + /// + ///

+ /// This implementation is a runtime pointcut, and so always returns + /// . + ///

+ ///
+ /// + /// if this is a runtime pointcut. + /// + /// + public bool IsRuntime + { + get { return true; } + } + + #endregion + + #region Methods + + /// + /// Should the pointcut apply to the supplied ? + /// + /// + ///

+ /// Subclasses are encouraged to override this method for greater + /// filtering (and performance). + ///

+ ///

+ /// This, the default, implementation always matches (returns + /// ). + ///

+ ///
+ /// The candidate target class. + /// + /// if the advice should apply to the supplied + /// + /// + public virtual bool Matches(Type type) + { + return true; + } + + /// + /// Does the supplied satisfy this matcher? + /// Perform static checking. If this returns false, or if the isRuntime() method + /// returns false, no runtime check will be made. + /// + /// + ///

+ /// Subclasses are encouraged to override this method if it is possible + /// to filter out some candidate classes. + ///

+ ///

+ /// This, the default, implementation always matches (returns + /// ). This means that the three argument + /// + /// method will always be invoked. + ///

+ ///
+ /// The candidate method. + /// + /// The target class (may be , in which case the + /// candidate class must be taken to be the 's + /// declaring class). + /// + /// + /// if this this method matches statically. + /// + /// + public virtual bool Matches(MethodInfo method, Type targetType) + { + return true; + } + + /// + /// Is there a runtime (dynamic) match for the supplied + /// ? + /// + /// + ///

+ /// Subclasses are encouraged to override this method if it is possible + /// to filter out some candidate classes. + ///

+ ///
+ /// The candidate method. + /// The target class. + /// The arguments to the method + /// + /// if there is a runtime match. + /// + public virtual bool Matches(MethodInfo method, Type targetType, object[] args) + { + ++_evaluationCount; + IControlFlow cflow = ControlFlowFactory.CreateControlFlow(); + return (_methodName != null) + ? cflow.Under(_type, _methodName) + : cflow.Under(_type); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/DefaultIntroductionAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/DefaultIntroductionAdvisor.cs index 00987686..3f94ced9 100644 --- a/src/Spring/Spring.Aop/Aop/Support/DefaultIntroductionAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/DefaultIntroductionAdvisor.cs @@ -1,241 +1,240 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Collections; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Simple implementation that - /// by default applies to any class. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: DefaultIntroductionAdvisor.cs,v 1.11 2007/03/16 04:01:23 aseovic Exp $ - [Serializable] - public class DefaultIntroductionAdvisor : IIntroductionAdvisor, ITypeFilter - { - private IAdvice _introduction; - private ISet _interfaces = new HybridSet(); - - /// - /// Creates a new instance of the - /// class using - /// the supplied - /// - /// - ///

- /// This constructor adds all interfaces implemented by the supplied - /// (except the - /// interface) to the list of - /// interfaces to introduce. - ///

- ///
- /// The introduction to use. - public DefaultIntroductionAdvisor(IAdvice introduction) - : this(introduction, introduction.GetType().GetInterfaces()) - { - } - - /// - /// Creates a new instance of the - /// class using - /// the supplied - /// - /// The introduction to use. - /// - /// The interface to introduce. - /// - public DefaultIntroductionAdvisor(IAdvice introduction, Type intf) - : this(introduction, new Type[] {intf}) - { - } - - /// - /// Creates a new instance of the - /// class using - /// the supplied - /// - /// The introduction to use. - /// - /// The interfaces to introduce. - /// - /// - /// If the supplied is . - /// - public DefaultIntroductionAdvisor(IAdvice introduction, Type[] interfaces) - { - if (introduction == null) - { - throw new ArgumentNullException("introduction", "Introduction cannot be null"); - } - _introduction = introduction; - foreach (Type intf in interfaces) - { - if (intf != typeof (IAdvice)) - { - AddInterface(intf); - } - } - } - - /// - /// Returns the filter determining which target classes this - /// introduction should apply to. - /// - /// - /// The filter determining which target classes this introduction - /// should apply to. - /// - public virtual ITypeFilter TypeFilter - { - get { return this; } - } - - /// - /// Gets the interfaces introduced by this - /// . - /// - /// - /// The interfaces introduced by this - /// . - /// - public virtual Type[] Interfaces - { - get - { - Type[] interfaces = new Type[_interfaces.Count]; - _interfaces.CopyTo(interfaces, 0); - return interfaces; - } - } - - /// - /// Is this advice associated with a particular instance? - /// - /// - ///

- /// Default for an introduction is per-instance interception. - ///

- ///
- /// - /// if this advice is associated with a - /// particular instance. - /// - public virtual bool IsPerInstance - { - get { return true; } - } - - /// - /// Return the advice part of this aspect. - /// - /// - /// The advice that should apply if the pointcut matches. - /// - public virtual IAdvice Advice - { - get { return this._introduction; } - } - - /// - /// Adds the supplied to the list of - /// introduced interfaces. - /// - /// The interface to add. - /// - /// If any of the are not interface . - /// - public virtual void AddInterface(Type intf) - { - if(intf != null) - { - BailIfNotAnInterfaceType(intf); - _interfaces.Add(intf); - } - } - - /// - /// Should the pointcut apply to the supplied - /// ? - /// - /// - ///

- /// This, the default, implementation always returns . - ///

- ///
- /// - /// The candidate . - /// - /// - /// if the advice should apply to the supplied - /// - /// - public virtual bool Matches(Type type) - { - return true; - } - - /// - /// Can the advised interfaces be implemented by the introduction - /// advice? - /// - /// - ///

- /// Invoked before adding an - /// . - ///

- ///
- /// - /// If the advised interfaces cannot be implemented by the introduction - /// advice. - /// - /// - /// - /// If any of the are not interface . - /// - public virtual void ValidateInterfaces() - { - foreach (Type intf in _interfaces) - { - BailIfNotAnInterfaceType(intf); - if (! intf.IsAssignableFrom(_introduction.GetType())) - { - throw new ArgumentException("Introduction [" + _introduction.GetType().FullName + "] " + - "does not implement interface '" + intf.FullName + "' specified in introduction advice."); - } - } - } - - private static void BailIfNotAnInterfaceType(Type intf) - { - if (intf != null && !intf.IsInterface) - { - throw new ArgumentException("Type [" + intf.FullName + "] is not an interface; cannot be used in an introduction."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Collections; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Simple implementation that + /// by default applies to any class. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class DefaultIntroductionAdvisor : IIntroductionAdvisor, ITypeFilter + { + private IAdvice _introduction; + private ISet _interfaces = new HybridSet(); + + /// + /// Creates a new instance of the + /// class using + /// the supplied + /// + /// + ///

+ /// This constructor adds all interfaces implemented by the supplied + /// (except the + /// interface) to the list of + /// interfaces to introduce. + ///

+ ///
+ /// The introduction to use. + public DefaultIntroductionAdvisor(IAdvice introduction) + : this(introduction, introduction.GetType().GetInterfaces()) + { + } + + /// + /// Creates a new instance of the + /// class using + /// the supplied + /// + /// The introduction to use. + /// + /// The interface to introduce. + /// + public DefaultIntroductionAdvisor(IAdvice introduction, Type intf) + : this(introduction, new Type[] {intf}) + { + } + + /// + /// Creates a new instance of the + /// class using + /// the supplied + /// + /// The introduction to use. + /// + /// The interfaces to introduce. + /// + /// + /// If the supplied is . + /// + public DefaultIntroductionAdvisor(IAdvice introduction, Type[] interfaces) + { + if (introduction == null) + { + throw new ArgumentNullException("introduction", "Introduction cannot be null"); + } + _introduction = introduction; + foreach (Type intf in interfaces) + { + if (intf != typeof (IAdvice)) + { + AddInterface(intf); + } + } + } + + /// + /// Returns the filter determining which target classes this + /// introduction should apply to. + /// + /// + /// The filter determining which target classes this introduction + /// should apply to. + /// + public virtual ITypeFilter TypeFilter + { + get { return this; } + } + + /// + /// Gets the interfaces introduced by this + /// . + /// + /// + /// The interfaces introduced by this + /// . + /// + public virtual Type[] Interfaces + { + get + { + Type[] interfaces = new Type[_interfaces.Count]; + _interfaces.CopyTo(interfaces, 0); + return interfaces; + } + } + + /// + /// Is this advice associated with a particular instance? + /// + /// + ///

+ /// Default for an introduction is per-instance interception. + ///

+ ///
+ /// + /// if this advice is associated with a + /// particular instance. + /// + public virtual bool IsPerInstance + { + get { return true; } + } + + /// + /// Return the advice part of this aspect. + /// + /// + /// The advice that should apply if the pointcut matches. + /// + public virtual IAdvice Advice + { + get { return this._introduction; } + } + + /// + /// Adds the supplied to the list of + /// introduced interfaces. + /// + /// The interface to add. + /// + /// If any of the are not interface . + /// + public virtual void AddInterface(Type intf) + { + if(intf != null) + { + BailIfNotAnInterfaceType(intf); + _interfaces.Add(intf); + } + } + + /// + /// Should the pointcut apply to the supplied + /// ? + /// + /// + ///

+ /// This, the default, implementation always returns . + ///

+ ///
+ /// + /// The candidate . + /// + /// + /// if the advice should apply to the supplied + /// + /// + public virtual bool Matches(Type type) + { + return true; + } + + /// + /// Can the advised interfaces be implemented by the introduction + /// advice? + /// + /// + ///

+ /// Invoked before adding an + /// . + ///

+ ///
+ /// + /// If the advised interfaces cannot be implemented by the introduction + /// advice. + /// + /// + /// + /// If any of the are not interface . + /// + public virtual void ValidateInterfaces() + { + foreach (Type intf in _interfaces) + { + BailIfNotAnInterfaceType(intf); + if (! intf.IsAssignableFrom(_introduction.GetType())) + { + throw new ArgumentException("Introduction [" + _introduction.GetType().FullName + "] " + + "does not implement interface '" + intf.FullName + "' specified in introduction advice."); + } + } + } + + private static void BailIfNotAnInterfaceType(Type intf) + { + if (intf != null && !intf.IsInterface) + { + throw new ArgumentException("Type [" + intf.FullName + "] is not an interface; cannot be used in an introduction."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/DefaultObjectFactoryPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/DefaultObjectFactoryPointcutAdvisor.cs index 07a0d700..e93e1ce7 100644 --- a/src/Spring/Spring.Aop/Aop/Support/DefaultObjectFactoryPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/DefaultObjectFactoryPointcutAdvisor.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Concrete ObjectFactory-based IPointcutAdvisor thta allows for any Advice to be - /// configured as reference to an Advice object in the ObjectFatory, as well as - /// the Pointcut to be configured through an object property. - /// - /// - /// Specifying the name of an advice object instead of the advice object itself - /// (if running within a ObjectFactory/ApplicationContext) increases loose coupling - /// at initialization time, in order to not intialize the advice object until the pointcut - /// actually matches. - /// - /// Juerge Hoeller - /// Mark Pollack - /// $Id: DefaultObjectFactoryPointcutAdvisor.cs,v 1.1 2007/05/30 22:35:43 markpollack Exp $ - public class DefaultObjectFactoryPointcutAdvisor : AbstractObjectFactoryPointcutAdvisor - { - private IPointcut pointcut = TruePointcut.True; - - - /// - /// The that drives this advisor. - /// - public override IPointcut Pointcut - { - get { return pointcut; } - set { pointcut = (pointcut != null ? value : TruePointcut.True); } - } - - /// - /// Describe this Advisor, showing pointcut and name of advice object. - /// - /// Type name , pointcut, and advice object name. - public override string ToString() - { - return GetType().Name + ": pointcut [" + Pointcut + "]; advice object = '" + AdviceObjectName + "'"; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Concrete ObjectFactory-based IPointcutAdvisor thta allows for any Advice to be + /// configured as reference to an Advice object in the ObjectFatory, as well as + /// the Pointcut to be configured through an object property. + /// + /// + /// Specifying the name of an advice object instead of the advice object itself + /// (if running within a ObjectFactory/ApplicationContext) increases loose coupling + /// at initialization time, in order to not intialize the advice object until the pointcut + /// actually matches. + /// + /// Juerge Hoeller + /// Mark Pollack + public class DefaultObjectFactoryPointcutAdvisor : AbstractObjectFactoryPointcutAdvisor + { + private IPointcut pointcut = TruePointcut.True; + + + /// + /// The that drives this advisor. + /// + public override IPointcut Pointcut + { + get { return pointcut; } + set { pointcut = (pointcut != null ? value : TruePointcut.True); } + } + + /// + /// Describe this Advisor, showing pointcut and name of advice object. + /// + /// Type name , pointcut, and advice object name. + public override string ToString() + { + return GetType().Name + ": pointcut [" + Pointcut + "]; advice object = '" + AdviceObjectName + "'"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/DefaultPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/DefaultPointcutAdvisor.cs index 0a0929a0..42ceb535 100644 --- a/src/Spring/Spring.Aop/Aop/Support/DefaultPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/DefaultPointcutAdvisor.cs @@ -1,111 +1,110 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient pointcut-driven advisor implementation. - /// - /// - ///

- /// This is the most commonly used implementation. - /// It can be used with any pointcut and advice type, except for introductions. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: DefaultPointcutAdvisor.cs,v 1.8 2007/05/30 22:35:43 markpollack Exp $ - [Serializable] - public class DefaultPointcutAdvisor : AbstractGenericPointcutAdvisor - { - - private IPointcut pointcut = TruePointcut.True; - - /// - /// Creates a new instance of the - /// class. - /// - public DefaultPointcutAdvisor() - { - } - - /// - /// Creates a new instance of the - /// - /// class for the supplied , - /// - /// - /// The advice to use. - /// - public DefaultPointcutAdvisor(IAdvice advice) - : this(TruePointcut.True, advice) - { - } - - /// - /// Creates a new instance of the - /// - /// class for the supplied and - /// . - /// - /// - /// The advice to use. - /// - /// - /// The pointcut to use. - /// - public DefaultPointcutAdvisor(IPointcut pointcut, IAdvice advice) - { - this.pointcut = pointcut; - Advice = advice; - } - - /// - /// The that drives this advisor. - /// - public override IPointcut Pointcut - { - get { return pointcut; } - set { pointcut = value;} - } - - - - - /// - /// Returns a that represents the current - /// . - /// - /// - /// A representation of this advisor. - /// - public override string ToString() - { - return GetType().Name + ": pointcut=[" + pointcut + "] advice=[" + Advice + "]"; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient pointcut-driven advisor implementation. + /// + /// + ///

+ /// This is the most commonly used implementation. + /// It can be used with any pointcut and advice type, except for introductions. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class DefaultPointcutAdvisor : AbstractGenericPointcutAdvisor + { + + private IPointcut pointcut = TruePointcut.True; + + /// + /// Creates a new instance of the + /// class. + /// + public DefaultPointcutAdvisor() + { + } + + /// + /// Creates a new instance of the + /// + /// class for the supplied , + /// + /// + /// The advice to use. + /// + public DefaultPointcutAdvisor(IAdvice advice) + : this(TruePointcut.True, advice) + { + } + + /// + /// Creates a new instance of the + /// + /// class for the supplied and + /// . + /// + /// + /// The advice to use. + /// + /// + /// The pointcut to use. + /// + public DefaultPointcutAdvisor(IPointcut pointcut, IAdvice advice) + { + this.pointcut = pointcut; + Advice = advice; + } + + /// + /// The that drives this advisor. + /// + public override IPointcut Pointcut + { + get { return pointcut; } + set { pointcut = value;} + } + + + + + /// + /// Returns a that represents the current + /// . + /// + /// + /// A representation of this advisor. + /// + public override string ToString() + { + return GetType().Name + ": pointcut=[" + pointcut + "] advice=[" + Advice + "]"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcher.cs b/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcher.cs index 5b3301ba..34ad8422 100644 --- a/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcher.cs +++ b/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcher.cs @@ -1,114 +1,113 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient abstract superclass for dynamic method matchers that do - /// care about arguments at runtime. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: DynamicMethodMatcher.cs,v 1.5 2006/04/09 07:18:37 markpollack Exp $ - public abstract class DynamicMethodMatcher : IMethodMatcher - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected DynamicMethodMatcher() - { - } - - #endregion - - /// - /// Is this dynamic? - /// - /// - /// Always returns , to specify that this is a - /// dynamic matcher. - /// - public virtual bool IsRuntime - { - get { return true; } - } - - /// - /// Does the supplied satisfy this matcher? - /// - /// - ///

- /// Derived classes can override this method to add preconditions for - /// dynamic matching. - ///

- ///

- /// This implementation always returns . - ///

- ///
- /// The candidate method. - /// - /// The target (may be , - /// in which case the candidate must be taken - /// to be the 's declaring class). - /// - /// - /// if this this method matches statically. - /// - public virtual bool Matches(MethodInfo method, Type targetType) - { - return true; - } - - /// - /// Is there a runtime (dynamic) match for the supplied - /// ? - /// - /// - ///

- /// Must be overriden by derived classes to provide criteria for dynamic matching. - ///

- ///
- /// The candidate method. - /// - /// The target . - /// - /// The arguments to the method - /// - /// if there is a runtime match. - public abstract bool Matches(MethodInfo method, Type targetType, object[] args); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient abstract superclass for dynamic method matchers that do + /// care about arguments at runtime. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public abstract class DynamicMethodMatcher : IMethodMatcher + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected DynamicMethodMatcher() + { + } + + #endregion + + /// + /// Is this dynamic? + /// + /// + /// Always returns , to specify that this is a + /// dynamic matcher. + /// + public virtual bool IsRuntime + { + get { return true; } + } + + /// + /// Does the supplied satisfy this matcher? + /// + /// + ///

+ /// Derived classes can override this method to add preconditions for + /// dynamic matching. + ///

+ ///

+ /// This implementation always returns . + ///

+ ///
+ /// The candidate method. + /// + /// The target (may be , + /// in which case the candidate must be taken + /// to be the 's declaring class). + /// + /// + /// if this this method matches statically. + /// + public virtual bool Matches(MethodInfo method, Type targetType) + { + return true; + } + + /// + /// Is there a runtime (dynamic) match for the supplied + /// ? + /// + /// + ///

+ /// Must be overriden by derived classes to provide criteria for dynamic matching. + ///

+ ///
+ /// The candidate method. + /// + /// The target . + /// + /// The arguments to the method + /// + /// if there is a runtime match. + public abstract bool Matches(MethodInfo method, Type targetType, object[] args); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcherPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcherPointcutAdvisor.cs index 00371f96..a2be9be7 100644 --- a/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcherPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/DynamicMethodMatcherPointcutAdvisor.cs @@ -1,176 +1,175 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Core; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient superclass for s - /// that are also dynamic pointcuts. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: DynamicMethodMatcherPointcutAdvisor.cs,v 1.6 2007/03/16 04:01:24 aseovic Exp $ - [Serializable] - public abstract class DynamicMethodMatcherPointcutAdvisor - : DynamicMethodMatcher, IPointcutAdvisor, IPointcut, IOrdered - { - private int _order = Int32.MaxValue; - private IAdvice _advice; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- protected DynamicMethodMatcherPointcutAdvisor() - { - } - - /// - /// Creates a new instance of the - /// - /// class for the supplied . - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- /// - /// The advice portion of this advisor. - /// - protected DynamicMethodMatcherPointcutAdvisor(IAdvice advice) - { - this._advice = advice; - } - - /// - /// Is this advice associated with a particular instance? - /// - /// - ///

- /// Not supported for dynamic advisors. - ///

- ///
- /// - /// if this advice is associated with a - /// particular instance. - /// - /// Always. - /// - public virtual bool IsPerInstance - { - get - { - throw new NotSupportedException( - "The 'IsPerInstance' property of the IAdvisor interface " + - "is not yet supported in Spring.NET."); - } - } - - /// - /// The for this pointcut. - /// - /// - ///

- /// This implementation always returns a filter that evaluates to - /// for any . - ///

- ///
- /// - /// The current . - /// - public virtual ITypeFilter TypeFilter - { - get { return TrueTypeFilter.True; } - } - - /// - /// The for this pointcut. - /// - /// - ///

- /// This implementation always returns itself (this object). - ///

- ///
- /// - /// The current . - /// - public virtual IMethodMatcher MethodMatcher - { - get { return this; } - } - - /// - /// Returns this s order in the - /// interception chain. - /// - /// - /// This s order in the - /// interception chain. - /// - public virtual int Order - { - get { return this._order; } - set { this._order = value; } - } - - /// - /// Return the advice part of this aspect. - /// - /// - /// The advice that should apply if the pointcut matches. - /// - /// - public virtual IAdvice Advice - { - get { return this._advice; } - set { this._advice = value; } - } - - /// - /// The that drives this advisor. - /// - /// - ///

- /// This implementation always returns itself (this object). - ///

- ///
- public IPointcut Pointcut - { - get { return this; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Core; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient superclass for s + /// that are also dynamic pointcuts. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public abstract class DynamicMethodMatcherPointcutAdvisor + : DynamicMethodMatcher, IPointcutAdvisor, IPointcut, IOrdered + { + private int _order = Int32.MaxValue; + private IAdvice _advice; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ protected DynamicMethodMatcherPointcutAdvisor() + { + } + + /// + /// Creates a new instance of the + /// + /// class for the supplied . + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ /// + /// The advice portion of this advisor. + /// + protected DynamicMethodMatcherPointcutAdvisor(IAdvice advice) + { + this._advice = advice; + } + + /// + /// Is this advice associated with a particular instance? + /// + /// + ///

+ /// Not supported for dynamic advisors. + ///

+ ///
+ /// + /// if this advice is associated with a + /// particular instance. + /// + /// Always. + /// + public virtual bool IsPerInstance + { + get + { + throw new NotSupportedException( + "The 'IsPerInstance' property of the IAdvisor interface " + + "is not yet supported in Spring.NET."); + } + } + + /// + /// The for this pointcut. + /// + /// + ///

+ /// This implementation always returns a filter that evaluates to + /// for any . + ///

+ ///
+ /// + /// The current . + /// + public virtual ITypeFilter TypeFilter + { + get { return TrueTypeFilter.True; } + } + + /// + /// The for this pointcut. + /// + /// + ///

+ /// This implementation always returns itself (this object). + ///

+ ///
+ /// + /// The current . + /// + public virtual IMethodMatcher MethodMatcher + { + get { return this; } + } + + /// + /// Returns this s order in the + /// interception chain. + /// + /// + /// This s order in the + /// interception chain. + /// + public virtual int Order + { + get { return this._order; } + set { this._order = value; } + } + + /// + /// Return the advice part of this aspect. + /// + /// + /// The advice that should apply if the pointcut matches. + /// + /// + public virtual IAdvice Advice + { + get { return this._advice; } + set { this._advice = value; } + } + + /// + /// The that drives this advisor. + /// + /// + ///

+ /// This implementation always returns itself (this object). + ///

+ ///
+ public IPointcut Pointcut + { + get { return this; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/MethodMatchers.cs b/src/Spring/Spring.Aop/Aop/Support/MethodMatchers.cs index 9047ac75..762e0037 100644 --- a/src/Spring/Spring.Aop/Aop/Support/MethodMatchers.cs +++ b/src/Spring/Spring.Aop/Aop/Support/MethodMatchers.cs @@ -1,181 +1,180 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Various utility methods relating to the composition of - /// s. - /// - /// - ///

- /// A method matcher may be evaluated statically (based on method and target - /// class) or need further evaluation dynamically (based on arguments at - /// the time of method invocation). - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: MethodMatchers.cs,v 1.7 2007/03/16 04:01:24 aseovic Exp $ - public sealed class MethodMatchers - { - /// - /// Creates a new that is the - /// union of the two supplied s. - /// - /// - ///

- /// The newly created matcher will match all the methods that either of the two - /// supplied matchers would match. - ///

- ///
- /// The first method matcher. - /// The second method matcher. - /// - /// A new that is the - /// union of the two supplied s - /// - public static IMethodMatcher Union( - IMethodMatcher firstMatcher, IMethodMatcher secondMatcher) - { - return new UnionMethodMatcher(firstMatcher, secondMatcher); - } - - /// - /// Creates a new that is the - /// intersection of the two supplied s. - /// - /// - ///

- /// The newly created matcher will match only those methods that both - /// of the supplied matchers would match. - ///

- ///
- /// The first method matcher. - /// The second method matcher. - /// - /// A new that is the - /// intersection of the two supplied s - /// - public static IMethodMatcher Intersection( - IMethodMatcher firstMatcher, IMethodMatcher secondMatcher) - { - return new IntersectionMethodMatcher(firstMatcher, secondMatcher); - } - - #region Inner Class : UnionMethodMatcher - - [Serializable] - private sealed class UnionMethodMatcher : IMethodMatcher - { - private IMethodMatcher a; - private IMethodMatcher b; - - public UnionMethodMatcher(IMethodMatcher a, IMethodMatcher b) - { - this.a = a; - this.b = b; - } - - public bool IsRuntime - { - get { return a.IsRuntime || b.IsRuntime; } - } - - public bool Matches(MethodInfo m, Type targetType) - { - return a.Matches(m, targetType) || b.Matches(m, targetType); - } - - public bool Matches(MethodInfo m, Type targetType, object[] args) - { - return a.Matches(m, targetType, args) || b.Matches(m, targetType, args); - } - } - - #endregion - - #region Inner Class : IntersectionMethodMatcher - - [Serializable] - private sealed class IntersectionMethodMatcher : IMethodMatcher - { - private IMethodMatcher a; - private IMethodMatcher b; - - public IntersectionMethodMatcher(IMethodMatcher a, IMethodMatcher b) - { - this.a = a; - this.b = b; - } - - public bool IsRuntime - { - get { return a.IsRuntime || b.IsRuntime; } - } - - public bool Matches(MethodInfo m, Type targetType) - { - return a.Matches(m, targetType) && b.Matches(m, targetType); - } - - public bool Matches(MethodInfo m, Type targetType, object[] args) - { - // Because a dynamic intersection may be composed of a static and dynamic part, - // we must avoid calling the 3-arg matches method on a dynamic matcher, as - // it will probably be an unsupported operation. - bool aMatches = a.IsRuntime ? a.Matches(m, targetType, args) : a.Matches(m, targetType); - bool bMatches = b.IsRuntime ? b.Matches(m, targetType, args) : b.Matches(m, targetType); - return aMatches && bMatches; - } - } - - #endregion - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly - /// visible constructors. - ///

- ///
- private MethodMatchers() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Various utility methods relating to the composition of + /// s. + /// + /// + ///

+ /// A method matcher may be evaluated statically (based on method and target + /// class) or need further evaluation dynamically (based on arguments at + /// the time of method invocation). + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public sealed class MethodMatchers + { + /// + /// Creates a new that is the + /// union of the two supplied s. + /// + /// + ///

+ /// The newly created matcher will match all the methods that either of the two + /// supplied matchers would match. + ///

+ ///
+ /// The first method matcher. + /// The second method matcher. + /// + /// A new that is the + /// union of the two supplied s + /// + public static IMethodMatcher Union( + IMethodMatcher firstMatcher, IMethodMatcher secondMatcher) + { + return new UnionMethodMatcher(firstMatcher, secondMatcher); + } + + /// + /// Creates a new that is the + /// intersection of the two supplied s. + /// + /// + ///

+ /// The newly created matcher will match only those methods that both + /// of the supplied matchers would match. + ///

+ ///
+ /// The first method matcher. + /// The second method matcher. + /// + /// A new that is the + /// intersection of the two supplied s + /// + public static IMethodMatcher Intersection( + IMethodMatcher firstMatcher, IMethodMatcher secondMatcher) + { + return new IntersectionMethodMatcher(firstMatcher, secondMatcher); + } + + #region Inner Class : UnionMethodMatcher + + [Serializable] + private sealed class UnionMethodMatcher : IMethodMatcher + { + private IMethodMatcher a; + private IMethodMatcher b; + + public UnionMethodMatcher(IMethodMatcher a, IMethodMatcher b) + { + this.a = a; + this.b = b; + } + + public bool IsRuntime + { + get { return a.IsRuntime || b.IsRuntime; } + } + + public bool Matches(MethodInfo m, Type targetType) + { + return a.Matches(m, targetType) || b.Matches(m, targetType); + } + + public bool Matches(MethodInfo m, Type targetType, object[] args) + { + return a.Matches(m, targetType, args) || b.Matches(m, targetType, args); + } + } + + #endregion + + #region Inner Class : IntersectionMethodMatcher + + [Serializable] + private sealed class IntersectionMethodMatcher : IMethodMatcher + { + private IMethodMatcher a; + private IMethodMatcher b; + + public IntersectionMethodMatcher(IMethodMatcher a, IMethodMatcher b) + { + this.a = a; + this.b = b; + } + + public bool IsRuntime + { + get { return a.IsRuntime || b.IsRuntime; } + } + + public bool Matches(MethodInfo m, Type targetType) + { + return a.Matches(m, targetType) && b.Matches(m, targetType); + } + + public bool Matches(MethodInfo m, Type targetType, object[] args) + { + // Because a dynamic intersection may be composed of a static and dynamic part, + // we must avoid calling the 3-arg matches method on a dynamic matcher, as + // it will probably be an unsupported operation. + bool aMatches = a.IsRuntime ? a.Matches(m, targetType, args) : a.Matches(m, targetType); + bool bMatches = b.IsRuntime ? b.Matches(m, targetType, args) : b.Matches(m, targetType); + return aMatches && bMatches; + } + } + + #endregion + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ private MethodMatchers() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcut.cs index 72a91684..465744d9 100644 --- a/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcut.cs @@ -1,122 +1,121 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Pointcut object for simple method name matches, useful as an alternative to pure - /// regular expression based patterns. - /// - /// Juergen Hoeller - /// Aleksandar Seovic (.NET) - /// $Id: NameMatchMethodPointcut.cs,v 1.9 2007/03/16 04:01:24 aseovic Exp $ - [Serializable] - public class NameMatchMethodPointcut : StaticMethodMatcherPointcut - { - private string[] _mappedNames = new string[0]; - - /// - /// Convenience property when we have only a single method name - /// to match. - /// - /// - /// - /// Use either this property or the - /// property, - /// not both. - /// - /// - public virtual string MappedName - { - set { MappedNames = new string[] {value}; } - } - - /// - /// Set the method names defining methods to match. - /// - /// - ///

- /// Matching will be the union of all these; if any match, the pointcut matches. - ///

- ///
- public virtual string[] MappedNames - { - set { this._mappedNames = value; } - } - - /// - /// Does the of the supplied - /// matches any of the mapped names? - /// - /// - /// The to check. - /// - /// - /// The of the target class. - /// - /// - /// if the name of the supplied - /// matches one of the mapped names. - /// - public override bool Matches(MethodInfo method, Type targetType) - { - for (int i = 0; i < this._mappedNames.Length; i++) - { - string mappedName = this._mappedNames[i]; - if (mappedName.Equals(method.Name) || IsMatch(method.Name, mappedName)) - { - return true; - } - } - return false; - } - - /// - /// Does the supplied match the supplied ? - /// - /// - ///

- /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, - /// as well as direct equality. Can be overridden in subclasses. - ///

- ///
- /// - /// The method name of the class. - /// - /// - /// The name in the descriptor. - /// - /// - /// True if the names match. - /// - protected virtual bool IsMatch(string methodName, string mappedName) - { - return PatternMatchUtils.SimpleMatch(mappedName, methodName); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Pointcut object for simple method name matches, useful as an alternative to pure + /// regular expression based patterns. + /// + /// Juergen Hoeller + /// Aleksandar Seovic (.NET) + [Serializable] + public class NameMatchMethodPointcut : StaticMethodMatcherPointcut + { + private string[] _mappedNames = new string[0]; + + /// + /// Convenience property when we have only a single method name + /// to match. + /// + /// + /// + /// Use either this property or the + /// property, + /// not both. + /// + /// + public virtual string MappedName + { + set { MappedNames = new string[] {value}; } + } + + /// + /// Set the method names defining methods to match. + /// + /// + ///

+ /// Matching will be the union of all these; if any match, the pointcut matches. + ///

+ ///
+ public virtual string[] MappedNames + { + set { this._mappedNames = value; } + } + + /// + /// Does the of the supplied + /// matches any of the mapped names? + /// + /// + /// The to check. + /// + /// + /// The of the target class. + /// + /// + /// if the name of the supplied + /// matches one of the mapped names. + /// + public override bool Matches(MethodInfo method, Type targetType) + { + for (int i = 0; i < this._mappedNames.Length; i++) + { + string mappedName = this._mappedNames[i]; + if (mappedName.Equals(method.Name) || IsMatch(method.Name, mappedName)) + { + return true; + } + } + return false; + } + + /// + /// Does the supplied match the supplied ? + /// + /// + ///

+ /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, + /// as well as direct equality. Can be overridden in subclasses. + ///

+ ///
+ /// + /// The method name of the class. + /// + /// + /// The name in the descriptor. + /// + /// + /// True if the names match. + /// + protected virtual bool IsMatch(string methodName, string mappedName) + { + return PatternMatchUtils.SimpleMatch(mappedName, methodName); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcutAdvisor.cs index 0e86300c..c523ac43 100644 --- a/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/NameMatchMethodPointcutAdvisor.cs @@ -1,130 +1,129 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient class for name-match method pointcuts that hold an Interceptor, - /// making them an Advisor. - /// - /// Juergen Hoeller - /// Aleksandar Seovic (.NET) - /// Mark Pollack (.NET) - /// $Id: NameMatchMethodPointcutAdvisor.cs,v 1.5 2007/05/30 22:35:43 markpollack Exp $ - [Serializable] - public class NameMatchMethodPointcutAdvisor : AbstractGenericPointcutAdvisor - { - - private NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); - - #region Constructor(s) - - /// - /// Creates a new instance of the - /// class. - /// - public NameMatchMethodPointcutAdvisor() - { - } - - /// - /// Creates a new instance of the - /// class - /// for the supplied . - /// - /// - public NameMatchMethodPointcutAdvisor(IAdvice advice) - { - Advice = advice; - } - - #endregion - - - #region Properties - /// - /// The for this pointcut. - /// - /// Default is - /// - /// The current . - /// - public ITypeFilter TypeFilter { - set - { - pointcut.TypeFilter = value; - } - } - - /// - /// Convenience property when we have only a single method name - /// to match. - /// - /// - /// - /// Use either this property or the - /// property, - /// not both. - /// - /// - public string MappedName - { - set { pointcut.MappedName = value; } - } - - /// - /// Set the method names defining methods to match. - /// - /// - ///

- /// Matching will be the union of all these; if any match, the pointcut matches. - ///

- ///
- public string[] MappedNames - { - set { pointcut.MappedNames = value; } - } - - /// - /// The that drives this advisor. - /// - public override IPointcut Pointcut - { - get { return pointcut; } - set - { - AssertUtils.AssertArgumentType(value, "pointcut", typeof(NameMatchMethodPointcut), - "Pointcut most be compatible with type NameMatchMethodPointcut"); - pointcut = value as NameMatchMethodPointcut; - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient class for name-match method pointcuts that hold an Interceptor, + /// making them an Advisor. + /// + /// Juergen Hoeller + /// Aleksandar Seovic (.NET) + /// Mark Pollack (.NET) + [Serializable] + public class NameMatchMethodPointcutAdvisor : AbstractGenericPointcutAdvisor + { + + private NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); + + #region Constructor(s) + + /// + /// Creates a new instance of the + /// class. + /// + public NameMatchMethodPointcutAdvisor() + { + } + + /// + /// Creates a new instance of the + /// class + /// for the supplied . + /// + /// + public NameMatchMethodPointcutAdvisor(IAdvice advice) + { + Advice = advice; + } + + #endregion + + + #region Properties + /// + /// The for this pointcut. + /// + /// Default is + /// + /// The current . + /// + public ITypeFilter TypeFilter { + set + { + pointcut.TypeFilter = value; + } + } + + /// + /// Convenience property when we have only a single method name + /// to match. + /// + /// + /// + /// Use either this property or the + /// property, + /// not both. + /// + /// + public string MappedName + { + set { pointcut.MappedName = value; } + } + + /// + /// Set the method names defining methods to match. + /// + /// + ///

+ /// Matching will be the union of all these; if any match, the pointcut matches. + ///

+ ///
+ public string[] MappedNames + { + set { pointcut.MappedNames = value; } + } + + /// + /// The that drives this advisor. + /// + public override IPointcut Pointcut + { + get { return pointcut; } + set + { + AssertUtils.AssertArgumentType(value, "pointcut", typeof(NameMatchMethodPointcut), + "Pointcut most be compatible with type NameMatchMethodPointcut"); + pointcut = value as NameMatchMethodPointcut; + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/Pointcuts.cs b/src/Spring/Spring.Aop/Aop/Support/Pointcuts.cs index 33c86860..da6274f4 100644 --- a/src/Spring/Spring.Aop/Aop/Support/Pointcuts.cs +++ b/src/Spring/Spring.Aop/Aop/Support/Pointcuts.cs @@ -1,146 +1,145 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Various related utility methods. - /// - /// - ///

- /// These methods are particularly useful for composing pointcuts - /// using the union and intersection methods. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: Pointcuts.cs,v 1.6 2007/03/16 04:01:25 aseovic Exp $ - public sealed class Pointcuts - { - /// - /// Creates a union of the two supplied pointcuts. - /// - /// The first pointcut. - /// The second pointcut. - /// - /// The union of the two supplied pointcuts. - /// - /// - public static IPointcut Union(IPointcut firstPointcut, IPointcut secondPointcut) - { - return new UnionPointcut(firstPointcut, secondPointcut); - } - - /// - /// Creates an that is the - /// intersection of the two supplied pointcuts. - /// - /// The first pointcut. - /// The second pointcut. - /// - /// An that is the - /// intersection of the two supplied pointcuts. - /// - public static IPointcut Intersection(IPointcut firstPointcut, IPointcut secondPointcut) - { - return new ComposablePointcut( - firstPointcut.TypeFilter, firstPointcut.MethodMatcher) - .Intersection(secondPointcut); - } - - /// - /// Performs the least expensive check for a match. - /// - /// - /// The to be evaluated. - /// - /// The candidate method. - /// - /// The target . - /// - /// The arguments to the method - /// if there is a runtime match. - /// - public static bool Matches( - IPointcut pointcut, MethodInfo method, Type targetType, object[] args) - { - if(pointcut != null) - { - if (pointcut == TruePointcut.True) - { - return true; - } - if (pointcut.TypeFilter.Matches(targetType)) - { - IMethodMatcher mm = pointcut.MethodMatcher; - if (mm.Matches(method, targetType)) - { - return mm.IsRuntime ? mm.Matches(method, targetType, args) : true; - } - } - } - return false; - } - - /// - /// Are the supplied s equal? - /// - /// The first pointcut. - /// The second pointcut. - /// - /// if the supplied s - /// are equal. - /// - public static bool AreEqual(IPointcut firstPointcut, IPointcut secondPointcut) - { - return firstPointcut.TypeFilter == secondPointcut.TypeFilter - && firstPointcut.MethodMatcher == secondPointcut.MethodMatcher; - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly - /// visible constructors. - ///

- ///
- private Pointcuts() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Various related utility methods. + /// + /// + ///

+ /// These methods are particularly useful for composing pointcuts + /// using the union and intersection methods. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + public sealed class Pointcuts + { + /// + /// Creates a union of the two supplied pointcuts. + /// + /// The first pointcut. + /// The second pointcut. + /// + /// The union of the two supplied pointcuts. + /// + /// + public static IPointcut Union(IPointcut firstPointcut, IPointcut secondPointcut) + { + return new UnionPointcut(firstPointcut, secondPointcut); + } + + /// + /// Creates an that is the + /// intersection of the two supplied pointcuts. + /// + /// The first pointcut. + /// The second pointcut. + /// + /// An that is the + /// intersection of the two supplied pointcuts. + /// + public static IPointcut Intersection(IPointcut firstPointcut, IPointcut secondPointcut) + { + return new ComposablePointcut( + firstPointcut.TypeFilter, firstPointcut.MethodMatcher) + .Intersection(secondPointcut); + } + + /// + /// Performs the least expensive check for a match. + /// + /// + /// The to be evaluated. + /// + /// The candidate method. + /// + /// The target . + /// + /// The arguments to the method + /// if there is a runtime match. + /// + public static bool Matches( + IPointcut pointcut, MethodInfo method, Type targetType, object[] args) + { + if(pointcut != null) + { + if (pointcut == TruePointcut.True) + { + return true; + } + if (pointcut.TypeFilter.Matches(targetType)) + { + IMethodMatcher mm = pointcut.MethodMatcher; + if (mm.Matches(method, targetType)) + { + return mm.IsRuntime ? mm.Matches(method, targetType, args) : true; + } + } + } + return false; + } + + /// + /// Are the supplied s equal? + /// + /// The first pointcut. + /// The second pointcut. + /// + /// if the supplied s + /// are equal. + /// + public static bool AreEqual(IPointcut firstPointcut, IPointcut secondPointcut) + { + return firstPointcut.TypeFilter == secondPointcut.TypeFilter + && firstPointcut.MethodMatcher == secondPointcut.MethodMatcher; + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ private Pointcuts() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/RegularExpressionMethodPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/RegularExpressionMethodPointcutAdvisor.cs index 2195a67a..ab85e2f4 100644 --- a/src/Spring/Spring.Aop/Aop/Support/RegularExpressionMethodPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/RegularExpressionMethodPointcutAdvisor.cs @@ -1,140 +1,140 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient class for regular expression method pointcuts that hold an - /// , making them an - /// . - /// - /// - ///

- /// Configure this class using the and - /// pass-through properties. These are analogous - /// to the and - /// s properties of the - /// class. - ///

- ///

- /// Can delegate to any type of regular expression pointcut. Currently only - /// pointcuts based on the regular expression classes from the .NET Base - /// Class Library are supported. The - /// - /// property must be a subclass of the - /// class. - ///

- ///

- /// This should not normally be set directly. - ///

- ///
- /// Dmitriy Kopylenko - /// Rod Johnson - /// Simon White (.NET) - /// Mark Pollack (.NET) - /// - [Serializable] - public class RegularExpressionMethodPointcutAdvisor : AbstractGenericPointcutAdvisor - { - private AbstractRegularExpressionMethodPointcut pointcut; - - #region Constructors - - /// - /// Creates a new instance of the - /// class. - /// - public RegularExpressionMethodPointcutAdvisor() - { - InitPointcut(); - } - - /// - /// Creates a new instance of the - /// class for the supplied . - /// - /// The target advice. - /// - public RegularExpressionMethodPointcutAdvisor(IAdvice advice) - { - Advice = advice; - InitPointcut(); - } - - #endregion - - #region Properties - - /// - /// A single pattern to be used during method evaluation. - /// - public string Pattern - { - set - { - AbstractRegularExpressionMethodPointcut armp = (AbstractRegularExpressionMethodPointcut) Pointcut; - armp.Pattern = value; - } - } - - /// - /// Multiple patterns to be used during method evaluation. - /// - public string[] Patterns - { - set - { - AbstractRegularExpressionMethodPointcut armp = (AbstractRegularExpressionMethodPointcut) Pointcut; - armp.Patterns = value; - } - } - - /// - /// The that drives this advisor. - /// - public override IPointcut Pointcut - { - get { return pointcut; } - set { - AssertUtils.AssertArgumentType(value, "pointcut", typeof(AbstractRegularExpressionMethodPointcut), - "Pointcut most be compatible with type AbstractRegularExpressionMethodPointuct"); - pointcut = value as AbstractRegularExpressionMethodPointcut; - } - } - - #endregion - - /// - /// Initialises the pointcut. - /// - protected void InitPointcut() - { - pointcut = new SdkRegularExpressionMethodPointcut(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient class for regular expression method pointcuts that hold an + /// , making them an + /// . + /// + /// + ///

+ /// Configure this class using the and + /// pass-through properties. These are analogous + /// to the and + /// s properties of the + /// class. + ///

+ ///

+ /// Can delegate to any type of regular expression pointcut. Currently only + /// pointcuts based on the regular expression classes from the .NET Base + /// Class Library are supported. The + /// + /// property must be a subclass of the + /// class. + ///

+ ///

+ /// This should not normally be set directly. + ///

+ ///
+ /// Dmitriy Kopylenko + /// Rod Johnson + /// Simon White (.NET) + /// Mark Pollack (.NET) + /// + [Serializable] + public class RegularExpressionMethodPointcutAdvisor : AbstractGenericPointcutAdvisor + { + private AbstractRegularExpressionMethodPointcut pointcut; + + #region Constructors + + /// + /// Creates a new instance of the + /// class. + /// + public RegularExpressionMethodPointcutAdvisor() + { + InitPointcut(); + } + + /// + /// Creates a new instance of the + /// class for the supplied . + /// + /// The target advice. + /// + public RegularExpressionMethodPointcutAdvisor(IAdvice advice) + { + Advice = advice; + InitPointcut(); + } + + #endregion + + #region Properties + + /// + /// A single pattern to be used during method evaluation. + /// + public string Pattern + { + set + { + AbstractRegularExpressionMethodPointcut armp = (AbstractRegularExpressionMethodPointcut) Pointcut; + armp.Pattern = value; + } + } + + /// + /// Multiple patterns to be used during method evaluation. + /// + public string[] Patterns + { + set + { + AbstractRegularExpressionMethodPointcut armp = (AbstractRegularExpressionMethodPointcut) Pointcut; + armp.Patterns = value; + } + } + + /// + /// The that drives this advisor. + /// + public override IPointcut Pointcut + { + get { return pointcut; } + set { + AssertUtils.AssertArgumentType(value, "pointcut", typeof(AbstractRegularExpressionMethodPointcut), + "Pointcut most be compatible with type AbstractRegularExpressionMethodPointuct"); + pointcut = value as AbstractRegularExpressionMethodPointcut; + } + } + + #endregion + + /// + /// Initialises the pointcut. + /// + protected void InitPointcut() + { + pointcut = new SdkRegularExpressionMethodPointcut(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/RootTypeFilter.cs b/src/Spring/Spring.Aop/Aop/Support/RootTypeFilter.cs index f4ad59da..33833a3b 100644 --- a/src/Spring/Spring.Aop/Aop/Support/RootTypeFilter.cs +++ b/src/Spring/Spring.Aop/Aop/Support/RootTypeFilter.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Simple implementation that matches - /// all classes classes (and any derived subclasses) of a give root - /// . - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: RootTypeFilter.cs,v 1.3 2007/03/16 04:01:25 aseovic Exp $ - [Serializable] - public class RootTypeFilter : ITypeFilter - { - private Type _rootType; - - /// - /// Creates a new instance of the - /// for the supplied - /// . - /// - /// The root . - /// - /// If the supplied is . - /// - public RootTypeFilter(Type rootType) - { - AssertUtils.ArgumentNotNull(rootType, "rootType"); - _rootType = rootType; - } - - /// - /// Should the pointcut apply to the supplied - /// ? - /// - /// - ///

- /// Returns if the supplied - /// can be assigned to the root . - ///

- ///
- /// - /// The candidate . - /// - /// - /// if the advice should apply to the supplied - /// - /// - public virtual bool Matches(Type type) - { - return _rootType.IsAssignableFrom(type); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Simple implementation that matches + /// all classes classes (and any derived subclasses) of a give root + /// . + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public class RootTypeFilter : ITypeFilter + { + private Type _rootType; + + /// + /// Creates a new instance of the + /// for the supplied + /// . + /// + /// The root . + /// + /// If the supplied is . + /// + public RootTypeFilter(Type rootType) + { + AssertUtils.ArgumentNotNull(rootType, "rootType"); + _rootType = rootType; + } + + /// + /// Should the pointcut apply to the supplied + /// ? + /// + /// + ///

+ /// Returns if the supplied + /// can be assigned to the root . + ///

+ ///
+ /// + /// The candidate . + /// + /// + /// if the advice should apply to the supplied + /// + /// + public virtual bool Matches(Type type) + { + return _rootType.IsAssignableFrom(type); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/SdkRegularExpressionMethodPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/SdkRegularExpressionMethodPointcut.cs index fb7d5900..efda9cd1 100644 --- a/src/Spring/Spring.Aop/Aop/Support/SdkRegularExpressionMethodPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/SdkRegularExpressionMethodPointcut.cs @@ -1,207 +1,207 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Text.RegularExpressions; -using Common.Logging; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Regular expression based pointcut object. - /// - /// - ///

- /// Uses the regular expression classes from the .NET Base Class Library. - ///

- ///

- /// The regular expressions must be a match. For example, the - /// .*Get* pattern will match Com.Mycom.Foo.GetBar(), and - /// Get.* will not. - ///

- ///
- /// Rod Johnson - /// Simon White (.NET) - [Serializable] - public class SdkRegularExpressionMethodPointcut : AbstractRegularExpressionMethodPointcut - { - private ILog _logger = LogManager.GetLogger(typeof(SdkRegularExpressionMethodPointcut)); - private Regex[] _compiledPatterns = new Regex[0]; - private RegexOptions _defaultOptions = RegexOptions.None; - - #region Constructors - - /// - /// Creates a new instance of the - /// class. - /// - public SdkRegularExpressionMethodPointcut() - { - } - - /// - /// Creates a new instance of the - /// class, - /// using the supplied pattern or . - /// - /// - /// The intial pattern value(s) to be matched against. - /// - public SdkRegularExpressionMethodPointcut(params string[] patterns) - { - Patterns = patterns; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - /// - /// If an error was encountered during the deserialization process. - /// - protected SdkRegularExpressionMethodPointcut(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets default options that should be used by - /// regular expressions that don't have options explicitly set. - /// - /// - /// Default options that should be used by regular expressions - /// that don't have options explicitly set. - /// - public RegexOptions DefaultOptions - { - get { return _defaultOptions; } - set - { - _defaultOptions = value; - InitPatternRepresentation(Patterns); - } - } - - #endregion - - #region Methods - - /// - /// Initializes the regular expression pointcuts. - /// - /// - ///

- /// Can be invoked multiple times. - ///

- ///

- /// This method will be invoked from the - /// property, - /// and also on deserialization. - ///

- ///
- /// - /// The patterns to initialize. - /// - /// - /// In the case of an invalid pattern. - /// - /// - /// If the supplied is . - /// - protected override void InitPatternRepresentation(object[] patterns) - { - AssertUtils.ArgumentNotNull(patterns, "patterns"); - - if (patterns.Length > 0) - { - _compiledPatterns = new Regex[patterns.Length]; - for (int i = 0; i < patterns.Length; i++) - { - if (patterns[i] == null) - { - throw new ArgumentNullException( - "Null is not a valid value for an element of the Patterns property."); - } - else if (patterns[i] is Regex) - { - _compiledPatterns[i] = (Regex)patterns[i]; - } - else if (patterns[i] is string) - { - _compiledPatterns[i] = new Regex((string)patterns[i], DefaultOptions); - } - else - { - throw new ArgumentException( - "You can only specify a string value or an instance of a Regex class " + - "as an element of the 'Patterns' property."); - } - } - } - } - - /// - /// Does the pattern at the supplied - /// match this ? - /// - /// The pattern to match - /// The index of pattern. - /// - /// if there is a match. - /// - protected override bool Matches(string pattern, int patternIndex) - { - Match match = _compiledPatterns[patternIndex].Match(pattern); - bool matched = match.Success; - - #region Instrumentation - - if (_logger.IsDebugEnabled) - { - _logger.Debug("Candidate is: '" + pattern + "'; pattern is '" + - _compiledPatterns[patternIndex].ToString() + "'; matched=" + matched); - } - - #endregion - - return matched; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Text.RegularExpressions; +using Common.Logging; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Regular expression based pointcut object. + /// + /// + ///

+ /// Uses the regular expression classes from the .NET Base Class Library. + ///

+ ///

+ /// The regular expressions must be a match. For example, the + /// .*Get* pattern will match Com.Mycom.Foo.GetBar(), and + /// Get.* will not. + ///

+ ///
+ /// Rod Johnson + /// Simon White (.NET) + [Serializable] + public class SdkRegularExpressionMethodPointcut : AbstractRegularExpressionMethodPointcut + { + private ILog _logger = LogManager.GetLogger(typeof(SdkRegularExpressionMethodPointcut)); + private Regex[] _compiledPatterns = new Regex[0]; + private RegexOptions _defaultOptions = RegexOptions.None; + + #region Constructors + + /// + /// Creates a new instance of the + /// class. + /// + public SdkRegularExpressionMethodPointcut() + { + } + + /// + /// Creates a new instance of the + /// class, + /// using the supplied pattern or . + /// + /// + /// The intial pattern value(s) to be matched against. + /// + public SdkRegularExpressionMethodPointcut(params string[] patterns) + { + Patterns = patterns; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + /// + /// If an error was encountered during the deserialization process. + /// + protected SdkRegularExpressionMethodPointcut(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets default options that should be used by + /// regular expressions that don't have options explicitly set. + /// + /// + /// Default options that should be used by regular expressions + /// that don't have options explicitly set. + /// + public RegexOptions DefaultOptions + { + get { return _defaultOptions; } + set + { + _defaultOptions = value; + InitPatternRepresentation(Patterns); + } + } + + #endregion + + #region Methods + + /// + /// Initializes the regular expression pointcuts. + /// + /// + ///

+ /// Can be invoked multiple times. + ///

+ ///

+ /// This method will be invoked from the + /// property, + /// and also on deserialization. + ///

+ ///
+ /// + /// The patterns to initialize. + /// + /// + /// In the case of an invalid pattern. + /// + /// + /// If the supplied is . + /// + protected override void InitPatternRepresentation(object[] patterns) + { + AssertUtils.ArgumentNotNull(patterns, "patterns"); + + if (patterns.Length > 0) + { + _compiledPatterns = new Regex[patterns.Length]; + for (int i = 0; i < patterns.Length; i++) + { + if (patterns[i] == null) + { + throw new ArgumentNullException( + "Null is not a valid value for an element of the Patterns property."); + } + else if (patterns[i] is Regex) + { + _compiledPatterns[i] = (Regex)patterns[i]; + } + else if (patterns[i] is string) + { + _compiledPatterns[i] = new Regex((string)patterns[i], DefaultOptions); + } + else + { + throw new ArgumentException( + "You can only specify a string value or an instance of a Regex class " + + "as an element of the 'Patterns' property."); + } + } + } + } + + /// + /// Does the pattern at the supplied + /// match this ? + /// + /// The pattern to match + /// The index of pattern. + /// + /// if there is a match. + /// + protected override bool Matches(string pattern, int patternIndex) + { + Match match = _compiledPatterns[patternIndex].Match(pattern); + bool matched = match.Success; + + #region Instrumentation + + if (_logger.IsDebugEnabled) + { + _logger.Debug("Candidate is: '" + pattern + "'; pattern is '" + + _compiledPatterns[patternIndex].ToString() + "'; matched=" + matched); + } + + #endregion + + return matched; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcher.cs b/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcher.cs index 0f930290..58a16374 100644 --- a/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcher.cs +++ b/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcher.cs @@ -1,103 +1,102 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient abstract superclass for static method matchers that don't care - /// about arguments at runtime. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: StaticMethodMatcher.cs,v 1.6 2006/04/09 07:18:37 markpollack Exp $ - [Serializable] - public abstract class StaticMethodMatcher : IMethodMatcher - { - /// - /// Is this dynamic? - /// - /// - ///

- /// Always returns . - ///

- ///
- /// - /// Always returns . - /// - public bool IsRuntime - { - get { return false; } - } - - /// - /// Is there a runtime (dynamic) match for the supplied - /// ? - /// - /// - ///

- /// Always throws a . This - /// method should never be called on a static matcher. - ///

- ///
- /// The candidate method. - /// - /// The target . - /// - /// The arguments to the method - /// - /// Always throws a . - /// - /// - /// Always. - /// - public bool Matches(MethodInfo method, Type targetType, object[] args) - { - throw new NotSupportedException( - "Illegal IMethodMatcher usage. Cannot call 3-arg Matches method on a static matcher."); - } - - /// - /// Does the supplied satisfy this matcher? - /// - /// - ///

- /// Must be implemented by a derived class in order to specify matching - /// rules. - ///

- ///
- /// The candidate method. - /// - /// The target (may be , - /// in which case the candidate must be taken - /// to be the 's declaring class). - /// - /// - /// if this this method matches statically. - /// - public abstract bool Matches(MethodInfo method, Type targetType); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient abstract superclass for static method matchers that don't care + /// about arguments at runtime. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public abstract class StaticMethodMatcher : IMethodMatcher + { + /// + /// Is this dynamic? + /// + /// + ///

+ /// Always returns . + ///

+ ///
+ /// + /// Always returns . + /// + public bool IsRuntime + { + get { return false; } + } + + /// + /// Is there a runtime (dynamic) match for the supplied + /// ? + /// + /// + ///

+ /// Always throws a . This + /// method should never be called on a static matcher. + ///

+ ///
+ /// The candidate method. + /// + /// The target . + /// + /// The arguments to the method + /// + /// Always throws a . + /// + /// + /// Always. + /// + public bool Matches(MethodInfo method, Type targetType, object[] args) + { + throw new NotSupportedException( + "Illegal IMethodMatcher usage. Cannot call 3-arg Matches method on a static matcher."); + } + + /// + /// Does the supplied satisfy this matcher? + /// + /// + ///

+ /// Must be implemented by a derived class in order to specify matching + /// rules. + ///

+ ///
+ /// The candidate method. + /// + /// The target (may be , + /// in which case the candidate must be taken + /// to be the 's declaring class). + /// + /// + /// if this this method matches statically. + /// + public abstract bool Matches(MethodInfo method, Type targetType); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcut.cs index 89c7c2fa..d1c7ab2e 100644 --- a/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcut.cs @@ -1,85 +1,84 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; - -namespace Spring.Aop.Support -{ - /// - /// Convenient superclass when one wants to force subclasses to - /// implement the interface - /// but subclasses will still want to be pointcuts. - /// - /// - ///

- /// The - /// property can be overriden to customize filter - /// behavior as well. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// Mark Pollack (.NET) - /// $Id: StaticMethodMatcherPointcut.cs,v 1.8 2007/05/30 22:35:43 markpollack Exp $ - [Serializable] - public abstract class StaticMethodMatcherPointcut : StaticMethodMatcher, IPointcut - { - private ITypeFilter typeFilter = TrueTypeFilter.True; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- protected StaticMethodMatcherPointcut() - { - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public virtual ITypeFilter TypeFilter - { - get { return typeFilter; } - set { typeFilter = value;} - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public virtual IMethodMatcher MethodMatcher - { - get { return this; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; + +namespace Spring.Aop.Support +{ + /// + /// Convenient superclass when one wants to force subclasses to + /// implement the interface + /// but subclasses will still want to be pointcuts. + /// + /// + ///

+ /// The + /// property can be overriden to customize filter + /// behavior as well. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + /// Mark Pollack (.NET) + [Serializable] + public abstract class StaticMethodMatcherPointcut : StaticMethodMatcher, IPointcut + { + private ITypeFilter typeFilter = TrueTypeFilter.True; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ protected StaticMethodMatcherPointcut() + { + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public virtual ITypeFilter TypeFilter + { + get { return typeFilter; } + set { typeFilter = value;} + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public virtual IMethodMatcher MethodMatcher + { + get { return this; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcutAdvisor.cs b/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcutAdvisor.cs index e4f6ccdd..407526b2 100644 --- a/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcutAdvisor.cs +++ b/src/Spring/Spring.Aop/Aop/Support/StaticMethodMatcherPointcutAdvisor.cs @@ -1,134 +1,133 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Core; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Convenient superclass for s that - /// are also static pointcuts. - /// - /// Rod Johnson - /// Aleksandar Seovic (.Net) - /// $Id: StaticMethodMatcherPointcutAdvisor.cs,v 1.6 2006/04/09 07:18:37 markpollack Exp $ - [Serializable] - public abstract class StaticMethodMatcherPointcutAdvisor - : StaticMethodMatcherPointcut, IPointcutAdvisor, IOrdered - { - private int _order = Int32.MaxValue; - private IAdvice _advice; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- protected StaticMethodMatcherPointcutAdvisor() - { - } - - /// - /// Creates a new instance of the - /// - /// class for the supplied - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- /// - /// The advice to use. - /// - public StaticMethodMatcherPointcutAdvisor(IAdvice advice) - { - this._advice = advice; - } - - /// - /// Is this advice associated with a particular instance? - /// - /// - /// if this advice is associated with a - /// particular instance. - /// - /// - /// Always; this property is not yet supported. - /// - public virtual bool IsPerInstance - { - get - { - throw new NotSupportedException( - "The 'IsPerInstance' property of the IAdvisor interface is " + - "not yet supported in Spring.NET."); - } - } - - /// - /// Returns this s order in the - /// interception chain. - /// - /// - /// This s order in the - /// interception chain. - /// - public virtual int Order - { - get { return this._order; } - set { this._order = value; } - } - - /// - /// Return the advice part of this advisor. - /// - /// - /// The advice that should apply if the pointcut matches. - /// - /// - public virtual IAdvice Advice - { - get { return this._advice; } - set { this._advice = value; } - } - - /// - /// The that drives this advisor. - /// - public virtual IPointcut Pointcut - { - get { return this; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Core; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Convenient superclass for s that + /// are also static pointcuts. + /// + /// Rod Johnson + /// Aleksandar Seovic (.Net) + [Serializable] + public abstract class StaticMethodMatcherPointcutAdvisor + : StaticMethodMatcherPointcut, IPointcutAdvisor, IOrdered + { + private int _order = Int32.MaxValue; + private IAdvice _advice; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ protected StaticMethodMatcherPointcutAdvisor() + { + } + + /// + /// Creates a new instance of the + /// + /// class for the supplied + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ /// + /// The advice to use. + /// + public StaticMethodMatcherPointcutAdvisor(IAdvice advice) + { + this._advice = advice; + } + + /// + /// Is this advice associated with a particular instance? + /// + /// + /// if this advice is associated with a + /// particular instance. + /// + /// + /// Always; this property is not yet supported. + /// + public virtual bool IsPerInstance + { + get + { + throw new NotSupportedException( + "The 'IsPerInstance' property of the IAdvisor interface is " + + "not yet supported in Spring.NET."); + } + } + + /// + /// Returns this s order in the + /// interception chain. + /// + /// + /// This s order in the + /// interception chain. + /// + public virtual int Order + { + get { return this._order; } + set { this._order = value; } + } + + /// + /// Return the advice part of this advisor. + /// + /// + /// The advice that should apply if the pointcut matches. + /// + /// + public virtual IAdvice Advice + { + get { return this._advice; } + set { this._advice = value; } + } + + /// + /// The that drives this advisor. + /// + public virtual IPointcut Pointcut + { + get { return this; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/TypeFilters.cs b/src/Spring/Spring.Aop/Aop/Support/TypeFilters.cs index 2ad45c5f..f4dad5bb 100644 --- a/src/Spring/Spring.Aop/Aop/Support/TypeFilters.cs +++ b/src/Spring/Spring.Aop/Aop/Support/TypeFilters.cs @@ -1,158 +1,157 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// Defines miscellaneous filter operations. - /// - /// Rod Johnson - /// Aleksandar Seovic (.Net) - /// $Id: TypeFilters.cs,v 1.4 2007/03/16 04:01:25 aseovic Exp $ - public sealed class TypeFilters - { - /// - /// Creates a union of two filters. - /// - /// - ///

- /// The filter arising from the union will match all of the - /// that either of the two supplied filters - /// would match. - ///

- ///
- /// - /// The first filter. - /// - /// - /// The second filter. - /// - /// - /// The union of the supplied filters. - /// - public static ITypeFilter Union(ITypeFilter first, ITypeFilter second) - { - return new UnionTypeFilter(new ITypeFilter[] {first, second}); - } - - /// - /// Creates the intersection of two filters. - /// - /// - ///

- /// The filter arising from the intersection will match all of the - /// that both of the two supplied filters - /// would match. - ///

- ///
- /// - /// The first filter. - /// - /// - /// The second filter. - /// - /// - /// The intersection of the supplied filters. - /// - public static ITypeFilter Intersection(ITypeFilter first, ITypeFilter second) - { - return new IntersectionTypeFilter(new ITypeFilter[] {first, second}); - } - - /// - /// Union class filter implementation. - /// - [Serializable] - private sealed class UnionTypeFilter : ITypeFilter - { - private ITypeFilter[] _filters; - - public UnionTypeFilter(ITypeFilter[] filters) - { - _filters = filters; - } - - public bool Matches(Type type) - { - for (int i = 0; i < _filters.Length; i++) - { - if (_filters[i].Matches(type)) - { - return true; - } - } - return false; - } - } - - /// - /// Intersection implementation. - /// - [Serializable] - private sealed class IntersectionTypeFilter : ITypeFilter - { - private ITypeFilter[] _filters; - - public IntersectionTypeFilter(ITypeFilter[] filters) - { - _filters = filters; - } - - public bool Matches(Type type) - { - for (int i = 0; i < _filters.Length; i++) - { - if (!_filters[i].Matches(type)) - { - return false; - } - } - return true; - } - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible constructors. - ///

- ///
- private TypeFilters() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// Defines miscellaneous filter operations. + /// + /// Rod Johnson + /// Aleksandar Seovic (.Net) + public sealed class TypeFilters + { + /// + /// Creates a union of two filters. + /// + /// + ///

+ /// The filter arising from the union will match all of the + /// that either of the two supplied filters + /// would match. + ///

+ ///
+ /// + /// The first filter. + /// + /// + /// The second filter. + /// + /// + /// The union of the supplied filters. + /// + public static ITypeFilter Union(ITypeFilter first, ITypeFilter second) + { + return new UnionTypeFilter(new ITypeFilter[] {first, second}); + } + + /// + /// Creates the intersection of two filters. + /// + /// + ///

+ /// The filter arising from the intersection will match all of the + /// that both of the two supplied filters + /// would match. + ///

+ ///
+ /// + /// The first filter. + /// + /// + /// The second filter. + /// + /// + /// The intersection of the supplied filters. + /// + public static ITypeFilter Intersection(ITypeFilter first, ITypeFilter second) + { + return new IntersectionTypeFilter(new ITypeFilter[] {first, second}); + } + + /// + /// Union class filter implementation. + /// + [Serializable] + private sealed class UnionTypeFilter : ITypeFilter + { + private ITypeFilter[] _filters; + + public UnionTypeFilter(ITypeFilter[] filters) + { + _filters = filters; + } + + public bool Matches(Type type) + { + for (int i = 0; i < _filters.Length; i++) + { + if (_filters[i].Matches(type)) + { + return true; + } + } + return false; + } + } + + /// + /// Intersection implementation. + /// + [Serializable] + private sealed class IntersectionTypeFilter : ITypeFilter + { + private ITypeFilter[] _filters; + + public IntersectionTypeFilter(ITypeFilter[] filters) + { + _filters = filters; + } + + public bool Matches(Type type) + { + for (int i = 0; i < _filters.Length; i++) + { + if (!_filters[i].Matches(type)) + { + return false; + } + } + return true; + } + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible constructors. + ///

+ ///
+ private TypeFilters() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Support/UnionPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/UnionPointcut.cs index 85956bae..e2e35ee5 100644 --- a/src/Spring/Spring.Aop/Aop/Support/UnionPointcut.cs +++ b/src/Spring/Spring.Aop/Aop/Support/UnionPointcut.cs @@ -1,124 +1,123 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Aop.Support -{ - /// - /// A union. - /// - /// - ///

- /// Such pointcut unions are tricky, because one cannot simply OR - /// the respective s: one has to - /// ascertain that each 's - /// is also satisfied. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: UnionPointcut.cs,v 1.8 2007/03/16 04:01:25 aseovic Exp $ - [Serializable] - internal class UnionPointcut : IPointcut - { - private IPointcut a; - private IPointcut b; - private IMethodMatcher mm; - - /// - /// Creates a new instance of the - /// class. - /// - /// The first pointcut. - /// The second pointcut. - public UnionPointcut(IPointcut firstPointcut, IPointcut secondPointcut) - { - this.a = firstPointcut; - this.b = secondPointcut; - this.mm = new PointcutUnionMethodMatcher(this); - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public ITypeFilter TypeFilter - { - get { return TypeFilters.Union(a.TypeFilter, b.TypeFilter); } - - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public IMethodMatcher MethodMatcher - { - get { return mm; } - } - - /// - /// Internal method matcher class for union pointcut. - /// - private sealed class PointcutUnionMethodMatcher : IMethodMatcher - { - private UnionPointcut _enclosingInstance; - - public PointcutUnionMethodMatcher(UnionPointcut enclosingInstance) - { - this._enclosingInstance = enclosingInstance; - } - - public bool IsRuntime - { - get - { - return _enclosingInstance.a.MethodMatcher.IsRuntime - || _enclosingInstance.b.MethodMatcher.IsRuntime; - } - } - - public bool Matches(MethodInfo method, Type targetType) - { - return (_enclosingInstance.a.TypeFilter.Matches(targetType) - && _enclosingInstance.a.MethodMatcher.Matches(method, targetType)) - || (_enclosingInstance.b.TypeFilter.Matches(targetType) - && _enclosingInstance.b.MethodMatcher.Matches(method, targetType)); - } - - public bool Matches(MethodInfo method, Type targetType, object[] args) - { - // 2-arg matcher will already have run, so we don't need to do type filtering again... - return _enclosingInstance.a.MethodMatcher.Matches(method, targetType, args) - || _enclosingInstance.b.MethodMatcher.Matches(method, targetType, args); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Aop.Support +{ + /// + /// A union. + /// + /// + ///

+ /// Such pointcut unions are tricky, because one cannot simply OR + /// the respective s: one has to + /// ascertain that each 's + /// is also satisfied. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + internal class UnionPointcut : IPointcut + { + private IPointcut a; + private IPointcut b; + private IMethodMatcher mm; + + /// + /// Creates a new instance of the + /// class. + /// + /// The first pointcut. + /// The second pointcut. + public UnionPointcut(IPointcut firstPointcut, IPointcut secondPointcut) + { + this.a = firstPointcut; + this.b = secondPointcut; + this.mm = new PointcutUnionMethodMatcher(this); + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public ITypeFilter TypeFilter + { + get { return TypeFilters.Union(a.TypeFilter, b.TypeFilter); } + + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public IMethodMatcher MethodMatcher + { + get { return mm; } + } + + /// + /// Internal method matcher class for union pointcut. + /// + private sealed class PointcutUnionMethodMatcher : IMethodMatcher + { + private UnionPointcut _enclosingInstance; + + public PointcutUnionMethodMatcher(UnionPointcut enclosingInstance) + { + this._enclosingInstance = enclosingInstance; + } + + public bool IsRuntime + { + get + { + return _enclosingInstance.a.MethodMatcher.IsRuntime + || _enclosingInstance.b.MethodMatcher.IsRuntime; + } + } + + public bool Matches(MethodInfo method, Type targetType) + { + return (_enclosingInstance.a.TypeFilter.Matches(targetType) + && _enclosingInstance.a.MethodMatcher.Matches(method, targetType)) + || (_enclosingInstance.b.TypeFilter.Matches(targetType) + && _enclosingInstance.b.MethodMatcher.Matches(method, targetType)); + } + + public bool Matches(MethodInfo method, Type targetType, object[] args) + { + // 2-arg matcher will already have run, so we don't need to do type filtering again... + return _enclosingInstance.a.MethodMatcher.Matches(method, targetType, args) + || _enclosingInstance.b.MethodMatcher.Matches(method, targetType, args); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/AbstractPoolingTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/AbstractPoolingTargetSource.cs index e6977f7c..0de77005 100644 --- a/src/Spring/Spring.Aop/Aop/Target/AbstractPoolingTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/AbstractPoolingTargetSource.cs @@ -1,204 +1,203 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; -using Spring.Aop.Support; -using Spring.Objects; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// Abstract superclass for pooling s. - /// - /// - ///

- /// Maintains a pool of target instances, acquiring and releasing a target - /// object from the pool for each method invocation. - ///

- ///

- /// This class is independent of pooling technology. - ///

- ///

- /// Subclasses must implement the - /// and - /// - /// methods to work with their chosen pool. The - /// - /// method inherited from the - /// base class - /// can be used to create objects to put in the pool. Subclasses must also - /// implement some of the monitoring methods from the - /// interface. This class - /// provides the - /// - /// method to return an - /// making these statistics available on proxied objects. - ///

- ///

- /// This class implements the interface in - /// order to force subclasses to implement the - /// method to cleanup and close - /// down their pool. - ///

- ///
- /// Rod Johnson - /// Federico Spinazzi (.NET) - /// $Id: AbstractPoolingTargetSource.cs,v 1.7 2007/03/16 04:01:26 aseovic Exp $ - [Serializable] - public abstract class AbstractPoolingTargetSource - : AbstractPrototypeTargetSource, PoolingConfig, IDisposable, IAdvice - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected AbstractPoolingTargetSource() - { - } - - #endregion - - /// - /// Returns the target object (acquired from the pool). - /// - /// The target object (acquired from the pool). - /// - /// If unable to obtain the target object. - /// - public abstract override object GetTarget(); - - /// - /// Gets the mixin. - /// - /// - /// An exposing statistics - /// about the pool maintained by this object. - /// - public DefaultIntroductionAdvisor GetPoolingConfigMixin() - { - return new DefaultIntroductionAdvisor(this, typeof (PoolingConfig)); - } - - /// - /// The maximum number of object instances in this pool. - /// - public int MaxSize - { - get { return _maxSize; } - set { _maxSize = value; } - } - - /// - /// The number of active object instances in this pool. - /// - public abstract int Active { get; } - - /// - /// The number of free object instances in this pool. - /// - public abstract int Free { get; } - - /// - /// The target factory that will be used to perform the lookup - /// of the object referred to by the - /// - /// property. - /// - /// - /// The owning - /// (will never be ). - /// - /// - /// In case of initialization errors. - /// - /// - public override IObjectFactory ObjectFactory - { - set - { - base.ObjectFactory = value; - try - { - CreatePool(value); - } - catch (ObjectsException) - { - throw; - } - catch (Exception ex) - { - throw new ObjectInitializationException("Could not create instance pool.", ex); - } - } - } - - /// - /// Create the pool. - /// - /// - /// The owning , in - /// case one needs collaborators from it (normally one's own properties - /// are sufficient). - /// - /// - /// In the case of errors encountered during the creation of the pool. - /// - protected abstract void CreatePool(IObjectFactory factory); - - /// - /// Releases the target object (returns it to the pool). - /// - /// - /// The target object to release (return to the pool). - /// - /// - /// In the case that the could not be released. - /// - public abstract override void ReleaseTarget(object target); - - /// - /// Performs application-defined tasks associated with freeing, releasing, or - /// resetting unmanaged resources. - /// - /// - ///

- /// Disposes of the pool. - ///

- ///
- public abstract void Dispose(); - - private int _maxSize; - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; +using Spring.Aop.Support; +using Spring.Objects; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// Abstract superclass for pooling s. + /// + /// + ///

+ /// Maintains a pool of target instances, acquiring and releasing a target + /// object from the pool for each method invocation. + ///

+ ///

+ /// This class is independent of pooling technology. + ///

+ ///

+ /// Subclasses must implement the + /// and + /// + /// methods to work with their chosen pool. The + /// + /// method inherited from the + /// base class + /// can be used to create objects to put in the pool. Subclasses must also + /// implement some of the monitoring methods from the + /// interface. This class + /// provides the + /// + /// method to return an + /// making these statistics available on proxied objects. + ///

+ ///

+ /// This class implements the interface in + /// order to force subclasses to implement the + /// method to cleanup and close + /// down their pool. + ///

+ ///
+ /// Rod Johnson + /// Federico Spinazzi (.NET) + [Serializable] + public abstract class AbstractPoolingTargetSource + : AbstractPrototypeTargetSource, PoolingConfig, IDisposable, IAdvice + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected AbstractPoolingTargetSource() + { + } + + #endregion + + /// + /// Returns the target object (acquired from the pool). + /// + /// The target object (acquired from the pool). + /// + /// If unable to obtain the target object. + /// + public abstract override object GetTarget(); + + /// + /// Gets the mixin. + /// + /// + /// An exposing statistics + /// about the pool maintained by this object. + /// + public DefaultIntroductionAdvisor GetPoolingConfigMixin() + { + return new DefaultIntroductionAdvisor(this, typeof (PoolingConfig)); + } + + /// + /// The maximum number of object instances in this pool. + /// + public int MaxSize + { + get { return _maxSize; } + set { _maxSize = value; } + } + + /// + /// The number of active object instances in this pool. + /// + public abstract int Active { get; } + + /// + /// The number of free object instances in this pool. + /// + public abstract int Free { get; } + + /// + /// The target factory that will be used to perform the lookup + /// of the object referred to by the + /// + /// property. + /// + /// + /// The owning + /// (will never be ). + /// + /// + /// In case of initialization errors. + /// + /// + public override IObjectFactory ObjectFactory + { + set + { + base.ObjectFactory = value; + try + { + CreatePool(value); + } + catch (ObjectsException) + { + throw; + } + catch (Exception ex) + { + throw new ObjectInitializationException("Could not create instance pool.", ex); + } + } + } + + /// + /// Create the pool. + /// + /// + /// The owning , in + /// case one needs collaborators from it (normally one's own properties + /// are sufficient). + /// + /// + /// In the case of errors encountered during the creation of the pool. + /// + protected abstract void CreatePool(IObjectFactory factory); + + /// + /// Releases the target object (returns it to the pool). + /// + /// + /// The target object to release (return to the pool). + /// + /// + /// In the case that the could not be released. + /// + public abstract override void ReleaseTarget(object target); + + /// + /// Performs application-defined tasks associated with freeing, releasing, or + /// resetting unmanaged resources. + /// + /// + ///

+ /// Disposes of the pool. + ///

+ ///
+ public abstract void Dispose(); + + private int _maxSize; + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/AbstractPrototypeTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/AbstractPrototypeTargetSource.cs index 902ffd7e..85352fe3 100644 --- a/src/Spring/Spring.Aop/Aop/Target/AbstractPrototypeTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/AbstractPrototypeTargetSource.cs @@ -1,238 +1,237 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Common.Logging; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Support; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// Base class for dynamic - /// implementations that can create new prototype object instances to - /// support a pooling or new-instance-per-invocation strategy. - /// - /// - ///

- /// All such s must run in an - /// , as they need to - /// call the - /// method to create a new prototype instance. - ///

- ///
- /// Rod Johnson - /// Federico Spinazzi (.NET) - /// $Id: AbstractPrototypeTargetSource.cs,v 1.11 2007/07/28 07:32:52 markpollack Exp $ - public abstract class AbstractPrototypeTargetSource - : ITargetSource, IObjectFactoryAware, IInitializingObject - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected AbstractPrototypeTargetSource() - { - } - - #endregion - - #region Properties - - /// - /// The name of the target object to be created on each invocation. - /// - /// - ///

- /// This object should be a prototype, or the same instance will always - /// be obtained from the owning . - ///

- ///
- public virtual string TargetObjectName - { - get { return _targetObjectName; } - set { - _targetObjectName = value; - } - } - - /// - /// The of the target object. - /// - public virtual Type TargetType - { - get { return _targetType; } - } - - /// - /// Is the target source static? - /// - /// - /// if the target source is static. - /// - public virtual bool IsStatic - { - get { return false; } - } - - /// - /// The target factory that will be used to perform the lookup - /// of the object referred to by the - /// property. - /// - /// - ///

- /// Needed so that prototype instances can be created as necessary. - ///

- ///
- /// - /// The owning - /// (will never be ). - /// - /// - /// In case of initialization errors. - /// - /// - public virtual IObjectFactory ObjectFactory - { - get { return _owningObjectFactory; } - set - { - _owningObjectFactory = value; - if (!value.IsPrototype(TargetObjectName)) - { - throw new ObjectDefinitionStoreException( - "Cannot use PrototypeTargetSource against a " + - "Singleton object; instances would not be independent."); - } - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format( - "Getting object with name '{0}' to determine class.", - TargetObjectName)); - } - - #endregion - - _targetType = _owningObjectFactory.GetType(TargetObjectName); - } - } - - #endregion - - #region Methods - - /// - /// Subclasses should use this method to create a new prototype instance. - /// - protected virtual object NewPrototypeInstance() - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format( - "Creating new target from object '{0}'.", - TargetObjectName)); - } - - #endregion - - return ObjectFactory.GetObject(TargetObjectName); - } - - /// - /// Returns the target object. - /// - /// The target object. - /// - /// If unable to obtain the target object. - /// - public abstract object GetTarget(); - - /// - /// Releases the target object. - /// - /// The target object to release. - public virtual void ReleaseTarget(object target) - { - } - - /// - /// Invoked by an - /// after it has set all object properties supplied - /// (and satisfied the - /// - /// and - /// interfaces). - /// - /// - ///

- /// Ensures that the property has been - /// set to a valid value (i.e. is not or a string - /// that consists solely of whitespace). - ///

- ///
- /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - /// - public virtual void AfterPropertiesSet() - { - AssertUtils.ArgumentHasText( - TargetObjectName, "TargetObjectName", - "The 'TargetObjectName' property must have a value."); - } - - #endregion - - #region Fields - - /// - /// The shared instance for this class (and derived classes). - /// - protected readonly ILog logger = LogManager.GetLogger(typeof (AbstractPrototypeTargetSource)); - - private String _targetObjectName; - private IObjectFactory _owningObjectFactory; - private Type _targetType; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Common.Logging; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Support; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// Base class for dynamic + /// implementations that can create new prototype object instances to + /// support a pooling or new-instance-per-invocation strategy. + /// + /// + ///

+ /// All such s must run in an + /// , as they need to + /// call the + /// method to create a new prototype instance. + ///

+ ///
+ /// Rod Johnson + /// Federico Spinazzi (.NET) + public abstract class AbstractPrototypeTargetSource + : ITargetSource, IObjectFactoryAware, IInitializingObject + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected AbstractPrototypeTargetSource() + { + } + + #endregion + + #region Properties + + /// + /// The name of the target object to be created on each invocation. + /// + /// + ///

+ /// This object should be a prototype, or the same instance will always + /// be obtained from the owning . + ///

+ ///
+ public virtual string TargetObjectName + { + get { return _targetObjectName; } + set { + _targetObjectName = value; + } + } + + /// + /// The of the target object. + /// + public virtual Type TargetType + { + get { return _targetType; } + } + + /// + /// Is the target source static? + /// + /// + /// if the target source is static. + /// + public virtual bool IsStatic + { + get { return false; } + } + + /// + /// The target factory that will be used to perform the lookup + /// of the object referred to by the + /// property. + /// + /// + ///

+ /// Needed so that prototype instances can be created as necessary. + ///

+ ///
+ /// + /// The owning + /// (will never be ). + /// + /// + /// In case of initialization errors. + /// + /// + public virtual IObjectFactory ObjectFactory + { + get { return _owningObjectFactory; } + set + { + _owningObjectFactory = value; + if (!value.IsPrototype(TargetObjectName)) + { + throw new ObjectDefinitionStoreException( + "Cannot use PrototypeTargetSource against a " + + "Singleton object; instances would not be independent."); + } + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format( + "Getting object with name '{0}' to determine class.", + TargetObjectName)); + } + + #endregion + + _targetType = _owningObjectFactory.GetType(TargetObjectName); + } + } + + #endregion + + #region Methods + + /// + /// Subclasses should use this method to create a new prototype instance. + /// + protected virtual object NewPrototypeInstance() + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format( + "Creating new target from object '{0}'.", + TargetObjectName)); + } + + #endregion + + return ObjectFactory.GetObject(TargetObjectName); + } + + /// + /// Returns the target object. + /// + /// The target object. + /// + /// If unable to obtain the target object. + /// + public abstract object GetTarget(); + + /// + /// Releases the target object. + /// + /// The target object to release. + public virtual void ReleaseTarget(object target) + { + } + + /// + /// Invoked by an + /// after it has set all object properties supplied + /// (and satisfied the + /// + /// and + /// interfaces). + /// + /// + ///

+ /// Ensures that the property has been + /// set to a valid value (i.e. is not or a string + /// that consists solely of whitespace). + ///

+ ///
+ /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + /// + public virtual void AfterPropertiesSet() + { + AssertUtils.ArgumentHasText( + TargetObjectName, "TargetObjectName", + "The 'TargetObjectName' property must have a value."); + } + + #endregion + + #region Fields + + /// + /// The shared instance for this class (and derived classes). + /// + protected readonly ILog logger = LogManager.GetLogger(typeof (AbstractPrototypeTargetSource)); + + private String _targetObjectName; + private IObjectFactory _owningObjectFactory; + private Type _targetType; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/EmptyTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/EmptyTargetSource.cs index 8ffe6569..a376ac2f 100644 --- a/src/Spring/Spring.Aop/Aop/Target/EmptyTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/EmptyTargetSource.cs @@ -1,161 +1,160 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// The to be used - /// when there is no target object, and behavior is supplied by the - /// advisors. - /// - /// - ///

- /// This class is exposed as a singleton. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: EmptyTargetSource.cs,v 1.4 2007/10/08 22:04:51 markpollack Exp $ - [Serializable] - public sealed class EmptyTargetSource : ITargetSource, ISerializable - { - /// - /// The to be used - /// when there is no target object, and behavior is supplied by the - /// advisors. - /// - public static readonly ITargetSource Empty = new EmptyTargetSource(); - - private object _dummyTarget = new object(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible constructors. - ///

- ///
- private EmptyTargetSource() - { - } - - /// - /// The of the target object. - /// - public Type TargetType - { - get { return typeof(object); } - } - - /// - /// Is the target source static? - /// - /// - ///

- /// The - /// instance is static, and this always returns . - ///

- ///
- /// - /// if the target source is static. - /// - public bool IsStatic - { - get { return true; } - } - - /// - /// Returns the target object. - /// - /// The target object. - /// - /// If unable to obtain the target object. - /// - public object GetTarget() - { - return _dummyTarget; - } - - /// - /// Releases the target object. - /// - /// - /// - /// This is a no-op operation in this implementation. - /// - /// - /// The target object to release. - public void ReleaseTarget(object target) - { - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return "EmptyTargetSource: no target"; - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.SetType(typeof (EmptyTargetSourceObjectReference)); - } - - - - [Serializable] - private sealed class EmptyTargetSourceObjectReference : IObjectReference - { - public object GetRealObject(StreamingContext context) - { - return EmptyTargetSource.Empty; - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// The to be used + /// when there is no target object, and behavior is supplied by the + /// advisors. + /// + /// + ///

+ /// This class is exposed as a singleton. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class EmptyTargetSource : ITargetSource, ISerializable + { + /// + /// The to be used + /// when there is no target object, and behavior is supplied by the + /// advisors. + /// + public static readonly ITargetSource Empty = new EmptyTargetSource(); + + private object _dummyTarget = new object(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible constructors. + ///

+ ///
+ private EmptyTargetSource() + { + } + + /// + /// The of the target object. + /// + public Type TargetType + { + get { return typeof(object); } + } + + /// + /// Is the target source static? + /// + /// + ///

+ /// The + /// instance is static, and this always returns . + ///

+ ///
+ /// + /// if the target source is static. + /// + public bool IsStatic + { + get { return true; } + } + + /// + /// Returns the target object. + /// + /// The target object. + /// + /// If unable to obtain the target object. + /// + public object GetTarget() + { + return _dummyTarget; + } + + /// + /// Releases the target object. + /// + /// + /// + /// This is a no-op operation in this implementation. + /// + /// + /// The target object to release. + public void ReleaseTarget(object target) + { + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return "EmptyTargetSource: no target"; + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof (EmptyTargetSourceObjectReference)); + } + + + + [Serializable] + private sealed class EmptyTargetSourceObjectReference : IObjectReference + { + public object GetRealObject(StreamingContext context) + { + return EmptyTargetSource.Empty; + } + } + } +} diff --git a/src/Spring/Spring.Aop/Aop/Target/HotSwappableTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/HotSwappableTargetSource.cs index fe051edf..721de875 100644 --- a/src/Spring/Spring.Aop/Aop/Target/HotSwappableTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/HotSwappableTargetSource.cs @@ -1,172 +1,171 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// implementation that caches a - /// local target object, but allows the target to be swapped while the - /// application is running - /// - /// - ///

- /// If configuring an object of this class in a Spring IoC container, - /// use constructor injection to supply the intial target. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.Net) - /// $Id: HotSwappableTargetSource.cs,v 1.6 2007/03/16 04:01:26 aseovic Exp $ - [Serializable] - public class HotSwappableTargetSource : ITargetSource - { - private object _target; - - /// - /// Creates a new instance of the - /// with the initial target. - /// - /// - /// The initial target. May be . - /// - public HotSwappableTargetSource(object initialTarget) - { - _target = initialTarget; - } - - /// - /// The of the target object. - /// - /// - ///

- /// Can return . - ///

- ///
- public virtual Type TargetType - { - get { return _target.GetType(); } - } - - /// - /// Is the target source static? - /// - /// - /// if the target source is static. - /// - public virtual bool IsStatic - { - get { return false; } - } - - /// - /// Returns the target object. - /// - /// The target object. - /// - /// If unable to obtain the target object. - /// - public object GetTarget() - { - // synchronization around something that takes so little time is fine... - lock (this) - { - return _target; - } - } - - /// - /// Releases the target object. - /// - /// - ///

- /// No-op implementation. - ///

- ///
- /// The target object to release. - public virtual void ReleaseTarget(Object target) - { - } - - /// - /// Swap the target, returning the old target. - /// - /// The new target. - /// The old target. - /// - /// If the new target is . - /// - public virtual object Swap(object newTarget) - { - AssertUtils.ArgumentNotNull(newTarget, "newTarget", "Cannot swap to null."); - lock (this) - { - // TODO: type checks - object old = _target; - _target = newTarget; - return old; - } - } - - /// - /// Determines whether the specified - /// is equal to the current . - /// - /// - ///

- /// Two invoker interceptors are equal if they have the same target or - /// if the targets are equal. - ///

- ///
- /// The target source to compare with. - /// - /// if this instance is equal to the - /// specified . - /// - public override bool Equals(object other) - { - HotSwappableTargetSource otherTargetSource = other as HotSwappableTargetSource; - if (other == null) - { - return false; - } - return otherTargetSource._target == _target || otherTargetSource._target.Equals(_target); - } - - /// - /// Serves as a hash function for a particular type, suitable for use - /// in hashing algorithms and data structures like a hash table. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return base.GetHashCode() + 13 * - (_target == null ? 0 : _target.GetHashCode()); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// implementation that caches a + /// local target object, but allows the target to be swapped while the + /// application is running + /// + /// + ///

+ /// If configuring an object of this class in a Spring IoC container, + /// use constructor injection to supply the intial target. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.Net) + [Serializable] + public class HotSwappableTargetSource : ITargetSource + { + private object _target; + + /// + /// Creates a new instance of the + /// with the initial target. + /// + /// + /// The initial target. May be . + /// + public HotSwappableTargetSource(object initialTarget) + { + _target = initialTarget; + } + + /// + /// The of the target object. + /// + /// + ///

+ /// Can return . + ///

+ ///
+ public virtual Type TargetType + { + get { return _target.GetType(); } + } + + /// + /// Is the target source static? + /// + /// + /// if the target source is static. + /// + public virtual bool IsStatic + { + get { return false; } + } + + /// + /// Returns the target object. + /// + /// The target object. + /// + /// If unable to obtain the target object. + /// + public object GetTarget() + { + // synchronization around something that takes so little time is fine... + lock (this) + { + return _target; + } + } + + /// + /// Releases the target object. + /// + /// + ///

+ /// No-op implementation. + ///

+ ///
+ /// The target object to release. + public virtual void ReleaseTarget(Object target) + { + } + + /// + /// Swap the target, returning the old target. + /// + /// The new target. + /// The old target. + /// + /// If the new target is . + /// + public virtual object Swap(object newTarget) + { + AssertUtils.ArgumentNotNull(newTarget, "newTarget", "Cannot swap to null."); + lock (this) + { + // TODO: type checks + object old = _target; + _target = newTarget; + return old; + } + } + + /// + /// Determines whether the specified + /// is equal to the current . + /// + /// + ///

+ /// Two invoker interceptors are equal if they have the same target or + /// if the targets are equal. + ///

+ ///
+ /// The target source to compare with. + /// + /// if this instance is equal to the + /// specified . + /// + public override bool Equals(object other) + { + HotSwappableTargetSource otherTargetSource = other as HotSwappableTargetSource; + if (other == null) + { + return false; + } + return otherTargetSource._target == _target || otherTargetSource._target.Equals(_target); + } + + /// + /// Serves as a hash function for a particular type, suitable for use + /// in hashing algorithms and data structures like a hash table. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return base.GetHashCode() + 13 * + (_target == null ? 0 : _target.GetHashCode()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/IThreadLocalTargetSourceStats.cs b/src/Spring/Spring.Aop/Aop/Target/IThreadLocalTargetSourceStats.cs index 16af7515..9ab76f90 100644 --- a/src/Spring/Spring.Aop/Aop/Target/IThreadLocalTargetSourceStats.cs +++ b/src/Spring/Spring.Aop/Aop/Target/IThreadLocalTargetSourceStats.cs @@ -1,64 +1,63 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Intercept; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// Statistics for a thread local . - /// - /// Rod Johnson - /// Federico Spinazzi (.NET) - /// $Id: IThreadLocalTargetSourceStats.cs,v 1.3 2006/04/09 07:18:37 markpollack Exp $ - public interface IThreadLocalTargetSourceStats - { - /// - /// Gets the number of invocations of the - /// and - /// methods. - /// - /// - /// The number of invocations of the - /// and - /// methods. - /// - int Invocations { get; } - - /// - /// Gets the number of hits that were satisfied by a thread bound object. - /// - /// - /// The number of hits that were satisfied by a thread bound object. - /// - int Hits { get; } - - /// - /// Gets the number of thread bound objects created. - /// - /// The number of thread bound objects created. - int Objects { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Intercept; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// Statistics for a thread local . + /// + /// Rod Johnson + /// Federico Spinazzi (.NET) + public interface IThreadLocalTargetSourceStats + { + /// + /// Gets the number of invocations of the + /// and + /// methods. + /// + /// + /// The number of invocations of the + /// and + /// methods. + /// + int Invocations { get; } + + /// + /// Gets the number of hits that were satisfied by a thread bound object. + /// + /// + /// The number of hits that were satisfied by a thread bound object. + /// + int Hits { get; } + + /// + /// Gets the number of thread bound objects created. + /// + /// The number of thread bound objects created. + int Objects { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/PoolingConfig.cs b/src/Spring/Spring.Aop/Aop/Target/PoolingConfig.cs index dabed2e1..e676fdb2 100644 --- a/src/Spring/Spring.Aop/Aop/Target/PoolingConfig.cs +++ b/src/Spring/Spring.Aop/Aop/Target/PoolingConfig.cs @@ -1,52 +1,51 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// Configuration interface for a pooling invoker. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: PoolingConfig.cs,v 1.4 2006/04/09 07:18:37 markpollack Exp $ - public interface PoolingConfig - { - /// - /// The number of active object instances in a pool. - /// - int Active { get; } - - /// - /// The number of free object instances in a pool. - /// - int Free { get; } - - /// - /// The maximum number of object instances in a pool. - /// - int MaxSize { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// Configuration interface for a pooling invoker. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + public interface PoolingConfig + { + /// + /// The number of active object instances in a pool. + /// + int Active { get; } + + /// + /// The number of free object instances in a pool. + /// + int Free { get; } + + /// + /// The maximum number of object instances in a pool. + /// + int MaxSize { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/PrototypeTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/PrototypeTargetSource.cs index 728b5455..5342f61f 100644 --- a/src/Spring/Spring.Aop/Aop/Target/PrototypeTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/PrototypeTargetSource.cs @@ -1,80 +1,78 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// implementation that creates a - /// new instance of the target object for each request. - /// - /// - ///

- /// Can only be used in an object factory. - ///

- ///
- /// Rod Johnson - /// Spinazzi Federico (.NET) - /// $Id: PrototypeTargetSource.cs,v 1.3 2006/04/09 07:18:37 markpollack Exp $ - /// - public sealed class PrototypeTargetSource : AbstractPrototypeTargetSource - { - /// - /// Returns the target object. - /// - /// The target object. - /// - /// If unable to obtain the target object. - /// - public override Object GetTarget() - { - return NewPrototypeInstance(); - } - - /// - /// Releases the target object. - /// - /// - ///

- /// No-op implementation. - ///

- ///
- /// The target object to release. - public override void ReleaseTarget(object target) - { - } - - /// - /// Is the target source static? - /// - /// - /// because this target source is never static. - /// - public override bool IsStatic - { - get { return false; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// implementation that creates a + /// new instance of the target object for each request. + /// + /// + ///

+ /// Can only be used in an object factory. + ///

+ ///
+ /// Rod Johnson + /// Spinazzi Federico (.NET) + public sealed class PrototypeTargetSource : AbstractPrototypeTargetSource + { + /// + /// Returns the target object. + /// + /// The target object. + /// + /// If unable to obtain the target object. + /// + public override Object GetTarget() + { + return NewPrototypeInstance(); + } + + /// + /// Releases the target object. + /// + /// + ///

+ /// No-op implementation. + ///

+ ///
+ /// The target object to release. + public override void ReleaseTarget(object target) + { + } + + /// + /// Is the target source static? + /// + /// + /// because this target source is never static. + /// + public override bool IsStatic + { + get { return false; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/SimplePoolTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/SimplePoolTargetSource.cs index 977167b0..a7357484 100644 --- a/src/Spring/Spring.Aop/Aop/Target/SimplePoolTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/SimplePoolTargetSource.cs @@ -1,209 +1,207 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory; -using Spring.Pool; -using Spring.Pool.Support; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// Pooling target source implementation based on the - /// - /// - /// Rod Johnson - /// Federico Spinazzi - /// $Id: SimplePoolTargetSource.cs,v 1.9 2007/03/16 04:01:26 aseovic Exp $ - /// - [Serializable] - public class SimplePoolTargetSource : AbstractPoolingTargetSource, IPoolableObjectFactory - { - private IObjectPool objectPool; - - /// - /// Returns the target object (acquired from the pool). - /// - /// - /// The target object (acquired from the pool). - /// - /// - /// If unable to obtain the target object. - /// - public override object GetTarget() - { - return this.objectPool.BorrowObject(); - } - - /// - /// Creates the pool. - /// - /// - /// The owning , in - /// case one needs collaborators from it (normally one's own properties - /// are sufficient). - /// - /// - protected override void CreatePool(IObjectFactory factory) - { - #region Instrumentation - - if(logger.IsDebugEnabled) - { - logger.Debug("Creating object pool."); - } - - #endregion - - this.objectPool = CreateObjectPool(); - } - - /// - /// Creates a new instance of an appropriate - /// implementation. - /// - /// - ///

- /// Subclasses can, of course, override this method if they want to - /// return a different implementation. - ///

- ///
- /// - /// An empty . - /// - protected virtual IObjectPool CreateObjectPool() - { - return new SimplePool(this, MaxSize); - } - - /// - /// Releases the target object (returns it to the pool). - /// - /// The target object to release (return to the pool). - /// - /// In the case that the could not be released. - /// - public override void ReleaseTarget(object target) - { - this.objectPool.ReturnObject(target); - } - - /// - /// The number of active object instances in this pool. - /// - public override int Active - { - get { return this.objectPool.NumActive; } - } - - /// - /// The number of free object instances in this pool. - /// - public override int Free - { - get { return this.objectPool.NumIdle; } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or - /// resetting unmanaged resources. - /// - /// - ///

- /// Disposes of the pool. - ///

- ///
- public override void Dispose() - { - #region Instrumentation - - if(logger.IsDebugEnabled) - { - logger.Debug("Closing pool..."); - } - - #endregion - - this.objectPool.Close(); - } - - /// - /// Creates an instance that can be returned by the pool. - /// - /// - /// An instance that can be returned by the pool. - /// - /// - public virtual Object MakeObject() - { - return NewPrototypeInstance(); - } - - /// - /// Destroys an instance no longer needed by the pool. - /// - /// The instance to be destroyed. - /// - public virtual void DestroyObject(object obj) - { - if (obj is IDisposable) - { - ((IDisposable) obj).Dispose(); - } - } - - /// - /// Ensures that the instance is safe to be returned by the pool. - /// Returns false if this object should be destroyed. - /// - /// The instance to validate. - /// - /// if this object is not valid and - /// should be dropped from the pool, otherwise . - /// - /// - public virtual bool ValidateObject(object obj) - { - return true; - } - - /// - /// Reinitialize an instance to be returned by the pool. - /// - /// The instance to be activated. - /// - public virtual void ActivateObject(object obj) - { - } - - /// - /// Passivates the object. - /// - /// The instance returned to the pool. - /// - public virtual void PassivateObject(object obj) - { - } - } +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory; +using Spring.Pool; +using Spring.Pool.Support; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// Pooling target source implementation based on the + /// + /// + /// Rod Johnson + /// Federico Spinazzi + [Serializable] + public class SimplePoolTargetSource : AbstractPoolingTargetSource, IPoolableObjectFactory + { + private IObjectPool objectPool; + + /// + /// Returns the target object (acquired from the pool). + /// + /// + /// The target object (acquired from the pool). + /// + /// + /// If unable to obtain the target object. + /// + public override object GetTarget() + { + return this.objectPool.BorrowObject(); + } + + /// + /// Creates the pool. + /// + /// + /// The owning , in + /// case one needs collaborators from it (normally one's own properties + /// are sufficient). + /// + /// + protected override void CreatePool(IObjectFactory factory) + { + #region Instrumentation + + if(logger.IsDebugEnabled) + { + logger.Debug("Creating object pool."); + } + + #endregion + + this.objectPool = CreateObjectPool(); + } + + /// + /// Creates a new instance of an appropriate + /// implementation. + /// + /// + ///

+ /// Subclasses can, of course, override this method if they want to + /// return a different implementation. + ///

+ ///
+ /// + /// An empty . + /// + protected virtual IObjectPool CreateObjectPool() + { + return new SimplePool(this, MaxSize); + } + + /// + /// Releases the target object (returns it to the pool). + /// + /// The target object to release (return to the pool). + /// + /// In the case that the could not be released. + /// + public override void ReleaseTarget(object target) + { + this.objectPool.ReturnObject(target); + } + + /// + /// The number of active object instances in this pool. + /// + public override int Active + { + get { return this.objectPool.NumActive; } + } + + /// + /// The number of free object instances in this pool. + /// + public override int Free + { + get { return this.objectPool.NumIdle; } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or + /// resetting unmanaged resources. + /// + /// + ///

+ /// Disposes of the pool. + ///

+ ///
+ public override void Dispose() + { + #region Instrumentation + + if(logger.IsDebugEnabled) + { + logger.Debug("Closing pool..."); + } + + #endregion + + this.objectPool.Close(); + } + + /// + /// Creates an instance that can be returned by the pool. + /// + /// + /// An instance that can be returned by the pool. + /// + /// + public virtual Object MakeObject() + { + return NewPrototypeInstance(); + } + + /// + /// Destroys an instance no longer needed by the pool. + /// + /// The instance to be destroyed. + /// + public virtual void DestroyObject(object obj) + { + if (obj is IDisposable) + { + ((IDisposable) obj).Dispose(); + } + } + + /// + /// Ensures that the instance is safe to be returned by the pool. + /// Returns false if this object should be destroyed. + /// + /// The instance to validate. + /// + /// if this object is not valid and + /// should be dropped from the pool, otherwise . + /// + /// + public virtual bool ValidateObject(object obj) + { + return true; + } + + /// + /// Reinitialize an instance to be returned by the pool. + /// + /// The instance to be activated. + /// + public virtual void ActivateObject(object obj) + { + } + + /// + /// Passivates the object. + /// + /// The instance returned to the pool. + /// + public virtual void PassivateObject(object obj) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/SingletonTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/SingletonTargetSource.cs index beb57231..66c58617 100644 --- a/src/Spring/Spring.Aop/Aop/Target/SingletonTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/SingletonTargetSource.cs @@ -1,162 +1,161 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// implementation that holds a local - /// object. - /// - /// - ///

- /// This is the default implementation of the - /// interface used by the AOP - /// framework. There should be no need to create objects of this class in - /// application code. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: SingletonTargetSource.cs,v 1.8 2008/03/21 14:11:57 markpollack Exp $ - [Serializable] - public sealed class SingletonTargetSource : ITargetSource - { - private object target; - - /// - /// Creates a new instance of the - /// - /// for the specified target object. - /// - /// The target object to expose. - /// - /// If the supplied is - /// . - /// - public SingletonTargetSource(object target) - { - AssertUtils.ArgumentNotNull(target, "target"); - this.target = target; - } - - #region ITarget Source impl - - /// - /// The of the target object. - /// - public Type TargetType - { - get { return target.GetType(); } - } - - /// - /// Is the target source static? - /// - /// - /// because this target source is always static. - /// - public bool IsStatic - { - get { return true; } - } - - /// - /// Returns the target object. - /// - /// The target object. - /// - /// If unable to obtain the target object. - /// - public object GetTarget() - { - return target; - } - - /// - /// Releases the target object. - /// - /// - ///

- /// No-op implementation. - ///

- ///
- /// The target object to release. - public void ReleaseTarget(object target) - { - - } - - #endregion - - /// - /// Returns a stringified representation of this target source. - /// - /// - /// A stringified representation of this target source. - /// - public override string ToString() - { - return "Singleton target source (not dynamic): target=[" + target + "]"; - } - - /// - /// Determines whether the specified - /// is equal to the current . - /// - /// The target source to compare with. - /// - /// if this instance is equal to the - /// specified . - /// - public override bool Equals(object other) - { - if (this == other) - { - return true; - } - SingletonTargetSource b = other as SingletonTargetSource; - if (b == null) - { - return false; - } - return target.Equals(b.target); - } - - /// - /// Serves as a hash function for a particular type, suitable for use - /// in hashing algorithms and data structures like a hash table. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return base.GetHashCode() + 13 * - (target == null ? 0 : target.GetHashCode()); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// implementation that holds a local + /// object. + /// + /// + ///

+ /// This is the default implementation of the + /// interface used by the AOP + /// framework. There should be no need to create objects of this class in + /// application code. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class SingletonTargetSource : ITargetSource + { + private object target; + + /// + /// Creates a new instance of the + /// + /// for the specified target object. + /// + /// The target object to expose. + /// + /// If the supplied is + /// . + /// + public SingletonTargetSource(object target) + { + AssertUtils.ArgumentNotNull(target, "target"); + this.target = target; + } + + #region ITarget Source impl + + /// + /// The of the target object. + /// + public Type TargetType + { + get { return target.GetType(); } + } + + /// + /// Is the target source static? + /// + /// + /// because this target source is always static. + /// + public bool IsStatic + { + get { return true; } + } + + /// + /// Returns the target object. + /// + /// The target object. + /// + /// If unable to obtain the target object. + /// + public object GetTarget() + { + return target; + } + + /// + /// Releases the target object. + /// + /// + ///

+ /// No-op implementation. + ///

+ ///
+ /// The target object to release. + public void ReleaseTarget(object target) + { + + } + + #endregion + + /// + /// Returns a stringified representation of this target source. + /// + /// + /// A stringified representation of this target source. + /// + public override string ToString() + { + return "Singleton target source (not dynamic): target=[" + target + "]"; + } + + /// + /// Determines whether the specified + /// is equal to the current . + /// + /// The target source to compare with. + /// + /// if this instance is equal to the + /// specified . + /// + public override bool Equals(object other) + { + if (this == other) + { + return true; + } + SingletonTargetSource b = other as SingletonTargetSource; + if (b == null) + { + return false; + } + return target.Equals(b.target); + } + + /// + /// Serves as a hash function for a particular type, suitable for use + /// in hashing algorithms and data structures like a hash table. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return base.GetHashCode() + 13 * + (target == null ? 0 : target.GetHashCode()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/Target/ThreadLocalTargetSource.cs b/src/Spring/Spring.Aop/Aop/Target/ThreadLocalTargetSource.cs index 91c8a446..90803f46 100644 --- a/src/Spring/Spring.Aop/Aop/Target/ThreadLocalTargetSource.cs +++ b/src/Spring/Spring.Aop/Aop/Target/ThreadLocalTargetSource.cs @@ -1,244 +1,243 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Threading; -using AopAlliance.Intercept; -using Spring.Aop.Support; -using Spring.Collections; -using Spring.Util; - -#endregion - -namespace Spring.Aop.Target -{ - /// - /// implementation that uses a - /// threading model in which every thread has its own copy of the target. - /// - /// - ///

- /// Alternative to an object pool. - ///

- ///

- /// Application code is written as to a normal pool; callers can't assume - /// they will be dealing with the same instance in invocations in different - /// threads. However, state can be relied on during the operations of a - /// single thread: for example, if one caller makes repeated calls on the - /// AOP proxy. - ///

- ///

- /// This class act both as an introduction and as an interceptor, so it - /// should be added twice, once as an introduction and once as an - /// interceptor. - ///

- ///
- /// Rod Johnson - /// Federico Spinazzi (.NET) - /// $Id: ThreadLocalTargetSource.cs,v 1.8 2006/04/09 07:18:37 markpollack Exp $ - public sealed class ThreadLocalTargetSource : AbstractPrototypeTargetSource, - IThreadLocalTargetSourceStats, IDisposable, IMethodInterceptor - { - #region Fields - - /// - /// ThreadLocal holding the target associated with the current thread. - /// - /// - ///

- /// Unlike most thread local storage which is static, this variable is - /// meant to be per thread per instance of this class. - ///

- ///
- private LocalDataStoreSlot _targetInThread = Thread.AllocateDataSlot(); - - /// - /// The set of managed targets, enabling us to keep track of the - /// targets we've created. - /// - private ISet _targetSet = new ListSet(); - - private int _invocations; - private int _hits; - - #endregion - - #region Properties - - /// - /// Gets the number of invocations of the and - /// methods. - /// - /// - /// The number of invocations of the and - /// methods. - /// - public int Invocations - { - get { return _invocations; } - } - - /// - /// Gets the number of hits that were satisfied by a thread bound object. - /// - /// - /// The number of hits that were satisfied by a thread bound object. - /// - public int Hits - { - get { return _hits; } - } - - /// - /// Gets the number of thread bound objects created. - /// - /// The number of thread bound objects created. - public int Objects - { - get { return _targetSet.Count; } - } - - private object ThreadBoundTarget - { - get { return Thread.GetData(_targetInThread); } - } - - #endregion - - #region Methods - - /// - /// Returns the target object. - /// - /// - ///

- /// Tries to locate the target from thread local storage. If no target - /// is found, a target will be obtained and bound to the thread. - ///

- ///
- /// The target object. - /// - /// If unable to obtain the target object. - /// - /// - public override Object GetTarget() - { - ++_invocations; - object target = ThreadBoundTarget; - if (target == null) - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format( - "No target for apartment prototype '{0}' " + - "found in thread: creating one and binding it to thread '#{1}'", - TargetObjectName, Thread.CurrentThread.GetHashCode())); - } - - #endregion - - target = NewPrototypeInstance(); - Thread.SetData(_targetInThread, target); - _targetSet.Add(target); - } - else - { - ++_hits; - } - return ThreadBoundTarget; - } - - /// - /// Return an introduction advisor mixin that allows the AOP proxy to be - /// cast to an reference. - /// - public IIntroductionAdvisor GetStatsMixin() - { - return new DefaultIntroductionAdvisor(this, typeof (IThreadLocalTargetSourceStats)); - } - - /// - /// Cleans up this instance's thread storage, and disposes of any - /// targets as necessary. - /// - /// - public void Dispose() - { - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug("Destroying ThreadLocal bindings"); - } - - #endregion - - foreach (object target in _targetSet) - { - if (target is IDisposable) - { - try - { - ((IDisposable) target).Dispose(); - } - catch (Exception ex) - { - #region Instrumentation - - if (logger.IsWarnEnabled) - { - logger.Warn(string.Format( - "Thread-bound target of class '{0}' " + - "threw exception from it's IDisposable.Dispose() method.", - target.GetType()), ex); - } - - #endregion - } - } - } - _targetSet.Clear(); - _targetInThread = null; - } - - /// - /// Increments Invocations and Hits statistics - /// - /// The method invocation joinpoint - /// The result of the call to IJoinpoint.Proceed(), might be intercepted by the interceptor. - /// if the interceptors or the target-object throws an exception. - public object Invoke(IMethodInvocation invocation) - { - if (ReflectionUtils.MethodIsOnOneOfTheseInterfaces( - invocation.Method, new Type[] {typeof (IThreadLocalTargetSourceStats)})) - { - return invocation.Method.Invoke(this, invocation.Arguments); - } - return invocation.Method.Invoke(GetTarget(), invocation.Arguments); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Threading; +using AopAlliance.Intercept; +using Spring.Aop.Support; +using Spring.Collections; +using Spring.Util; + +#endregion + +namespace Spring.Aop.Target +{ + /// + /// implementation that uses a + /// threading model in which every thread has its own copy of the target. + /// + /// + ///

+ /// Alternative to an object pool. + ///

+ ///

+ /// Application code is written as to a normal pool; callers can't assume + /// they will be dealing with the same instance in invocations in different + /// threads. However, state can be relied on during the operations of a + /// single thread: for example, if one caller makes repeated calls on the + /// AOP proxy. + ///

+ ///

+ /// This class act both as an introduction and as an interceptor, so it + /// should be added twice, once as an introduction and once as an + /// interceptor. + ///

+ ///
+ /// Rod Johnson + /// Federico Spinazzi (.NET) + public sealed class ThreadLocalTargetSource : AbstractPrototypeTargetSource, + IThreadLocalTargetSourceStats, IDisposable, IMethodInterceptor + { + #region Fields + + /// + /// ThreadLocal holding the target associated with the current thread. + /// + /// + ///

+ /// Unlike most thread local storage which is static, this variable is + /// meant to be per thread per instance of this class. + ///

+ ///
+ private LocalDataStoreSlot _targetInThread = Thread.AllocateDataSlot(); + + /// + /// The set of managed targets, enabling us to keep track of the + /// targets we've created. + /// + private ISet _targetSet = new ListSet(); + + private int _invocations; + private int _hits; + + #endregion + + #region Properties + + /// + /// Gets the number of invocations of the and + /// methods. + /// + /// + /// The number of invocations of the and + /// methods. + /// + public int Invocations + { + get { return _invocations; } + } + + /// + /// Gets the number of hits that were satisfied by a thread bound object. + /// + /// + /// The number of hits that were satisfied by a thread bound object. + /// + public int Hits + { + get { return _hits; } + } + + /// + /// Gets the number of thread bound objects created. + /// + /// The number of thread bound objects created. + public int Objects + { + get { return _targetSet.Count; } + } + + private object ThreadBoundTarget + { + get { return Thread.GetData(_targetInThread); } + } + + #endregion + + #region Methods + + /// + /// Returns the target object. + /// + /// + ///

+ /// Tries to locate the target from thread local storage. If no target + /// is found, a target will be obtained and bound to the thread. + ///

+ ///
+ /// The target object. + /// + /// If unable to obtain the target object. + /// + /// + public override Object GetTarget() + { + ++_invocations; + object target = ThreadBoundTarget; + if (target == null) + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format( + "No target for apartment prototype '{0}' " + + "found in thread: creating one and binding it to thread '#{1}'", + TargetObjectName, Thread.CurrentThread.GetHashCode())); + } + + #endregion + + target = NewPrototypeInstance(); + Thread.SetData(_targetInThread, target); + _targetSet.Add(target); + } + else + { + ++_hits; + } + return ThreadBoundTarget; + } + + /// + /// Return an introduction advisor mixin that allows the AOP proxy to be + /// cast to an reference. + /// + public IIntroductionAdvisor GetStatsMixin() + { + return new DefaultIntroductionAdvisor(this, typeof (IThreadLocalTargetSourceStats)); + } + + /// + /// Cleans up this instance's thread storage, and disposes of any + /// targets as necessary. + /// + /// + public void Dispose() + { + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug("Destroying ThreadLocal bindings"); + } + + #endregion + + foreach (object target in _targetSet) + { + if (target is IDisposable) + { + try + { + ((IDisposable) target).Dispose(); + } + catch (Exception ex) + { + #region Instrumentation + + if (logger.IsWarnEnabled) + { + logger.Warn(string.Format( + "Thread-bound target of class '{0}' " + + "threw exception from it's IDisposable.Dispose() method.", + target.GetType()), ex); + } + + #endregion + } + } + } + _targetSet.Clear(); + _targetInThread = null; + } + + /// + /// Increments Invocations and Hits statistics + /// + /// The method invocation joinpoint + /// The result of the call to IJoinpoint.Proceed(), might be intercepted by the interceptor. + /// if the interceptors or the target-object throws an exception. + public object Invoke(IMethodInvocation invocation) + { + if (ReflectionUtils.MethodIsOnOneOfTheseInterfaces( + invocation.Method, new Type[] {typeof (IThreadLocalTargetSourceStats)})) + { + return invocation.Method.Invoke(this, invocation.Arguments); + } + return invocation.Method.Invoke(GetTarget(), invocation.Arguments); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aop/TrueMethodMatcher.cs b/src/Spring/Spring.Aop/Aop/TrueMethodMatcher.cs index 12c43729..3aa5e7ba 100644 --- a/src/Spring/Spring.Aop/Aop/TrueMethodMatcher.cs +++ b/src/Spring/Spring.Aop/Aop/TrueMethodMatcher.cs @@ -1,155 +1,154 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Runtime.Serialization; -using System.Security.Permissions; - -#endregion - -namespace Spring.Aop -{ - /// - /// Canonical that matches - /// all methods. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: TrueMethodMatcher.cs,v 1.5 2006/04/09 07:18:36 markpollack Exp $ - [Serializable] - public sealed class TrueMethodMatcher : IMethodMatcher, ISerializable - { - /// - /// Canonical instance that matches all methods. - /// - /// - ///

- /// It is not dynamic. - ///

- ///
- public static readonly IMethodMatcher True = new TrueMethodMatcher(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible - /// constructors. - ///

- ///
- private TrueMethodMatcher() - { - } - - /// - /// Is this dynamic? - /// - /// - /// if this - /// is dynamic. - /// - /// - public bool IsRuntime - { - get { return false; } - } - - /// - /// Does the supplied satisfy this matcher? - /// Perform static checking. If this returns false, or if the isRuntime() method - /// returns false, no runtime check will be made. - /// - /// The candidate method. - /// - /// The target class (may be , in which case the - /// candidate class must be taken to be the 's - /// declaring class). - /// - /// - /// if this this method matches statically. - /// - /// - public bool Matches(MethodInfo method, Type targetType) - { - return true; - } - - /// - /// Is there a runtime (dynamic) match for the supplied - /// ? - /// - /// The candidate method. - /// The target class. - /// The arguments to the method - /// - /// if there is a runtime match. - /// - public bool Matches(MethodInfo method, Type targetType, object[] args) - { - // should never be invoked if IsRuntime is false - return true; - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return "TrueMethodMatcher.True"; - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.SetType(typeof (TrueMethodMatcherObjectReference)); - } - - [Serializable] - private sealed class TrueMethodMatcherObjectReference : IObjectReference - { - public object GetRealObject(StreamingContext context) - { - return TrueMethodMatcher.True; - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Runtime.Serialization; +using System.Security.Permissions; + +#endregion + +namespace Spring.Aop +{ + /// + /// Canonical that matches + /// all methods. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class TrueMethodMatcher : IMethodMatcher, ISerializable + { + /// + /// Canonical instance that matches all methods. + /// + /// + ///

+ /// It is not dynamic. + ///

+ ///
+ public static readonly IMethodMatcher True = new TrueMethodMatcher(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible + /// constructors. + ///

+ ///
+ private TrueMethodMatcher() + { + } + + /// + /// Is this dynamic? + /// + /// + /// if this + /// is dynamic. + /// + /// + public bool IsRuntime + { + get { return false; } + } + + /// + /// Does the supplied satisfy this matcher? + /// Perform static checking. If this returns false, or if the isRuntime() method + /// returns false, no runtime check will be made. + /// + /// The candidate method. + /// + /// The target class (may be , in which case the + /// candidate class must be taken to be the 's + /// declaring class). + /// + /// + /// if this this method matches statically. + /// + /// + public bool Matches(MethodInfo method, Type targetType) + { + return true; + } + + /// + /// Is there a runtime (dynamic) match for the supplied + /// ? + /// + /// The candidate method. + /// The target class. + /// The arguments to the method + /// + /// if there is a runtime match. + /// + public bool Matches(MethodInfo method, Type targetType, object[] args) + { + // should never be invoked if IsRuntime is false + return true; + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return "TrueMethodMatcher.True"; + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof (TrueMethodMatcherObjectReference)); + } + + [Serializable] + private sealed class TrueMethodMatcherObjectReference : IObjectReference + { + public object GetRealObject(StreamingContext context) + { + return TrueMethodMatcher.True; + } + } + } +} diff --git a/src/Spring/Spring.Aop/Aop/TruePointcut.cs b/src/Spring/Spring.Aop/Aop/TruePointcut.cs index 0b467f3f..a8e50e41 100644 --- a/src/Spring/Spring.Aop/Aop/TruePointcut.cs +++ b/src/Spring/Spring.Aop/Aop/TruePointcut.cs @@ -1,121 +1,121 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; - -#endregion - -namespace Spring.Aop -{ - /// - /// Canonical instance that matches - /// everything. - /// - /// Rod Johnson - /// Aleksandar Seovic (.NET) - [Serializable] - public sealed class TruePointcut : IPointcut, ISerializable - { - /// - /// Canonical instance that matches everything. - /// - public static readonly IPointcut True = new TruePointcut(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly - /// visible constructors. - ///

- ///
- private TruePointcut() - { - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public ITypeFilter TypeFilter - { - get { return Aop.TrueTypeFilter.True; } - } - - /// - /// The for this pointcut. - /// - /// - /// The current . - /// - public IMethodMatcher MethodMatcher - { - get { return TrueMethodMatcher.True; } - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return "TruePointcut.TRUE"; - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.SetType(typeof (TruePointcutObjectReference)); - } - - [Serializable] - private sealed class TruePointcutObjectReference : IObjectReference - { - public object GetRealObject(StreamingContext context) - { - return TruePointcut.True; - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; + +#endregion + +namespace Spring.Aop +{ + /// + /// Canonical instance that matches + /// everything. + /// + /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class TruePointcut : IPointcut, ISerializable + { + /// + /// Canonical instance that matches everything. + /// + public static readonly IPointcut True = new TruePointcut(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ private TruePointcut() + { + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public ITypeFilter TypeFilter + { + get { return Aop.TrueTypeFilter.True; } + } + + /// + /// The for this pointcut. + /// + /// + /// The current . + /// + public IMethodMatcher MethodMatcher + { + get { return TrueMethodMatcher.True; } + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return "TruePointcut.TRUE"; + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof (TruePointcutObjectReference)); + } + + [Serializable] + private sealed class TruePointcutObjectReference : IObjectReference + { + public object GetRealObject(StreamingContext context) + { + return TruePointcut.True; + } + } + } +} diff --git a/src/Spring/Spring.Aop/Aop/TrueTypeFilter.cs b/src/Spring/Spring.Aop/Aop/TrueTypeFilter.cs index f3f78242..7bebcaf2 100644 --- a/src/Spring/Spring.Aop/Aop/TrueTypeFilter.cs +++ b/src/Spring/Spring.Aop/Aop/TrueTypeFilter.cs @@ -1,124 +1,123 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; - -#endregion - -namespace Spring.Aop -{ - /// - /// Canonical instances. - /// - /// - ///

- /// Only one canonical instance is - /// provided out of the box. The - /// matches all classes. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.NET) - /// $Id: TrueTypeFilter.cs,v 1.4 2006/04/09 07:18:36 markpollack Exp $ - [Serializable] - public sealed class TrueTypeFilter : ITypeFilter, ISerializable - { - /// - /// Canonical instance that - /// matches all classes. - /// - public static readonly ITypeFilter True = new TrueTypeFilter(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible - /// constructors. - ///

- ///
- private TrueTypeFilter() - { - } - - /// - /// Should the pointcut apply to the supplied - /// ? - /// - /// - /// The candidate . - /// - /// - /// if the advice should apply to the supplied - /// - /// - /// - public bool Matches(Type type) - { - return true; - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return "TrueTypeFilter.True"; - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.SetType(typeof (TrueTypeFilterObjectReference)); - } - - [Serializable] - private sealed class TrueTypeFilterObjectReference : IObjectReference - { - public object GetRealObject(StreamingContext context) - { - return TrueTypeFilter.True; - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; + +#endregion + +namespace Spring.Aop +{ + /// + /// Canonical instances. + /// + /// + ///

+ /// Only one canonical instance is + /// provided out of the box. The + /// matches all classes. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.NET) + [Serializable] + public sealed class TrueTypeFilter : ITypeFilter, ISerializable + { + /// + /// Canonical instance that + /// matches all classes. + /// + public static readonly ITypeFilter True = new TrueTypeFilter(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible + /// constructors. + ///

+ ///
+ private TrueTypeFilter() + { + } + + /// + /// Should the pointcut apply to the supplied + /// ? + /// + /// + /// The candidate . + /// + /// + /// if the advice should apply to the supplied + /// + /// + /// + public bool Matches(Type type) + { + return true; + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return "TrueTypeFilter.True"; + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.SetType(typeof (TrueTypeFilterObjectReference)); + } + + [Serializable] + private sealed class TrueTypeFilterObjectReference : IObjectReference + { + public object GetRealObject(StreamingContext context) + { + return TrueTypeFilter.True; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/AopAlliance/Aop/AspectException.cs b/src/Spring/Spring.Aop/AopAlliance/Aop/AspectException.cs index 90fa9526..1f15c7d1 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Aop/AspectException.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Aop/AspectException.cs @@ -1,80 +1,79 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace AopAlliance.Aop -{ - /// - /// Superclass for all AOP infrastructure exceptions. - /// - /// Aleksandar Seovic - /// $Id: AspectException.cs,v 1.3 2006/04/09 07:18:33 markpollack Exp $ - [Serializable] - public class AspectException : Exception - { - /// - /// Creates a new instance of the - /// class. - /// - public AspectException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public AspectException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public AspectException(string message, Exception innerException) - : base(message, innerException) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected AspectException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace AopAlliance.Aop +{ + /// + /// Superclass for all AOP infrastructure exceptions. + /// + /// Aleksandar Seovic + [Serializable] + public class AspectException : Exception + { + /// + /// Creates a new instance of the + /// class. + /// + public AspectException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public AspectException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public AspectException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected AspectException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/AopAlliance/Aop/IAdvice.cs b/src/Spring/Spring.Aop/AopAlliance/Aop/IAdvice.cs index 5b4436d4..dd94810d 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Aop/IAdvice.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Aop/IAdvice.cs @@ -1,31 +1,31 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace AopAlliance.Aop -{ - /// - /// Tag interface for advice. - /// - /// - ///

- /// Implementations can be any type of advice, such as interceptors. - ///

- ///
- public interface IAdvice - { - } -} +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace AopAlliance.Aop +{ + /// + /// Tag interface for advice. + /// + /// + ///

+ /// Implementations can be any type of advice, such as interceptors. + ///

+ ///
+ public interface IAdvice + { + } +} diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInterceptor.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInterceptor.cs index 46d2b2df..8f39324e 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInterceptor.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInterceptor.cs @@ -1,54 +1,54 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// Intercepts the construction of a new object. - /// - /// - ///

- /// Such interceptions are nested "on top" of the target. - ///

- ///
- public interface IConstructorInterceptor : IInterceptor - { - /// - /// Implement this method to perform extra treatments before and after - /// the consruction of a new object. - /// - /// - ///

- /// Polite implementations would certainly like to invoke - /// . - ///

- ///
- /// - /// The constructor invocation that is being intercepted. - /// - /// - /// The newly created object, which is also the result of the call to - /// , and might be - /// replaced by the interceptor. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - object Construct(IConstructorInvocation invocation); - } +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// Intercepts the construction of a new object. + /// + /// + ///

+ /// Such interceptions are nested "on top" of the target. + ///

+ ///
+ public interface IConstructorInterceptor : IInterceptor + { + /// + /// Implement this method to perform extra treatments before and after + /// the consruction of a new object. + /// + /// + ///

+ /// Polite implementations would certainly like to invoke + /// . + ///

+ ///
+ /// + /// The constructor invocation that is being intercepted. + /// + /// + /// The newly created object, which is also the result of the call to + /// , and might be + /// replaced by the interceptor. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + object Construct(IConstructorInvocation invocation); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInvocation.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInvocation.cs index 1da95926..ee766145 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInvocation.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IConstructorInvocation.cs @@ -1,51 +1,51 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System.Reflection; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// A description of an invocation to a constuctor, given to an interceptor - /// upon constructor-call. - /// - /// - ///

- /// A constructor invocation is a joinpoint and can be intercepted by a - /// constructor interceptor. - ///

- ///
- /// - public interface IConstructorInvocation : IInvocation - { - /// - /// Gets the constructor invocation that is to be invoked. - /// - /// - ///

- /// This property is a friendly implementation of the - /// property. - /// It should be used in preference to the - /// property - /// because it provides immediate access to the underlying constructor - /// without the need to resort to a cast. - ///

- ///
- /// - /// The constructor invocation that is to be invoked. - /// - ConstructorInfo Constructor { get; } - } +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System.Reflection; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// A description of an invocation to a constuctor, given to an interceptor + /// upon constructor-call. + /// + /// + ///

+ /// A constructor invocation is a joinpoint and can be intercepted by a + /// constructor interceptor. + ///

+ ///
+ /// + public interface IConstructorInvocation : IInvocation + { + /// + /// Gets the constructor invocation that is to be invoked. + /// + /// + ///

+ /// This property is a friendly implementation of the + /// property. + /// It should be used in preference to the + /// property + /// because it provides immediate access to the underlying constructor + /// without the need to resort to a cast. + ///

+ ///
+ /// + /// The constructor invocation that is to be invoked. + /// + ConstructorInfo Constructor { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IInterceptor.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IInterceptor.cs index 121c2ef4..0689389b 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IInterceptor.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IInterceptor.cs @@ -1,39 +1,39 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; -using AopAlliance.Aop; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// Represents a generic interceptor. - /// - /// - ///

- /// A generic interceptor can intercept runtime events that occur within a - /// base program. Those events are materialized by (reified in) joinpoints. - /// Runtime joinpoints can be invocations, field access, exceptions, etc. - ///

- ///

- /// This interface is not used directly. Use the various derived interfaces - /// to intercept specific events. - ///

- ///
- /// - public interface IInterceptor : IAdvice - { - } -} +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; +using AopAlliance.Aop; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// Represents a generic interceptor. + /// + /// + ///

+ /// A generic interceptor can intercept runtime events that occur within a + /// base program. Those events are materialized by (reified in) joinpoints. + /// Runtime joinpoints can be invocations, field access, exceptions, etc. + ///

+ ///

+ /// This interface is not used directly. Use the various derived interfaces + /// to intercept specific events. + ///

+ ///
+ /// + public interface IInterceptor : IAdvice + { + } +} diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IInvocation.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IInvocation.cs index af4d0e8f..8782ae19 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IInvocation.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IInvocation.cs @@ -1,45 +1,45 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// Represents an invocation in the program. - /// - /// - ///

- /// An invocation is a joinpoint and can be intercepted by an interceptor. - /// Typical examples would be a constructor invocation and a method call. - ///

- ///
- public interface IInvocation : IJoinpoint - { - /// - /// Gets the arguments to an invocation. - /// - /// - ///

- /// It is of course possible to change element values within this array - /// to change the arguments to an intercepted invocation. - ///

- ///
- /// - /// The arguments to an invocation. - /// - object[] Arguments { get; } - } -} +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// Represents an invocation in the program. + /// + /// + ///

+ /// An invocation is a joinpoint and can be intercepted by an interceptor. + /// Typical examples would be a constructor invocation and a method call. + ///

+ ///
+ public interface IInvocation : IJoinpoint + { + /// + /// Gets the arguments to an invocation. + /// + /// + ///

+ /// It is of course possible to change element values within this array + /// to change the arguments to an intercepted invocation. + ///

+ ///
+ /// + /// The arguments to an invocation. + /// + object[] Arguments { get; } + } +} diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IJoinpoint.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IJoinpoint.cs index 971fa7e9..98a97f73 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IJoinpoint.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IJoinpoint.cs @@ -1,88 +1,88 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System.Reflection; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// Represents a generic runtime joinpoint (in the AOP terminology). - /// - /// - ///

- /// A runtime joinpoint is an event that occurs on a static - /// joinpoint (i.e. a location in a program). For instance, an - /// invocation is the runtime joinpoint on a method (static joinpoint). - /// The static part of a given joinpoint can be generically retrieved - /// using the - /// property. - ///

- ///

- /// In the context of an interception framework, a runtime joinpoint - /// is then the reification of an access to an accessible object (a - /// method, a constructor, a field), i.e. the static part of the - /// joinpoint. It is passed to the interceptors that are installed on - /// the static joinpoint. - ///

- ///
- /// - public interface IJoinpoint - { - /// - /// Gets the static part of this joinpoint. - /// - /// - ///

- /// The static part is an accessible object on which a chain of - /// interceptors are installed. - ///

- ///
- /// - /// The static part of this joinpoint. - /// - MemberInfo StaticPart { get; } - - /// - /// Gets the object that holds the current joinpoint's static part. - /// - /// - ///

- /// For instance, the target object for a method invocation. - ///

- ///
- /// - /// The object that holds the current joinpoint's static part. - /// - object This { get; } - - /// - /// Proceeds to the next interceptor in the chain. - /// - /// - ///

- /// The implementation and semantics of this method depend on the - /// actual joinpoint type. Consult the derived interfaces of this - /// interface for specifics. - ///

- ///
- /// - /// Consult the derived interfaces of this interface for specifics. - /// - /// - /// If any of the interceptors at the joinpoint throws an exception. - /// - object Proceed(); - } +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System.Reflection; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// Represents a generic runtime joinpoint (in the AOP terminology). + /// + /// + ///

+ /// A runtime joinpoint is an event that occurs on a static + /// joinpoint (i.e. a location in a program). For instance, an + /// invocation is the runtime joinpoint on a method (static joinpoint). + /// The static part of a given joinpoint can be generically retrieved + /// using the + /// property. + ///

+ ///

+ /// In the context of an interception framework, a runtime joinpoint + /// is then the reification of an access to an accessible object (a + /// method, a constructor, a field), i.e. the static part of the + /// joinpoint. It is passed to the interceptors that are installed on + /// the static joinpoint. + ///

+ ///
+ /// + public interface IJoinpoint + { + /// + /// Gets the static part of this joinpoint. + /// + /// + ///

+ /// The static part is an accessible object on which a chain of + /// interceptors are installed. + ///

+ ///
+ /// + /// The static part of this joinpoint. + /// + MemberInfo StaticPart { get; } + + /// + /// Gets the object that holds the current joinpoint's static part. + /// + /// + ///

+ /// For instance, the target object for a method invocation. + ///

+ ///
+ /// + /// The object that holds the current joinpoint's static part. + /// + object This { get; } + + /// + /// Proceeds to the next interceptor in the chain. + /// + /// + ///

+ /// The implementation and semantics of this method depend on the + /// actual joinpoint type. Consult the derived interfaces of this + /// interface for specifics. + ///

+ ///
+ /// + /// Consult the derived interfaces of this interface for specifics. + /// + /// + /// If any of the interceptors at the joinpoint throws an exception. + /// + object Proceed(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInterceptor.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInterceptor.cs index 79bc1c16..0b0355ef 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInterceptor.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInterceptor.cs @@ -1,55 +1,55 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// Intercepts calls on an interface on its way to the target. - /// - /// - ///

- /// Such interceptions are nested "on top" of the target. - ///

- ///
- public interface IMethodInterceptor : IInterceptor - { - /// - /// Implement this method to perform extra treatments before and after - /// the call to the supplied . - /// - /// - ///

- /// Polite implementations would certainly like to invoke - /// . - ///

- ///
- /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied ; this return value may - /// well have been intercepted by the interceptor. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - object Invoke(IMethodInvocation invocation); - } -} +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// Intercepts calls on an interface on its way to the target. + /// + /// + ///

+ /// Such interceptions are nested "on top" of the target. + ///

+ ///
+ public interface IMethodInterceptor : IInterceptor + { + /// + /// Implement this method to perform extra treatments before and after + /// the call to the supplied . + /// + /// + ///

+ /// Polite implementations would certainly like to invoke + /// . + ///

+ ///
+ /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied ; this return value may + /// well have been intercepted by the interceptor. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + object Invoke(IMethodInvocation invocation); + } +} diff --git a/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInvocation.cs b/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInvocation.cs index e4c27839..689ce09e 100644 --- a/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInvocation.cs +++ b/src/Spring/Spring.Aop/AopAlliance/Intercept/IMethodInvocation.cs @@ -1,77 +1,77 @@ -#region License - -/* - * All the source code provided by AOP Alliance is Public Domain. - * - * http://aopalliance.sourceforge.net/ - * - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace AopAlliance.Intercept -{ - /// - /// Description of an invocation to a method, given to an interceptor - /// upon method-call. - /// - /// - ///

- /// A method invocation is a joinpoint and can be intercepted by a method - /// interceptor. - ///

- ///
- /// - public interface IMethodInvocation : IInvocation - { - /// - /// Gets the method invocation that is to be invoked. - /// - /// - ///

- /// This property is a friendly implementation of the - /// property. - /// It should be used in preference to the - /// property - /// because it provides immediate access to the underlying method - /// without the need to resort to a cast. - ///

- ///
- /// - /// The method invocation that is to be invoked. - /// - MethodInfo Method { get; } - - /// - /// Gets the proxy object for the invocation. - /// - /// - /// The proxy object for this method invocation. - /// - object Proxy { get; } - - /// - /// Gets the target object for the invocation. - /// - /// - /// The target object for this method invocation. - /// - object Target { get; } - - /// - /// Gets the type of the target object. - /// - /// - /// The type of the target object. - /// - Type TargetType { get; } - - } +#region License + +/* + * All the source code provided by AOP Alliance is Public Domain. + * + * http://aopalliance.sourceforge.net/ + * + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace AopAlliance.Intercept +{ + /// + /// Description of an invocation to a method, given to an interceptor + /// upon method-call. + /// + /// + ///

+ /// A method invocation is a joinpoint and can be intercepted by a method + /// interceptor. + ///

+ ///
+ /// + public interface IMethodInvocation : IInvocation + { + /// + /// Gets the method invocation that is to be invoked. + /// + /// + ///

+ /// This property is a friendly implementation of the + /// property. + /// It should be used in preference to the + /// property + /// because it provides immediate access to the underlying method + /// without the need to resort to a cast. + ///

+ ///
+ /// + /// The method invocation that is to be invoked. + /// + MethodInfo Method { get; } + + /// + /// Gets the proxy object for the invocation. + /// + /// + /// The proxy object for this method invocation. + /// + object Proxy { get; } + + /// + /// Gets the target object for the invocation. + /// + /// + /// The target object for this method invocation. + /// + object Target { get; } + + /// + /// Gets the type of the target object. + /// + /// + /// The type of the target object. + /// + Type TargetType { get; } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandler.cs index 9304354e..50382bc5 100644 --- a/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandler.cs @@ -1,184 +1,183 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Common.Logging; -using Spring.Expressions; - -namespace Spring.Aspects -{ - /// - /// An abstract base class providing all necessary functionality for typical IExceptionHandler implementations. - /// - /// Mark Pollack - /// $Id: AbstractExceptionHandler.cs,v 1.2 2007/10/10 18:07:46 markpollack Exp $ - public abstract class AbstractExceptionHandler : IExceptionHandler - { - #region Fields - - /// - /// The logging instance - /// - protected readonly ILog log; - - private IList sourceExceptionNames = new ArrayList(); - private IList sourceExceptionTypes = new ArrayList(); - private string actionExpressionText; - private bool continueProcessing = false; - private string constraintExpressionText; - - #endregion - - #region Constructor(s) - - /// - /// Initializes a new instance of the class. - /// - public AbstractExceptionHandler() - { - log = LogManager.GetLogger(GetType()); - } - - /// - /// Initializes a new instance of the class. - /// - /// The exception names. - public AbstractExceptionHandler(string[] exceptionNames) - { - log = LogManager.GetLogger(GetType()); - foreach (string exceptionName in exceptionNames) - { - SourceExceptionNames.Add(exceptionName); - } - } - - #endregion - - #region Implementation of IExceptionHandler - - #region Properties - - /// - /// Gets the source exception names. - /// - /// The source exception names. - public IList SourceExceptionNames - { - get { return sourceExceptionNames; } - set { sourceExceptionNames = value; } - } - - /// - /// Gets the source exception types. - /// - /// The source exception types. - public IList SourceExceptionTypes - { - get { return sourceExceptionTypes; } - set { sourceExceptionTypes = value; } - } - - /// - /// Gets the action translation expression text - /// - /// The action translation expression. - public string ActionExpressionText - { - get { return actionExpressionText; } - set { actionExpressionText = value; } - } - - - /// - /// Gets or sets the constraint expression text. - /// - /// The constraint expression text. - public string ConstraintExpressionText - { - get { return constraintExpressionText; } - set { constraintExpressionText = value; } - } - - /// - /// Gets a value indicating whether to continue processing. - /// - /// true if continue processing; otherwise, false. - public bool ContinueProcessing - { - get { return continueProcessing; } - set { continueProcessing = value; } - } - - #endregion - - - - /// - /// Determines whether this instance can handle the exception the specified exception. - /// - /// The exception. - /// The call context dictionary. - /// - /// true if this instance can handle the specified exception; otherwise, false. - /// - public bool CanHandleException(Exception ex, IDictionary callContextDictionary) - { - if (SourceExceptionNames != null) - { - foreach (string exceptionName in SourceExceptionNames) - { - if (ex.GetType().Name.IndexOf(exceptionName) >= 0) - { - return true; - } - } - } - if (ConstraintExpressionText != null) - { - bool canProcess; - try - { - IExpression expression = Expression.Parse(ConstraintExpressionText); - canProcess = (bool) expression.GetValue(null, callContextDictionary); - } catch (InvalidCastException e) - { - log.Warn("Was not able to unbox constraint expression to boolean [" + ConstraintExpressionText + "]", e); - return false; - } catch (Exception e) - { - log.Warn("Was not able to evaluate constraint expression [" + ConstraintExpressionText + "]",e); - return false; - } - return canProcess; - } - - return false; - } - - /// - /// Handles the exception. - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - public abstract object HandleException(IDictionary callContextDictionary); - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Common.Logging; +using Spring.Expressions; + +namespace Spring.Aspects +{ + /// + /// An abstract base class providing all necessary functionality for typical IExceptionHandler implementations. + /// + /// Mark Pollack + public abstract class AbstractExceptionHandler : IExceptionHandler + { + #region Fields + + /// + /// The logging instance + /// + protected readonly ILog log; + + private IList sourceExceptionNames = new ArrayList(); + private IList sourceExceptionTypes = new ArrayList(); + private string actionExpressionText; + private bool continueProcessing = false; + private string constraintExpressionText; + + #endregion + + #region Constructor(s) + + /// + /// Initializes a new instance of the class. + /// + public AbstractExceptionHandler() + { + log = LogManager.GetLogger(GetType()); + } + + /// + /// Initializes a new instance of the class. + /// + /// The exception names. + public AbstractExceptionHandler(string[] exceptionNames) + { + log = LogManager.GetLogger(GetType()); + foreach (string exceptionName in exceptionNames) + { + SourceExceptionNames.Add(exceptionName); + } + } + + #endregion + + #region Implementation of IExceptionHandler + + #region Properties + + /// + /// Gets the source exception names. + /// + /// The source exception names. + public IList SourceExceptionNames + { + get { return sourceExceptionNames; } + set { sourceExceptionNames = value; } + } + + /// + /// Gets the source exception types. + /// + /// The source exception types. + public IList SourceExceptionTypes + { + get { return sourceExceptionTypes; } + set { sourceExceptionTypes = value; } + } + + /// + /// Gets the action translation expression text + /// + /// The action translation expression. + public string ActionExpressionText + { + get { return actionExpressionText; } + set { actionExpressionText = value; } + } + + + /// + /// Gets or sets the constraint expression text. + /// + /// The constraint expression text. + public string ConstraintExpressionText + { + get { return constraintExpressionText; } + set { constraintExpressionText = value; } + } + + /// + /// Gets a value indicating whether to continue processing. + /// + /// true if continue processing; otherwise, false. + public bool ContinueProcessing + { + get { return continueProcessing; } + set { continueProcessing = value; } + } + + #endregion + + + + /// + /// Determines whether this instance can handle the exception the specified exception. + /// + /// The exception. + /// The call context dictionary. + /// + /// true if this instance can handle the specified exception; otherwise, false. + /// + public bool CanHandleException(Exception ex, IDictionary callContextDictionary) + { + if (SourceExceptionNames != null) + { + foreach (string exceptionName in SourceExceptionNames) + { + if (ex.GetType().Name.IndexOf(exceptionName) >= 0) + { + return true; + } + } + } + if (ConstraintExpressionText != null) + { + bool canProcess; + try + { + IExpression expression = Expression.Parse(ConstraintExpressionText); + canProcess = (bool) expression.GetValue(null, callContextDictionary); + } catch (InvalidCastException e) + { + log.Warn("Was not able to unbox constraint expression to boolean [" + ConstraintExpressionText + "]", e); + return false; + } catch (Exception e) + { + log.Warn("Was not able to evaluate constraint expression [" + ConstraintExpressionText + "]",e); + return false; + } + return canProcess; + } + + return false; + } + + /// + /// Handles the exception. + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + public abstract object HandleException(IDictionary callContextDictionary); + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandlerAdvice.cs b/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandlerAdvice.cs index b84f1962..55f5d21c 100644 --- a/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandlerAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/AbstractExceptionHandlerAdvice.cs @@ -1,157 +1,156 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Text.RegularExpressions; -using AopAlliance.Intercept; -using Spring.Objects.Factory; -using Spring.Util; - -namespace Spring.Aspects -{ - /// - /// This is - /// - /// - /// - /// - /// Mark Pollack - /// $Id: AbstractExceptionHandlerAdvice.cs,v 1.1 2007/10/08 22:05:16 markpollack Exp $ - public abstract class AbstractExceptionHandlerAdvice : IMethodInterceptor, IInitializingObject - { - /// - /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception name' and subclass specific actions. - /// - /// The regex string to parse advice expressions starting with 'on exception name' and subclass specific actions. - public abstract string OnExceptionNameRegex - { - get; set; - } - - /// - /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception (constraint)' and subclass specific actions. - /// - /// The regex string to parse advice expressions starting with 'on exception (constraint)' and subclass specific actions. - public abstract string OnExceptionRegex - { - get; set; - } - - /// - /// Implement this method to perform extra treatments before and after - /// the call to the supplied . - /// - /// - ///

- /// Polite implementations would certainly like to invoke - /// . - ///

- ///
- /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied ; this return value may - /// well have been intercepted by the interceptor. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public abstract object Invoke(IMethodInvocation invocation); - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public abstract void AfterPropertiesSet(); - - /// - /// Parses the advice expression. - /// - /// The advice expression. - /// An instance of ParsedAdviceExpression - protected virtual ParsedAdviceExpression ParseAdviceExpression(string adviceExpression) - { - ParsedAdviceExpression parsedAdviceExpression = new ParsedAdviceExpression(adviceExpression); - - Match match = GetMatch(adviceExpression, OnExceptionNameRegex); - if (match.Success) - { - parsedAdviceExpression.Success = true; - //using exception names for exception filter - parsedAdviceExpression.ExceptionNames = StringUtils.CommaDelimitedListToStringArray(match.Groups[2].Value.Trim()); - parsedAdviceExpression.ActionText = match.Groups[3].Value.Trim(); - parsedAdviceExpression.ActionExpressionText = match.Groups[4].Value.Trim(); - } - else - { - match = GetMatch(adviceExpression, OnExceptionRegex); - if (match.Success) - { - parsedAdviceExpression.Success = true; - //using constratin expression for exception filter - string constraintExpression = match.Groups[2].Value.Trim().Remove(0, 1); - parsedAdviceExpression.ConstraintExpression = constraintExpression.Substring(0, constraintExpression.Length - 1); - parsedAdviceExpression.ActionText = match.Groups[3].Value.Trim(); - parsedAdviceExpression.ActionExpressionText = match.Groups[4].Value.Trim(); - } - } - return parsedAdviceExpression; - } - - - /// - /// Gets the match using exception constraint expression. - /// - /// The advice expression string. - /// The regex string. - /// The Match object resulting from the regular expression match. - protected virtual Match GetMatch(string adviceExpressionString, string regexString) - { - RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase); - Regex reg = new Regex(regexString, options); - return reg.Match(adviceExpressionString); - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Text.RegularExpressions; +using AopAlliance.Intercept; +using Spring.Objects.Factory; +using Spring.Util; + +namespace Spring.Aspects +{ + /// + /// This is + /// + /// + /// + /// + /// Mark Pollack + public abstract class AbstractExceptionHandlerAdvice : IMethodInterceptor, IInitializingObject + { + /// + /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception name' and subclass specific actions. + /// + /// The regex string to parse advice expressions starting with 'on exception name' and subclass specific actions. + public abstract string OnExceptionNameRegex + { + get; set; + } + + /// + /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception (constraint)' and subclass specific actions. + /// + /// The regex string to parse advice expressions starting with 'on exception (constraint)' and subclass specific actions. + public abstract string OnExceptionRegex + { + get; set; + } + + /// + /// Implement this method to perform extra treatments before and after + /// the call to the supplied . + /// + /// + ///

+ /// Polite implementations would certainly like to invoke + /// . + ///

+ ///
+ /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied ; this return value may + /// well have been intercepted by the interceptor. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public abstract object Invoke(IMethodInvocation invocation); + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public abstract void AfterPropertiesSet(); + + /// + /// Parses the advice expression. + /// + /// The advice expression. + /// An instance of ParsedAdviceExpression + protected virtual ParsedAdviceExpression ParseAdviceExpression(string adviceExpression) + { + ParsedAdviceExpression parsedAdviceExpression = new ParsedAdviceExpression(adviceExpression); + + Match match = GetMatch(adviceExpression, OnExceptionNameRegex); + if (match.Success) + { + parsedAdviceExpression.Success = true; + //using exception names for exception filter + parsedAdviceExpression.ExceptionNames = StringUtils.CommaDelimitedListToStringArray(match.Groups[2].Value.Trim()); + parsedAdviceExpression.ActionText = match.Groups[3].Value.Trim(); + parsedAdviceExpression.ActionExpressionText = match.Groups[4].Value.Trim(); + } + else + { + match = GetMatch(adviceExpression, OnExceptionRegex); + if (match.Success) + { + parsedAdviceExpression.Success = true; + //using constratin expression for exception filter + string constraintExpression = match.Groups[2].Value.Trim().Remove(0, 1); + parsedAdviceExpression.ConstraintExpression = constraintExpression.Substring(0, constraintExpression.Length - 1); + parsedAdviceExpression.ActionText = match.Groups[3].Value.Trim(); + parsedAdviceExpression.ActionExpressionText = match.Groups[4].Value.Trim(); + } + } + return parsedAdviceExpression; + } + + + /// + /// Gets the match using exception constraint expression. + /// + /// The advice expression string. + /// The regex string. + /// The Match object resulting from the regular expression match. + protected virtual Match GetMatch(string adviceExpressionString, string regexString) + { + RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase); + Regex reg = new Regex(regexString, options); + return reg.Match(adviceExpressionString); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/BaseCacheAdvice.cs b/src/Spring/Spring.Aop/Aspects/Cache/BaseCacheAdvice.cs index 28359226..0d2c84ce 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/BaseCacheAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/BaseCacheAdvice.cs @@ -1,160 +1,159 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -using Spring.Caching; -using Spring.Context; -using Spring.Expressions; -using System.Collections; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Base class for different cache advice implementations that provide - /// access to common functionality, such as obtaining a cache instance. - /// - /// Aleksandar Seovic - /// $Id: BaseCacheAdvice.cs,v 1.3 2007/04/01 15:04:04 bbaia Exp $ - public class BaseCacheAdvice : IApplicationContextAware - { - private IApplicationContext applicationContext; - - /// - /// Set the that this - /// object runs in. - /// - public IApplicationContext ApplicationContext - { - get { return applicationContext; } - set { applicationContext = value; } - } - - /// - /// Returns an instance based on the cache name. - /// - /// The name of the cache. - /// - /// Cache instance for the specified if one - /// is registered in the application context, or null if it isn't. - /// - public ICache GetCache(string name) - { - return applicationContext.GetObject(name) as ICache; - } - - /// - /// Prepares variables for expression evaluation by packaging all - /// method arguments into a dictionary, keyed by argument name. - /// - /// - /// Method to get parameters info from. - /// - /// - /// Argument values to package. - /// - /// - /// A dictionary containing all method arguments, keyed by method name. - /// - protected static IDictionary PrepareVariables(MethodInfo method, object[] arguments) - { - ParameterInfo[] parameters = method.GetParameters(); - - IDictionary vars = new Hashtable(); - for (int i = 0; i < parameters.Length; i++) - { - ParameterInfo p = parameters[i]; - vars[p.Name] = arguments[i]; - } - return vars; - } - - /// - /// Evaluates a SpEL expression as a boolean value. - /// - /// - /// The expression string that should be evaluated. - /// - /// - /// The SpEL expression instance that should be evaluated. - /// - /// - /// The object to evaluate expression against. - /// - /// - /// The expression variables dictionary. - /// - /// - /// The evaluated boolean. - /// - /// - /// If the SpEL expression could not be successfuly resolved to a boolean. - /// - protected static bool EvalCondition(string condition, - IExpression conditionExpression, object context, IDictionary variables) - { - if (conditionExpression == null) - { - return true; - } - else - { - object value = conditionExpression.GetValue(context, variables); - if (value is bool) - { - return (bool)value; - } - else - { - throw new InvalidOperationException(String.Format( - "The SpEL expression '{0}' could not be successfuly resolved to a boolean.", - condition)); - } - } - } - - /// - /// Retrieves custom attribute for the specified attribute type. - /// - /// - /// Method to get attribute from. - /// - /// - /// Attribute type. - /// - /// - /// Attribute instance if one is found, null otherwise. - /// - protected static object GetCustomAttribute(MethodInfo method, Type attributeType) - { - object[] attributes = method.GetCustomAttributes(attributeType, false); - if (attributes.Length > 0) - { - return attributes[0]; - } - return null; - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +using Spring.Caching; +using Spring.Context; +using Spring.Expressions; +using System.Collections; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Base class for different cache advice implementations that provide + /// access to common functionality, such as obtaining a cache instance. + /// + /// Aleksandar Seovic + public class BaseCacheAdvice : IApplicationContextAware + { + private IApplicationContext applicationContext; + + /// + /// Set the that this + /// object runs in. + /// + public IApplicationContext ApplicationContext + { + get { return applicationContext; } + set { applicationContext = value; } + } + + /// + /// Returns an instance based on the cache name. + /// + /// The name of the cache. + /// + /// Cache instance for the specified if one + /// is registered in the application context, or null if it isn't. + /// + public ICache GetCache(string name) + { + return applicationContext.GetObject(name) as ICache; + } + + /// + /// Prepares variables for expression evaluation by packaging all + /// method arguments into a dictionary, keyed by argument name. + /// + /// + /// Method to get parameters info from. + /// + /// + /// Argument values to package. + /// + /// + /// A dictionary containing all method arguments, keyed by method name. + /// + protected static IDictionary PrepareVariables(MethodInfo method, object[] arguments) + { + ParameterInfo[] parameters = method.GetParameters(); + + IDictionary vars = new Hashtable(); + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo p = parameters[i]; + vars[p.Name] = arguments[i]; + } + return vars; + } + + /// + /// Evaluates a SpEL expression as a boolean value. + /// + /// + /// The expression string that should be evaluated. + /// + /// + /// The SpEL expression instance that should be evaluated. + /// + /// + /// The object to evaluate expression against. + /// + /// + /// The expression variables dictionary. + /// + /// + /// The evaluated boolean. + /// + /// + /// If the SpEL expression could not be successfuly resolved to a boolean. + /// + protected static bool EvalCondition(string condition, + IExpression conditionExpression, object context, IDictionary variables) + { + if (conditionExpression == null) + { + return true; + } + else + { + object value = conditionExpression.GetValue(context, variables); + if (value is bool) + { + return (bool)value; + } + else + { + throw new InvalidOperationException(String.Format( + "The SpEL expression '{0}' could not be successfuly resolved to a boolean.", + condition)); + } + } + } + + /// + /// Retrieves custom attribute for the specified attribute type. + /// + /// + /// Method to get attribute from. + /// + /// + /// Attribute type. + /// + /// + /// Attribute instance if one is found, null otherwise. + /// + protected static object GetCustomAttribute(MethodInfo method, Type attributeType) + { + object[] attributes = method.GetCustomAttributes(attributeType, false); + if (attributes.Length > 0) + { + return attributes[0]; + } + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/CacheAspect.cs b/src/Spring/Spring.Aop/Aspects/Cache/CacheAspect.cs index f574e551..3b98e5c5 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/CacheAspect.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/CacheAspect.cs @@ -1,107 +1,106 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Aop; -using Spring.Context; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Caching aspect implementation. - /// - /// - /// This class encapsulates all the advisors that need to be configured to support - /// Spring's full caching functionality. - /// - /// - /// - /// - /// Aleksandar Seovic - /// $Id: CacheAspect.cs,v 1.2 2007/08/03 14:38:35 markpollack Exp $ - public class CacheAspect : IAdvisors, IApplicationContextAware - { - private IAdvisor[] advisors; - private IApplicationContext applicationContext; - - /// - /// Creates a new instance. - /// - public CacheAspect() - { - advisors = new IAdvisor[] { new CacheResultAdvisor(), new CacheParameterAdvisor(), new InvalidateCacheAdvisor() }; - } - - /// - /// Gets or sets a list of advisors for this aspect. - /// - /// - /// A list of advisors for this aspect. - /// - public IList Advisors - { - get { return advisors; } - set { throw new NotSupportedException("Cache aspect advisors cannot be set externally."); } - } - /// - /// Set the that this - /// object runs in. - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - public IApplicationContext ApplicationContext - { - get { return applicationContext; } - set - { - applicationContext = value; - for (int i = 0; i < advisors.Length; i++) - { - ((IApplicationContextAware) advisors[i]).ApplicationContext = applicationContext; - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Aop; +using Spring.Context; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Caching aspect implementation. + /// + /// + /// This class encapsulates all the advisors that need to be configured to support + /// Spring's full caching functionality. + /// + /// + /// + /// + /// Aleksandar Seovic + public class CacheAspect : IAdvisors, IApplicationContextAware + { + private IAdvisor[] advisors; + private IApplicationContext applicationContext; + + /// + /// Creates a new instance. + /// + public CacheAspect() + { + advisors = new IAdvisor[] { new CacheResultAdvisor(), new CacheParameterAdvisor(), new InvalidateCacheAdvisor() }; + } + + /// + /// Gets or sets a list of advisors for this aspect. + /// + /// + /// A list of advisors for this aspect. + /// + public IList Advisors + { + get { return advisors; } + set { throw new NotSupportedException("Cache aspect advisors cannot be set externally."); } + } + /// + /// Set the that this + /// object runs in. + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + public IApplicationContext ApplicationContext + { + get { return applicationContext; } + set + { + applicationContext = value; + for (int i = 0; i < advisors.Length; i++) + { + ((IApplicationContextAware) advisors[i]).ApplicationContext = applicationContext; + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvice.cs b/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvice.cs index f3b705f6..caa3d5fa 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvice.cs @@ -1,113 +1,112 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Reflection; -using Common.Logging; -using Spring.Aop; -using Spring.Caching; -using Spring.Util; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Implementation of a parameter caching advice. - /// - /// - ///

- /// This advice can be used to cache the parameter of the method. - ///

- ///

- /// Information that determines where, how and for how long the return value - /// will be cached are retrieved from the s - /// that are defined on the pointcut. - ///

- ///

- /// Parameter values are cached *after* the target method is invoked in order to - /// capture any parameter state changes it might make (for example, it is common - /// to set an object identifier within the save method for the persistent entity). - ///

- ///
- /// - /// Aleksandar Seovic - /// $Id: CacheParameterAdvice.cs,v 1.7 2008/05/05 15:00:55 markpollack Exp $ - public class CacheParameterAdvice : BaseCacheAdvice, IAfterReturningAdvice - { - // shared logger instance - private static readonly ILog logger = LogManager.GetLogger(typeof(CacheParameterAdvice)); - - /// - /// Executes after target - /// returns successfully. - /// - /// - ///

- /// Note that the supplied cannot - /// be changed by this type of advice... use the around advice type - /// () if you - /// need to change the return value of an advised method invocation. - /// The data encapsulated by the supplied - /// can of course be modified though. - ///

- ///
- /// - /// The value returned by the . - /// - /// The intecepted method. - /// The intercepted method's arguments. - /// The target object. - /// - public void AfterReturning(object returnValue, MethodInfo method, object[] arguments, object target) - { - ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - ParameterInfo p = parameters[i]; - CacheParameterAttribute[] paramInfoArray = - (CacheParameterAttribute[])p.GetCustomAttributes(typeof(CacheParameterAttribute), false); - - bool isLogDebugEnabled = logger.IsDebugEnabled; - foreach (CacheParameterAttribute paramInfo in paramInfoArray) - { - if (EvalCondition(paramInfo.Condition, paramInfo.ConditionExpression, arguments[i], null)) - { - ICache cache = GetCache(paramInfo.CacheName); - AssertUtils.ArgumentNotNull(cache, "CacheName", - "Parameter cache with the specified name [" + paramInfo.CacheName + - "] does not exist."); - object key = paramInfo.KeyExpression.GetValue(arguments[i]); - #region Instrumentation - - if (isLogDebugEnabled) - { - logger.Debug("Caching parameter for key [" + key + "]."); - } - - #endregion - cache.Insert(key, arguments[i], paramInfo.TimeToLiveTimeSpan); - } - } - } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Reflection; +using Common.Logging; +using Spring.Aop; +using Spring.Caching; +using Spring.Util; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Implementation of a parameter caching advice. + /// + /// + ///

+ /// This advice can be used to cache the parameter of the method. + ///

+ ///

+ /// Information that determines where, how and for how long the return value + /// will be cached are retrieved from the s + /// that are defined on the pointcut. + ///

+ ///

+ /// Parameter values are cached *after* the target method is invoked in order to + /// capture any parameter state changes it might make (for example, it is common + /// to set an object identifier within the save method for the persistent entity). + ///

+ ///
+ /// + /// Aleksandar Seovic + public class CacheParameterAdvice : BaseCacheAdvice, IAfterReturningAdvice + { + // shared logger instance + private static readonly ILog logger = LogManager.GetLogger(typeof(CacheParameterAdvice)); + + /// + /// Executes after target + /// returns successfully. + /// + /// + ///

+ /// Note that the supplied cannot + /// be changed by this type of advice... use the around advice type + /// () if you + /// need to change the return value of an advised method invocation. + /// The data encapsulated by the supplied + /// can of course be modified though. + ///

+ ///
+ /// + /// The value returned by the . + /// + /// The intecepted method. + /// The intercepted method's arguments. + /// The target object. + /// + public void AfterReturning(object returnValue, MethodInfo method, object[] arguments, object target) + { + ParameterInfo[] parameters = method.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo p = parameters[i]; + CacheParameterAttribute[] paramInfoArray = + (CacheParameterAttribute[])p.GetCustomAttributes(typeof(CacheParameterAttribute), false); + + bool isLogDebugEnabled = logger.IsDebugEnabled; + foreach (CacheParameterAttribute paramInfo in paramInfoArray) + { + if (EvalCondition(paramInfo.Condition, paramInfo.ConditionExpression, arguments[i], null)) + { + ICache cache = GetCache(paramInfo.CacheName); + AssertUtils.ArgumentNotNull(cache, "CacheName", + "Parameter cache with the specified name [" + paramInfo.CacheName + + "] does not exist."); + object key = paramInfo.KeyExpression.GetValue(arguments[i]); + #region Instrumentation + + if (isLogDebugEnabled) + { + logger.Debug("Caching parameter for key [" + key + "]."); + } + + #endregion + cache.Insert(key, arguments[i], paramInfo.TimeToLiveTimeSpan); + } + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvisor.cs b/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvisor.cs index 5186f4d6..a8d337b4 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvisor.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/CacheParameterAdvisor.cs @@ -1,113 +1,112 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Aop.Support; -using Spring.Caching; -using Spring.Context; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Convinience advisor implementation that applies - /// to all the methods that have defined on one or - /// more of their parameters. - /// - /// Aleksandar Seovic - /// $Id: CacheParameterAdvisor.cs,v 1.1 2007/02/16 03:12:56 aseovic Exp $ - public class CacheParameterAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware - { - /// - /// Creates new advisor instance. - /// - public CacheParameterAdvisor() - { - Advice = new CacheParameterAdvice(); - Attribute = typeof(CacheParameterAttribute); - Inherit = false; - } - - /// - /// Set the that this - /// object runs in. - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - public IApplicationContext ApplicationContext - { - get { return ((IApplicationContextAware) Advice).ApplicationContext; } - set { ((IApplicationContextAware)Advice).ApplicationContext = value; } - } - - /// - /// Returns true if any of the parameters of the specified - /// has applied. - /// - /// - /// Method to check. - /// - /// - /// Type of target object. - /// - /// - /// true if any of the parameters of the specified - /// has applied; false otherwise. - /// - public override bool Matches(MethodInfo method, Type targetType) - { - ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - ParameterInfo p = parameters[i]; - if (p.IsDefined(Attribute, Inherit)) - { - return true; - } - } - - return false; - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Aop.Support; +using Spring.Caching; +using Spring.Context; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Convinience advisor implementation that applies + /// to all the methods that have defined on one or + /// more of their parameters. + /// + /// Aleksandar Seovic + public class CacheParameterAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware + { + /// + /// Creates new advisor instance. + /// + public CacheParameterAdvisor() + { + Advice = new CacheParameterAdvice(); + Attribute = typeof(CacheParameterAttribute); + Inherit = false; + } + + /// + /// Set the that this + /// object runs in. + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + public IApplicationContext ApplicationContext + { + get { return ((IApplicationContextAware) Advice).ApplicationContext; } + set { ((IApplicationContextAware)Advice).ApplicationContext = value; } + } + + /// + /// Returns true if any of the parameters of the specified + /// has applied. + /// + /// + /// Method to check. + /// + /// + /// Type of target object. + /// + /// + /// true if any of the parameters of the specified + /// has applied; false otherwise. + /// + public override bool Matches(MethodInfo method, Type targetType) + { + ParameterInfo[] parameters = method.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo p = parameters[i]; + if (p.IsDefined(Attribute, Inherit)) + { + return true; + } + } + + return false; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvice.cs b/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvice.cs index 17836b70..1cfce4a8 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvice.cs @@ -1,222 +1,221 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Reflection; -using AopAlliance.Intercept; -using Common.Logging; -using Spring.Caching; -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Implementation of a result caching advice. - /// - /// - ///

- /// This advice can be used to cache the return value of the method. - ///

- ///

- /// Parameters that determine where, how and for how long the return value - /// will be cached are retrieved from the and/or - /// that are defined on the pointcut. - ///

- ///
- /// - /// - /// Aleksandar Seovic - /// $Id: CacheResultAdvice.cs,v 1.6 2008/05/05 15:00:55 markpollack Exp $ - public class CacheResultAdvice : BaseCacheAdvice, IMethodInterceptor - { - // shared logger instance - private static readonly ILog logger = LogManager.GetLogger(typeof (CacheResultAdvice)); - - // NullValue - private static readonly object NullValue = new object(); - - /// - /// Applies caching around a method invocation. - /// - /// - ///

- /// This method tries to retrieve an object from the cache, using the supplied - /// to generate a cache key. If an object is found - /// in the cache, the cached value is returned and the method call does not - /// proceed any further down the invocation chain. - ///

- ///

- /// If object does not exist in the cache, the advised method is called (using - /// ) - /// and any return value is cached for the next method invocation. - ///

- ///
- /// - /// The method invocation that is being intercepted. - /// - /// - /// A cached object or the result of the - /// call. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public object Invoke(IMethodInvocation invocation) - { - CacheResultAttribute resultInfo = - (CacheResultAttribute) GetCustomAttribute(invocation.Method, typeof (CacheResultAttribute)); - CacheResultItemsAttribute[] itemInfoArray = - (CacheResultItemsAttribute[])invocation.Method.GetCustomAttributes(typeof(CacheResultItemsAttribute), false); - - bool cacheHit = false; - object returnValue = GetReturnValue(invocation, resultInfo, out cacheHit); - - if (!cacheHit && itemInfoArray.Length > 0 && returnValue is ICollection) - { - CacheResultItems((ICollection)returnValue, itemInfoArray); - } - - return returnValue; - } - - /// - /// Obtains return value either from cache or by invoking target method - /// and caches it if necessary. - /// - /// - /// The method invocation that is being intercepted. - /// - /// - /// Attribute specifying where and how to cache return value. Can be null, - /// in which case no caching of the result as a whole will be performed - /// (if the result is collection, individual items could still be cached separately). - /// - /// - /// Returns true if the return value was found in cache, false otherwise. - /// - /// - /// Return value for the specified . - /// - private object GetReturnValue(IMethodInvocation invocation, CacheResultAttribute resultInfo, out bool cacheHit) - { - if (resultInfo != null) - { - object returnValue = null; - bool isLogDebugEnabled = logger.IsDebugEnabled; - - IDictionary vars = PrepareVariables(invocation.Method, invocation.Arguments); - - object resultKey = resultInfo.KeyExpression.GetValue(null, vars); - ICache cache = GetCache(resultInfo.CacheName); - AssertUtils.ArgumentNotNull(cache, "CacheName", - "Result cache with the specified name [" + resultInfo.CacheName + - "] does not exist."); - - returnValue = cache.Get(resultKey); - cacheHit = (returnValue != null); - if (!cacheHit) - { - #region Instrumentation - - if (isLogDebugEnabled) - { - logger.Debug("Object for key [" + resultKey + "] was not found in cache. Proceeding..."); - } - - #endregion - - returnValue = invocation.Proceed(); - if (EvalCondition(resultInfo.Condition, resultInfo.ConditionExpression, returnValue, vars)) - { - #region Instrumentation - - if (isLogDebugEnabled) - { - logger.Debug("Caching object for key [" + resultKey + "]."); - } - - #endregion - cache.Insert(resultKey, (returnValue==null)?NullValue:returnValue, resultInfo.TimeToLiveTimeSpan); - } - } - else - { - #region Instrumentation - - if (isLogDebugEnabled) - { - logger.Debug("Cache hit for [" + resultKey + "]. Aborting invocation..."); - } - - #endregion - } - - return (returnValue==NullValue)?null:returnValue; - } - - cacheHit = false; - return invocation.Proceed(); - } - - /// - /// Caches each item from the collection returned by target method. - /// - /// - /// A collection of items to cache. - /// - /// - /// Attributes specifying where and how to cache each item from the collection. - /// - private void CacheResultItems(ICollection items, CacheResultItemsAttribute[] itemInfoArray) - { - foreach (CacheResultItemsAttribute itemInfo in itemInfoArray) - { - ICache cache = GetCache(itemInfo.CacheName); - AssertUtils.ArgumentNotNull(cache, "CacheName", - "Result item cache with the specified name [" + itemInfo.CacheName + - "] does not exist."); - - bool isDebugEnabled = logger.IsDebugEnabled; - foreach (object item in items) - { - if (EvalCondition(itemInfo.Condition, itemInfo.ConditionExpression, item, null)) - { - object itemKey = itemInfo.KeyExpression.GetValue(item); - #region Instrumentation - - if (isDebugEnabled) - { - logger.Debug("Caching collection item for key [" + itemKey + "]."); - } - - #endregion - cache.Insert(itemKey, (item==null?NullValue:item), itemInfo.TimeToLiveTimeSpan); - } - } - } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Reflection; +using AopAlliance.Intercept; +using Common.Logging; +using Spring.Caching; +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Implementation of a result caching advice. + /// + /// + ///

+ /// This advice can be used to cache the return value of the method. + ///

+ ///

+ /// Parameters that determine where, how and for how long the return value + /// will be cached are retrieved from the and/or + /// that are defined on the pointcut. + ///

+ ///
+ /// + /// + /// Aleksandar Seovic + public class CacheResultAdvice : BaseCacheAdvice, IMethodInterceptor + { + // shared logger instance + private static readonly ILog logger = LogManager.GetLogger(typeof (CacheResultAdvice)); + + // NullValue + private static readonly object NullValue = new object(); + + /// + /// Applies caching around a method invocation. + /// + /// + ///

+ /// This method tries to retrieve an object from the cache, using the supplied + /// to generate a cache key. If an object is found + /// in the cache, the cached value is returned and the method call does not + /// proceed any further down the invocation chain. + ///

+ ///

+ /// If object does not exist in the cache, the advised method is called (using + /// ) + /// and any return value is cached for the next method invocation. + ///

+ ///
+ /// + /// The method invocation that is being intercepted. + /// + /// + /// A cached object or the result of the + /// call. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public object Invoke(IMethodInvocation invocation) + { + CacheResultAttribute resultInfo = + (CacheResultAttribute) GetCustomAttribute(invocation.Method, typeof (CacheResultAttribute)); + CacheResultItemsAttribute[] itemInfoArray = + (CacheResultItemsAttribute[])invocation.Method.GetCustomAttributes(typeof(CacheResultItemsAttribute), false); + + bool cacheHit = false; + object returnValue = GetReturnValue(invocation, resultInfo, out cacheHit); + + if (!cacheHit && itemInfoArray.Length > 0 && returnValue is ICollection) + { + CacheResultItems((ICollection)returnValue, itemInfoArray); + } + + return returnValue; + } + + /// + /// Obtains return value either from cache or by invoking target method + /// and caches it if necessary. + /// + /// + /// The method invocation that is being intercepted. + /// + /// + /// Attribute specifying where and how to cache return value. Can be null, + /// in which case no caching of the result as a whole will be performed + /// (if the result is collection, individual items could still be cached separately). + /// + /// + /// Returns true if the return value was found in cache, false otherwise. + /// + /// + /// Return value for the specified . + /// + private object GetReturnValue(IMethodInvocation invocation, CacheResultAttribute resultInfo, out bool cacheHit) + { + if (resultInfo != null) + { + object returnValue = null; + bool isLogDebugEnabled = logger.IsDebugEnabled; + + IDictionary vars = PrepareVariables(invocation.Method, invocation.Arguments); + + object resultKey = resultInfo.KeyExpression.GetValue(null, vars); + ICache cache = GetCache(resultInfo.CacheName); + AssertUtils.ArgumentNotNull(cache, "CacheName", + "Result cache with the specified name [" + resultInfo.CacheName + + "] does not exist."); + + returnValue = cache.Get(resultKey); + cacheHit = (returnValue != null); + if (!cacheHit) + { + #region Instrumentation + + if (isLogDebugEnabled) + { + logger.Debug("Object for key [" + resultKey + "] was not found in cache. Proceeding..."); + } + + #endregion + + returnValue = invocation.Proceed(); + if (EvalCondition(resultInfo.Condition, resultInfo.ConditionExpression, returnValue, vars)) + { + #region Instrumentation + + if (isLogDebugEnabled) + { + logger.Debug("Caching object for key [" + resultKey + "]."); + } + + #endregion + cache.Insert(resultKey, (returnValue==null)?NullValue:returnValue, resultInfo.TimeToLiveTimeSpan); + } + } + else + { + #region Instrumentation + + if (isLogDebugEnabled) + { + logger.Debug("Cache hit for [" + resultKey + "]. Aborting invocation..."); + } + + #endregion + } + + return (returnValue==NullValue)?null:returnValue; + } + + cacheHit = false; + return invocation.Proceed(); + } + + /// + /// Caches each item from the collection returned by target method. + /// + /// + /// A collection of items to cache. + /// + /// + /// Attributes specifying where and how to cache each item from the collection. + /// + private void CacheResultItems(ICollection items, CacheResultItemsAttribute[] itemInfoArray) + { + foreach (CacheResultItemsAttribute itemInfo in itemInfoArray) + { + ICache cache = GetCache(itemInfo.CacheName); + AssertUtils.ArgumentNotNull(cache, "CacheName", + "Result item cache with the specified name [" + itemInfo.CacheName + + "] does not exist."); + + bool isDebugEnabled = logger.IsDebugEnabled; + foreach (object item in items) + { + if (EvalCondition(itemInfo.Condition, itemInfo.ConditionExpression, item, null)) + { + object itemKey = itemInfo.KeyExpression.GetValue(item); + #region Instrumentation + + if (isDebugEnabled) + { + logger.Debug("Caching collection item for key [" + itemKey + "]."); + } + + #endregion + cache.Insert(itemKey, (item==null?NullValue:item), itemInfo.TimeToLiveTimeSpan); + } + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvisor.cs b/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvisor.cs index 160cfd5b..0928b56d 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvisor.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/CacheResultAdvisor.cs @@ -1,103 +1,102 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Aop.Support; -using Spring.Caching; -using Spring.Context; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Convinience advisor implementation that applies - /// to all the methods that have defined. - /// - /// Aleksandar Seovic - /// $Id: CacheResultAdvisor.cs,v 1.1 2007/02/16 03:13:01 aseovic Exp $ - public class CacheResultAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware - { - /// - /// Creates new advisor instance. - /// - public CacheResultAdvisor() - { - Advice = new CacheResultAdvice(); - Inherit = false; - } - - /// - /// Set the that this - /// object runs in. - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - public IApplicationContext ApplicationContext - { - get { return ((IApplicationContextAware) Advice).ApplicationContext; } - set { ((IApplicationContextAware) Advice).ApplicationContext = value; } - } - - /// - /// Returns true if either or - /// is applied to the - /// . - /// - /// - /// Method to check. - /// - /// - /// Type of target object. - /// - /// - /// true if either or - /// is applied to the - /// ; false otherwise. - /// - public override bool Matches(System.Reflection.MethodInfo method, Type targetType) - { - return method.IsDefined(typeof (CacheResultAttribute), Inherit) - || method.IsDefined(typeof (CacheResultItemsAttribute), Inherit); - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Aop.Support; +using Spring.Caching; +using Spring.Context; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Convinience advisor implementation that applies + /// to all the methods that have defined. + /// + /// Aleksandar Seovic + public class CacheResultAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware + { + /// + /// Creates new advisor instance. + /// + public CacheResultAdvisor() + { + Advice = new CacheResultAdvice(); + Inherit = false; + } + + /// + /// Set the that this + /// object runs in. + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + public IApplicationContext ApplicationContext + { + get { return ((IApplicationContextAware) Advice).ApplicationContext; } + set { ((IApplicationContextAware) Advice).ApplicationContext = value; } + } + + /// + /// Returns true if either or + /// is applied to the + /// . + /// + /// + /// Method to check. + /// + /// + /// Type of target object. + /// + /// + /// true if either or + /// is applied to the + /// ; false otherwise. + /// + public override bool Matches(System.Reflection.MethodInfo method, Type targetType) + { + return method.IsDefined(typeof (CacheResultAttribute), Inherit) + || method.IsDefined(typeof (CacheResultItemsAttribute), Inherit); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvice.cs b/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvice.cs index 993f29ad..37be5eda 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvice.cs @@ -1,121 +1,120 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Reflection; - -using Spring.Aop; -using Spring.Caching; -using Spring.Util; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Implementation of a cache invalidation advice. - /// - /// - ///

- /// This advice can be used to evict items from the cache. - ///

- ///

- /// Information that determines which items should be evicted and from which cache - /// are retrieved from the s that are defined - /// on the pointcut. - ///

- ///

- /// Items are evicted *after* target method is invoked. Return value of the method, - /// as well as method arguments, can be used to determine a list of keys for the items - /// that should be evicted (return value will be passed as a context for - /// expression evaluation, and method - /// arguments will be passed as variables, keyed by argument name). - ///

- ///
- /// - /// Aleksandar Seovic - /// $Id: InvalidateCacheAdvice.cs,v 1.4 2007/04/01 15:04:05 bbaia Exp $ - public class InvalidateCacheAdvice : BaseCacheAdvice, IAfterReturningAdvice - { - // shared logger instance - //private static readonly ILog logger = LogManager.GetLogger(typeof(InvalidateCacheAdvice)); - - /// - /// Executes after - /// returns successfully. - /// - /// - ///

- /// Note that the supplied cannot - /// be changed by this type of advice... use the around advice type - /// () if you - /// need to change the return value of an advised method invocation. - /// The data encapsulated by the supplied - /// can of course be modified though. - ///

- ///
- /// - /// The value returned by the . - /// - /// The intecepted method. - /// The intercepted method's arguments. - /// The target object. - /// - public void AfterReturning(object returnValue, MethodInfo method, object[] arguments, object target) - { - InvalidateCacheAttribute[] cacheInfoArray = - (InvalidateCacheAttribute[]) method.GetCustomAttributes(typeof(InvalidateCacheAttribute), false); - - if (cacheInfoArray.Length > 0) - { - IDictionary vars = PrepareVariables(method, arguments); - foreach (InvalidateCacheAttribute cacheInfo in cacheInfoArray) - { - if (EvalCondition(cacheInfo.Condition, cacheInfo.ConditionExpression, returnValue, vars)) - { - ICache cache = GetCache(cacheInfo.CacheName); - AssertUtils.ArgumentNotNull(cache, "CacheName", - "Cache with the specified name [" + cacheInfo.CacheName + - "] does not exist."); - - if (cacheInfo.KeysExpression != null) - { - object keys = cacheInfo.KeysExpression.GetValue(returnValue, vars); - if (keys is ICollection) - { - cache.RemoveAll(keys as ICollection); - } - else - { - cache.Remove(keys); - } - } - else - { - cache.Clear(); - } - } - } - } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Reflection; + +using Spring.Aop; +using Spring.Caching; +using Spring.Util; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Implementation of a cache invalidation advice. + /// + /// + ///

+ /// This advice can be used to evict items from the cache. + ///

+ ///

+ /// Information that determines which items should be evicted and from which cache + /// are retrieved from the s that are defined + /// on the pointcut. + ///

+ ///

+ /// Items are evicted *after* target method is invoked. Return value of the method, + /// as well as method arguments, can be used to determine a list of keys for the items + /// that should be evicted (return value will be passed as a context for + /// expression evaluation, and method + /// arguments will be passed as variables, keyed by argument name). + ///

+ ///
+ /// + /// Aleksandar Seovic + public class InvalidateCacheAdvice : BaseCacheAdvice, IAfterReturningAdvice + { + // shared logger instance + //private static readonly ILog logger = LogManager.GetLogger(typeof(InvalidateCacheAdvice)); + + /// + /// Executes after + /// returns successfully. + /// + /// + ///

+ /// Note that the supplied cannot + /// be changed by this type of advice... use the around advice type + /// () if you + /// need to change the return value of an advised method invocation. + /// The data encapsulated by the supplied + /// can of course be modified though. + ///

+ ///
+ /// + /// The value returned by the . + /// + /// The intecepted method. + /// The intercepted method's arguments. + /// The target object. + /// + public void AfterReturning(object returnValue, MethodInfo method, object[] arguments, object target) + { + InvalidateCacheAttribute[] cacheInfoArray = + (InvalidateCacheAttribute[]) method.GetCustomAttributes(typeof(InvalidateCacheAttribute), false); + + if (cacheInfoArray.Length > 0) + { + IDictionary vars = PrepareVariables(method, arguments); + foreach (InvalidateCacheAttribute cacheInfo in cacheInfoArray) + { + if (EvalCondition(cacheInfo.Condition, cacheInfo.ConditionExpression, returnValue, vars)) + { + ICache cache = GetCache(cacheInfo.CacheName); + AssertUtils.ArgumentNotNull(cache, "CacheName", + "Cache with the specified name [" + cacheInfo.CacheName + + "] does not exist."); + + if (cacheInfo.KeysExpression != null) + { + object keys = cacheInfo.KeysExpression.GetValue(returnValue, vars); + if (keys is ICollection) + { + cache.RemoveAll(keys as ICollection); + } + else + { + cache.Remove(keys); + } + } + else + { + cache.Clear(); + } + } + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvisor.cs b/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvisor.cs index 5eaf46e6..85bd84ec 100644 --- a/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvisor.cs +++ b/src/Spring/Spring.Aop/Aspects/Cache/InvalidateCacheAdvisor.cs @@ -1,82 +1,81 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Aop.Support; -using Spring.Caching; -using Spring.Context; - -#endregion - -namespace Spring.Aspects.Cache -{ - /// - /// Convinience advisor implementation that applies - /// to all the methods that have defined. - /// - /// Aleksandar Seovic - /// $Id: InvalidateCacheAdvisor.cs,v 1.1 2007/02/16 03:13:01 aseovic Exp $ - public class InvalidateCacheAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware - { - /// - /// Creates new advisor instance. - /// - public InvalidateCacheAdvisor() - { - Advice = new InvalidateCacheAdvice(); - Attribute = typeof(InvalidateCacheAttribute); - Inherit = false; - } - - /// - /// Set the that this - /// object runs in. - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - public IApplicationContext ApplicationContext - { - get { return ((IApplicationContextAware) Advice).ApplicationContext; } - set { ((IApplicationContextAware) Advice).ApplicationContext = value; } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Aop.Support; +using Spring.Caching; +using Spring.Context; + +#endregion + +namespace Spring.Aspects.Cache +{ + /// + /// Convinience advisor implementation that applies + /// to all the methods that have defined. + /// + /// Aleksandar Seovic + public class InvalidateCacheAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware + { + /// + /// Creates new advisor instance. + /// + public InvalidateCacheAdvisor() + { + Advice = new InvalidateCacheAdvice(); + Attribute = typeof(InvalidateCacheAttribute); + Inherit = false; + } + + /// + /// Set the that this + /// object runs in. + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + public IApplicationContext ApplicationContext + { + get { return ((IApplicationContextAware) Advice).ApplicationContext; } + set { ((IApplicationContextAware) Advice).ApplicationContext = value; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Exceptions/ExceptionHandlerAdvice.cs b/src/Spring/Spring.Aop/Aspects/Exceptions/ExceptionHandlerAdvice.cs index 17bc8b35..dade0c85 100644 --- a/src/Spring/Spring.Aop/Aspects/Exceptions/ExceptionHandlerAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Exceptions/ExceptionHandlerAdvice.cs @@ -1,391 +1,390 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; -using AopAlliance.Intercept; -using Common.Logging; - -namespace Spring.Aspects.Exceptions -{ - /// - /// Exception advice to perform exception translation, conversion of exceptions to default return values, and - /// exception swallowing. Configuration is via a DSL like string for ease of use in common cases as well as - /// allowing for custom translation logic by leveraging the Spring expression language. - /// - /// - /// - /// The exception handler collection can be filled with either instances of objects that implement the interface - /// or a string that follows a simple syntax for most common exception management - /// needs. The source exceptions to perform processing on are listed immediately after the keyword 'on' and can - /// be comma delmited. Following that is the action to perform, either log, translate, wrap, replace, return, or - /// swallow. Following the action is a Spring expression language (SpEL) fragment that is used to either create the - /// translated/wrapped/replaced exception or specify an alternative return value. The variables available to be - /// used in the expression language fragment are, #method, #args, #target, and #e which are 1) the method that - /// threw the exception, the arguments to the method, the target object itself, and the exception that was thrown. - /// Using SpEL gives you great flexibility in creating a translation of an exception that has access to the calling context. - /// - /// Common translation cases, wrap and rethrow, are supported with a shorter syntax where you can specify only - /// the exception text for the new translated exception. If you ommit the exception text a default value will be - /// used. - /// The exceptionsHandlers are compared to the thrown exception in the order they are listed. logging - /// an exception will continue the evaluation process, in all other cases exceution stops at that point and the - /// appropriate exceptions handler is executed. - /// - /// - /// - /// on FooException1 log 'My Message, Method Name ' + #method.Name - /// on FooException1 translate new BarException('My Message, Method Called = ' + #method.Name", #e) - /// on FooException2,Foo3Exception wrap BarException 'My Bar Message' - /// on FooException4 replace BarException 'My Bar Message' - /// on FooException5 return 32 - /// on FooException6 swallow - /// - /// - /// - /// - /// - /// - /// Mark Pollack - /// $Id: ExceptionHandlerAdvice.cs,v 1.9 2007/10/11 01:29:42 markpollack Exp $ - public class ExceptionHandlerAdvice : AbstractExceptionHandlerAdvice - { - #region Fields - - private static readonly ILog log = LogManager.GetLogger(typeof(ExceptionHandlerAdvice)); - - private IList exceptionHandlers = new ArrayList(); - - private string onExceptionNameRegex = @"^(on\s+exception\s+name)\s+(.*?)\s+(log|translate|wrap|replace|return|swallow)\s*(.*?)$"; - - private string onExceptionRegex = @"^(on\s+exception\s+)(\(.*?\))\s+(log|translate|wrap|replace|return|swallow)\s*(.*?)$"; - - #endregion - - #region Properties - - /// - /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception name' and exception handling actions. - /// - /// The regex string to parse advice expressions starting with 'on exception name' and exception handling actions. - public override string OnExceptionNameRegex - { - get { return onExceptionNameRegex; } - set { onExceptionNameRegex = value; } - } - - /// - /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. - /// - /// The regex string to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. - public override string OnExceptionRegex - { - get { return onExceptionRegex; } - set { onExceptionRegex = value; } - } - - /// - /// Gets or sets the exception handler. - /// - /// The exception handler. - public IList ExceptionHandlers - { - get { return exceptionHandlers; } - set { exceptionHandlers = value; } - } - - #endregion - - #region IMethodInterceptor implementation - - /// - /// Implement this method to perform extra treatments before and after - /// the call to the supplied . - /// - /// - ///

- /// Polite implementations would certainly like to invoke - /// . - ///

- ///
- /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied ; this return value may - /// well have been intercepted by the interceptor. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public override object Invoke(IMethodInvocation invocation) - { - try - { - return invocation.Proceed(); - } - catch (TargetInvocationException ex) - { - Exception realException = ex.InnerException; - InvokeHandlers(realException, invocation); - throw realException; - } - catch (Exception ex) - { - object returnVal = InvokeHandlers(ex, invocation); - - if (returnVal == null) - { - return null; - } - - // if only logged - if (returnVal.Equals("logged")) - { - throw; - } - - //only here if we only are swallowing, returning alternative value, no matching handler was found. - - // no matching handler. - if (returnVal.Equals("nomatch")) - { - throw; - } - else - { - //TODO make spring specific value. - if (!returnVal.Equals("swallow")) - { - return returnVal; - } - else - { - return null; - } - } - } - } - - #endregion - - #region IInitializingObject implementation - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public override void AfterPropertiesSet() - { - if (exceptionHandlers.Count == 0) - { - throw new ArgumentException("At least one handler is required"); - } - IList newExceptionHandlers = new ArrayList(); - foreach (object o in exceptionHandlers) - { - string handlerString = o as string; - if (handlerString != null) - { - IExceptionHandler handler = Parse(handlerString); - if (handler == null) - { - throw new ArgumentException("Was not able to parse exception handler string [" + handlerString + - "]"); - } - newExceptionHandlers.Add(handler); - } - - } - //TODO sync. - exceptionHandlers = newExceptionHandlers; - } - - #endregion - - #region Methods - - /// - /// Invokes handlers registered for the passed exception and - /// - /// The exception to be handled - /// The that raised this exception. - /// The output of - protected virtual object InvokeHandlers(Exception ex, IMethodInvocation invocation) - { - IDictionary callContextDictionary = new Hashtable(); - callContextDictionary.Add("method", invocation.Method); - callContextDictionary.Add("args", invocation.Arguments); - callContextDictionary.Add("target", invocation.Target); - callContextDictionary.Add("e", ex); - object retValue = "nomatch"; - foreach (IExceptionHandler handler in exceptionHandlers) - { - if (handler != null) - { - if (handler.CanHandleException(ex, callContextDictionary)) - { - retValue = handler.HandleException(callContextDictionary); - if (!handler.ContinueProcessing) - { - return retValue; - } - } - } - } - return retValue; - } - - /// - /// Parses the specified handler string, creating an instance of IExceptionHander. - /// - /// The handler string. - /// an instance of an exception handler or null if was not able to correctly parse - /// handler string. - protected virtual IExceptionHandler Parse(string handlerString) - { - ParsedAdviceExpression parsedAdviceExpression = ParseAdviceExpression(handlerString); - - if (!parsedAdviceExpression.Success) - { - log.Warn("Could not parse exception hander statement " + handlerString); - return null; - } - - return CreateExceptionHandler(parsedAdviceExpression); - } - - private static IExceptionHandler CreateExceptionHandler(ParsedAdviceExpression parsedAdviceExpression) - { - if (parsedAdviceExpression.ActionText.IndexOf("log") >= 0) - { - //TODO support user selection of level, log.Debug , log.Info etc. - LogExceptionHandler handler = new LogExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - handler.ActionExpressionText = "#log.Trace(" + parsedAdviceExpression.ActionExpressionText + ")"; - return handler; - } - else if (parsedAdviceExpression.ActionText.IndexOf("translate") >= 0) - { - TranslationExceptionHandler handler = new TranslationExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - handler.ActionExpressionText = parsedAdviceExpression.ActionExpressionText; - return handler; - } - else if (parsedAdviceExpression.ActionText.IndexOf("wrap") >= 0) - { - TranslationExceptionHandler handler = new TranslationExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - handler.ActionExpressionText = ParseWrappedExceptionExpression("wrap", parsedAdviceExpression.AdviceExpression); - return handler; - } - else if (parsedAdviceExpression.ActionText.IndexOf("replace") >= 0) - { - TranslationExceptionHandler handler = new TranslationExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - handler.ActionExpressionText = ParseWrappedExceptionExpression("replace", parsedAdviceExpression.AdviceExpression); - return handler; - } - else if (parsedAdviceExpression.ActionText.IndexOf("swallow") >= 0) - { - SwallowExceptionHandler handler = new SwallowExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - return handler; - } - else if (parsedAdviceExpression.ActionText.IndexOf("return") >= 0) - { - ReturnValueExceptionHandler handler = new ReturnValueExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - handler.ActionExpressionText = parsedAdviceExpression.ActionExpressionText; - return handler; - } - else - { - log.Warn("Could not parse exception hander statement " + parsedAdviceExpression.AdviceExpression); - } - return null; - } - - private static string ParseWrappedExceptionExpression(string action, string handlerString) - { - int endOfActionIndex = handlerString.IndexOf(action) + action.Length; - string exceptionAndMessage = handlerString.Substring(endOfActionIndex).Trim(); - int endOfExceptionTypeIndex = exceptionAndMessage.IndexOf(" "); - - string rawExpressionTextPart; - string exception; - //Has two pieces. - if (endOfExceptionTypeIndex > 0) - { - exception = exceptionAndMessage.Substring(0, endOfExceptionTypeIndex).Trim(); - rawExpressionTextPart = exceptionAndMessage.Substring(endOfExceptionTypeIndex).Trim(); - } - else - { - exception = exceptionAndMessage; - if (action.Equals("wrap")) - { - rawExpressionTextPart = "'Wrapped ' + #e.GetType().Name"; - } else - { - rawExpressionTextPart = "'Replaced ' + #e.GetType().Name"; - } - } - - if (action.Equals("wrap")) - { - return string.Format("new {0}({1}, #e)", exception, rawExpressionTextPart); - } else - { - return string.Format("new {0}({1})", exception, rawExpressionTextPart); - } - } - - - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; +using AopAlliance.Intercept; +using Common.Logging; + +namespace Spring.Aspects.Exceptions +{ + /// + /// Exception advice to perform exception translation, conversion of exceptions to default return values, and + /// exception swallowing. Configuration is via a DSL like string for ease of use in common cases as well as + /// allowing for custom translation logic by leveraging the Spring expression language. + /// + /// + /// + /// The exception handler collection can be filled with either instances of objects that implement the interface + /// or a string that follows a simple syntax for most common exception management + /// needs. The source exceptions to perform processing on are listed immediately after the keyword 'on' and can + /// be comma delmited. Following that is the action to perform, either log, translate, wrap, replace, return, or + /// swallow. Following the action is a Spring expression language (SpEL) fragment that is used to either create the + /// translated/wrapped/replaced exception or specify an alternative return value. The variables available to be + /// used in the expression language fragment are, #method, #args, #target, and #e which are 1) the method that + /// threw the exception, the arguments to the method, the target object itself, and the exception that was thrown. + /// Using SpEL gives you great flexibility in creating a translation of an exception that has access to the calling context. + /// + /// Common translation cases, wrap and rethrow, are supported with a shorter syntax where you can specify only + /// the exception text for the new translated exception. If you ommit the exception text a default value will be + /// used. + /// The exceptionsHandlers are compared to the thrown exception in the order they are listed. logging + /// an exception will continue the evaluation process, in all other cases exceution stops at that point and the + /// appropriate exceptions handler is executed. + /// + /// + /// + /// on FooException1 log 'My Message, Method Name ' + #method.Name + /// on FooException1 translate new BarException('My Message, Method Called = ' + #method.Name", #e) + /// on FooException2,Foo3Exception wrap BarException 'My Bar Message' + /// on FooException4 replace BarException 'My Bar Message' + /// on FooException5 return 32 + /// on FooException6 swallow + /// + /// + /// + /// + /// + /// + /// Mark Pollack + public class ExceptionHandlerAdvice : AbstractExceptionHandlerAdvice + { + #region Fields + + private static readonly ILog log = LogManager.GetLogger(typeof(ExceptionHandlerAdvice)); + + private IList exceptionHandlers = new ArrayList(); + + private string onExceptionNameRegex = @"^(on\s+exception\s+name)\s+(.*?)\s+(log|translate|wrap|replace|return|swallow)\s*(.*?)$"; + + private string onExceptionRegex = @"^(on\s+exception\s+)(\(.*?\))\s+(log|translate|wrap|replace|return|swallow)\s*(.*?)$"; + + #endregion + + #region Properties + + /// + /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception name' and exception handling actions. + /// + /// The regex string to parse advice expressions starting with 'on exception name' and exception handling actions. + public override string OnExceptionNameRegex + { + get { return onExceptionNameRegex; } + set { onExceptionNameRegex = value; } + } + + /// + /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. + /// + /// The regex string to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. + public override string OnExceptionRegex + { + get { return onExceptionRegex; } + set { onExceptionRegex = value; } + } + + /// + /// Gets or sets the exception handler. + /// + /// The exception handler. + public IList ExceptionHandlers + { + get { return exceptionHandlers; } + set { exceptionHandlers = value; } + } + + #endregion + + #region IMethodInterceptor implementation + + /// + /// Implement this method to perform extra treatments before and after + /// the call to the supplied . + /// + /// + ///

+ /// Polite implementations would certainly like to invoke + /// . + ///

+ ///
+ /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied ; this return value may + /// well have been intercepted by the interceptor. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public override object Invoke(IMethodInvocation invocation) + { + try + { + return invocation.Proceed(); + } + catch (TargetInvocationException ex) + { + Exception realException = ex.InnerException; + InvokeHandlers(realException, invocation); + throw realException; + } + catch (Exception ex) + { + object returnVal = InvokeHandlers(ex, invocation); + + if (returnVal == null) + { + return null; + } + + // if only logged + if (returnVal.Equals("logged")) + { + throw; + } + + //only here if we only are swallowing, returning alternative value, no matching handler was found. + + // no matching handler. + if (returnVal.Equals("nomatch")) + { + throw; + } + else + { + //TODO make spring specific value. + if (!returnVal.Equals("swallow")) + { + return returnVal; + } + else + { + return null; + } + } + } + } + + #endregion + + #region IInitializingObject implementation + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public override void AfterPropertiesSet() + { + if (exceptionHandlers.Count == 0) + { + throw new ArgumentException("At least one handler is required"); + } + IList newExceptionHandlers = new ArrayList(); + foreach (object o in exceptionHandlers) + { + string handlerString = o as string; + if (handlerString != null) + { + IExceptionHandler handler = Parse(handlerString); + if (handler == null) + { + throw new ArgumentException("Was not able to parse exception handler string [" + handlerString + + "]"); + } + newExceptionHandlers.Add(handler); + } + + } + //TODO sync. + exceptionHandlers = newExceptionHandlers; + } + + #endregion + + #region Methods + + /// + /// Invokes handlers registered for the passed exception and + /// + /// The exception to be handled + /// The that raised this exception. + /// The output of + protected virtual object InvokeHandlers(Exception ex, IMethodInvocation invocation) + { + IDictionary callContextDictionary = new Hashtable(); + callContextDictionary.Add("method", invocation.Method); + callContextDictionary.Add("args", invocation.Arguments); + callContextDictionary.Add("target", invocation.Target); + callContextDictionary.Add("e", ex); + object retValue = "nomatch"; + foreach (IExceptionHandler handler in exceptionHandlers) + { + if (handler != null) + { + if (handler.CanHandleException(ex, callContextDictionary)) + { + retValue = handler.HandleException(callContextDictionary); + if (!handler.ContinueProcessing) + { + return retValue; + } + } + } + } + return retValue; + } + + /// + /// Parses the specified handler string, creating an instance of IExceptionHander. + /// + /// The handler string. + /// an instance of an exception handler or null if was not able to correctly parse + /// handler string. + protected virtual IExceptionHandler Parse(string handlerString) + { + ParsedAdviceExpression parsedAdviceExpression = ParseAdviceExpression(handlerString); + + if (!parsedAdviceExpression.Success) + { + log.Warn("Could not parse exception hander statement " + handlerString); + return null; + } + + return CreateExceptionHandler(parsedAdviceExpression); + } + + private static IExceptionHandler CreateExceptionHandler(ParsedAdviceExpression parsedAdviceExpression) + { + if (parsedAdviceExpression.ActionText.IndexOf("log") >= 0) + { + //TODO support user selection of level, log.Debug , log.Info etc. + LogExceptionHandler handler = new LogExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + handler.ActionExpressionText = "#log.Trace(" + parsedAdviceExpression.ActionExpressionText + ")"; + return handler; + } + else if (parsedAdviceExpression.ActionText.IndexOf("translate") >= 0) + { + TranslationExceptionHandler handler = new TranslationExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + handler.ActionExpressionText = parsedAdviceExpression.ActionExpressionText; + return handler; + } + else if (parsedAdviceExpression.ActionText.IndexOf("wrap") >= 0) + { + TranslationExceptionHandler handler = new TranslationExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + handler.ActionExpressionText = ParseWrappedExceptionExpression("wrap", parsedAdviceExpression.AdviceExpression); + return handler; + } + else if (parsedAdviceExpression.ActionText.IndexOf("replace") >= 0) + { + TranslationExceptionHandler handler = new TranslationExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + handler.ActionExpressionText = ParseWrappedExceptionExpression("replace", parsedAdviceExpression.AdviceExpression); + return handler; + } + else if (parsedAdviceExpression.ActionText.IndexOf("swallow") >= 0) + { + SwallowExceptionHandler handler = new SwallowExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + return handler; + } + else if (parsedAdviceExpression.ActionText.IndexOf("return") >= 0) + { + ReturnValueExceptionHandler handler = new ReturnValueExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + handler.ActionExpressionText = parsedAdviceExpression.ActionExpressionText; + return handler; + } + else + { + log.Warn("Could not parse exception hander statement " + parsedAdviceExpression.AdviceExpression); + } + return null; + } + + private static string ParseWrappedExceptionExpression(string action, string handlerString) + { + int endOfActionIndex = handlerString.IndexOf(action) + action.Length; + string exceptionAndMessage = handlerString.Substring(endOfActionIndex).Trim(); + int endOfExceptionTypeIndex = exceptionAndMessage.IndexOf(" "); + + string rawExpressionTextPart; + string exception; + //Has two pieces. + if (endOfExceptionTypeIndex > 0) + { + exception = exceptionAndMessage.Substring(0, endOfExceptionTypeIndex).Trim(); + rawExpressionTextPart = exceptionAndMessage.Substring(endOfExceptionTypeIndex).Trim(); + } + else + { + exception = exceptionAndMessage; + if (action.Equals("wrap")) + { + rawExpressionTextPart = "'Wrapped ' + #e.GetType().Name"; + } else + { + rawExpressionTextPart = "'Replaced ' + #e.GetType().Name"; + } + } + + if (action.Equals("wrap")) + { + return string.Format("new {0}({1}, #e)", exception, rawExpressionTextPart); + } else + { + return string.Format("new {0}({1})", exception, rawExpressionTextPart); + } + } + + + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Exceptions/LogExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/Exceptions/LogExceptionHandler.cs index 56305bc1..36334288 100644 --- a/src/Spring/Spring.Aop/Aspects/Exceptions/LogExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/Exceptions/LogExceptionHandler.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Common.Logging; -using Spring.Expressions; - -namespace Spring.Aspects.Exceptions -{ - /// - /// Log the exceptions. Default log nameis "LogExceptionHandler" and log level is Debug - /// - /// Mark Pollack - /// $Id: LogExceptionHandler.cs,v 1.6 2008/02/26 00:03:24 markpollack Exp $ - public class LogExceptionHandler : AbstractExceptionHandler - { - private string logName = "LogExceptionHandler"; - - - /// - /// Initializes a new instance of the class. - /// - public LogExceptionHandler() - { - ContinueProcessing = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// The exception names. - public LogExceptionHandler(string[] exceptionNames) : base(exceptionNames) - { - ContinueProcessing = true; - } - - - - /// - /// Gets or sets the name of the log. - /// - /// The name of the log. - public string LogName - { - get { return logName; } - set { logName = value; } - } - - - /// - /// Handles the exception. - /// - /// the calling context dictionary - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - /// - public override object HandleException(IDictionary callContextDictionary) - { - ILog log = LogManager.GetLogger(logName); - callContextDictionary.Add("log", log); - try - { - IExpression expression = Expression.Parse(ActionExpressionText); - expression.GetValue(null, callContextDictionary); - } - catch (Exception e) - { - log.Warn("Was not able to evaluate action expression [" + ActionExpressionText + "]", e); - } - return "logged"; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Common.Logging; +using Spring.Expressions; + +namespace Spring.Aspects.Exceptions +{ + /// + /// Log the exceptions. Default log nameis "LogExceptionHandler" and log level is Debug + /// + /// Mark Pollack + public class LogExceptionHandler : AbstractExceptionHandler + { + private string logName = "LogExceptionHandler"; + + + /// + /// Initializes a new instance of the class. + /// + public LogExceptionHandler() + { + ContinueProcessing = true; + } + + /// + /// Initializes a new instance of the class. + /// + /// The exception names. + public LogExceptionHandler(string[] exceptionNames) : base(exceptionNames) + { + ContinueProcessing = true; + } + + + + /// + /// Gets or sets the name of the log. + /// + /// The name of the log. + public string LogName + { + get { return logName; } + set { logName = value; } + } + + + /// + /// Handles the exception. + /// + /// the calling context dictionary + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + /// + public override object HandleException(IDictionary callContextDictionary) + { + ILog log = LogManager.GetLogger(logName); + callContextDictionary.Add("log", log); + try + { + IExpression expression = Expression.Parse(ActionExpressionText); + expression.GetValue(null, callContextDictionary); + } + catch (Exception e) + { + log.Warn("Was not able to evaluate action expression [" + ActionExpressionText + "]", e); + } + return "logged"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Exceptions/ReturnValueExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/Exceptions/ReturnValueExceptionHandler.cs index 46c239df..262dc295 100644 --- a/src/Spring/Spring.Aop/Aspects/Exceptions/ReturnValueExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/Exceptions/ReturnValueExceptionHandler.cs @@ -1,72 +1,71 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Common.Logging; -using Spring.Expressions; - -namespace Spring.Aspects.Exceptions -{ - /// - /// Evaluates the expression for the return value of the method. - /// - /// Mark Pollack - /// $Id: ReturnValueExceptionHandler.cs,v 1.3 2007/10/10 18:07:46 markpollack Exp $ - public class ReturnValueExceptionHandler : AbstractExceptionHandler - { - - /// - /// Initializes a new instance of the class. - /// - public ReturnValueExceptionHandler() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The exception names. - public ReturnValueExceptionHandler(string[] exceptionNames) : base(exceptionNames) - { - } - - - - /// - /// Returns the result of evaluating the translation expression. - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - public override object HandleException(IDictionary callContextDictionary) - { - object returnVal = null; - try - { - IExpression expression = Expression.Parse(ActionExpressionText); - returnVal = expression.GetValue(null, callContextDictionary); - } - catch (Exception e) - { - log.Warn("Was not able to evaluate action expression [" + ActionExpressionText + "]", e); - } - return returnVal; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Common.Logging; +using Spring.Expressions; + +namespace Spring.Aspects.Exceptions +{ + /// + /// Evaluates the expression for the return value of the method. + /// + /// Mark Pollack + public class ReturnValueExceptionHandler : AbstractExceptionHandler + { + + /// + /// Initializes a new instance of the class. + /// + public ReturnValueExceptionHandler() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The exception names. + public ReturnValueExceptionHandler(string[] exceptionNames) : base(exceptionNames) + { + } + + + + /// + /// Returns the result of evaluating the translation expression. + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + public override object HandleException(IDictionary callContextDictionary) + { + object returnVal = null; + try + { + IExpression expression = Expression.Parse(ActionExpressionText); + returnVal = expression.GetValue(null, callContextDictionary); + } + catch (Exception e) + { + log.Warn("Was not able to evaluate action expression [" + ActionExpressionText + "]", e); + } + return returnVal; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Exceptions/SwallowExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/Exceptions/SwallowExceptionHandler.cs index f7f22db2..0b02bf91 100644 --- a/src/Spring/Spring.Aop/Aspects/Exceptions/SwallowExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/Exceptions/SwallowExceptionHandler.cs @@ -1,58 +1,57 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Aspects.Exceptions -{ - /// - /// Returns a token to indicate that this exception should be swallowed. - /// - /// Mark Pollack - /// $Id: SwallowExceptionHandler.cs,v 1.2 2007/10/02 21:56:53 markpollack Exp $ - public class SwallowExceptionHandler : AbstractExceptionHandler - { - /// - /// Initializes a new instance of the class. - /// - public SwallowExceptionHandler() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The exception names. - public SwallowExceptionHandler(string[] exceptionNames) : base(exceptionNames) - { - } - - - - /// - /// Handles the exception. - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - public override object HandleException(IDictionary callContextDictionary) - { - return "swallow"; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Aspects.Exceptions +{ + /// + /// Returns a token to indicate that this exception should be swallowed. + /// + /// Mark Pollack + public class SwallowExceptionHandler : AbstractExceptionHandler + { + /// + /// Initializes a new instance of the class. + /// + public SwallowExceptionHandler() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The exception names. + public SwallowExceptionHandler(string[] exceptionNames) : base(exceptionNames) + { + } + + + + /// + /// Handles the exception. + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + public override object HandleException(IDictionary callContextDictionary) + { + return "swallow"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Exceptions/TranslationExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/Exceptions/TranslationExceptionHandler.cs index 65700a5a..2709fd90 100644 --- a/src/Spring/Spring.Aop/Aspects/Exceptions/TranslationExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/Exceptions/TranslationExceptionHandler.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Common.Logging; -using Spring.Expressions; - -namespace Spring.Aspects.Exceptions -{ - /// - /// Translates from one exception to another based. My wrap or replace exception depending on the expression. - /// - /// Mark Pollack - /// $Id: TranslationExceptionHandler.cs,v 1.3 2007/10/10 18:07:46 markpollack Exp $ - public class TranslationExceptionHandler : AbstractExceptionHandler - { - /// - /// Initializes a new instance of the class. - /// - public TranslationExceptionHandler() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The exception names. - public TranslationExceptionHandler(string[] exceptionNames) : base(exceptionNames) - { - } - - - - /// - /// Handles the exception. - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - public override object HandleException(IDictionary callContextDictionary) - { - object o = null; - try { - IExpression expression = Expression.Parse(ActionExpressionText); - o = expression.GetValue(null, callContextDictionary); - } - catch (Exception e) - { - log.Warn("Was not able to evaluate action expression [" + ActionExpressionText + "]", e); - } - Exception translatedException = o as Exception; - if (translatedException != null) - { - ThrowTranslatedException(translatedException); - } - return null; - } - - private void ThrowTranslatedException(Exception exception) - { - throw exception; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Common.Logging; +using Spring.Expressions; + +namespace Spring.Aspects.Exceptions +{ + /// + /// Translates from one exception to another based. My wrap or replace exception depending on the expression. + /// + /// Mark Pollack + public class TranslationExceptionHandler : AbstractExceptionHandler + { + /// + /// Initializes a new instance of the class. + /// + public TranslationExceptionHandler() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The exception names. + public TranslationExceptionHandler(string[] exceptionNames) : base(exceptionNames) + { + } + + + + /// + /// Handles the exception. + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + public override object HandleException(IDictionary callContextDictionary) + { + object o = null; + try { + IExpression expression = Expression.Parse(ActionExpressionText); + o = expression.GetValue(null, callContextDictionary); + } + catch (Exception e) + { + log.Warn("Was not able to evaluate action expression [" + ActionExpressionText + "]", e); + } + Exception translatedException = o as Exception; + if (translatedException != null) + { + ThrowTranslatedException(translatedException); + } + return null; + } + + private void ThrowTranslatedException(Exception exception) + { + throw exception; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/IExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/IExceptionHandler.cs index 3ac61223..73f65cbd 100644 --- a/src/Spring/Spring.Aop/Aspects/IExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/IExceptionHandler.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -namespace Spring.Aspects -{ - /// - /// Handles a thrown exception providing calling context. - /// - /// Mark Pollack - /// $Id: IExceptionHandler.cs,v 1.1 2007/10/08 22:05:16 markpollack Exp $ - public interface IExceptionHandler - { - /// - /// Determines whether this instance can handle the exception the specified exception. - /// - /// The exception. - /// The call context dictionary. - /// - /// true if this instance can handle the specified exception; otherwise, false. - /// - bool CanHandleException(Exception ex, IDictionary callContextDictionary); - - /// - /// Handles the exception. - /// - /// The call context dictionary. - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - /// - object HandleException(IDictionary callContextDictionary); - - /// - /// Gets the source exception names. - /// - /// The source exception names. - IList SourceExceptionNames - { - get; set; - } - - /// - /// Gets the source exception types. - /// - /// The source exception types. - IList SourceExceptionTypes - { - get; set; - } - - /// - /// Gets the translation expression text - /// - /// The translation expression text - string ActionExpressionText - { - get; set; - } - - /// - /// Gets or sets the constraint expression text. - /// - /// The constraint expression text. - string ConstraintExpressionText - { - get; set; - } - - /// - /// Gets a value indicating whether to continue processing. - /// - /// true if continue processing; otherwise, false. - bool ContinueProcessing - { - get; set; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +namespace Spring.Aspects +{ + /// + /// Handles a thrown exception providing calling context. + /// + /// Mark Pollack + public interface IExceptionHandler + { + /// + /// Determines whether this instance can handle the exception the specified exception. + /// + /// The exception. + /// The call context dictionary. + /// + /// true if this instance can handle the specified exception; otherwise, false. + /// + bool CanHandleException(Exception ex, IDictionary callContextDictionary); + + /// + /// Handles the exception. + /// + /// The call context dictionary. + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + /// + object HandleException(IDictionary callContextDictionary); + + /// + /// Gets the source exception names. + /// + /// The source exception names. + IList SourceExceptionNames + { + get; set; + } + + /// + /// Gets the source exception types. + /// + /// The source exception types. + IList SourceExceptionTypes + { + get; set; + } + + /// + /// Gets the translation expression text + /// + /// The translation expression text + string ActionExpressionText + { + get; set; + } + + /// + /// Gets or sets the constraint expression text. + /// + /// The constraint expression text. + string ConstraintExpressionText + { + get; set; + } + + /// + /// Gets a value indicating whether to continue processing. + /// + /// true if continue processing; otherwise, false. + bool ContinueProcessing + { + get; set; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs b/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs index a0b0b581..24016876 100644 --- a/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Logging/AbstractLoggingAdvice.cs @@ -1,240 +1,239 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using AopAlliance.Intercept; -using Common.Logging; -using Spring.Aop.Framework; - -namespace Spring.Aspects.Logging -{ - /// - /// Abstract base class for logging advice - /// - /// - /// - /// - /// Mark Pollack - /// $Id: AbstractLoggingAdvice.cs,v 1.2 2007/12/06 17:17:19 markpollack Exp $ - public abstract class AbstractLoggingAdvice : IMethodInterceptor - { - #region Fields - - /// - /// The default ILog instance used to write logging messages. - /// - protected ILog defaultLogger = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType); - - /// - /// Indicates whether or not proxy type names should be hidden when using dynamic loggers. - /// - private bool hideProxyTypeNames = false; - - #endregion - - #region Properties - - /// - /// Sets a value indicating whether to use a dynamic logger or static logger - /// - /// Default is to use a static logger. - /// - /// Used to determine which ILog instance should be used to write log messages for - /// a particular method invocation: a dynamic one for the Type getting called, - /// or a static one for the Type of the trace interceptor. - /// - /// - /// Specify either this property or LoggerName, not both. - /// - /// - /// true if use dynamic logger; otherwise, false. - public bool UseDynamicLogger - { - set - { - defaultLogger = (value ? null : LogManager.GetLogger(GetType())); - } - } - - /// - /// Sets the name of the logger to use. - /// - /// - /// The name will be passed to the underlying logging implementation through Common.Logging, - /// getting interpreted as the log category according to the loggers configuration. - /// - /// This can be specified to not log into the category of a Type (whether this - /// interceptor's class or the class getting called) but rather to a specific named category. - /// - /// - /// Specify either this property or UseDynamicLogger, but not both. - /// - /// - /// The name of the logger. - public string LoggerName - { - set - { - defaultLogger = LogManager.GetLogger(value); - } - } - - - /// - /// Sets a value indicating whether hide proxy type names (whenever possible) - /// when using dynamic loggers, i.e. property UseDynamicLogger is set to true. - /// - /// true if [hide proxy type names]; otherwise, false. - public bool HideProxyTypeNames - { - set { hideProxyTypeNames = value; } - } - - #endregion - - #region Methods - - /// - /// Adds logging to the method invocation. - /// - /// - /// The method IsInterceptorEnabled is called - /// as an optimization to determine if logging should be applied. If logging should be - /// applied, the method invocation is passed to the InvokeUnderLog method for handling. - /// If not, the method proceeds as normal. - /// - /// - /// The method invocation that is being intercepted. - /// - /// - /// The result of the call to the - /// method of - /// the supplied ; this return value may - /// well have been intercepted by the interceptor. - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public object Invoke(IMethodInvocation invocation) - { - object o = invocation.This; - ILog log = GetLoggerForInvocation(invocation); - if (IsInterceptorEnabled(invocation, log)) - { - return InvokeUnderLog(invocation, log); - } - else - { - return invocation.Proceed(); - } - - } - - /// - /// Determines whether the interceptor is enabled for the specified invocation, that - /// is, whether the method InvokeUnderLog is called. - /// - /// The default behavior is to check whether the given ILog instance - /// is enabled by calling IsLogEnabled, whose default behavior is to check if - /// the TRACE level of logging is enabled. Subclasses - /// The invocation. - /// The log to write messages to - /// - /// true if [is interceptor enabled] [the specified invocation]; otherwise, false. - /// - protected virtual bool IsInterceptorEnabled(IMethodInvocation invocation, ILog log) - { - return IsLogEnabled(log); - } - - /// - /// Determines whether the given log is enabled. - /// - /// - /// Default is true when the trace level is enabled. Subclasses may override this - /// to change the level at which logging occurs, or return true to ignore level - /// checks. - /// The log instance to check. - /// - /// true if log is for a given log level; otherwise, false. - /// - protected virtual bool IsLogEnabled(ILog log) - { - return log.IsTraceEnabled; - } - - /// - /// Subclasses must override this method to perform any tracing around the supplied - /// IMethodInvocation. - /// - /// - /// Subclasses are resonsible for ensuring that the IMethodInvocation actually executes - /// by calling IMethodInvocation.Proceed(). - /// - /// By default, the passed-in ILog instance will have log level - /// "trace" enabled. Subclasses do not have to check for this again, unless - /// they overwrite the IsInterceptorEnabled method to modify - /// the default behavior. - /// - /// - /// The method invocation to log - /// The log to write messages to - /// The result of the call to IMethodInvocation.Proceed() - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - protected abstract object InvokeUnderLog(IMethodInvocation invocation, ILog log); - - - /// - /// Gets the appropriate log instance to use for the given IMethodInvocation. - /// - /// - /// If the UseDynamicLogger property is set to true, the ILog instance will be - /// for the target class of the IMethodInvocation, otherwise the log will be the - /// default static logger. - /// - /// The method invocation being logged. - /// The ILog instance to use. - protected virtual ILog GetLoggerForInvocation(IMethodInvocation invocation) - { - if (defaultLogger != null) - { - return defaultLogger; - } - else - { - object target = invocation.This; - Type logCategoryType = target.GetType(); - if (hideProxyTypeNames) - { - logCategoryType = AopUtils.GetTargetType(target); - } - return LogManager.GetLogger(logCategoryType); - } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using AopAlliance.Intercept; +using Common.Logging; +using Spring.Aop.Framework; + +namespace Spring.Aspects.Logging +{ + /// + /// Abstract base class for logging advice + /// + /// + /// + /// + /// Mark Pollack + public abstract class AbstractLoggingAdvice : IMethodInterceptor + { + #region Fields + + /// + /// The default ILog instance used to write logging messages. + /// + protected ILog defaultLogger = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType); + + /// + /// Indicates whether or not proxy type names should be hidden when using dynamic loggers. + /// + private bool hideProxyTypeNames = false; + + #endregion + + #region Properties + + /// + /// Sets a value indicating whether to use a dynamic logger or static logger + /// + /// Default is to use a static logger. + /// + /// Used to determine which ILog instance should be used to write log messages for + /// a particular method invocation: a dynamic one for the Type getting called, + /// or a static one for the Type of the trace interceptor. + /// + /// + /// Specify either this property or LoggerName, not both. + /// + /// + /// true if use dynamic logger; otherwise, false. + public bool UseDynamicLogger + { + set + { + defaultLogger = (value ? null : LogManager.GetLogger(GetType())); + } + } + + /// + /// Sets the name of the logger to use. + /// + /// + /// The name will be passed to the underlying logging implementation through Common.Logging, + /// getting interpreted as the log category according to the loggers configuration. + /// + /// This can be specified to not log into the category of a Type (whether this + /// interceptor's class or the class getting called) but rather to a specific named category. + /// + /// + /// Specify either this property or UseDynamicLogger, but not both. + /// + /// + /// The name of the logger. + public string LoggerName + { + set + { + defaultLogger = LogManager.GetLogger(value); + } + } + + + /// + /// Sets a value indicating whether hide proxy type names (whenever possible) + /// when using dynamic loggers, i.e. property UseDynamicLogger is set to true. + /// + /// true if [hide proxy type names]; otherwise, false. + public bool HideProxyTypeNames + { + set { hideProxyTypeNames = value; } + } + + #endregion + + #region Methods + + /// + /// Adds logging to the method invocation. + /// + /// + /// The method IsInterceptorEnabled is called + /// as an optimization to determine if logging should be applied. If logging should be + /// applied, the method invocation is passed to the InvokeUnderLog method for handling. + /// If not, the method proceeds as normal. + /// + /// + /// The method invocation that is being intercepted. + /// + /// + /// The result of the call to the + /// method of + /// the supplied ; this return value may + /// well have been intercepted by the interceptor. + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public object Invoke(IMethodInvocation invocation) + { + object o = invocation.This; + ILog log = GetLoggerForInvocation(invocation); + if (IsInterceptorEnabled(invocation, log)) + { + return InvokeUnderLog(invocation, log); + } + else + { + return invocation.Proceed(); + } + + } + + /// + /// Determines whether the interceptor is enabled for the specified invocation, that + /// is, whether the method InvokeUnderLog is called. + /// + /// The default behavior is to check whether the given ILog instance + /// is enabled by calling IsLogEnabled, whose default behavior is to check if + /// the TRACE level of logging is enabled. Subclasses + /// The invocation. + /// The log to write messages to + /// + /// true if [is interceptor enabled] [the specified invocation]; otherwise, false. + /// + protected virtual bool IsInterceptorEnabled(IMethodInvocation invocation, ILog log) + { + return IsLogEnabled(log); + } + + /// + /// Determines whether the given log is enabled. + /// + /// + /// Default is true when the trace level is enabled. Subclasses may override this + /// to change the level at which logging occurs, or return true to ignore level + /// checks. + /// The log instance to check. + /// + /// true if log is for a given log level; otherwise, false. + /// + protected virtual bool IsLogEnabled(ILog log) + { + return log.IsTraceEnabled; + } + + /// + /// Subclasses must override this method to perform any tracing around the supplied + /// IMethodInvocation. + /// + /// + /// Subclasses are resonsible for ensuring that the IMethodInvocation actually executes + /// by calling IMethodInvocation.Proceed(). + /// + /// By default, the passed-in ILog instance will have log level + /// "trace" enabled. Subclasses do not have to check for this again, unless + /// they overwrite the IsInterceptorEnabled method to modify + /// the default behavior. + /// + /// + /// The method invocation to log + /// The log to write messages to + /// The result of the call to IMethodInvocation.Proceed() + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + protected abstract object InvokeUnderLog(IMethodInvocation invocation, ILog log); + + + /// + /// Gets the appropriate log instance to use for the given IMethodInvocation. + /// + /// + /// If the UseDynamicLogger property is set to true, the ILog instance will be + /// for the target class of the IMethodInvocation, otherwise the log will be the + /// default static logger. + /// + /// The method invocation being logged. + /// The ILog instance to use. + protected virtual ILog GetLoggerForInvocation(IMethodInvocation invocation) + { + if (defaultLogger != null) + { + return defaultLogger; + } + else + { + object target = invocation.This; + Type logCategoryType = target.GetType(); + if (hideProxyTypeNames) + { + logCategoryType = AopUtils.GetTargetType(target); + } + return LogManager.GetLogger(logCategoryType); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs b/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs index c7374ec8..2135e1ce 100644 --- a/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Logging/SimpleLoggingAdvice.cs @@ -1,459 +1,458 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using System.Text; -using AopAlliance.Intercept; -using Common.Logging; - -namespace Spring.Aspects.Logging -{ - /// - /// Configurable advice for logging. - /// - /// - /// - /// - /// Mark Pollack - /// $Id: SimpleLoggingAdvice.cs,v 1.7 2008/04/04 15:30:13 markpollack Exp $ - public class SimpleLoggingAdvice : AbstractLoggingAdvice - { - #region Fields - - /// - /// Flag to indicate if unique identifier should be in the log message. - /// - private bool logUniqueIdentifier; - - /// - /// Flag to indicate if the execution time should be in the log message. - /// - private bool logExecutionTime; - - /// - /// Flag to indicate if the method arguments should be in the log message. - /// - private bool logMethodArguments; - - /// - /// Flag to indicate if the return value should be in the log message. - /// - private bool logReturnValue; - - /// - /// The separator string to use for delmiting log message fields. - /// - private string separator = ", "; - - /// - /// The log level to use for logging the entry, exit, exception messages. - /// - private LogLevel logLevel = LogLevel.Trace; - - - #endregion - - #region Constructor(s) - - /// - /// Initializes a new instance of the class. - /// - public SimpleLoggingAdvice() - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// if set to true to use dynamic logger, if - /// false use static logger. - public SimpleLoggingAdvice(bool useDynamicLogger) - { - UseDynamicLogger = useDynamicLogger; - } - - #endregion - - #region Properties - - /// - /// Gets or sets a value indicating whether to log a unique identifier with the log message. - /// - /// true if [log unique identifier]; otherwise, false. - public bool LogUniqueIdentifier - { - get { return logUniqueIdentifier; } - set { logUniqueIdentifier = value; } - } - - /// - /// Gets or sets a value indicating whether to log execution time. - /// - /// true if log execution time; otherwise, false. - public bool LogExecutionTime - { - get { return logExecutionTime; } - set { logExecutionTime = value; } - } - - /// - /// Gets or sets a value indicating whether log method arguments. - /// - /// true if log method arguments]; otherwise, false. - public bool LogMethodArguments - { - get { return logMethodArguments; } - set { logMethodArguments = value; } - } - - /// - /// Gets or sets a value indicating whether log return value. - /// - /// true if log return value; otherwise, false. - public bool LogReturnValue - { - get { return logReturnValue; } - set { logReturnValue = value; } - } - - /// - /// Gets or sets the seperator string to use for delmiting log message fields. - /// - /// The seperator. - public string Separator - { - get { return separator; } - set { separator = value; } - } - - /// - /// Gets or sets the entry log level. - /// - /// The entry log level. - public LogLevel LogLevel - { - get { return logLevel; } - set { logLevel = value; } - } - - #endregion - - #region Protected Methods - - /// - /// Subclasses must override this method to perform any tracing around the supplied - /// IMethodInvocation. - /// - /// The method invocation to log - /// The log to write messages to - /// - /// The result of the call to IMethodInvocation.Proceed() - /// - /// - /// Subclasses are resonsible for ensuring that the IMethodInvocation actually executes - /// by calling IMethodInvocation.Proceed(). - /// - /// By default, the passed-in ILog instance will have log level - /// "trace" enabled. Subclasses do not have to check for this again, unless - /// they overwrite the IsInterceptorEnabled method to modify - /// the default behavior. - /// - /// - /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - protected override object InvokeUnderLog(IMethodInvocation invocation, ILog log) - { - object returnValue = null; - bool exitThroughException = false; - - DateTime startTime = DateTime.Now; - string uniqueIdentifier = null; - - if (LogUniqueIdentifier) - { - uniqueIdentifier = CreateUniqueIdentifier(); - } - try - { - WriteToLog(LogLevel, log, GetEntryMessage(invocation, uniqueIdentifier), null); - returnValue = invocation.Proceed(); - return returnValue; - } catch (Exception e) - { - TimeSpan executionTimeSpan = DateTime.Now - startTime; - WriteToLog(LogLevel, log, GetExceptionMessage(invocation, e, executionTimeSpan, uniqueIdentifier), e); - exitThroughException = true; - throw; - } - finally - { - if (!exitThroughException) - { - TimeSpan executionTimeSpan = DateTime.Now - startTime; - WriteToLog(LogLevel, log, GetExitMessage(invocation, returnValue, executionTimeSpan, uniqueIdentifier), null); - } - } - } - - /// - /// Determines whether the given log is enabled. - /// - /// The log instance to check. - /// - /// true if log is for a given log level; otherwise, false. - /// - /// - /// Default is true when the trace level is enabled. Subclasses may override this - /// to change the level at which logging occurs, or return true to ignore level - /// checks. - protected override bool IsLogEnabled(ILog log) - { - switch (LogLevel) - { - case LogLevel.All: - case LogLevel.Trace: - if (log.IsTraceEnabled) - { - return true; - } - break; - case LogLevel.Debug: - if (log.IsDebugEnabled) - { - return true; - } - break; - case LogLevel.Error: - if (log.IsErrorEnabled) - { - return true; - } - break; - case LogLevel.Fatal: - if (log.IsFatalEnabled) - { - return true; - } - break; - case LogLevel.Info: - if (log.IsInfoEnabled) - { - return true; - } - break; - case LogLevel.Warn: - if (log.IsWarnEnabled) - { - return true; - } - break; - case LogLevel.Off: - default: - break; - } - return false; - } - - /// - /// Creates a unique identifier. - /// - /// - /// Default implementation uses Guid.NewGuid(). Subclasses may override to provide an alternative - /// ID generation implementation. - /// - /// A unique identifier - protected virtual string CreateUniqueIdentifier() - { - return Guid.NewGuid().ToString(); - } - - /// - /// Gets the entry message to log - /// - /// The invocation. - /// The id string. - /// The entry log message - protected virtual string GetEntryMessage(IMethodInvocation invocation, string idString) - { - StringBuilder sb = new StringBuilder(128); - sb.Append("Entering "); - AppendCommonInformation(sb, invocation, idString); - if (logMethodArguments) - { - sb.Append(GetMethodArgumentAsString(invocation)); - } - - return RemoveLastSeparator(sb.ToString(), Separator); - } - - /// - /// Gets the exception message. - /// - /// The method invocation. - /// The thown exception. - /// The execution time span. - /// The id string. - /// The exception log message. - protected virtual string GetExceptionMessage(IMethodInvocation invocation, Exception e, TimeSpan executionTimeSpan, string idString) - { - StringBuilder sb = new StringBuilder(128); - sb.Append("Exception thrown in "); - sb.Append(invocation.Method.Name).Append(Separator); - AppendCommonInformation(sb, invocation, idString); - if (LogExecutionTime) - { - sb.Append(executionTimeSpan.TotalMilliseconds).Append(" ms"); - } - - return RemoveLastSeparator(sb.ToString(), Separator); - } - - - /// - /// Gets the exit log message. - /// - /// The method invocation. - /// The return value. - /// The execution time span. - /// The id string. - /// the exit log message - protected virtual string GetExitMessage(IMethodInvocation invocation, object returnValue, TimeSpan executionTimeSpan, string idString) - { - StringBuilder sb = new StringBuilder(128); - sb.Append("Exiting "); - AppendCommonInformation(sb, invocation, idString); - if (LogReturnValue && invocation.Method.ReturnType != typeof(void)) - { - sb.Append("return=").Append(returnValue).Append(Separator); - } - if (LogExecutionTime) - { - sb.Append(executionTimeSpan.TotalMilliseconds).Append(" ms"); - } - return RemoveLastSeparator(sb.ToString(), Separator); - } - - - /// - /// Appends common information across entry,exit, exception logging - /// - /// Add method name and unique identifier if required. - /// The string buffer building logging message. - /// The method invocation. - /// The unique identifier string. - protected virtual void AppendCommonInformation(StringBuilder sb, IMethodInvocation invocation, string idString) - { - sb.Append(invocation.Method.Name); - if (LogUniqueIdentifier) - { - sb.Append(Separator).Append(idString); - } - sb.Append(Separator); - } - - /// - /// Gets the method argument as argumen name/value pairs. - /// - /// The method invocation. - /// string for logging method argument name and values. - protected virtual string GetMethodArgumentAsString(IMethodInvocation invocation) - { - StringBuilder sb = new StringBuilder(128); - ParameterInfo[] parameterInfos = invocation.Method.GetParameters(); - object[] argValues = invocation.Arguments; - for (int i=0; i< parameterInfos.Length; i++) - { - sb.Append(parameterInfos[i].Name).Append("=").Append(argValues[i]); - if (i != parameterInfos.Length) sb.Append("; "); - } - - return RemoveLastSeparator(sb.ToString(), "; "); - } - - #endregion - - #region Private Methods - - private string RemoveLastSeparator(string str, string separator) - { - if (str.EndsWith(separator)) - { - return str.Substring(0, str.Length - separator.Length); - } - else - { - return str; - } - } - - private void WriteToLog(LogLevel logLevel, ILog log, string text, Exception e) - { - switch (logLevel) - { - case LogLevel.All: - case LogLevel.Trace: - if (log.IsTraceEnabled) - { - if (e == null) log.Trace(text); else log.Trace(text, e); - } - break; - case LogLevel.Debug: - if (log.IsDebugEnabled) - { - if (e == null) log.Debug(text); else log.Debug(text, e); - } - break; - case LogLevel.Error: - if (log.IsErrorEnabled) - { - if (e == null) log.Error(text); else log.Error(text, e); - } - break; - case LogLevel.Fatal: - if (log.IsFatalEnabled) - { - if (e == null) log.Fatal(text); else log.Fatal(text, e); - } - break; - case LogLevel.Info: - if (log.IsInfoEnabled) - { - if (e == null) log.Info(text); else log.Info(text, e); - } - break; - case LogLevel.Warn: - if (log.IsWarnEnabled) - { - if (e == null) log.Warn(text); else log.Warn(text, e); - } - break; - case LogLevel.Off: - default: - break; - } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using System.Text; +using AopAlliance.Intercept; +using Common.Logging; + +namespace Spring.Aspects.Logging +{ + /// + /// Configurable advice for logging. + /// + /// + /// + /// + /// Mark Pollack + public class SimpleLoggingAdvice : AbstractLoggingAdvice + { + #region Fields + + /// + /// Flag to indicate if unique identifier should be in the log message. + /// + private bool logUniqueIdentifier; + + /// + /// Flag to indicate if the execution time should be in the log message. + /// + private bool logExecutionTime; + + /// + /// Flag to indicate if the method arguments should be in the log message. + /// + private bool logMethodArguments; + + /// + /// Flag to indicate if the return value should be in the log message. + /// + private bool logReturnValue; + + /// + /// The separator string to use for delmiting log message fields. + /// + private string separator = ", "; + + /// + /// The log level to use for logging the entry, exit, exception messages. + /// + private LogLevel logLevel = LogLevel.Trace; + + + #endregion + + #region Constructor(s) + + /// + /// Initializes a new instance of the class. + /// + public SimpleLoggingAdvice() + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// if set to true to use dynamic logger, if + /// false use static logger. + public SimpleLoggingAdvice(bool useDynamicLogger) + { + UseDynamicLogger = useDynamicLogger; + } + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether to log a unique identifier with the log message. + /// + /// true if [log unique identifier]; otherwise, false. + public bool LogUniqueIdentifier + { + get { return logUniqueIdentifier; } + set { logUniqueIdentifier = value; } + } + + /// + /// Gets or sets a value indicating whether to log execution time. + /// + /// true if log execution time; otherwise, false. + public bool LogExecutionTime + { + get { return logExecutionTime; } + set { logExecutionTime = value; } + } + + /// + /// Gets or sets a value indicating whether log method arguments. + /// + /// true if log method arguments]; otherwise, false. + public bool LogMethodArguments + { + get { return logMethodArguments; } + set { logMethodArguments = value; } + } + + /// + /// Gets or sets a value indicating whether log return value. + /// + /// true if log return value; otherwise, false. + public bool LogReturnValue + { + get { return logReturnValue; } + set { logReturnValue = value; } + } + + /// + /// Gets or sets the seperator string to use for delmiting log message fields. + /// + /// The seperator. + public string Separator + { + get { return separator; } + set { separator = value; } + } + + /// + /// Gets or sets the entry log level. + /// + /// The entry log level. + public LogLevel LogLevel + { + get { return logLevel; } + set { logLevel = value; } + } + + #endregion + + #region Protected Methods + + /// + /// Subclasses must override this method to perform any tracing around the supplied + /// IMethodInvocation. + /// + /// The method invocation to log + /// The log to write messages to + /// + /// The result of the call to IMethodInvocation.Proceed() + /// + /// + /// Subclasses are resonsible for ensuring that the IMethodInvocation actually executes + /// by calling IMethodInvocation.Proceed(). + /// + /// By default, the passed-in ILog instance will have log level + /// "trace" enabled. Subclasses do not have to check for this again, unless + /// they overwrite the IsInterceptorEnabled method to modify + /// the default behavior. + /// + /// + /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + protected override object InvokeUnderLog(IMethodInvocation invocation, ILog log) + { + object returnValue = null; + bool exitThroughException = false; + + DateTime startTime = DateTime.Now; + string uniqueIdentifier = null; + + if (LogUniqueIdentifier) + { + uniqueIdentifier = CreateUniqueIdentifier(); + } + try + { + WriteToLog(LogLevel, log, GetEntryMessage(invocation, uniqueIdentifier), null); + returnValue = invocation.Proceed(); + return returnValue; + } catch (Exception e) + { + TimeSpan executionTimeSpan = DateTime.Now - startTime; + WriteToLog(LogLevel, log, GetExceptionMessage(invocation, e, executionTimeSpan, uniqueIdentifier), e); + exitThroughException = true; + throw; + } + finally + { + if (!exitThroughException) + { + TimeSpan executionTimeSpan = DateTime.Now - startTime; + WriteToLog(LogLevel, log, GetExitMessage(invocation, returnValue, executionTimeSpan, uniqueIdentifier), null); + } + } + } + + /// + /// Determines whether the given log is enabled. + /// + /// The log instance to check. + /// + /// true if log is for a given log level; otherwise, false. + /// + /// + /// Default is true when the trace level is enabled. Subclasses may override this + /// to change the level at which logging occurs, or return true to ignore level + /// checks. + protected override bool IsLogEnabled(ILog log) + { + switch (LogLevel) + { + case LogLevel.All: + case LogLevel.Trace: + if (log.IsTraceEnabled) + { + return true; + } + break; + case LogLevel.Debug: + if (log.IsDebugEnabled) + { + return true; + } + break; + case LogLevel.Error: + if (log.IsErrorEnabled) + { + return true; + } + break; + case LogLevel.Fatal: + if (log.IsFatalEnabled) + { + return true; + } + break; + case LogLevel.Info: + if (log.IsInfoEnabled) + { + return true; + } + break; + case LogLevel.Warn: + if (log.IsWarnEnabled) + { + return true; + } + break; + case LogLevel.Off: + default: + break; + } + return false; + } + + /// + /// Creates a unique identifier. + /// + /// + /// Default implementation uses Guid.NewGuid(). Subclasses may override to provide an alternative + /// ID generation implementation. + /// + /// A unique identifier + protected virtual string CreateUniqueIdentifier() + { + return Guid.NewGuid().ToString(); + } + + /// + /// Gets the entry message to log + /// + /// The invocation. + /// The id string. + /// The entry log message + protected virtual string GetEntryMessage(IMethodInvocation invocation, string idString) + { + StringBuilder sb = new StringBuilder(128); + sb.Append("Entering "); + AppendCommonInformation(sb, invocation, idString); + if (logMethodArguments) + { + sb.Append(GetMethodArgumentAsString(invocation)); + } + + return RemoveLastSeparator(sb.ToString(), Separator); + } + + /// + /// Gets the exception message. + /// + /// The method invocation. + /// The thown exception. + /// The execution time span. + /// The id string. + /// The exception log message. + protected virtual string GetExceptionMessage(IMethodInvocation invocation, Exception e, TimeSpan executionTimeSpan, string idString) + { + StringBuilder sb = new StringBuilder(128); + sb.Append("Exception thrown in "); + sb.Append(invocation.Method.Name).Append(Separator); + AppendCommonInformation(sb, invocation, idString); + if (LogExecutionTime) + { + sb.Append(executionTimeSpan.TotalMilliseconds).Append(" ms"); + } + + return RemoveLastSeparator(sb.ToString(), Separator); + } + + + /// + /// Gets the exit log message. + /// + /// The method invocation. + /// The return value. + /// The execution time span. + /// The id string. + /// the exit log message + protected virtual string GetExitMessage(IMethodInvocation invocation, object returnValue, TimeSpan executionTimeSpan, string idString) + { + StringBuilder sb = new StringBuilder(128); + sb.Append("Exiting "); + AppendCommonInformation(sb, invocation, idString); + if (LogReturnValue && invocation.Method.ReturnType != typeof(void)) + { + sb.Append("return=").Append(returnValue).Append(Separator); + } + if (LogExecutionTime) + { + sb.Append(executionTimeSpan.TotalMilliseconds).Append(" ms"); + } + return RemoveLastSeparator(sb.ToString(), Separator); + } + + + /// + /// Appends common information across entry,exit, exception logging + /// + /// Add method name and unique identifier if required. + /// The string buffer building logging message. + /// The method invocation. + /// The unique identifier string. + protected virtual void AppendCommonInformation(StringBuilder sb, IMethodInvocation invocation, string idString) + { + sb.Append(invocation.Method.Name); + if (LogUniqueIdentifier) + { + sb.Append(Separator).Append(idString); + } + sb.Append(Separator); + } + + /// + /// Gets the method argument as argumen name/value pairs. + /// + /// The method invocation. + /// string for logging method argument name and values. + protected virtual string GetMethodArgumentAsString(IMethodInvocation invocation) + { + StringBuilder sb = new StringBuilder(128); + ParameterInfo[] parameterInfos = invocation.Method.GetParameters(); + object[] argValues = invocation.Arguments; + for (int i=0; i< parameterInfos.Length; i++) + { + sb.Append(parameterInfos[i].Name).Append("=").Append(argValues[i]); + if (i != parameterInfos.Length) sb.Append("; "); + } + + return RemoveLastSeparator(sb.ToString(), "; "); + } + + #endregion + + #region Private Methods + + private string RemoveLastSeparator(string str, string separator) + { + if (str.EndsWith(separator)) + { + return str.Substring(0, str.Length - separator.Length); + } + else + { + return str; + } + } + + private void WriteToLog(LogLevel logLevel, ILog log, string text, Exception e) + { + switch (logLevel) + { + case LogLevel.All: + case LogLevel.Trace: + if (log.IsTraceEnabled) + { + if (e == null) log.Trace(text); else log.Trace(text, e); + } + break; + case LogLevel.Debug: + if (log.IsDebugEnabled) + { + if (e == null) log.Debug(text); else log.Debug(text, e); + } + break; + case LogLevel.Error: + if (log.IsErrorEnabled) + { + if (e == null) log.Error(text); else log.Error(text, e); + } + break; + case LogLevel.Fatal: + if (log.IsFatalEnabled) + { + if (e == null) log.Fatal(text); else log.Fatal(text, e); + } + break; + case LogLevel.Info: + if (log.IsInfoEnabled) + { + if (e == null) log.Info(text); else log.Info(text, e); + } + break; + case LogLevel.Warn: + if (log.IsWarnEnabled) + { + if (e == null) log.Warn(text); else log.Warn(text, e); + } + break; + case LogLevel.Off: + default: + break; + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/ParsedAdviceExpression.cs b/src/Spring/Spring.Aop/Aspects/ParsedAdviceExpression.cs index 0c127b7b..45253ff7 100644 --- a/src/Spring/Spring.Aop/Aspects/ParsedAdviceExpression.cs +++ b/src/Spring/Spring.Aop/Aspects/ParsedAdviceExpression.cs @@ -1,115 +1,114 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Aspects -{ - /// - /// This class contains the results of parsing an advice expresion of the form - /// on exception name [ExceptionName1,ExceptionName2,...] [action] [action expression] - /// or - /// on exception [constraint expression] [action] [action expression] - /// - /// - /// - /// - /// Mark Pollack - /// $Id: ParsedAdviceExpression.cs,v 1.1 2007/10/08 22:05:16 markpollack Exp $ - public class ParsedAdviceExpression - { - private string adviceExpression; - - private string[] exceptionNames = new string[0]; - private string constraintExpression = null; - private string actionExpressionText = null; - private string actionText = null; - private bool success; - - - /// - /// Initializes a new instance of the class. - /// - /// The advice expression. - public ParsedAdviceExpression(string adviceExpression) - { - this.adviceExpression = adviceExpression; - } - - - /// - /// Gets or sets the advice expression. - /// - /// The advice expression. - public string AdviceExpression - { - get { return adviceExpression; } - set { adviceExpression = value; } - } - - /// - /// Gets or sets the exception names. - /// - /// The exception names. - public string[] ExceptionNames - { - get { return exceptionNames; } - set { exceptionNames = value; } - } - - /// - /// Gets or sets the constraint expression. - /// - /// The constraint expression. - public string ConstraintExpression - { - get { return constraintExpression; } - set { constraintExpression = value; } - } - - /// - /// Gets or sets the action expression text. - /// - /// The action expression text. - public string ActionExpressionText - { - get { return actionExpressionText; } - set { actionExpressionText = value; } - } - - /// - /// Gets or sets the action text. - /// - /// The action text. - public string ActionText - { - get { return actionText; } - set { actionText = value; } - } - - /// - /// Gets or sets a value indicating whether this is success. - /// - /// true if success; otherwise, false. - public bool Success - { - get { return success; } - set { success = value; } - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Aspects +{ + /// + /// This class contains the results of parsing an advice expresion of the form + /// on exception name [ExceptionName1,ExceptionName2,...] [action] [action expression] + /// or + /// on exception [constraint expression] [action] [action expression] + /// + /// + /// + /// + /// Mark Pollack + public class ParsedAdviceExpression + { + private string adviceExpression; + + private string[] exceptionNames = new string[0]; + private string constraintExpression = null; + private string actionExpressionText = null; + private string actionText = null; + private bool success; + + + /// + /// Initializes a new instance of the class. + /// + /// The advice expression. + public ParsedAdviceExpression(string adviceExpression) + { + this.adviceExpression = adviceExpression; + } + + + /// + /// Gets or sets the advice expression. + /// + /// The advice expression. + public string AdviceExpression + { + get { return adviceExpression; } + set { adviceExpression = value; } + } + + /// + /// Gets or sets the exception names. + /// + /// The exception names. + public string[] ExceptionNames + { + get { return exceptionNames; } + set { exceptionNames = value; } + } + + /// + /// Gets or sets the constraint expression. + /// + /// The constraint expression. + public string ConstraintExpression + { + get { return constraintExpression; } + set { constraintExpression = value; } + } + + /// + /// Gets or sets the action expression text. + /// + /// The action expression text. + public string ActionExpressionText + { + get { return actionExpressionText; } + set { actionExpressionText = value; } + } + + /// + /// Gets or sets the action text. + /// + /// The action text. + public string ActionText + { + get { return actionText; } + set { actionText = value; } + } + + /// + /// Gets or sets a value indicating whether this is success. + /// + /// true if success; otherwise, false. + public bool Success + { + get { return success; } + set { success = value; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs b/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs index 514e43af..b2ab7fd8 100644 --- a/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs @@ -1,316 +1,315 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Text.RegularExpressions; -using System.Threading; -using AopAlliance.Intercept; -using Common.Logging; -using Spring.Core.TypeConversion; -using Spring.Expressions; - -namespace Spring.Aspects -{ - /// - /// AOP Advice to retry a method invocation on an exception. The retry semantics are defined by a DSL of the - /// form on exception name [ExceptionName1,ExceptionName2,...] retry [number of times] [delay|rate] [delay time|rate expression]. - /// For example, on exception name ArithmeticException retry 3x delay 1s - /// - /// - /// - /// - /// Mark Pollack - /// $Id: RetryAdvice.cs,v 1.5 2008/03/17 20:25:34 markpollack Exp $ - public class RetryAdvice : AbstractExceptionHandlerAdvice - { - #region Fields - - private static readonly ILog log = LogManager.GetLogger(typeof (RetryAdvice)); - - private TimeSpanConverter timeSpanConverter = new TimeSpanConverter(); - - private RetryExceptionHandler retryExceptionHandler; - - private string retryExpression; - - private string onExceptionNameRegex = @"^(on\s+exception\s+name)\s+(.*?)\s+(retry)\s*(.*?)$"; - - private string onExceptionRegex = @"^(on\s+exception\s+)(\(.*?\))\s+(retry)\s*(.*?)$"; - - //retry 3x delay 10s - private string delayRegex = @"^(\d+)x\s+(delay)\s+(\d+\w+)?$"; - - //retry 3x rate 10n+5 - private string rateRegex = @"^(\d+)x\s+(rate)\s+(\(.*?\))?$"; - #endregion - - #region Properties - - /// - /// Gets or sets the retry expression. - /// - /// The retry expression. - public string RetryExpression - { - get { return retryExpression; } - set { retryExpression = value; } - } - - /// - /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception name' and exception handling actions. - /// - /// The regex string to parse advice expressions starting with 'on exception name' and exception handling actions. - public override string OnExceptionNameRegex - { - get { return onExceptionNameRegex; } - set { onExceptionNameRegex = value; } - } - - /// - /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. - /// - /// The regex string to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. - public override string OnExceptionRegex - { - get { return onExceptionRegex; } - set { onExceptionRegex = value; } - } - - #endregion - - #region IMethodInterceptor implementation - - /// - /// Implement this method to perform extra treatments before and after - /// the call to the supplied . - /// - /// The method invocation that is being intercepted. - /// - /// The result of the call to the - /// method of - /// the supplied ; this return value may - /// well have been intercepted by the interceptor. - /// - /// - ///

- /// Polite implementations would certainly like to invoke - /// . - ///

- ///
- /// - /// If any of the interceptors in the chain or the target object itself - /// throws an exception. - /// - public override object Invoke(IMethodInvocation invocation) - { - IDictionary callContextDictionary = new Hashtable(); - callContextDictionary.Add("method", invocation.Method); - callContextDictionary.Add("args", invocation.Arguments); - callContextDictionary.Add("target", invocation.Target); - int numAttempts = 0; - - object returnVal = null; - do - { - try - { - returnVal = invocation.Proceed(); - break; - } - catch (Exception ex) - { - callContextDictionary["e"] = ex; - if (retryExceptionHandler.CanHandleException(ex, callContextDictionary)) - { - numAttempts++; - if (numAttempts == retryExceptionHandler.MaximumRetryCount) - { - throw; - } - else - { - if (log.IsTraceEnabled) - { - log.Trace("Retrying " + invocation.Method.Name); - } - callContextDictionary["n"] = numAttempts; - Sleep(retryExceptionHandler, callContextDictionary); - } - } - else - { - throw; - } - } - } while (numAttempts <= retryExceptionHandler.MaximumRetryCount); - - - log.Debug("Invoked successfully after " + numAttempts + " attempt(s)"); - return returnVal; - } - - private static void Sleep(RetryExceptionHandler handler, IDictionary callContextDictionary) - { - if (handler.IsDelayBased) - { - Thread.Sleep(handler.DelayTimeSpan); - } - else - { - try - { - IExpression expression = Expression.Parse(handler.DelayRateExpression); - object result = expression.GetValue(null, callContextDictionary); - decimal d = decimal.Parse(result.ToString()); - decimal rounded = decimal.Round(d*1000,0); - int sleepInSeconds = decimal.ToInt32(rounded); - Thread.Sleep(sleepInSeconds); - } - catch (InvalidCastException e) - { - log.Warn("Was not able to cast expression to decimal [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); - Thread.Sleep(1000); - } - catch (Exception e) - { - log.Warn("Was not able to evaluate rate expression [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); - Thread.Sleep(1000); - } - } - } - - #endregion - - #region IInitializingObject implementation - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public override void AfterPropertiesSet() - { - if (retryExpression == null) - { - throw new ArgumentException("Must specify retry expression."); - } - RetryExceptionHandler handler = Parse(retryExpression); - if (handler == null) - { - throw new ArgumentException("Was not able to parse retry expression string [" + retryExpression + "]"); - } - retryExceptionHandler = handler; - } - - #endregion - - /// - /// Parses the specified handler string. - /// - /// The handler string. - /// - protected virtual RetryExceptionHandler Parse(string retryExpressionString) - { - - ParsedAdviceExpression parsedAdviceExpression = ParseAdviceExpression(retryExpressionString); - - if (!parsedAdviceExpression.Success) - { - log.Warn("Could not parse retry expression " + retryExpressionString); - return null; - } - - RetryExceptionHandler handler = new RetryExceptionHandler(parsedAdviceExpression.ExceptionNames); - handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; - handler.ActionExpressionText = parsedAdviceExpression.AdviceExpression; - - Match match = GetMatchForActionExpression(parsedAdviceExpression.ActionExpressionText, delayRegex); - - if (match.Success) - { - handler.MaximumRetryCount = int.Parse(match.Groups[1].Value.Trim()); - handler.IsDelayBased = true; - - try - { - string ts = match.Groups[3].Value.Trim(); - handler.DelayTimeSpan = (TimeSpan) timeSpanConverter.ConvertFrom(null, null, ts); - } catch (Exception) - { - log.Warn("Could not parse timespan " + match.Groups[3].Value.Trim()); - return null; - } - return handler; - } - else - { - match = GetMatchForActionExpression(parsedAdviceExpression.ActionExpressionText, rateRegex); - if (match.Success) - { - handler.MaximumRetryCount = int.Parse(match.Groups[1].Value.Trim()); - handler.IsDelayBased = false; - handler.DelayRateExpression = match.Groups[3].Value.Trim(); - return handler; - } - else - { - return null; - } - } - - } - - /// - /// Gets the match for action expression. - /// - /// The action expression string. - /// The regex string. - /// The Match object resulting from the regular expression match. - protected virtual Match GetMatchForActionExpression(string actionExpressionString, string regexString) - { - RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase); - Regex reg = new Regex(regexString, options); - return reg.Match(actionExpressionString); - } - - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Text.RegularExpressions; +using System.Threading; +using AopAlliance.Intercept; +using Common.Logging; +using Spring.Core.TypeConversion; +using Spring.Expressions; + +namespace Spring.Aspects +{ + /// + /// AOP Advice to retry a method invocation on an exception. The retry semantics are defined by a DSL of the + /// form on exception name [ExceptionName1,ExceptionName2,...] retry [number of times] [delay|rate] [delay time|rate expression]. + /// For example, on exception name ArithmeticException retry 3x delay 1s + /// + /// + /// + /// + /// Mark Pollack + public class RetryAdvice : AbstractExceptionHandlerAdvice + { + #region Fields + + private static readonly ILog log = LogManager.GetLogger(typeof (RetryAdvice)); + + private TimeSpanConverter timeSpanConverter = new TimeSpanConverter(); + + private RetryExceptionHandler retryExceptionHandler; + + private string retryExpression; + + private string onExceptionNameRegex = @"^(on\s+exception\s+name)\s+(.*?)\s+(retry)\s*(.*?)$"; + + private string onExceptionRegex = @"^(on\s+exception\s+)(\(.*?\))\s+(retry)\s*(.*?)$"; + + //retry 3x delay 10s + private string delayRegex = @"^(\d+)x\s+(delay)\s+(\d+\w+)?$"; + + //retry 3x rate 10n+5 + private string rateRegex = @"^(\d+)x\s+(rate)\s+(\(.*?\))?$"; + #endregion + + #region Properties + + /// + /// Gets or sets the retry expression. + /// + /// The retry expression. + public string RetryExpression + { + get { return retryExpression; } + set { retryExpression = value; } + } + + /// + /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception name' and exception handling actions. + /// + /// The regex string to parse advice expressions starting with 'on exception name' and exception handling actions. + public override string OnExceptionNameRegex + { + get { return onExceptionNameRegex; } + set { onExceptionNameRegex = value; } + } + + /// + /// Gets or sets the Regex string used to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. + /// + /// The regex string to parse advice expressions starting with 'on exception (constraint)' and exception handling actions. + public override string OnExceptionRegex + { + get { return onExceptionRegex; } + set { onExceptionRegex = value; } + } + + #endregion + + #region IMethodInterceptor implementation + + /// + /// Implement this method to perform extra treatments before and after + /// the call to the supplied . + /// + /// The method invocation that is being intercepted. + /// + /// The result of the call to the + /// method of + /// the supplied ; this return value may + /// well have been intercepted by the interceptor. + /// + /// + ///

+ /// Polite implementations would certainly like to invoke + /// . + ///

+ ///
+ /// + /// If any of the interceptors in the chain or the target object itself + /// throws an exception. + /// + public override object Invoke(IMethodInvocation invocation) + { + IDictionary callContextDictionary = new Hashtable(); + callContextDictionary.Add("method", invocation.Method); + callContextDictionary.Add("args", invocation.Arguments); + callContextDictionary.Add("target", invocation.Target); + int numAttempts = 0; + + object returnVal = null; + do + { + try + { + returnVal = invocation.Proceed(); + break; + } + catch (Exception ex) + { + callContextDictionary["e"] = ex; + if (retryExceptionHandler.CanHandleException(ex, callContextDictionary)) + { + numAttempts++; + if (numAttempts == retryExceptionHandler.MaximumRetryCount) + { + throw; + } + else + { + if (log.IsTraceEnabled) + { + log.Trace("Retrying " + invocation.Method.Name); + } + callContextDictionary["n"] = numAttempts; + Sleep(retryExceptionHandler, callContextDictionary); + } + } + else + { + throw; + } + } + } while (numAttempts <= retryExceptionHandler.MaximumRetryCount); + + + log.Debug("Invoked successfully after " + numAttempts + " attempt(s)"); + return returnVal; + } + + private static void Sleep(RetryExceptionHandler handler, IDictionary callContextDictionary) + { + if (handler.IsDelayBased) + { + Thread.Sleep(handler.DelayTimeSpan); + } + else + { + try + { + IExpression expression = Expression.Parse(handler.DelayRateExpression); + object result = expression.GetValue(null, callContextDictionary); + decimal d = decimal.Parse(result.ToString()); + decimal rounded = decimal.Round(d*1000,0); + int sleepInSeconds = decimal.ToInt32(rounded); + Thread.Sleep(sleepInSeconds); + } + catch (InvalidCastException e) + { + log.Warn("Was not able to cast expression to decimal [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); + Thread.Sleep(1000); + } + catch (Exception e) + { + log.Warn("Was not able to evaluate rate expression [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); + Thread.Sleep(1000); + } + } + } + + #endregion + + #region IInitializingObject implementation + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public override void AfterPropertiesSet() + { + if (retryExpression == null) + { + throw new ArgumentException("Must specify retry expression."); + } + RetryExceptionHandler handler = Parse(retryExpression); + if (handler == null) + { + throw new ArgumentException("Was not able to parse retry expression string [" + retryExpression + "]"); + } + retryExceptionHandler = handler; + } + + #endregion + + /// + /// Parses the specified handler string. + /// + /// The handler string. + /// + protected virtual RetryExceptionHandler Parse(string retryExpressionString) + { + + ParsedAdviceExpression parsedAdviceExpression = ParseAdviceExpression(retryExpressionString); + + if (!parsedAdviceExpression.Success) + { + log.Warn("Could not parse retry expression " + retryExpressionString); + return null; + } + + RetryExceptionHandler handler = new RetryExceptionHandler(parsedAdviceExpression.ExceptionNames); + handler.ConstraintExpressionText = parsedAdviceExpression.ConstraintExpression; + handler.ActionExpressionText = parsedAdviceExpression.AdviceExpression; + + Match match = GetMatchForActionExpression(parsedAdviceExpression.ActionExpressionText, delayRegex); + + if (match.Success) + { + handler.MaximumRetryCount = int.Parse(match.Groups[1].Value.Trim()); + handler.IsDelayBased = true; + + try + { + string ts = match.Groups[3].Value.Trim(); + handler.DelayTimeSpan = (TimeSpan) timeSpanConverter.ConvertFrom(null, null, ts); + } catch (Exception) + { + log.Warn("Could not parse timespan " + match.Groups[3].Value.Trim()); + return null; + } + return handler; + } + else + { + match = GetMatchForActionExpression(parsedAdviceExpression.ActionExpressionText, rateRegex); + if (match.Success) + { + handler.MaximumRetryCount = int.Parse(match.Groups[1].Value.Trim()); + handler.IsDelayBased = false; + handler.DelayRateExpression = match.Groups[3].Value.Trim(); + return handler; + } + else + { + return null; + } + } + + } + + /// + /// Gets the match for action expression. + /// + /// The action expression string. + /// The regex string. + /// The Match object resulting from the regular expression match. + protected virtual Match GetMatchForActionExpression(string actionExpressionString, string regexString) + { + RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase); + Regex reg = new Regex(regexString, options); + return reg.Match(actionExpressionString); + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/RetryExceptionHandler.cs b/src/Spring/Spring.Aop/Aspects/RetryExceptionHandler.cs index 660fbc50..3e7c11e0 100644 --- a/src/Spring/Spring.Aop/Aspects/RetryExceptionHandler.cs +++ b/src/Spring/Spring.Aop/Aspects/RetryExceptionHandler.cs @@ -1,130 +1,129 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -namespace Spring.Aspects -{ - /// - /// Sleeps for the appropriate amount of time for an exception. - /// - /// - /// - /// - /// Mark Pollack - /// $Id: RetryExceptionHandler.cs,v 1.1 2007/10/10 07:38:17 markpollack Exp $ - public class RetryExceptionHandler : AbstractExceptionHandler - { - #region Fields - - private int maximumRetryCount; - - private bool isDelayBased; - - private TimeSpan delayTimeSpan; - private string delayRateExpression; - - #endregion - - #region Constructor - - /// - /// Initializes a new instance of the class. - /// - public RetryExceptionHandler() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The exception names. - public RetryExceptionHandler(string[] exceptionNames) : base(exceptionNames) - { - } - - #endregion - - #region Properties - - /// - /// Gets the maximum retry count. - /// - /// The maximum retry count. - public int MaximumRetryCount - { - get { return maximumRetryCount; } - set { maximumRetryCount = value; } - } - - - /// - /// Gets a value indicating whether this instance is delay based. - /// - /// - /// true if this instance is delay based; otherwise, false. - /// - public bool IsDelayBased - { - get { return isDelayBased; } - set { isDelayBased = value; } - } - - /// - /// Gets or sets the delay time span to sleep after an exception is thrown and a rety is - /// attempted. - /// - /// The delay time span. - public TimeSpan DelayTimeSpan - { - get { return delayTimeSpan; } - set { delayTimeSpan = value; } - } - - /// - /// Gets or sets the delay rate expression. - /// - /// The delay rate expression. - public string DelayRateExpression - { - get { return delayRateExpression; } - set { delayRateExpression = value; } - } - - #endregion - - #region Methods - - /// - /// Handles the exception. - /// - /// - /// - /// The return value from handling the exception, if not rethrown or a new exception is thrown. - /// - public override object HandleException(IDictionary callContextDictionary) - { - return null; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +namespace Spring.Aspects +{ + /// + /// Sleeps for the appropriate amount of time for an exception. + /// + /// + /// + /// + /// Mark Pollack + public class RetryExceptionHandler : AbstractExceptionHandler + { + #region Fields + + private int maximumRetryCount; + + private bool isDelayBased; + + private TimeSpan delayTimeSpan; + private string delayRateExpression; + + #endregion + + #region Constructor + + /// + /// Initializes a new instance of the class. + /// + public RetryExceptionHandler() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The exception names. + public RetryExceptionHandler(string[] exceptionNames) : base(exceptionNames) + { + } + + #endregion + + #region Properties + + /// + /// Gets the maximum retry count. + /// + /// The maximum retry count. + public int MaximumRetryCount + { + get { return maximumRetryCount; } + set { maximumRetryCount = value; } + } + + + /// + /// Gets a value indicating whether this instance is delay based. + /// + /// + /// true if this instance is delay based; otherwise, false. + /// + public bool IsDelayBased + { + get { return isDelayBased; } + set { isDelayBased = value; } + } + + /// + /// Gets or sets the delay time span to sleep after an exception is thrown and a rety is + /// attempted. + /// + /// The delay time span. + public TimeSpan DelayTimeSpan + { + get { return delayTimeSpan; } + set { delayTimeSpan = value; } + } + + /// + /// Gets or sets the delay rate expression. + /// + /// The delay rate expression. + public string DelayRateExpression + { + get { return delayRateExpression; } + set { delayRateExpression = value; } + } + + #endregion + + #region Methods + + /// + /// Handles the exception. + /// + /// + /// + /// The return value from handling the exception, if not rethrown or a new exception is thrown. + /// + public override object HandleException(IDictionary callContextDictionary) + { + return null; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvice.cs b/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvice.cs index c1ea994a..157cbcd4 100644 --- a/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvice.cs @@ -1,76 +1,75 @@ -using System.Reflection; -using Spring.Aop; -using Spring.Context; -using Spring.Validation; - -namespace Spring.Aspects.Validation -{ - /// - /// This advice is typically applied to service-layer methods in order to validate - /// method arguments. - /// - /// - /// Each argument that should be validated has to be marked with one or more - /// s. - /// If the validation fails, this advice will throw , - /// thus preventing target method invocation. - /// - /// - /// Damjan Tomic - /// Aleksandar Seovic - /// $Id: ParameterValidationAdvice.cs,v 1.2 2008/04/02 23:00:28 markpollack Exp $ - public class ParameterValidationAdvice : IMethodBeforeAdvice, IApplicationContextAware - { - private IApplicationContext applicationContext; - - /// - /// Intercepts method invocation and validates arguments. - /// - /// - /// Method invocation. - /// - /// - /// Method arguments. - /// - /// - /// Target object. - /// - /// - /// If one or more method arguments fail validation. - /// - public void Before(MethodInfo method, object[] args, object target) - { - ValidationErrors errors = new ValidationErrors(); - ParameterInfo[] parameters = method.GetParameters(); - - for (int i = 0; i < parameters.Length; i++) - { - ParameterInfo info = parameters[i]; - ValidatedAttribute[] attributes = (ValidatedAttribute[]) info.GetCustomAttributes(typeof(ValidatedAttribute), true); - - foreach (ValidatedAttribute attribute in attributes) - { - // throws NoSuchObjectDefinitionException if validator cannot be found - IValidator validator = (IValidator) applicationContext.GetObject(attribute.ValidatorName); - validator.Validate(args[i], errors); - } - } - if (!errors.IsEmpty) - { - throw new ValidationException(errors); - } - } - - /// - /// Gets or sets the application context to search for validators in. - /// - /// - /// The application context to search for validators in. - /// - public IApplicationContext ApplicationContext - { - get { return this.applicationContext; } - set { this.applicationContext = value; } - } - } +using System.Reflection; +using Spring.Aop; +using Spring.Context; +using Spring.Validation; + +namespace Spring.Aspects.Validation +{ + /// + /// This advice is typically applied to service-layer methods in order to validate + /// method arguments. + /// + /// + /// Each argument that should be validated has to be marked with one or more + /// s. + /// If the validation fails, this advice will throw , + /// thus preventing target method invocation. + /// + /// + /// Damjan Tomic + /// Aleksandar Seovic + public class ParameterValidationAdvice : IMethodBeforeAdvice, IApplicationContextAware + { + private IApplicationContext applicationContext; + + /// + /// Intercepts method invocation and validates arguments. + /// + /// + /// Method invocation. + /// + /// + /// Method arguments. + /// + /// + /// Target object. + /// + /// + /// If one or more method arguments fail validation. + /// + public void Before(MethodInfo method, object[] args, object target) + { + ValidationErrors errors = new ValidationErrors(); + ParameterInfo[] parameters = method.GetParameters(); + + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo info = parameters[i]; + ValidatedAttribute[] attributes = (ValidatedAttribute[]) info.GetCustomAttributes(typeof(ValidatedAttribute), true); + + foreach (ValidatedAttribute attribute in attributes) + { + // throws NoSuchObjectDefinitionException if validator cannot be found + IValidator validator = (IValidator) applicationContext.GetObject(attribute.ValidatorName); + validator.Validate(args[i], errors); + } + } + if (!errors.IsEmpty) + { + throw new ValidationException(errors); + } + } + + /// + /// Gets or sets the application context to search for validators in. + /// + /// + /// The application context to search for validators in. + /// + public IApplicationContext ApplicationContext + { + get { return this.applicationContext; } + set { this.applicationContext = value; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvisor.cs b/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvisor.cs index ad3a83ac..b52e2040 100644 --- a/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvisor.cs +++ b/src/Spring/Spring.Aop/Aspects/Validation/ParameterValidationAdvisor.cs @@ -1,114 +1,113 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -using Spring.Aop.Support; -using Spring.Validation; -using Spring.Context; - -#endregion - -namespace Spring.Aspects.Validation -{ - /// - /// Convinience advisor implementation that applies - /// to all the methods that have defined on one or - /// more of their parameters. - /// - /// Bruno Baia - /// $Id: ParameterValidationAdvisor.cs,v 1.1 2008/05/26 09:17:50 bbaia Exp $ - public class ParameterValidationAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware - { - /// - /// Creates new advisor instance. - /// - public ParameterValidationAdvisor() - { - Advice = new ParameterValidationAdvice(); - Attribute = typeof(ValidatedAttribute); - Inherit = false; - } - - /// - /// Set the that this - /// object runs in. - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - public IApplicationContext ApplicationContext - { - get { return ((IApplicationContextAware)Advice).ApplicationContext; } - set { ((IApplicationContextAware)Advice).ApplicationContext = value; } - } - - /// - /// Returns true if any of the parameters of the specified - /// has applied. - /// - /// - /// Method to check. - /// - /// - /// Type of target object. - /// - /// - /// true if any of the parameters of the specified - /// has applied; false otherwise. - /// - public override bool Matches(MethodInfo method, Type targetType) - { - ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - ParameterInfo p = parameters[i]; - if (p.IsDefined(Attribute, Inherit)) - { - return true; - } - } - - return false; - } - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +using Spring.Aop.Support; +using Spring.Validation; +using Spring.Context; + +#endregion + +namespace Spring.Aspects.Validation +{ + /// + /// Convinience advisor implementation that applies + /// to all the methods that have defined on one or + /// more of their parameters. + /// + /// Bruno Baia + public class ParameterValidationAdvisor : AttributeMatchMethodPointcutAdvisor, IApplicationContextAware + { + /// + /// Creates new advisor instance. + /// + public ParameterValidationAdvisor() + { + Advice = new ParameterValidationAdvice(); + Attribute = typeof(ValidatedAttribute); + Inherit = false; + } + + /// + /// Set the that this + /// object runs in. + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + public IApplicationContext ApplicationContext + { + get { return ((IApplicationContextAware)Advice).ApplicationContext; } + set { ((IApplicationContextAware)Advice).ApplicationContext = value; } + } + + /// + /// Returns true if any of the parameters of the specified + /// has applied. + /// + /// + /// Method to check. + /// + /// + /// Type of target object. + /// + /// + /// true if any of the parameters of the specified + /// has applied; false otherwise. + /// + public override bool Matches(MethodInfo method, Type targetType) + { + ParameterInfo[] parameters = method.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo p = parameters[i]; + if (p.IsDefined(Attribute, Inherit)) + { + return true; + } + } + + return false; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/AssemblyInfo.cs b/src/Spring/Spring.Core/AssemblyInfo.cs index d6adf3f5..77d379c0 100644 --- a/src/Spring/Spring.Core/AssemblyInfo.cs +++ b/src/Spring/Spring.Core/AssemblyInfo.cs @@ -1,34 +1,34 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Reflection; -using System.Runtime.InteropServices; -using System.Security.Permissions; -[assembly: ComVisible(false)] -[assembly: AssemblyTitle("Spring.Net Core functionality")] -[assembly: AssemblyDescription("Core functionality for Spring.Net IoC container")] - -// -// Security Permissions -// -// we need full, unrestricted access to reflection metadata... -[assembly: ReflectionPermission(SecurityAction.RequestMinimum, Unrestricted=true)] -//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")] +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Permissions; +[assembly: ComVisible(false)] +[assembly: AssemblyTitle("Spring.Net Core functionality")] +[assembly: AssemblyDescription("Core functionality for Spring.Net IoC container")] + +// +// Security Permissions +// +// we need full, unrestricted access to reflection metadata... +[assembly: ReflectionPermission(SecurityAction.RequestMinimum, Unrestricted=true)] +//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")] //[assembly: AssemblyKeyFile(@"C:\projects\Spring.Net\Spring.Net.snk")] \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/AbstractCache.cs b/src/Spring/Spring.Core/Caching/AbstractCache.cs index 94c5c746..39cd995b 100644 --- a/src/Spring/Spring.Core/Caching/AbstractCache.cs +++ b/src/Spring/Spring.Core/Caching/AbstractCache.cs @@ -1,202 +1,201 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -namespace Spring.Caching -{ - /// - /// An abstract implementation that can - /// be used as base class for concrete implementations. - /// - /// Aleksandar Seovic - /// Erich Eichinger - /// $Id: AbstractCache.cs,v 1.7 2007/10/11 01:29:49 markpollack Exp $ - public abstract class AbstractCache : ICache - { - #region Fields - - private bool _enforceTimeToLive = false; - private TimeSpan _timeToLive = TimeSpan.Zero; - - #endregion - - #region Properties - - /// - /// Gets/Set the Default time-to-live (TTL) for items inserted into this cache. - /// Used by - /// - public TimeSpan TimeToLive - { - get { return _timeToLive; } - set { _timeToLive = value; } - } - - /// - /// Gets/Sets a value, whether the this cache instance's - /// shall be applied to all items, regardless of their individual TTL - /// when is called. - /// - public bool EnforceTimeToLive - { - get { return _enforceTimeToLive; } - set { _enforceTimeToLive = value; } - } - - #endregion - - #region ICache Implementation - - #region - - /// - /// Gets the number of items in the cache. - /// - /// - /// May be overridden by subclasses for cache-specific efficient implementation. - /// - public virtual int Count - { - get - { - return Keys.Count; - } - } - - /// - /// Gets a collection of all cache item keys. - /// - public abstract ICollection Keys { get; } - - - - /// - /// Retrieves an item from the cache. - /// - /// - /// Item key. - /// - /// - /// Item for the specified , or null. - /// - public abstract object Get(object key); - - /// - /// Removes an item from the cache. - /// - /// - /// Item key. - /// - public abstract void Remove(object key); - - /// - /// Removes collection of items from the cache. - /// - /// - /// Collection of keys to remove. - /// - public virtual void RemoveAll(ICollection keys) - { - foreach (object key in keys) - { - Remove(key); - } - } - - /// - /// Removes all items from the cache. - /// - public virtual void Clear() - { - RemoveAll(this.Keys); - } - - - /// - /// Inserts an item into the cache. - /// - /// - /// Items inserted using this method use the default - /// - /// - /// Item key. - /// - /// - /// Item value. - /// - public virtual void Insert(object key, object value) - { - Insert(key, value, TimeToLive); - } - - /// - /// Inserts an item into the cache. - /// - /// - /// If equals , - /// or is true, this cache - /// instance's value will be applied. - /// - /// - /// Item key. - /// - /// - /// Item value. - /// - /// - /// Item's time-to-live (TTL). - /// - public virtual void Insert(object key, object value, TimeSpan timeToLive) - { - if (_enforceTimeToLive || (timeToLive < TimeSpan.Zero)) - { - timeToLive = _timeToLive; - } - DoInsert(key, value, timeToLive); - } - - #endregion - - #endregion - - #region Methods - - /// - /// Actually does the cache implementation specific insert operation into the cache. - /// - /// - /// Items inserted using this method have default cache priority. - /// - /// - /// Item key. - /// - /// - /// Item value. - /// - /// - /// Item's time-to-live (TTL). - /// - protected abstract void DoInsert(object key, object value, TimeSpan timeToLive); - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +namespace Spring.Caching +{ + /// + /// An abstract implementation that can + /// be used as base class for concrete implementations. + /// + /// Aleksandar Seovic + /// Erich Eichinger + public abstract class AbstractCache : ICache + { + #region Fields + + private bool _enforceTimeToLive = false; + private TimeSpan _timeToLive = TimeSpan.Zero; + + #endregion + + #region Properties + + /// + /// Gets/Set the Default time-to-live (TTL) for items inserted into this cache. + /// Used by + /// + public TimeSpan TimeToLive + { + get { return _timeToLive; } + set { _timeToLive = value; } + } + + /// + /// Gets/Sets a value, whether the this cache instance's + /// shall be applied to all items, regardless of their individual TTL + /// when is called. + /// + public bool EnforceTimeToLive + { + get { return _enforceTimeToLive; } + set { _enforceTimeToLive = value; } + } + + #endregion + + #region ICache Implementation + + #region + + /// + /// Gets the number of items in the cache. + /// + /// + /// May be overridden by subclasses for cache-specific efficient implementation. + /// + public virtual int Count + { + get + { + return Keys.Count; + } + } + + /// + /// Gets a collection of all cache item keys. + /// + public abstract ICollection Keys { get; } + + + + /// + /// Retrieves an item from the cache. + /// + /// + /// Item key. + /// + /// + /// Item for the specified , or null. + /// + public abstract object Get(object key); + + /// + /// Removes an item from the cache. + /// + /// + /// Item key. + /// + public abstract void Remove(object key); + + /// + /// Removes collection of items from the cache. + /// + /// + /// Collection of keys to remove. + /// + public virtual void RemoveAll(ICollection keys) + { + foreach (object key in keys) + { + Remove(key); + } + } + + /// + /// Removes all items from the cache. + /// + public virtual void Clear() + { + RemoveAll(this.Keys); + } + + + /// + /// Inserts an item into the cache. + /// + /// + /// Items inserted using this method use the default + /// + /// + /// Item key. + /// + /// + /// Item value. + /// + public virtual void Insert(object key, object value) + { + Insert(key, value, TimeToLive); + } + + /// + /// Inserts an item into the cache. + /// + /// + /// If equals , + /// or is true, this cache + /// instance's value will be applied. + /// + /// + /// Item key. + /// + /// + /// Item value. + /// + /// + /// Item's time-to-live (TTL). + /// + public virtual void Insert(object key, object value, TimeSpan timeToLive) + { + if (_enforceTimeToLive || (timeToLive < TimeSpan.Zero)) + { + timeToLive = _timeToLive; + } + DoInsert(key, value, timeToLive); + } + + #endregion + + #endregion + + #region Methods + + /// + /// Actually does the cache implementation specific insert operation into the cache. + /// + /// + /// Items inserted using this method have default cache priority. + /// + /// + /// Item key. + /// + /// + /// Item value. + /// + /// + /// Item's time-to-live (TTL). + /// + protected abstract void DoInsert(object key, object value, TimeSpan timeToLive); + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs b/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs index c88378e8..09e2f76d 100644 --- a/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs +++ b/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs @@ -1,176 +1,175 @@ -using System; -using Spring.Core.TypeConversion; -using Spring.Expressions; - -namespace Spring.Caching -{ - /// - /// Abstract base class containing shared properties for all cache attributes. - /// - /// Aleksandar Seovic - /// $Id: BaseCacheAttribute.cs,v 1.5 2007/08/29 17:29:10 oakinger Exp $ - [Serializable] - public abstract class BaseCacheAttribute : Attribute - { - #region Fields - - /// - /// The instance used to parse values. - /// - /// - /// - protected static readonly TimeSpanConverter TimeSpanConverter = new TimeSpanConverter(); - - private string cacheName; - private string key; - private IExpression keyExpression; - private string condition; - private IExpression conditionExpression; - private string timeToLive = null; - private TimeSpan timeToLiveTimeSpan = TimeSpan.MinValue; - - #endregion - - #region Constructors - - /// - /// Creates an attribute instance. - /// - public BaseCacheAttribute() - { - } - - /// - /// Creates an attribute instance. - /// - /// - /// The name of the cache to use. - /// - /// - /// An expression string that should be evaluated in order to determine - /// the cache key for the item. - /// - public BaseCacheAttribute(string cacheName, string key) - { - this.CacheName = cacheName; - this.Key = key; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the name of the cache to use. - /// - /// - /// The name of the cache to use. - /// - public string CacheName - { - get { return cacheName; } - set { cacheName = value; } - } - - /// - /// Gets or sets a SpEL expression that should be evaluated in order - /// to determine the cache key for the item. - /// - /// - /// An expression string that should be evaluated in order to determine - /// the cache key for the item. - /// - public string Key - { - get { return key; } - set - { - key = value; - keyExpression = Expression.Parse(value); - } - } - - /// - /// Gets an expression instance that should be evaluated in order - /// to determine the cache key for the item. - /// - /// - /// An expression instance that should be evaluated in order to determine - /// the cache key for the item. - /// - public IExpression KeyExpression - { - get { return keyExpression; } - } - - /// - /// Gets or sets a SpEL expression that should be evaluated in order - /// to determine whether the item should be cached. - /// - /// - /// An expression string that should be evaluated in order to determine - /// whether the item should be cached. - /// - public string Condition - { - get { return condition; } - set - { - condition = value; - conditionExpression = Expression.Parse(value); - } - } - - /// - /// Gets an expression instance that should be evaluated in order - /// to determine whether the item should be cached. - /// - /// - /// An expression instance that should be evaluated in order to determine - /// whether the item should be cached. - /// - public IExpression ConditionExpression - { - get { return conditionExpression; } - } - - /// - /// The amount of time an object should remain in the cache. - /// - /// - /// If no TTL is specified, the default TTL defined by the - /// cache's policy will be applied. - /// - /// - /// The amount of time object should remain in the cache - /// formatted to be recognizable by . - /// - public string TimeToLive - { - get { return timeToLive; } - set - { - timeToLive = value; - timeToLiveTimeSpan = (timeToLive == null) ? TimeSpan.MinValue : (TimeSpan)TimeSpanConverter.ConvertFrom(timeToLive); - } - } - - - /// - /// The amount of time an object should remain in the cache (in seconds). - /// - /// - /// If no TTL is specified, the default TTL defined by the - /// cache's policy will be applied. - /// - /// - /// The amount of time object should remain in the cache (in seconds). - /// - public TimeSpan TimeToLiveTimeSpan - { - get { return timeToLiveTimeSpan; } - } - - #endregion - } +using System; +using Spring.Core.TypeConversion; +using Spring.Expressions; + +namespace Spring.Caching +{ + /// + /// Abstract base class containing shared properties for all cache attributes. + /// + /// Aleksandar Seovic + [Serializable] + public abstract class BaseCacheAttribute : Attribute + { + #region Fields + + /// + /// The instance used to parse values. + /// + /// + /// + protected static readonly TimeSpanConverter TimeSpanConverter = new TimeSpanConverter(); + + private string cacheName; + private string key; + private IExpression keyExpression; + private string condition; + private IExpression conditionExpression; + private string timeToLive = null; + private TimeSpan timeToLiveTimeSpan = TimeSpan.MinValue; + + #endregion + + #region Constructors + + /// + /// Creates an attribute instance. + /// + public BaseCacheAttribute() + { + } + + /// + /// Creates an attribute instance. + /// + /// + /// The name of the cache to use. + /// + /// + /// An expression string that should be evaluated in order to determine + /// the cache key for the item. + /// + public BaseCacheAttribute(string cacheName, string key) + { + this.CacheName = cacheName; + this.Key = key; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the name of the cache to use. + /// + /// + /// The name of the cache to use. + /// + public string CacheName + { + get { return cacheName; } + set { cacheName = value; } + } + + /// + /// Gets or sets a SpEL expression that should be evaluated in order + /// to determine the cache key for the item. + /// + /// + /// An expression string that should be evaluated in order to determine + /// the cache key for the item. + /// + public string Key + { + get { return key; } + set + { + key = value; + keyExpression = Expression.Parse(value); + } + } + + /// + /// Gets an expression instance that should be evaluated in order + /// to determine the cache key for the item. + /// + /// + /// An expression instance that should be evaluated in order to determine + /// the cache key for the item. + /// + public IExpression KeyExpression + { + get { return keyExpression; } + } + + /// + /// Gets or sets a SpEL expression that should be evaluated in order + /// to determine whether the item should be cached. + /// + /// + /// An expression string that should be evaluated in order to determine + /// whether the item should be cached. + /// + public string Condition + { + get { return condition; } + set + { + condition = value; + conditionExpression = Expression.Parse(value); + } + } + + /// + /// Gets an expression instance that should be evaluated in order + /// to determine whether the item should be cached. + /// + /// + /// An expression instance that should be evaluated in order to determine + /// whether the item should be cached. + /// + public IExpression ConditionExpression + { + get { return conditionExpression; } + } + + /// + /// The amount of time an object should remain in the cache. + /// + /// + /// If no TTL is specified, the default TTL defined by the + /// cache's policy will be applied. + /// + /// + /// The amount of time object should remain in the cache + /// formatted to be recognizable by . + /// + public string TimeToLive + { + get { return timeToLive; } + set + { + timeToLive = value; + timeToLiveTimeSpan = (timeToLive == null) ? TimeSpan.MinValue : (TimeSpan)TimeSpanConverter.ConvertFrom(timeToLive); + } + } + + + /// + /// The amount of time an object should remain in the cache (in seconds). + /// + /// + /// If no TTL is specified, the default TTL defined by the + /// cache's policy will be applied. + /// + /// + /// The amount of time object should remain in the cache (in seconds). + /// + public TimeSpan TimeToLiveTimeSpan + { + get { return timeToLiveTimeSpan; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/CacheParameterAttribute.cs b/src/Spring/Spring.Core/Caching/CacheParameterAttribute.cs index 63d0a728..8f02c1bb 100644 --- a/src/Spring/Spring.Core/Caching/CacheParameterAttribute.cs +++ b/src/Spring/Spring.Core/Caching/CacheParameterAttribute.cs @@ -1,72 +1,71 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Caching -{ - /// - /// This attribute should be used to mark methods whose argument(s) - /// need to be cached. - /// - /// - ///

- /// This attribute allows application developers to specify that an argument - /// of the method should be cached, but it will not do any caching by itself. - ///

- ///

- /// In order to actually cache the result, an application developer - /// must apply a Spring.Aspects.Cache.CacheParameterAdvice to - /// all of the members that have this attribute defined. - ///

- ///

- /// You can specify this attribute multiple times on the same method in order to - /// cache several method parameters. - ///

- ///
- /// Aleksandar Seovic - /// $Id: CacheParameterAttribute.cs,v 1.2 2007/03/31 01:07:26 bbaia Exp $ - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = false)] - [Serializable] - public sealed class CacheParameterAttribute : BaseCacheAttribute - { - /// - /// Creates an attribute instance. - /// - public CacheParameterAttribute() - { - } - - /// - /// Creates an attribute instance. - /// - /// - /// The name of the cache to use. - /// - /// - /// An expression string that should be evaluated in order to determine - /// the cache key for the item. - /// - public CacheParameterAttribute(string cacheName, string key) - : base(cacheName, key) - { - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Caching +{ + /// + /// This attribute should be used to mark methods whose argument(s) + /// need to be cached. + /// + /// + ///

+ /// This attribute allows application developers to specify that an argument + /// of the method should be cached, but it will not do any caching by itself. + ///

+ ///

+ /// In order to actually cache the result, an application developer + /// must apply a Spring.Aspects.Cache.CacheParameterAdvice to + /// all of the members that have this attribute defined. + ///

+ ///

+ /// You can specify this attribute multiple times on the same method in order to + /// cache several method parameters. + ///

+ ///
+ /// Aleksandar Seovic + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = false)] + [Serializable] + public sealed class CacheParameterAttribute : BaseCacheAttribute + { + /// + /// Creates an attribute instance. + /// + public CacheParameterAttribute() + { + } + + /// + /// Creates an attribute instance. + /// + /// + /// The name of the cache to use. + /// + /// + /// An expression string that should be evaluated in order to determine + /// the cache key for the item. + /// + public CacheParameterAttribute(string cacheName, string key) + : base(cacheName, key) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/CacheResultAttribute.cs b/src/Spring/Spring.Core/Caching/CacheResultAttribute.cs index bee2ef45..b575fd79 100644 --- a/src/Spring/Spring.Core/Caching/CacheResultAttribute.cs +++ b/src/Spring/Spring.Core/Caching/CacheResultAttribute.cs @@ -1,69 +1,68 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Caching -{ - /// - /// This attribute should be used to mark methods whose result - /// needs to be cached. - /// - /// - ///

- /// This attribute allows application developers to mark that a result - /// of the method invocation should be cached, but it will not do any - /// caching by itself. - ///

- ///

- /// In order to actually cache the result, an application developer - /// must apply a Spring.Aspects.Cache.CacheResultAdvice to - /// all of the members that have this attribute defined. - ///

- ///
- /// Aleksandar Seovic - /// $Id: CacheResultAttribute.cs,v 1.1 2007/02/09 07:12:23 aseovic Exp $ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] - [Serializable] - public sealed class CacheResultAttribute : BaseCacheAttribute - { - /// - /// Creates an attribute instance. - /// - public CacheResultAttribute() - { - } - - /// - /// Creates an attribute instance. - /// - /// - /// The name of the cache to use. - /// - /// - /// An expression string that should be evaluated in order to determine - /// the cache key for the item. - /// - public CacheResultAttribute(string cacheName, string key) - : base(cacheName, key) - { - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Caching +{ + /// + /// This attribute should be used to mark methods whose result + /// needs to be cached. + /// + /// + ///

+ /// This attribute allows application developers to mark that a result + /// of the method invocation should be cached, but it will not do any + /// caching by itself. + ///

+ ///

+ /// In order to actually cache the result, an application developer + /// must apply a Spring.Aspects.Cache.CacheResultAdvice to + /// all of the members that have this attribute defined. + ///

+ ///
+ /// Aleksandar Seovic + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + [Serializable] + public sealed class CacheResultAttribute : BaseCacheAttribute + { + /// + /// Creates an attribute instance. + /// + public CacheResultAttribute() + { + } + + /// + /// Creates an attribute instance. + /// + /// + /// The name of the cache to use. + /// + /// + /// An expression string that should be evaluated in order to determine + /// the cache key for the item. + /// + public CacheResultAttribute(string cacheName, string key) + : base(cacheName, key) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/CacheResultItemsAttribute.cs b/src/Spring/Spring.Core/Caching/CacheResultItemsAttribute.cs index 91824086..7c46add3 100644 --- a/src/Spring/Spring.Core/Caching/CacheResultItemsAttribute.cs +++ b/src/Spring/Spring.Core/Caching/CacheResultItemsAttribute.cs @@ -1,70 +1,69 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -namespace Spring.Caching -{ - /// - /// This attribute should be used with methods that return an - /// in order to cache each item separately. - /// - /// - ///

- /// This attribute allows application developers to specify that each item - /// from the collection returned by the method should be cached, - /// but it will not do any caching by itself. - ///

- ///

- /// In order to actually cache the result, an application developer - /// must apply a Spring.Aspects.Cache.CacheResultAdvice to - /// all of the members that have this attribute defined. - ///

- ///
- /// Aleksandar Seovic - /// $Id: CacheResultItemsAttribute.cs,v 1.2 2007/03/31 02:59:48 bbaia Exp $ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] - [Serializable] - public sealed class CacheResultItemsAttribute : BaseCacheAttribute - { - /// - /// Creates an attribute instance. - /// - public CacheResultItemsAttribute() - { - } - - /// - /// Creates an attribute instance. - /// - /// - /// The name of the cache to use. - /// - /// - /// An expression string that should be evaluated in order to determine - /// the cache key for the item. - /// - public CacheResultItemsAttribute(string cacheName, string key) - : base(cacheName, key) - { - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +namespace Spring.Caching +{ + /// + /// This attribute should be used with methods that return an + /// in order to cache each item separately. + /// + /// + ///

+ /// This attribute allows application developers to specify that each item + /// from the collection returned by the method should be cached, + /// but it will not do any caching by itself. + ///

+ ///

+ /// In order to actually cache the result, an application developer + /// must apply a Spring.Aspects.Cache.CacheResultAdvice to + /// all of the members that have this attribute defined. + ///

+ ///
+ /// Aleksandar Seovic + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + [Serializable] + public sealed class CacheResultItemsAttribute : BaseCacheAttribute + { + /// + /// Creates an attribute instance. + /// + public CacheResultItemsAttribute() + { + } + + /// + /// Creates an attribute instance. + /// + /// + /// The name of the cache to use. + /// + /// + /// An expression string that should be evaluated in order to determine + /// the cache key for the item. + /// + public CacheResultItemsAttribute(string cacheName, string key) + : base(cacheName, key) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/ICache.cs b/src/Spring/Spring.Core/Caching/ICache.cs index 86511f4b..ee18ce62 100644 --- a/src/Spring/Spring.Core/Caching/ICache.cs +++ b/src/Spring/Spring.Core/Caching/ICache.cs @@ -1,108 +1,107 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -namespace Spring.Caching -{ - /// - /// Defines a contract that all cache implementations have to fulfill. - /// - /// Aleksandar Seovic - /// Erich Eichinger - /// $Id: ICache.cs,v 1.5 2007/08/27 09:38:11 oakinger Exp $ - public interface ICache - { - /// - /// Gets the number of items in the cache. - /// - int Count { get; } - - /// - /// Gets a collection of all cache item keys. - /// - ICollection Keys { get; } - - /// - /// Retrieves an item from the cache. - /// - /// - /// Item key. - /// - /// - /// Item for the specified , or null. - /// - object Get(object key); - - /// - /// Removes an item from the cache. - /// - /// - /// Item key. - /// - void Remove(object key); - - /// - /// Removes collection of items from the cache. - /// - /// - /// Collection of keys to remove. - /// - void RemoveAll(ICollection keys); - - /// - /// Removes all items from the cache. - /// - void Clear(); - - /// - /// Inserts an item into the cache. - /// - /// - /// Items inserted using this method have no expiration time - /// and default cache priority. - /// - /// - /// Item key. - /// - /// - /// Item value. - /// - void Insert(object key, object value); - - /// - /// Inserts an item into the cache. - /// - /// - /// Items inserted using this method have default cache priority. - /// - /// - /// Item key. - /// - /// - /// Item value. - /// - /// - /// Item's time-to-live. - /// - void Insert(object key, object value, TimeSpan timeToLive); - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +namespace Spring.Caching +{ + /// + /// Defines a contract that all cache implementations have to fulfill. + /// + /// Aleksandar Seovic + /// Erich Eichinger + public interface ICache + { + /// + /// Gets the number of items in the cache. + /// + int Count { get; } + + /// + /// Gets a collection of all cache item keys. + /// + ICollection Keys { get; } + + /// + /// Retrieves an item from the cache. + /// + /// + /// Item key. + /// + /// + /// Item for the specified , or null. + /// + object Get(object key); + + /// + /// Removes an item from the cache. + /// + /// + /// Item key. + /// + void Remove(object key); + + /// + /// Removes collection of items from the cache. + /// + /// + /// Collection of keys to remove. + /// + void RemoveAll(ICollection keys); + + /// + /// Removes all items from the cache. + /// + void Clear(); + + /// + /// Inserts an item into the cache. + /// + /// + /// Items inserted using this method have no expiration time + /// and default cache priority. + /// + /// + /// Item key. + /// + /// + /// Item value. + /// + void Insert(object key, object value); + + /// + /// Inserts an item into the cache. + /// + /// + /// Items inserted using this method have default cache priority. + /// + /// + /// Item key. + /// + /// + /// Item value. + /// + /// + /// Item's time-to-live. + /// + void Insert(object key, object value, TimeSpan timeToLive); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/InvalidateCacheAttribute.cs b/src/Spring/Spring.Core/Caching/InvalidateCacheAttribute.cs index b16283d2..4a1bb535 100644 --- a/src/Spring/Spring.Core/Caching/InvalidateCacheAttribute.cs +++ b/src/Spring/Spring.Core/Caching/InvalidateCacheAttribute.cs @@ -1,146 +1,145 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Expressions; - -namespace Spring.Caching -{ - /// - /// This attribute should be used to mark method that should - /// invalidate one or more cache items when invoked. - /// - /// - ///

- /// This attribute allows application developers to specify that some - /// cache items should be evicted from cache when the method is invoked, - /// but it will not do any eviction by itself. - ///

- ///

- /// In order to actually evict cache items, an application developer - /// must apply a Spring.Aspects.Cache.InvalidateCacheAdvice to - /// all of the members that have this attribute defined. - ///

- ///
- /// Aleksandar Seovic - /// $Id: InvalidateCacheAttribute.cs,v 1.2 2007/04/01 15:04:39 bbaia Exp $ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] - [Serializable] - public sealed class InvalidateCacheAttribute : Attribute - { - private string cacheName; - private string keys; - private IExpression keysExpression; - private string condition; - private IExpression conditionExpression; - - /// - /// Creates an attribute instance. - /// - public InvalidateCacheAttribute() - { - } - - /// - /// Creates an attribute instance. - /// - /// - /// The name of the cache to use. - /// - public InvalidateCacheAttribute(string cacheName) - { - this.cacheName = cacheName; - } - - /// - /// Gets or sets the name of the cache to use. - /// - /// - /// The name of the cache to use. - /// - public string CacheName - { - get { return cacheName; } - set { cacheName = value; } - } - - /// - /// Gets or sets a SpEL expression that should be evaluated in order - /// to determine the keys for the items that should be evicted. - /// - /// - /// An expression string that should be evaluated in order - /// to determine the keys for the items that should be evicted. - /// - public string Keys - { - get { return keys; } - set - { - keys = value; - keysExpression = Expression.Parse(value); - } - } - - /// - /// Gets an expression instance that should be evaluated in order - /// to determine the keys for the items that should be evicted. - /// - /// - /// An expression instance that should be evaluated in order - /// to determine the keys for the items that should be evicted. - /// - public IExpression KeysExpression - { - get { return keysExpression; } - } - - /// - /// Gets or sets a SpEL expression that should be evaluated in order - /// to determine whether items should be evicted. - /// - /// - /// An expression string that should be evaluated in order to determine - /// whether items should be evicted. - /// - public string Condition - { - get { return condition; } - set - { - condition = value; - conditionExpression = Expression.Parse(value); - } - } - - /// - /// Gets an expression instance that should be evaluated in order - /// to determine whether items should be evicted. - /// - /// - /// An expression instance that should be evaluated in order to determine - /// whether items should be evicted. - /// - public IExpression ConditionExpression - { - get { return conditionExpression; } - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Expressions; + +namespace Spring.Caching +{ + /// + /// This attribute should be used to mark method that should + /// invalidate one or more cache items when invoked. + /// + /// + ///

+ /// This attribute allows application developers to specify that some + /// cache items should be evicted from cache when the method is invoked, + /// but it will not do any eviction by itself. + ///

+ ///

+ /// In order to actually evict cache items, an application developer + /// must apply a Spring.Aspects.Cache.InvalidateCacheAdvice to + /// all of the members that have this attribute defined. + ///

+ ///
+ /// Aleksandar Seovic + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + [Serializable] + public sealed class InvalidateCacheAttribute : Attribute + { + private string cacheName; + private string keys; + private IExpression keysExpression; + private string condition; + private IExpression conditionExpression; + + /// + /// Creates an attribute instance. + /// + public InvalidateCacheAttribute() + { + } + + /// + /// Creates an attribute instance. + /// + /// + /// The name of the cache to use. + /// + public InvalidateCacheAttribute(string cacheName) + { + this.cacheName = cacheName; + } + + /// + /// Gets or sets the name of the cache to use. + /// + /// + /// The name of the cache to use. + /// + public string CacheName + { + get { return cacheName; } + set { cacheName = value; } + } + + /// + /// Gets or sets a SpEL expression that should be evaluated in order + /// to determine the keys for the items that should be evicted. + /// + /// + /// An expression string that should be evaluated in order + /// to determine the keys for the items that should be evicted. + /// + public string Keys + { + get { return keys; } + set + { + keys = value; + keysExpression = Expression.Parse(value); + } + } + + /// + /// Gets an expression instance that should be evaluated in order + /// to determine the keys for the items that should be evicted. + /// + /// + /// An expression instance that should be evaluated in order + /// to determine the keys for the items that should be evicted. + /// + public IExpression KeysExpression + { + get { return keysExpression; } + } + + /// + /// Gets or sets a SpEL expression that should be evaluated in order + /// to determine whether items should be evicted. + /// + /// + /// An expression string that should be evaluated in order to determine + /// whether items should be evicted. + /// + public string Condition + { + get { return condition; } + set + { + condition = value; + conditionExpression = Expression.Parse(value); + } + } + + /// + /// Gets an expression instance that should be evaluated in order + /// to determine whether items should be evicted. + /// + /// + /// An expression instance that should be evaluated in order to determine + /// whether items should be evicted. + /// + public IExpression ConditionExpression + { + get { return conditionExpression; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Caching/NonExpiringCache.cs b/src/Spring/Spring.Core/Caching/NonExpiringCache.cs index 3b368f4e..2a665c4b 100644 --- a/src/Spring/Spring.Core/Caching/NonExpiringCache.cs +++ b/src/Spring/Spring.Core/Caching/NonExpiringCache.cs @@ -1,143 +1,142 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -namespace Spring.Caching -{ - /// - /// A simple implementation backed by a dictionary that - /// never expires cache items. - /// - /// Aleksandar Seovic - /// $Id: NonExpiringCache.cs,v 1.4 2007/08/24 22:43:55 oakinger Exp $ - public class NonExpiringCache : AbstractCache - { - private readonly IDictionary itemStore = new Hashtable(); - - /// - /// Gets the number of items in the cache. - /// - public override int Count - { - get - { - lock (itemStore.SyncRoot) - { - return itemStore.Count; - } - } - } - - /// - /// Gets a collection of all cache item keys. - /// - public override ICollection Keys - { - get - { - lock (itemStore.SyncRoot) - { - return itemStore.Keys; - } - } - } - - /// - /// Retrieves an item from the cache. - /// - /// - /// Item key. - /// - /// - /// Item for the specified , or null. - /// - public override object Get(object key) - { - lock (itemStore.SyncRoot) - { - return itemStore[key]; - } - } - - /// - /// Removes an item from the cache. - /// - /// - /// Item key. - /// - public override void Remove(object key) - { - lock (itemStore.SyncRoot) - { - itemStore.Remove(key); - } - } - - /// - /// Removes collection of items from the cache. - /// - /// - /// Collection of keys to remove. - /// - public override void RemoveAll(ICollection keys) - { - lock (itemStore.SyncRoot) - { - foreach (object key in keys) - { - itemStore.Remove(key); - } - } - } - - /// - /// Removes all items from the cache. - /// - public override void Clear() - { - lock (itemStore.SyncRoot) - { - itemStore.Clear(); - } - } - - /// - /// Inserts an item into the cache. - /// - /// - /// Item key. - /// - /// - /// Item value. - /// - /// - /// Item's time-to-live (TTL) in milliseconds. - /// - protected override void DoInsert(object key, object value, TimeSpan timeToLive) - { - lock (itemStore.SyncRoot) - { - itemStore[key] = value; - } - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +namespace Spring.Caching +{ + /// + /// A simple implementation backed by a dictionary that + /// never expires cache items. + /// + /// Aleksandar Seovic + public class NonExpiringCache : AbstractCache + { + private readonly IDictionary itemStore = new Hashtable(); + + /// + /// Gets the number of items in the cache. + /// + public override int Count + { + get + { + lock (itemStore.SyncRoot) + { + return itemStore.Count; + } + } + } + + /// + /// Gets a collection of all cache item keys. + /// + public override ICollection Keys + { + get + { + lock (itemStore.SyncRoot) + { + return itemStore.Keys; + } + } + } + + /// + /// Retrieves an item from the cache. + /// + /// + /// Item key. + /// + /// + /// Item for the specified , or null. + /// + public override object Get(object key) + { + lock (itemStore.SyncRoot) + { + return itemStore[key]; + } + } + + /// + /// Removes an item from the cache. + /// + /// + /// Item key. + /// + public override void Remove(object key) + { + lock (itemStore.SyncRoot) + { + itemStore.Remove(key); + } + } + + /// + /// Removes collection of items from the cache. + /// + /// + /// Collection of keys to remove. + /// + public override void RemoveAll(ICollection keys) + { + lock (itemStore.SyncRoot) + { + foreach (object key in keys) + { + itemStore.Remove(key); + } + } + } + + /// + /// Removes all items from the cache. + /// + public override void Clear() + { + lock (itemStore.SyncRoot) + { + itemStore.Clear(); + } + } + + /// + /// Inserts an item into the cache. + /// + /// + /// Item key. + /// + /// + /// Item value. + /// + /// + /// Item's time-to-live (TTL) in milliseconds. + /// + protected override void DoInsert(object key, object value, TimeSpan timeToLive) + { + lock (itemStore.SyncRoot) + { + itemStore[key] = value; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/AbstractQueue.cs b/src/Spring/Spring.Core/Collections/AbstractQueue.cs index 5fd846a7..dcb18403 100644 --- a/src/Spring/Spring.Core/Collections/AbstractQueue.cs +++ b/src/Spring/Spring.Core/Collections/AbstractQueue.cs @@ -1,347 +1,346 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// This class provides skeletal implementations of some - /// operations. - /// - /// - ///

- /// The implementations in this class are appropriate when the base - /// implementation does not allow elements. The methods - /// , - /// , and - /// are based on - /// the , - /// , and - /// methods - /// respectively but throw exceptions instead of indicating failure via - /// or returns. - ///

- /// An implementation that extends this class must - /// minimally define a method - /// which does - /// not permit the insertion of elements, along with methods - /// , and - /// . Typically, - /// additional methods will be overridden as well. If these requirements - /// cannot be met, consider instead subclassing - /// }. - ///

- ///
- /// Doug Lea - /// Griffin Caprio (.NET) - /// $Id: AbstractQueue.cs,v 1.8 2007/08/27 09:38:11 oakinger Exp $ - [Serializable] - public abstract class AbstractQueue : IQueue - { - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- protected AbstractQueue() - {} - - /// - /// Inserts the specified element into this queue if it is possible - /// to do so immediately without violating capacity restrictions. - /// - /// - /// The element to add. - /// - /// - /// if successful. - /// - /// - /// If the element cannot be added at this time due to capacity restrictions. - /// - public virtual bool Add(object objectToAdd) - { - if(Offer(objectToAdd)) - { - return true; - } - else - { - throw new InvalidOperationException("Queue full."); - } - } - - /// - /// Retrieves and removes the head of this queue. - /// - /// - ///

- /// This method differs from - /// only in that - /// it throws an exception if this queue is empty. - ///

- ///
- /// - /// The head of this queue - /// - /// - /// If this queue is empty. - /// - public virtual object Remove() - { - object element = Poll(); - if(element != null) - { - return element; - } - else - { - throw new NoElementsException("Queue is empty."); - } - } - - - /// - /// Retrieves, but does not remove, the head of this queue. - /// - /// - ///

- /// This method differs from - /// only in that it throws an exception if this queue is empty. - ///

- ///

- /// ALso note that this implementation returns the result of - /// unless the queue - /// is empty. - ///

- ///
- /// The head of this queue. - /// - /// If this queue is empty. - /// - public virtual object Element() - { - object element = Peek(); - if(element != null) - { - return element; - } - else - { - throw new NoElementsException("Queue is empty."); - } - } - - /// - /// Removes all of the elements from this queue. - /// - /// - ///

- /// The queue will be empty after this call returns. - ///

- ///

- /// This implementation repeatedly invokes - /// until it - /// returns . - ///

- ///
- public virtual void Clear() - { - while(Poll() != null) - { - ; - } - } - - /// - /// Adds all of the elements in the supplied - /// to this queue. - /// - /// - ///

- /// Attempts to - /// - /// of a queue to itself result in . - /// Further, the behavior of this operation is undefined if the specified - /// collection is modified while the operation is in progress. - ///

- ///

- /// This implementation iterates over the specified collection, - /// and adds each element returned by the iterator to this queue, in turn. - /// An exception encountered while trying to add an element (including, - /// in particular, a element) may result in only some - /// of the elements having been successfully added when the associated - /// exception is thrown. - ///

- ///
- /// - /// The collection containing the elements to be added to this queue. - /// - /// - /// if this queue changed as a result of the call. - /// - /// - /// If the supplied or any one of its elements are . - /// - /// - /// If the collection is the current or - /// the collection size is greater than the queue capacity. - /// - public virtual bool AddAll(ICollection collection) - { - if(collection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - if(collection == this) - { - throw new ArgumentException(); - } - if(collection.Count > Capacity) - { - throw new ArgumentException("Collcation size greater than queue capacity."); - } - bool modified = false; - foreach(object element in collection) - { - if(element == null) - { - throw new ArgumentNullException("Cannot add null elements to this queue."); - } - else if(Add(element)) - { - modified = true; - } - } - return modified; - } - - /// - /// Inserts the specified element into this queue if it is possible to do - /// so immediately without violating capacity restrictions. - /// - /// - ///

- /// When using a capacity-restricted queue, this method is generally - /// preferable to , - /// which can fail to insert an element only by throwing an exception. - ///

- ///
- /// - /// The element to add. - /// - /// - /// if the element was added to this queue. - /// - /// - /// If the element cannot be added at this time due to capacity restrictions. - /// - /// - /// If the supplied is - /// . - /// - /// - /// If some property of the supplied prevents - /// it from being added to this queue. - /// - public abstract bool Offer(object objectToAdd); - - /// - /// Retrieves, but does not remove, the head of this queue, - /// or returns if this queue is empty. - /// - /// - /// The head of this queue, or if this queue is empty. - /// - public abstract object Peek(); - - /// - /// Retrieves and removes the head of this queue, - /// or returns if this queue is empty. - /// - /// - /// The head of this queue, or if this queue is empty. - /// - public abstract object Poll(); - - /// - /// Returns if there are no elements in the , otherwise. - /// - public abstract bool IsEmpty { get; } - - /// - /// Returns the current capacity of this queue. - /// - public abstract int Capacity { get; } - - /// - ///Copies the elements of the to an , starting at a particular index. - /// - ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - ///The zero-based index in array at which copying begins. - ///array is null. - ///index is less than zero. - ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. - ///The type of the source cannot be cast automatically to the type of the destination array. 2 - public abstract void CopyTo(Array array, int index); - - /// - ///Gets the number of elements contained in the . - /// - /// - ///The number of elements contained in the . - /// - public abstract int Count { get; } - - /// - ///Gets an object that can be used to synchronize access to the . - /// - /// - ///An object that can be used to synchronize access to the . - /// - public abstract object SyncRoot { get; } - - /// - ///Gets a value indicating whether access to the is synchronized (thread safe). - /// - /// - ///true if access to the is synchronized (thread safe); otherwise, false. - /// - public abstract bool IsSynchronized { get; } - - /// - ///Returns an enumerator that iterates through a collection. - /// - /// - ///An object that can be used to iterate through the collection. - /// - public abstract IEnumerator GetEnumerator(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// This class provides skeletal implementations of some + /// operations. + /// + /// + ///

+ /// The implementations in this class are appropriate when the base + /// implementation does not allow elements. The methods + /// , + /// , and + /// are based on + /// the , + /// , and + /// methods + /// respectively but throw exceptions instead of indicating failure via + /// or returns. + ///

+ /// An implementation that extends this class must + /// minimally define a method + /// which does + /// not permit the insertion of elements, along with methods + /// , and + /// . Typically, + /// additional methods will be overridden as well. If these requirements + /// cannot be met, consider instead subclassing + /// }. + ///

+ ///
+ /// Doug Lea + /// Griffin Caprio (.NET) + [Serializable] + public abstract class AbstractQueue : IQueue + { + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ protected AbstractQueue() + {} + + /// + /// Inserts the specified element into this queue if it is possible + /// to do so immediately without violating capacity restrictions. + /// + /// + /// The element to add. + /// + /// + /// if successful. + /// + /// + /// If the element cannot be added at this time due to capacity restrictions. + /// + public virtual bool Add(object objectToAdd) + { + if(Offer(objectToAdd)) + { + return true; + } + else + { + throw new InvalidOperationException("Queue full."); + } + } + + /// + /// Retrieves and removes the head of this queue. + /// + /// + ///

+ /// This method differs from + /// only in that + /// it throws an exception if this queue is empty. + ///

+ ///
+ /// + /// The head of this queue + /// + /// + /// If this queue is empty. + /// + public virtual object Remove() + { + object element = Poll(); + if(element != null) + { + return element; + } + else + { + throw new NoElementsException("Queue is empty."); + } + } + + + /// + /// Retrieves, but does not remove, the head of this queue. + /// + /// + ///

+ /// This method differs from + /// only in that it throws an exception if this queue is empty. + ///

+ ///

+ /// ALso note that this implementation returns the result of + /// unless the queue + /// is empty. + ///

+ ///
+ /// The head of this queue. + /// + /// If this queue is empty. + /// + public virtual object Element() + { + object element = Peek(); + if(element != null) + { + return element; + } + else + { + throw new NoElementsException("Queue is empty."); + } + } + + /// + /// Removes all of the elements from this queue. + /// + /// + ///

+ /// The queue will be empty after this call returns. + ///

+ ///

+ /// This implementation repeatedly invokes + /// until it + /// returns . + ///

+ ///
+ public virtual void Clear() + { + while(Poll() != null) + { + ; + } + } + + /// + /// Adds all of the elements in the supplied + /// to this queue. + /// + /// + ///

+ /// Attempts to + /// + /// of a queue to itself result in . + /// Further, the behavior of this operation is undefined if the specified + /// collection is modified while the operation is in progress. + ///

+ ///

+ /// This implementation iterates over the specified collection, + /// and adds each element returned by the iterator to this queue, in turn. + /// An exception encountered while trying to add an element (including, + /// in particular, a element) may result in only some + /// of the elements having been successfully added when the associated + /// exception is thrown. + ///

+ ///
+ /// + /// The collection containing the elements to be added to this queue. + /// + /// + /// if this queue changed as a result of the call. + /// + /// + /// If the supplied or any one of its elements are . + /// + /// + /// If the collection is the current or + /// the collection size is greater than the queue capacity. + /// + public virtual bool AddAll(ICollection collection) + { + if(collection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + if(collection == this) + { + throw new ArgumentException(); + } + if(collection.Count > Capacity) + { + throw new ArgumentException("Collcation size greater than queue capacity."); + } + bool modified = false; + foreach(object element in collection) + { + if(element == null) + { + throw new ArgumentNullException("Cannot add null elements to this queue."); + } + else if(Add(element)) + { + modified = true; + } + } + return modified; + } + + /// + /// Inserts the specified element into this queue if it is possible to do + /// so immediately without violating capacity restrictions. + /// + /// + ///

+ /// When using a capacity-restricted queue, this method is generally + /// preferable to , + /// which can fail to insert an element only by throwing an exception. + ///

+ ///
+ /// + /// The element to add. + /// + /// + /// if the element was added to this queue. + /// + /// + /// If the element cannot be added at this time due to capacity restrictions. + /// + /// + /// If the supplied is + /// . + /// + /// + /// If some property of the supplied prevents + /// it from being added to this queue. + /// + public abstract bool Offer(object objectToAdd); + + /// + /// Retrieves, but does not remove, the head of this queue, + /// or returns if this queue is empty. + /// + /// + /// The head of this queue, or if this queue is empty. + /// + public abstract object Peek(); + + /// + /// Retrieves and removes the head of this queue, + /// or returns if this queue is empty. + /// + /// + /// The head of this queue, or if this queue is empty. + /// + public abstract object Poll(); + + /// + /// Returns if there are no elements in the , otherwise. + /// + public abstract bool IsEmpty { get; } + + /// + /// Returns the current capacity of this queue. + /// + public abstract int Capacity { get; } + + /// + ///Copies the elements of the to an , starting at a particular index. + /// + ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + ///The zero-based index in array at which copying begins. + ///array is null. + ///index is less than zero. + ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. + ///The type of the source cannot be cast automatically to the type of the destination array. 2 + public abstract void CopyTo(Array array, int index); + + /// + ///Gets the number of elements contained in the . + /// + /// + ///The number of elements contained in the . + /// + public abstract int Count { get; } + + /// + ///Gets an object that can be used to synchronize access to the . + /// + /// + ///An object that can be used to synchronize access to the . + /// + public abstract object SyncRoot { get; } + + /// + ///Gets a value indicating whether access to the is synchronized (thread safe). + /// + /// + ///true if access to the is synchronized (thread safe); otherwise, false. + /// + public abstract bool IsSynchronized { get; } + + /// + ///Returns an enumerator that iterates through a collection. + /// + /// + ///An object that can be used to iterate through the collection. + /// + public abstract IEnumerator GetEnumerator(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/DictionarySet.cs b/src/Spring/Spring.Core/Collections/DictionarySet.cs index 0d112d31..1e06dcd1 100644 --- a/src/Spring/Spring.Core/Collections/DictionarySet.cs +++ b/src/Spring/Spring.Core/Collections/DictionarySet.cs @@ -1,394 +1,393 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// is an - /// class that supports the creation of new - /// types where the underlying data - /// store is an instance. - /// - /// - ///

- /// You can use any object that implements the - /// interface to hold set - /// data. You can define your own, or you can use one of the objects - /// provided in the framework. The type of - /// you - /// choose will affect both the performance and the behavior of the - /// using it. - ///

- ///

- /// This object overrides the method, - /// but not the method, because - /// the class is mutable. - /// Therefore, it is not safe to use as a key value in a dictionary. - ///

- ///

- /// To make a typed based on your - /// own , simply derive a new - /// class with a constructor that takes no parameters. Some - /// implmentations cannot be defined - /// with a default constructor. If this is the case for your class, you - /// will need to override clone as well. - ///

- ///

- /// It is also standard practice that at least one of your constructors - /// takes an or an - /// as an argument. - ///

- ///
- /// - /// $Id: DictionarySet.cs,v 1.7 2007/03/16 04:01:27 aseovic Exp $ - [Serializable] - public abstract class DictionarySet : Set - { - private IDictionary _internalDictionary; - - private static readonly object PlaceholderObject = new object(); - private static readonly object NullPlaceHolderKey = new object(); - - /// - /// Provides the storage for elements in the - /// , stored as the key-set - /// of the object. - /// - /// - ///

- /// Set this object in the constructor if you create your own - /// class. - ///

- ///
- protected IDictionary InternalDictionary - { - get { return _internalDictionary; } - set { _internalDictionary = value; } - } - - /// - /// The placeholder object used as the value for the - /// instance. - /// - /// - /// There is a single instance of this object globally, used for all - /// s. - /// - protected static object Placeholder - { - get { return PlaceholderObject; } - } - - /// - /// Adds the specified element to this set if it is not already present. - /// - /// The object to add to the set. - /// - /// is the object was added, - /// if the object was already present. - /// - public override bool Add(object element) - { - element = MaskNull(element); - if (InternalDictionary[element] != null) - { - return false; - } - else - { - //The object we are adding is just a placeholder. The thing we are - //really concerned with is 'o', the key. - InternalDictionary.Add(element, PlaceholderObject); - return true; - } - } - - /// - /// Adds all the elements in the specified collection to the set if - /// they are not already present. - /// - /// A collection of objects to add to the set. - /// - /// is the set changed as a result of this - /// operation. - /// - public override bool AddAll(ICollection collection) - { - bool changed = false; - foreach (object o in collection) - { - changed |= this.Add(o); - } - return changed; - } - - /// - /// Removes all objects from this set. - /// - public override void Clear() - { - InternalDictionary.Clear(); - } - - /// - /// Returns if this set contains the specified - /// element. - /// - /// The element to look for. - /// - /// if this set contains the specified element. - /// - public override bool Contains(object element) - { - element = MaskNull(element); - return InternalDictionary[element] != null; - } - - /// - /// Returns if the set contains all the - /// elements in the specified collection. - /// - /// A collection of objects. - /// - /// if the set contains all the elements in the - /// specified collection; also if the - /// supplied is . - /// - public override bool ContainsAll(ICollection collection) - { - if(collection == null) - { - return false; - } - foreach (object o in collection) - { - if (!this.Contains(MaskNull(o))) - { - return false; - } - } - return true; - } - - /// - /// Returns if this set contains no elements. - /// - public override bool IsEmpty - { - get { return InternalDictionary.Count == 0; } - } - - /// - /// Removes the specified element from the set. - /// - /// The element to be removed. - /// - /// if the set contained the specified element. - /// - public override bool Remove(object element) - { - element = MaskNull(element); - bool contained = this.Contains(element); - if (contained) - { - InternalDictionary.Remove(element); - } - return contained; - } - - /// - /// Remove all the specified elements from this set, if they exist in - /// this set. - /// - /// A collection of elements to remove. - /// - /// if the set was modified as a result of this - /// operation. - /// - public override bool RemoveAll(ICollection collection) - { - bool changed = false; - foreach (object o in collection) - { - changed |= this.Remove(o); - } - return changed; - } - - /// - /// Retains only the elements in this set that are contained in the - /// specified collection. - /// - /// - /// The collection that defines the set of elements to be retained. - /// - /// - /// if this set changed as a result of this - /// operation. - /// - public override bool RetainAll(ICollection collection) - { - //Put data from C into a set so we can use the Contains() method. - Set cSet = new HybridSet(collection); - - //We are going to build a set of elements to remove. - Set removeSet = new HybridSet(); - - foreach (object o in this) - { - //If C does not contain O, then we need to remove O from our - //set. We can't do this while iterating through our set, so - //we put it into RemoveSet for later. - if (!cSet.Contains(o)) - { - removeSet.Add(o); - } - } - return this.RemoveAll(removeSet); - } - - /// - /// Copies the elements in the to - /// an array. - /// - /// - ///

- /// The type of array needs to be compatible with the objects in the - /// , obviously. - ///

- ///
- /// - /// An array that will be the target of the copy operation. - /// - /// - /// The zero-based index where copying will start. - /// - public override void CopyTo(Array array, int index) - { - int i = index; - foreach (object o in this) - { - array.SetValue(UnmaskNull(o), i++); - } - } - - /// - /// The number of elements currently contained in this collection. - /// - public override int Count - { - get { return InternalDictionary.Count; } - } - - /// - /// Returns if the - /// is synchronized across - /// threads. - /// - /// - public override bool IsSynchronized - { - get { return false; } - } - - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - /// - public override object SyncRoot - { - get { return InternalDictionary.SyncRoot; } - } - - /// - /// Gets an enumerator for the elements in the - /// . - /// - /// - /// An over the elements - /// in the . - /// - public override IEnumerator GetEnumerator() - { - return new DictionarySetEnumerator(InternalDictionary.Keys.GetEnumerator()); - } - - private static object MaskNull(object key) - { - return key == null ? NullPlaceHolderKey : key; - } - - private static object UnmaskNull(object key) - { - return key == NullPlaceHolderKey ? null : key; - } - - #region Inner Class : DictionarySetEnumerator - - private sealed class DictionarySetEnumerator : IEnumerator - { - #region Constructor (s) / Destructor - - public DictionarySetEnumerator(IEnumerator enumerator) - { - _enumerator = enumerator; - } - - #endregion - - #region IEnumerator Members - - public void Reset() - { - _enumerator.Reset(); - } - - public object Current - { - get { return UnmaskNull(_enumerator.Current); } - } - - public bool MoveNext() - { - return _enumerator.MoveNext(); - } - - #endregion - - private IEnumerator _enumerator; - } - - #endregion - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// is an + /// class that supports the creation of new + /// types where the underlying data + /// store is an instance. + /// + /// + ///

+ /// You can use any object that implements the + /// interface to hold set + /// data. You can define your own, or you can use one of the objects + /// provided in the framework. The type of + /// you + /// choose will affect both the performance and the behavior of the + /// using it. + ///

+ ///

+ /// This object overrides the method, + /// but not the method, because + /// the class is mutable. + /// Therefore, it is not safe to use as a key value in a dictionary. + ///

+ ///

+ /// To make a typed based on your + /// own , simply derive a new + /// class with a constructor that takes no parameters. Some + /// implmentations cannot be defined + /// with a default constructor. If this is the case for your class, you + /// will need to override clone as well. + ///

+ ///

+ /// It is also standard practice that at least one of your constructors + /// takes an or an + /// as an argument. + ///

+ ///
+ /// + [Serializable] + public abstract class DictionarySet : Set + { + private IDictionary _internalDictionary; + + private static readonly object PlaceholderObject = new object(); + private static readonly object NullPlaceHolderKey = new object(); + + /// + /// Provides the storage for elements in the + /// , stored as the key-set + /// of the object. + /// + /// + ///

+ /// Set this object in the constructor if you create your own + /// class. + ///

+ ///
+ protected IDictionary InternalDictionary + { + get { return _internalDictionary; } + set { _internalDictionary = value; } + } + + /// + /// The placeholder object used as the value for the + /// instance. + /// + /// + /// There is a single instance of this object globally, used for all + /// s. + /// + protected static object Placeholder + { + get { return PlaceholderObject; } + } + + /// + /// Adds the specified element to this set if it is not already present. + /// + /// The object to add to the set. + /// + /// is the object was added, + /// if the object was already present. + /// + public override bool Add(object element) + { + element = MaskNull(element); + if (InternalDictionary[element] != null) + { + return false; + } + else + { + //The object we are adding is just a placeholder. The thing we are + //really concerned with is 'o', the key. + InternalDictionary.Add(element, PlaceholderObject); + return true; + } + } + + /// + /// Adds all the elements in the specified collection to the set if + /// they are not already present. + /// + /// A collection of objects to add to the set. + /// + /// is the set changed as a result of this + /// operation. + /// + public override bool AddAll(ICollection collection) + { + bool changed = false; + foreach (object o in collection) + { + changed |= this.Add(o); + } + return changed; + } + + /// + /// Removes all objects from this set. + /// + public override void Clear() + { + InternalDictionary.Clear(); + } + + /// + /// Returns if this set contains the specified + /// element. + /// + /// The element to look for. + /// + /// if this set contains the specified element. + /// + public override bool Contains(object element) + { + element = MaskNull(element); + return InternalDictionary[element] != null; + } + + /// + /// Returns if the set contains all the + /// elements in the specified collection. + /// + /// A collection of objects. + /// + /// if the set contains all the elements in the + /// specified collection; also if the + /// supplied is . + /// + public override bool ContainsAll(ICollection collection) + { + if(collection == null) + { + return false; + } + foreach (object o in collection) + { + if (!this.Contains(MaskNull(o))) + { + return false; + } + } + return true; + } + + /// + /// Returns if this set contains no elements. + /// + public override bool IsEmpty + { + get { return InternalDictionary.Count == 0; } + } + + /// + /// Removes the specified element from the set. + /// + /// The element to be removed. + /// + /// if the set contained the specified element. + /// + public override bool Remove(object element) + { + element = MaskNull(element); + bool contained = this.Contains(element); + if (contained) + { + InternalDictionary.Remove(element); + } + return contained; + } + + /// + /// Remove all the specified elements from this set, if they exist in + /// this set. + /// + /// A collection of elements to remove. + /// + /// if the set was modified as a result of this + /// operation. + /// + public override bool RemoveAll(ICollection collection) + { + bool changed = false; + foreach (object o in collection) + { + changed |= this.Remove(o); + } + return changed; + } + + /// + /// Retains only the elements in this set that are contained in the + /// specified collection. + /// + /// + /// The collection that defines the set of elements to be retained. + /// + /// + /// if this set changed as a result of this + /// operation. + /// + public override bool RetainAll(ICollection collection) + { + //Put data from C into a set so we can use the Contains() method. + Set cSet = new HybridSet(collection); + + //We are going to build a set of elements to remove. + Set removeSet = new HybridSet(); + + foreach (object o in this) + { + //If C does not contain O, then we need to remove O from our + //set. We can't do this while iterating through our set, so + //we put it into RemoveSet for later. + if (!cSet.Contains(o)) + { + removeSet.Add(o); + } + } + return this.RemoveAll(removeSet); + } + + /// + /// Copies the elements in the to + /// an array. + /// + /// + ///

+ /// The type of array needs to be compatible with the objects in the + /// , obviously. + ///

+ ///
+ /// + /// An array that will be the target of the copy operation. + /// + /// + /// The zero-based index where copying will start. + /// + public override void CopyTo(Array array, int index) + { + int i = index; + foreach (object o in this) + { + array.SetValue(UnmaskNull(o), i++); + } + } + + /// + /// The number of elements currently contained in this collection. + /// + public override int Count + { + get { return InternalDictionary.Count; } + } + + /// + /// Returns if the + /// is synchronized across + /// threads. + /// + /// + public override bool IsSynchronized + { + get { return false; } + } + + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + /// + public override object SyncRoot + { + get { return InternalDictionary.SyncRoot; } + } + + /// + /// Gets an enumerator for the elements in the + /// . + /// + /// + /// An over the elements + /// in the . + /// + public override IEnumerator GetEnumerator() + { + return new DictionarySetEnumerator(InternalDictionary.Keys.GetEnumerator()); + } + + private static object MaskNull(object key) + { + return key == null ? NullPlaceHolderKey : key; + } + + private static object UnmaskNull(object key) + { + return key == NullPlaceHolderKey ? null : key; + } + + #region Inner Class : DictionarySetEnumerator + + private sealed class DictionarySetEnumerator : IEnumerator + { + #region Constructor (s) / Destructor + + public DictionarySetEnumerator(IEnumerator enumerator) + { + _enumerator = enumerator; + } + + #endregion + + #region IEnumerator Members + + public void Reset() + { + _enumerator.Reset(); + } + + public object Current + { + get { return UnmaskNull(_enumerator.Current); } + } + + public bool MoveNext() + { + return _enumerator.MoveNext(); + } + + #endregion + + private IEnumerator _enumerator; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/HashedSet.cs b/src/Spring/Spring.Core/Collections/HashedSet.cs index b1ac2f15..f218a10a 100644 --- a/src/Spring/Spring.Core/Collections/HashedSet.cs +++ b/src/Spring/Spring.Core/Collections/HashedSet.cs @@ -1,67 +1,66 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// Implements an based on a - /// hash table. - /// - /// - ///

- /// This will give the best lookup, add, and remove performance for very - /// large data-sets, but iteration will occur in no particular order. - ///

- ///
- /// - /// $Id: HashedSet.cs,v 1.6 2007/03/16 04:01:27 aseovic Exp $ - [Serializable] - public class HashedSet : DictionarySet - { - /// - /// Creates a new instance of the class. - /// - public HashedSet() - { - InternalDictionary = new Hashtable(); - } - - /// - /// Creates a new instance of the class, and - /// initializes it based on a collection of elements. - /// - /// - /// A collection of elements that defines the initial set contents. - /// - public HashedSet(ICollection initialValues) : this() - { - this.AddAll(initialValues); - } - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// Implements an based on a + /// hash table. + /// + /// + ///

+ /// This will give the best lookup, add, and remove performance for very + /// large data-sets, but iteration will occur in no particular order. + ///

+ ///
+ /// + [Serializable] + public class HashedSet : DictionarySet + { + /// + /// Creates a new instance of the class. + /// + public HashedSet() + { + InternalDictionary = new Hashtable(); + } + + /// + /// Creates a new instance of the class, and + /// initializes it based on a collection of elements. + /// + /// + /// A collection of elements that defines the initial set contents. + /// + public HashedSet(ICollection initialValues) : this() + { + this.AddAll(initialValues); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/HybridSet.cs b/src/Spring/Spring.Core/Collections/HybridSet.cs index f1264c4f..b9a6237d 100644 --- a/src/Spring/Spring.Core/Collections/HybridSet.cs +++ b/src/Spring/Spring.Core/Collections/HybridSet.cs @@ -1,76 +1,75 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; - -#endregion - -namespace Spring.Collections -{ - /// - /// Implements an that automatically - /// changes from a list based implementation to a hashtable based - /// implementation when the size reaches a certain threshold. - /// - /// - ///

- /// This is good if you are unsure about whether you data-set will be tiny - /// or huge. - ///

- /// - /// Because this uses a dual implementation, iteration order is not - /// guaranteed! - /// - ///
- /// - /// $Id: HybridSet.cs,v 1.6 2007/03/16 04:01:28 aseovic Exp $ - [Serializable] - public class HybridSet : DictionarySet - { - /// - /// Creates a new set instance based on either a list or a hash table, - /// depending on which will be more efficient based on the data-set - /// size. - /// - public HybridSet() - { - InternalDictionary = new HybridDictionary(); - } - - /// - /// Creates a new set instance based on either a list or a hash table, - /// depending on which will be more efficient based on the data-set - /// size, and initializes it based on a collection of elements. - /// - /// - /// A collection of elements that defines the initial set contents. - /// - public HybridSet(ICollection initialValues) : this() - { - this.AddAll(initialValues); - } - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; + +#endregion + +namespace Spring.Collections +{ + /// + /// Implements an that automatically + /// changes from a list based implementation to a hashtable based + /// implementation when the size reaches a certain threshold. + /// + /// + ///

+ /// This is good if you are unsure about whether you data-set will be tiny + /// or huge. + ///

+ /// + /// Because this uses a dual implementation, iteration order is not + /// guaranteed! + /// + ///
+ /// + [Serializable] + public class HybridSet : DictionarySet + { + /// + /// Creates a new set instance based on either a list or a hash table, + /// depending on which will be more efficient based on the data-set + /// size. + /// + public HybridSet() + { + InternalDictionary = new HybridDictionary(); + } + + /// + /// Creates a new set instance based on either a list or a hash table, + /// depending on which will be more efficient based on the data-set + /// size, and initializes it based on a collection of elements. + /// + /// + /// A collection of elements that defines the initial set contents. + /// + public HybridSet(ICollection initialValues) : this() + { + this.AddAll(initialValues); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/IQueue.cs b/src/Spring/Spring.Core/Collections/IQueue.cs index 990d6dc7..5ee4b71b 100644 --- a/src/Spring/Spring.Core/Collections/IQueue.cs +++ b/src/Spring/Spring.Core/Collections/IQueue.cs @@ -1,233 +1,232 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// A collection designed for holding elements prior to processing. - /// - /// - ///

- /// Besides basic operations, - /// queues provide additional insertion, extraction, and inspection - /// operations. - ///

- ///

- /// Each of these methods exists in two forms: one throws - /// an exception if the operation fails, the other returns a special - /// value (either or , depending on the - /// operation). The latter form of the insert operation is designed - /// specifically for use with capacity-restricted - /// implementations; in most implementations, insert operations cannot - /// fail. - ///

- ///

- /// Queues typically, but do not necessarily, order elements in a - /// FIFO (first-in-first-out) manner. Among the exceptions are - /// priority queues, which order elements according to a supplied - /// comparator, or the elements' natural ordering, and LIFO queues (or - /// stacks) which order the elements LIFO (last-in-first-out). - /// Whatever the ordering used, the head of the queue is that - /// element which would be removed by a call to - /// or - /// . In a FIFO queue, all new - /// elements are inserted at the tail of the queue. Other kinds of queues may - /// use different placement rules. Every implementation - /// must specify its ordering properties. - ///

- ///

- /// The method inserts an - /// element if possible, otherwise returning . This differs from the - /// method, which can fail to - /// add an element only by throwing an exception. The - /// method is designed for - /// use when failure is a normal, rather than exceptional occurrence, for example, - /// in fixed-capacity (or "bounded" queues. - ///

- ///

- /// The - /// methods remove and - /// return the head of the queue. Exactly which element is removed from the - /// queue is a function of the queue's ordering policy, which differs from - /// implementation to implementation. The - /// and - /// methods differ only in their - /// behavior when the queue is empty: the - /// method throws an exception, - /// while the method returns - /// . - ///

- ///

- /// The and - /// methods return, but do - /// not remove, the head of the queue. - ///

- ///

- /// The interface does not define the blocking queue - /// methods, which are common in concurrent programming. - ///

- ///

- /// implementations generally do not allow insertion - /// of elements, although some implementations, such as - /// a linked list, do not prohibit the insertion of . - /// Even in the implementations that permit it, should - /// not be inserted into a , as is also - /// used as a special return value by the - /// method to - /// indicate that the queue contains no elements. - ///

- ///

- /// implementations generally do not define - /// element-based versions of methods - /// and , but instead inherit the - /// identity based versions from the class object, because element-based equality - /// is not always well-defined for queues with the same elements but different - /// ordering properties. - ///

- ///

- /// Based on the back port of JCP JSR-166. - ///

- ///
- /// Doug Lea - /// Griffin Caprio (.NET) - /// $Id: IQueue.cs,v 1.7 2006/09/30 18:39:24 gcaprio Exp $ - public interface IQueue : ICollection - { - /// - /// Inserts the specified element into this queue if it is possible to do so - /// immediately without violating capacity restrictions, returning - /// upon success and throwing an - /// if no space is - /// currently available. - /// - /// - /// The element to add. - /// - /// - /// if successful. - /// - /// - /// If the element cannot be added at this time due to capacity restrictions. - /// - /// - /// If the class of the supplied prevents it - /// from being added to this queue. - /// - /// - /// If the specified element is and this queue does not - /// permit elements. - /// - /// - /// If some property of the supplied prevents - /// it from being added to this queue. - /// - bool Add(object objectToAdd); - - /// - /// Inserts the specified element into this queue if it is possible to do - /// so immediately without violating capacity restrictions. - /// - /// - ///

- /// When using a capacity-restricted queue, this method is generally - /// preferable to , - /// which can fail to insert an element only by throwing an exception. - ///

- ///
- /// - /// The element to add. - /// - /// - /// if the element was added to this queue. - /// - /// - /// If the element cannot be added at this time due to capacity restrictions. - /// - /// - /// If the supplied is - /// . - /// - /// - /// If some property of the supplied prevents - /// it from being added to this queue. - /// - bool Offer(object objectToAdd); - - /// - /// Retrieves and removes the head of this queue. - /// - /// - ///

- /// This method differs from - /// only in that it throws an exception if this queue is empty. - ///

- ///
- /// - /// The head of this queue - /// - /// if this queue is empty - object Remove(); - - /// - /// Retrieves and removes the head of this queue, - /// or returns if this queue is empty. - /// - /// - /// The head of this queue, or if this queue is empty. - /// - object Poll(); - - /// - /// Retrieves, but does not remove, the head of this queue. - /// - /// - ///

- /// This method differs from - /// only in that it throws an exception if this queue is empty. - ///

- ///
- /// - /// The head of this queue. - /// - /// If this queue is empty. - object Element(); - - /// - /// Retrieves, but does not remove, the head of this queue, - /// or returns if this queue is empty. - /// - /// - /// The head of this queue, or if this queue is empty. - /// - object Peek(); - - /// - /// Returns if there are no elements in the , otherwise. - /// - bool IsEmpty { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// A collection designed for holding elements prior to processing. + /// + /// + ///

+ /// Besides basic operations, + /// queues provide additional insertion, extraction, and inspection + /// operations. + ///

+ ///

+ /// Each of these methods exists in two forms: one throws + /// an exception if the operation fails, the other returns a special + /// value (either or , depending on the + /// operation). The latter form of the insert operation is designed + /// specifically for use with capacity-restricted + /// implementations; in most implementations, insert operations cannot + /// fail. + ///

+ ///

+ /// Queues typically, but do not necessarily, order elements in a + /// FIFO (first-in-first-out) manner. Among the exceptions are + /// priority queues, which order elements according to a supplied + /// comparator, or the elements' natural ordering, and LIFO queues (or + /// stacks) which order the elements LIFO (last-in-first-out). + /// Whatever the ordering used, the head of the queue is that + /// element which would be removed by a call to + /// or + /// . In a FIFO queue, all new + /// elements are inserted at the tail of the queue. Other kinds of queues may + /// use different placement rules. Every implementation + /// must specify its ordering properties. + ///

+ ///

+ /// The method inserts an + /// element if possible, otherwise returning . This differs from the + /// method, which can fail to + /// add an element only by throwing an exception. The + /// method is designed for + /// use when failure is a normal, rather than exceptional occurrence, for example, + /// in fixed-capacity (or "bounded" queues. + ///

+ ///

+ /// The + /// methods remove and + /// return the head of the queue. Exactly which element is removed from the + /// queue is a function of the queue's ordering policy, which differs from + /// implementation to implementation. The + /// and + /// methods differ only in their + /// behavior when the queue is empty: the + /// method throws an exception, + /// while the method returns + /// . + ///

+ ///

+ /// The and + /// methods return, but do + /// not remove, the head of the queue. + ///

+ ///

+ /// The interface does not define the blocking queue + /// methods, which are common in concurrent programming. + ///

+ ///

+ /// implementations generally do not allow insertion + /// of elements, although some implementations, such as + /// a linked list, do not prohibit the insertion of . + /// Even in the implementations that permit it, should + /// not be inserted into a , as is also + /// used as a special return value by the + /// method to + /// indicate that the queue contains no elements. + ///

+ ///

+ /// implementations generally do not define + /// element-based versions of methods + /// and , but instead inherit the + /// identity based versions from the class object, because element-based equality + /// is not always well-defined for queues with the same elements but different + /// ordering properties. + ///

+ ///

+ /// Based on the back port of JCP JSR-166. + ///

+ ///
+ /// Doug Lea + /// Griffin Caprio (.NET) + public interface IQueue : ICollection + { + /// + /// Inserts the specified element into this queue if it is possible to do so + /// immediately without violating capacity restrictions, returning + /// upon success and throwing an + /// if no space is + /// currently available. + /// + /// + /// The element to add. + /// + /// + /// if successful. + /// + /// + /// If the element cannot be added at this time due to capacity restrictions. + /// + /// + /// If the class of the supplied prevents it + /// from being added to this queue. + /// + /// + /// If the specified element is and this queue does not + /// permit elements. + /// + /// + /// If some property of the supplied prevents + /// it from being added to this queue. + /// + bool Add(object objectToAdd); + + /// + /// Inserts the specified element into this queue if it is possible to do + /// so immediately without violating capacity restrictions. + /// + /// + ///

+ /// When using a capacity-restricted queue, this method is generally + /// preferable to , + /// which can fail to insert an element only by throwing an exception. + ///

+ ///
+ /// + /// The element to add. + /// + /// + /// if the element was added to this queue. + /// + /// + /// If the element cannot be added at this time due to capacity restrictions. + /// + /// + /// If the supplied is + /// . + /// + /// + /// If some property of the supplied prevents + /// it from being added to this queue. + /// + bool Offer(object objectToAdd); + + /// + /// Retrieves and removes the head of this queue. + /// + /// + ///

+ /// This method differs from + /// only in that it throws an exception if this queue is empty. + ///

+ ///
+ /// + /// The head of this queue + /// + /// if this queue is empty + object Remove(); + + /// + /// Retrieves and removes the head of this queue, + /// or returns if this queue is empty. + /// + /// + /// The head of this queue, or if this queue is empty. + /// + object Poll(); + + /// + /// Retrieves, but does not remove, the head of this queue. + /// + /// + ///

+ /// This method differs from + /// only in that it throws an exception if this queue is empty. + ///

+ ///
+ /// + /// The head of this queue. + /// + /// If this queue is empty. + object Element(); + + /// + /// Retrieves, but does not remove, the head of this queue, + /// or returns if this queue is empty. + /// + /// + /// The head of this queue, or if this queue is empty. + /// + object Peek(); + + /// + /// Returns if there are no elements in the , otherwise. + /// + bool IsEmpty { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/ISet.cs b/src/Spring/Spring.Core/Collections/ISet.cs index fb27dd38..1069640c 100644 --- a/src/Spring/Spring.Core/Collections/ISet.cs +++ b/src/Spring/Spring.Core/Collections/ISet.cs @@ -1,275 +1,274 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// A collection that contains no duplicate elements. - /// - /// - ///

- /// This interface models the mathematical - /// abstraction. The order of - /// elements in a set is dependant on (a)the data-structure implementation, and - /// (b)the implementation of the various - /// methods, and thus is not - /// guaranteed. - ///

- ///

- /// overrides the - /// method to test for "equivalency": - /// whether the two sets contain the same elements. The "==" and "!=" - /// operators are not overridden by design, since it is often desirable to - /// compare object references for equality. - ///

- ///

- /// Also, the method is not - /// implemented on any of the set implementations, since none of them are - /// truly immutable. This is by design, and it is the way almost all - /// collections in the .NET framework function. So as a general rule, don't - /// store collection objects inside - /// instances. You would typically want to use a keyed - /// instead. - ///

- ///

- /// None of the implementations in - /// this library are guaranteed to be thread-safe in any way unless wrapped - /// in a . - ///

- ///

- /// The following table summarizes the binary operators that are supported - /// by the class. - ///

- /// - /// - /// Operation - /// Description - /// Method - /// - /// - /// Union (OR) - /// - /// Element included in result if it exists in either A OR - /// B. - /// - /// Union() - /// - /// - /// Intersection (AND) - /// - /// Element included in result if it exists in both A AND - /// B. - /// - /// InterSect() - /// - /// - /// Exclusive Or (XOR) - /// - /// Element included in result if it exists in one, but not both, - /// of A and B. - /// - /// ExclusiveOr() - /// - /// - /// Minus (n/a) - /// - /// Take all the elements in A. Now, if any of them exist in - /// B, remove them. Note that unlike the other operators, - /// A - B is not the same as B - A. - /// - /// Minus() - /// - /// - ///
- /// $Id: ISet.cs,v 1.5 2006/04/09 07:18:37 markpollack Exp $ - public interface ISet : ICollection, ICloneable - { - /// - /// Performs a "union" of the two sets, where all the elements - /// in both sets are present. - /// - /// - ///

- /// That is, the element is included if it is in either - /// or this set. Neither this set nor the input - /// set are modified during the operation. The return value is a - /// clone of this set with the extra elements added in. - ///

- ///
- /// A collection of elements. - /// - /// A new containing the union of - /// this with the specified - /// collection. Neither of the input objects is modified by the union. - /// - ISet Union(ISet setOne); - - /// - /// Performs an "intersection" of the two sets, where only the elements - /// that are present in both sets remain. - /// - /// - ///

- /// That is, the element is included if it exists in both sets. The - /// Intersect() operation does not modify the input sets. It - /// returns a clone of this set with the appropriate elements - /// removed. - ///

- ///
- /// A set of elements. - /// - /// The intersection of this set with . - /// - ISet Intersect(ISet setOne); - - /// - /// Performs a "minus" of this set from the - /// set. - /// - /// - ///

- /// This returns a set of all the elements in set - /// , removing the elements that are also in - /// this set. The original sets are not modified during this operation. - /// The result set is a clone of this - /// containing the elements from - /// the operation. - ///

- ///
- /// A set of elements. - /// - /// A set containing the elements from this set with the elements in - /// removed. - /// - ISet Minus(ISet setOne); - - /// - /// Performs an "exclusive-or" of the two sets, keeping only those - /// elements that are in one of the sets, but not in both. - /// - /// - ///

- /// The original sets are not modified during this operation. The - /// result set is a clone of this set containing the elements - /// from the exclusive-or operation. - ///

- ///
- /// A set of elements. - /// - /// A set containing the result of - /// ^ this. - /// - ISet ExclusiveOr(ISet setOne); - - /// - /// Returns if this set contains the specified - /// element. - /// - /// The element to look for. - /// - /// if this set contains the specified element. - /// - bool Contains(object element); - - /// - /// Returns if the set contains all the - /// elements in the specified collection. - /// - /// A collection of objects. - /// - /// if the set contains all the elements in the - /// specified collection. - /// - bool ContainsAll(ICollection collection); - - /// - /// Returns if this set contains no elements. - /// - bool IsEmpty { get; } - - /// - /// Adds the specified element to this set if it is not already present. - /// - /// The object to add to the set. - /// - /// is the object was added, - /// if the object was already present. - /// - bool Add(object element); - - /// - /// Adds all the elements in the specified collection to the set if - /// they are not already present. - /// - /// A collection of objects to add to the set. - /// - /// is the set changed as a result of this - /// operation. - /// - bool AddAll(ICollection collection); - - /// - /// Removes the specified element from the set. - /// - /// The element to be removed. - /// - /// if the set contained the specified element. - /// - bool Remove(object element); - - /// - /// Remove all the specified elements from this set, if they exist in - /// this set. - /// - /// A collection of elements to remove. - /// - /// if the set was modified as a result of this - /// operation. - /// - bool RemoveAll(ICollection collection); - - /// - /// Retains only the elements in this set that are contained in the - /// specified collection. - /// - /// - /// The collection that defines the set of elements to be retained. - /// - /// - /// if this set changed as a result of this - /// operation. - /// - bool RetainAll(ICollection collection); - - /// - /// Removes all objects from this set. - /// - void Clear(); - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// A collection that contains no duplicate elements. + /// + /// + ///

+ /// This interface models the mathematical + /// abstraction. The order of + /// elements in a set is dependant on (a)the data-structure implementation, and + /// (b)the implementation of the various + /// methods, and thus is not + /// guaranteed. + ///

+ ///

+ /// overrides the + /// method to test for "equivalency": + /// whether the two sets contain the same elements. The "==" and "!=" + /// operators are not overridden by design, since it is often desirable to + /// compare object references for equality. + ///

+ ///

+ /// Also, the method is not + /// implemented on any of the set implementations, since none of them are + /// truly immutable. This is by design, and it is the way almost all + /// collections in the .NET framework function. So as a general rule, don't + /// store collection objects inside + /// instances. You would typically want to use a keyed + /// instead. + ///

+ ///

+ /// None of the implementations in + /// this library are guaranteed to be thread-safe in any way unless wrapped + /// in a . + ///

+ ///

+ /// The following table summarizes the binary operators that are supported + /// by the class. + ///

+ /// + /// + /// Operation + /// Description + /// Method + /// + /// + /// Union (OR) + /// + /// Element included in result if it exists in either A OR + /// B. + /// + /// Union() + /// + /// + /// Intersection (AND) + /// + /// Element included in result if it exists in both A AND + /// B. + /// + /// InterSect() + /// + /// + /// Exclusive Or (XOR) + /// + /// Element included in result if it exists in one, but not both, + /// of A and B. + /// + /// ExclusiveOr() + /// + /// + /// Minus (n/a) + /// + /// Take all the elements in A. Now, if any of them exist in + /// B, remove them. Note that unlike the other operators, + /// A - B is not the same as B - A. + /// + /// Minus() + /// + /// + ///
+ public interface ISet : ICollection, ICloneable + { + /// + /// Performs a "union" of the two sets, where all the elements + /// in both sets are present. + /// + /// + ///

+ /// That is, the element is included if it is in either + /// or this set. Neither this set nor the input + /// set are modified during the operation. The return value is a + /// clone of this set with the extra elements added in. + ///

+ ///
+ /// A collection of elements. + /// + /// A new containing the union of + /// this with the specified + /// collection. Neither of the input objects is modified by the union. + /// + ISet Union(ISet setOne); + + /// + /// Performs an "intersection" of the two sets, where only the elements + /// that are present in both sets remain. + /// + /// + ///

+ /// That is, the element is included if it exists in both sets. The + /// Intersect() operation does not modify the input sets. It + /// returns a clone of this set with the appropriate elements + /// removed. + ///

+ ///
+ /// A set of elements. + /// + /// The intersection of this set with . + /// + ISet Intersect(ISet setOne); + + /// + /// Performs a "minus" of this set from the + /// set. + /// + /// + ///

+ /// This returns a set of all the elements in set + /// , removing the elements that are also in + /// this set. The original sets are not modified during this operation. + /// The result set is a clone of this + /// containing the elements from + /// the operation. + ///

+ ///
+ /// A set of elements. + /// + /// A set containing the elements from this set with the elements in + /// removed. + /// + ISet Minus(ISet setOne); + + /// + /// Performs an "exclusive-or" of the two sets, keeping only those + /// elements that are in one of the sets, but not in both. + /// + /// + ///

+ /// The original sets are not modified during this operation. The + /// result set is a clone of this set containing the elements + /// from the exclusive-or operation. + ///

+ ///
+ /// A set of elements. + /// + /// A set containing the result of + /// ^ this. + /// + ISet ExclusiveOr(ISet setOne); + + /// + /// Returns if this set contains the specified + /// element. + /// + /// The element to look for. + /// + /// if this set contains the specified element. + /// + bool Contains(object element); + + /// + /// Returns if the set contains all the + /// elements in the specified collection. + /// + /// A collection of objects. + /// + /// if the set contains all the elements in the + /// specified collection. + /// + bool ContainsAll(ICollection collection); + + /// + /// Returns if this set contains no elements. + /// + bool IsEmpty { get; } + + /// + /// Adds the specified element to this set if it is not already present. + /// + /// The object to add to the set. + /// + /// is the object was added, + /// if the object was already present. + /// + bool Add(object element); + + /// + /// Adds all the elements in the specified collection to the set if + /// they are not already present. + /// + /// A collection of objects to add to the set. + /// + /// is the set changed as a result of this + /// operation. + /// + bool AddAll(ICollection collection); + + /// + /// Removes the specified element from the set. + /// + /// The element to be removed. + /// + /// if the set contained the specified element. + /// + bool Remove(object element); + + /// + /// Remove all the specified elements from this set, if they exist in + /// this set. + /// + /// A collection of elements to remove. + /// + /// if the set was modified as a result of this + /// operation. + /// + bool RemoveAll(ICollection collection); + + /// + /// Retains only the elements in this set that are contained in the + /// specified collection. + /// + /// + /// The collection that defines the set of elements to be retained. + /// + /// + /// if this set changed as a result of this + /// operation. + /// + bool RetainAll(ICollection collection); + + /// + /// Removes all objects from this set. + /// + void Clear(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/ImmutableSet.cs b/src/Spring/Spring.Core/Collections/ImmutableSet.cs index 399c4e3b..e541102a 100644 --- a/src/Spring/Spring.Core/Collections/ImmutableSet.cs +++ b/src/Spring/Spring.Core/Collections/ImmutableSet.cs @@ -1,357 +1,356 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// Implements an immutable (read-only) - /// wrapper. - /// - /// - ///

- /// Although this class is advertised as immutable, it really isn't. - /// Anyone with access to the wrapped - /// can still change the data. So - /// is not implemented for this , as - /// is the case for all - /// implementations in this library. This design decision was based on the - /// efficiency of not having to clone the wrapped - /// every time you wrap a mutable - /// . - ///

- ///
- /// $Id: ImmutableSet.cs,v 1.6 2007/03/16 04:01:28 aseovic Exp $ - [Serializable] - public sealed class ImmutableSet : Set - { - private const string ErrorMessage = "Object is immutable."; - private ISet _mBasisSet; - - internal ISet BasisSet - { - get { return _mBasisSet; } - } - - /// - /// Constructs an immutable (read-only) - /// wrapper. - /// - /// - /// The that is to be wrapped. - /// - public ImmutableSet(ISet basisSet) - { - _mBasisSet = basisSet; - } - - /// - /// Adds the specified element to this set if it is not already present. - /// - /// The object to add to the set. - /// - /// is the object was added, - /// if the object was already present. - /// - /// - public override sealed bool Add(object element) - { - throw CreateNotSupportedException(); - } - - /// - /// Adds all the elements in the specified collection to the set if - /// they are not already present. - /// - /// A collection of objects to add to the set. - /// - /// is the set changed as a result of this - /// operation. - /// - /// - public override sealed bool AddAll(ICollection collection) - { - throw CreateNotSupportedException(); - } - - /// - /// Removes all objects from this set. - /// - /// - public override sealed void Clear() - { - throw CreateNotSupportedException(); - } - - /// - /// Returns if this set contains the specified - /// element. - /// - /// The element to look for. - /// - /// if this set contains the specified element. - /// - public override sealed bool Contains(object element) - { - return _mBasisSet.Contains(element); - } - - /// - /// Returns if the set contains all the - /// elements in the specified collection. - /// - /// A collection of objects. - /// - /// if the set contains all the elements in the - /// specified collection. - /// - public override sealed bool ContainsAll(ICollection collection) - { - return _mBasisSet.ContainsAll(collection); - } - - /// - /// Returns if this set contains no elements. - /// - public override sealed bool IsEmpty - { - get { return _mBasisSet.IsEmpty; } - } - - /// - /// Removes the specified element from the set. - /// - /// The element to be removed. - /// - /// if the set contained the specified element. - /// - /// - public override sealed bool Remove(object element) - { - throw CreateNotSupportedException(); - } - - /// - /// Remove all the specified elements from this set, if they exist in - /// this set. - /// - /// A collection of elements to remove. - /// - /// if the set was modified as a result of this - /// operation. - /// - /// - public override sealed bool RemoveAll(ICollection collection) - { - throw CreateNotSupportedException(); - } - - /// - /// Retains only the elements in this set that are contained in the - /// specified collection. - /// - /// - /// The collection that defines the set of elements to be retained. - /// - /// - /// if this set changed as a result of this - /// operation. - /// - /// - public override sealed bool RetainAll(ICollection collection) - { - throw CreateNotSupportedException(); - } - - private static NotSupportedException CreateNotSupportedException() - { - return new NotSupportedException(ImmutableSet.ErrorMessage); - } - - /// - /// Copies the elements in the to - /// an array. - /// - /// - ///

- /// The type of array needs to be compatible with the objects in the - /// , obviously. - ///

- ///
- /// - /// An array that will be the target of the copy operation. - /// - /// - /// The zero-based index where copying will start. - /// - public override sealed void CopyTo(Array array, int index) - { - _mBasisSet.CopyTo(array, index); - } - - /// - /// The number of elements currently contained in this collection. - /// - public override sealed int Count - { - get { return _mBasisSet.Count; } - } - - /// - /// Returns if the - /// is synchronized across - /// threads. - /// - /// - ///

- /// Note that enumeration is inherently not thread-safe. Use the - /// to lock the object during enumeration. - ///

- ///
- public override sealed bool IsSynchronized - { - get { return _mBasisSet.IsSynchronized; } - } - - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - public override sealed object SyncRoot - { - get { return _mBasisSet.SyncRoot; } - } - - /// - /// Gets an enumerator for the elements in the - /// . - /// - /// - /// An over the elements - /// in the . - /// - public override sealed IEnumerator GetEnumerator() - { - return _mBasisSet.GetEnumerator(); - } - - /// - /// Returns a clone of the - /// instance. - /// - /// A clone of this object. - public override sealed object Clone() - { - return new ImmutableSet(_mBasisSet); - } - - /// - /// Performs a "union" of the two sets, where all the elements - /// in both sets are present. - /// - /// A collection of elements. - /// - /// A new containing the union of - /// this with the specified - /// collection. Neither of the input objects is modified by the union. - /// - /// - public override sealed ISet Union(ISet setOne) - { - ISet m = this; - while (m is ImmutableSet) - { - m = ((ImmutableSet) m).BasisSet; - } - return new ImmutableSet(m.Union(setOne)); - } - - /// - /// Performs an "intersection" of the two sets, where only the elements - /// that are present in both sets remain. - /// - /// A set of elements. - /// - /// The intersection of this set with . - /// - /// - public override sealed ISet Intersect(ISet setOne) - { - ISet m = this; - while (m is ImmutableSet) - { - m = ((ImmutableSet) m).BasisSet; - } - return new ImmutableSet(m.Intersect(setOne)); - } - - /// - /// Performs a "minus" of this set from the - /// set. - /// - /// A set of elements. - /// - /// A set containing the elements from this set with the elements in - /// removed. - /// - /// - public override sealed ISet Minus(ISet setOne) - { - ISet m = this; - while (m is ImmutableSet) - { - m = ((ImmutableSet) m).BasisSet; - } - return new ImmutableSet(m.Minus(setOne)); - } - - /// - /// Performs an "exclusive-or" of the two sets, keeping only those - /// elements that are in one of the sets, but not in both. - /// - /// A set of elements. - /// - /// A set containing the result of - /// ^ this. - /// - /// - public override sealed ISet ExclusiveOr(ISet setOne) - { - ISet m = this; - while (m is ImmutableSet) - { - m = ((ImmutableSet) m).BasisSet; - } - return new ImmutableSet(m.ExclusiveOr(setOne)); - } - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// Implements an immutable (read-only) + /// wrapper. + /// + /// + ///

+ /// Although this class is advertised as immutable, it really isn't. + /// Anyone with access to the wrapped + /// can still change the data. So + /// is not implemented for this , as + /// is the case for all + /// implementations in this library. This design decision was based on the + /// efficiency of not having to clone the wrapped + /// every time you wrap a mutable + /// . + ///

+ ///
+ [Serializable] + public sealed class ImmutableSet : Set + { + private const string ErrorMessage = "Object is immutable."; + private ISet _mBasisSet; + + internal ISet BasisSet + { + get { return _mBasisSet; } + } + + /// + /// Constructs an immutable (read-only) + /// wrapper. + /// + /// + /// The that is to be wrapped. + /// + public ImmutableSet(ISet basisSet) + { + _mBasisSet = basisSet; + } + + /// + /// Adds the specified element to this set if it is not already present. + /// + /// The object to add to the set. + /// + /// is the object was added, + /// if the object was already present. + /// + /// + public override sealed bool Add(object element) + { + throw CreateNotSupportedException(); + } + + /// + /// Adds all the elements in the specified collection to the set if + /// they are not already present. + /// + /// A collection of objects to add to the set. + /// + /// is the set changed as a result of this + /// operation. + /// + /// + public override sealed bool AddAll(ICollection collection) + { + throw CreateNotSupportedException(); + } + + /// + /// Removes all objects from this set. + /// + /// + public override sealed void Clear() + { + throw CreateNotSupportedException(); + } + + /// + /// Returns if this set contains the specified + /// element. + /// + /// The element to look for. + /// + /// if this set contains the specified element. + /// + public override sealed bool Contains(object element) + { + return _mBasisSet.Contains(element); + } + + /// + /// Returns if the set contains all the + /// elements in the specified collection. + /// + /// A collection of objects. + /// + /// if the set contains all the elements in the + /// specified collection. + /// + public override sealed bool ContainsAll(ICollection collection) + { + return _mBasisSet.ContainsAll(collection); + } + + /// + /// Returns if this set contains no elements. + /// + public override sealed bool IsEmpty + { + get { return _mBasisSet.IsEmpty; } + } + + /// + /// Removes the specified element from the set. + /// + /// The element to be removed. + /// + /// if the set contained the specified element. + /// + /// + public override sealed bool Remove(object element) + { + throw CreateNotSupportedException(); + } + + /// + /// Remove all the specified elements from this set, if they exist in + /// this set. + /// + /// A collection of elements to remove. + /// + /// if the set was modified as a result of this + /// operation. + /// + /// + public override sealed bool RemoveAll(ICollection collection) + { + throw CreateNotSupportedException(); + } + + /// + /// Retains only the elements in this set that are contained in the + /// specified collection. + /// + /// + /// The collection that defines the set of elements to be retained. + /// + /// + /// if this set changed as a result of this + /// operation. + /// + /// + public override sealed bool RetainAll(ICollection collection) + { + throw CreateNotSupportedException(); + } + + private static NotSupportedException CreateNotSupportedException() + { + return new NotSupportedException(ImmutableSet.ErrorMessage); + } + + /// + /// Copies the elements in the to + /// an array. + /// + /// + ///

+ /// The type of array needs to be compatible with the objects in the + /// , obviously. + ///

+ ///
+ /// + /// An array that will be the target of the copy operation. + /// + /// + /// The zero-based index where copying will start. + /// + public override sealed void CopyTo(Array array, int index) + { + _mBasisSet.CopyTo(array, index); + } + + /// + /// The number of elements currently contained in this collection. + /// + public override sealed int Count + { + get { return _mBasisSet.Count; } + } + + /// + /// Returns if the + /// is synchronized across + /// threads. + /// + /// + ///

+ /// Note that enumeration is inherently not thread-safe. Use the + /// to lock the object during enumeration. + ///

+ ///
+ public override sealed bool IsSynchronized + { + get { return _mBasisSet.IsSynchronized; } + } + + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + public override sealed object SyncRoot + { + get { return _mBasisSet.SyncRoot; } + } + + /// + /// Gets an enumerator for the elements in the + /// . + /// + /// + /// An over the elements + /// in the . + /// + public override sealed IEnumerator GetEnumerator() + { + return _mBasisSet.GetEnumerator(); + } + + /// + /// Returns a clone of the + /// instance. + /// + /// A clone of this object. + public override sealed object Clone() + { + return new ImmutableSet(_mBasisSet); + } + + /// + /// Performs a "union" of the two sets, where all the elements + /// in both sets are present. + /// + /// A collection of elements. + /// + /// A new containing the union of + /// this with the specified + /// collection. Neither of the input objects is modified by the union. + /// + /// + public override sealed ISet Union(ISet setOne) + { + ISet m = this; + while (m is ImmutableSet) + { + m = ((ImmutableSet) m).BasisSet; + } + return new ImmutableSet(m.Union(setOne)); + } + + /// + /// Performs an "intersection" of the two sets, where only the elements + /// that are present in both sets remain. + /// + /// A set of elements. + /// + /// The intersection of this set with . + /// + /// + public override sealed ISet Intersect(ISet setOne) + { + ISet m = this; + while (m is ImmutableSet) + { + m = ((ImmutableSet) m).BasisSet; + } + return new ImmutableSet(m.Intersect(setOne)); + } + + /// + /// Performs a "minus" of this set from the + /// set. + /// + /// A set of elements. + /// + /// A set containing the elements from this set with the elements in + /// removed. + /// + /// + public override sealed ISet Minus(ISet setOne) + { + ISet m = this; + while (m is ImmutableSet) + { + m = ((ImmutableSet) m).BasisSet; + } + return new ImmutableSet(m.Minus(setOne)); + } + + /// + /// Performs an "exclusive-or" of the two sets, keeping only those + /// elements that are in one of the sets, but not in both. + /// + /// A set of elements. + /// + /// A set containing the result of + /// ^ this. + /// + /// + public override sealed ISet ExclusiveOr(ISet setOne) + { + ISet m = this; + while (m is ImmutableSet) + { + m = ((ImmutableSet) m).BasisSet; + } + return new ImmutableSet(m.ExclusiveOr(setOne)); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/LinkedList.cs b/src/Spring/Spring.Core/Collections/LinkedList.cs index 18e188dc..1e8963ae 100644 --- a/src/Spring/Spring.Core/Collections/LinkedList.cs +++ b/src/Spring/Spring.Core/Collections/LinkedList.cs @@ -1,545 +1,544 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// Simple linked list implementation. - /// - /// Simon White - /// $Id: LinkedList.cs,v 1.9 2007/03/16 04:01:28 aseovic Exp $ - [Serializable] - public class LinkedList : IList - { - private int _nodeIndex; - private Node _rootNode; - private int _modId; - - #region Constructors - - /// - /// Creates a new instance of the - /// class. - /// - public LinkedList() - { - _rootNode = new Node(null, null, null); - _rootNode.PreviousNode = _rootNode; - _rootNode.NextNode = _rootNode; - } - - /// - /// Creates a new instance of the - /// class that contains all - /// elements of the specified list. - /// - /// - /// A list of elements that defines the initial contents. - /// - public LinkedList(IList list) : this() - { - AddAll(list); - } - - #endregion - - #region IList Members - - /// - /// Is list read only? - /// - /// - /// if the list is read only. - /// - public bool IsReadOnly - { - get { return false; } - } - - /// - /// Returns the node at the specified index. - /// - /// - ///

- /// This is the indexer for the - /// class. - ///

- ///
- /// - public object this[int index] - { - get { return GetNode(index).Value; } - set { GetNode(index).Value = value; } - } - - /// - /// Removes the object at the specified index. - /// - /// The lookup index. - /// - /// If the specified is greater than the - /// number of objects within the list. - /// - public void RemoveAt(int index) - { - CheckUpdateState(); - RemoveNode(GetNode(index)); - } - - /// - /// Inserts an object at the specified index. - /// - /// The lookup index. - /// The object to be inserted. - /// - /// If the specified is greater than the - /// number of objects within the list. - /// - public void Insert(int index, object value) - { - CheckUpdateState(); - - Node node = null; - if (index == _nodeIndex) - { - node = new Node(value, _rootNode.PreviousNode, _rootNode); - } - else - { - Node insert = GetNode(index); - node = new Node(value, insert.PreviousNode, insert); - } - node.PreviousNode.NextNode = node; - node.NextNode.PreviousNode = node; - _nodeIndex++; - _modId++; - } - - /// - /// Removes the first instance of the specified object found. - /// - /// The object to remove - public void Remove(object value) - { - CheckUpdateState(); - NodeHolder nh = GetNode(value); - RemoveNode(nh.Node); - } - - /// - /// Returns if this list contains the specified - /// element. - /// - /// The element to look for. - /// - /// if this list contains the specified element. - /// - public bool Contains(object value) - { - return GetNode(value) != null; - } - - /// - /// Removes all objects from the list. - /// - public void Clear() - { - _rootNode = new Node(null, null, null); - _nodeIndex = 0; - _modId++; - } - - /// - /// Returns the index of the first instance of the specified - /// found. - /// - /// The object to search for - /// - /// The index of the first instance found, or -1 if the element was not - /// found. - /// - public int IndexOf(object value) - { - NodeHolder nh = GetNode(value); - if (nh == null) - { - return -1; - } - return nh.Index; - } - - /// - /// Adds the specified object to the end of the list. - /// - /// The object to add - /// The index that the object was added at. - public int Add(object value) - { - Insert(_nodeIndex, value); - return _nodeIndex - 1; - } - - /// - /// Adds all of the elements of the supplied - /// list to the end of this list. - /// - /// The list of objects to add. - public void AddAll(IList elements) - { - foreach (object obj in elements) - { - Add(obj); - } - } - - /// - /// Is the list a fixed size? - /// - /// - /// if the list is a fixed size list. - /// - public bool IsFixedSize - { - get { return false; } - } - - #endregion - - #region Private Methods - - /// - /// Checks whether the list can be modified. - /// - /// - /// If the list cannot be modified. - /// - private void CheckUpdateState() - { - if (IsReadOnly || IsFixedSize) - { - throw new NotSupportedException("LinkedList cannot be modified."); - } - } - - /// - /// Validates the specified index. - /// - /// The lookup index. - /// - /// If the index is invalid. - /// - private void ValidateIndex(int index) - { - if (index < 0 || index >= _nodeIndex) - { - throw new ArgumentOutOfRangeException("index"); - } - } - - /// - /// Returns the node at the specified index. - /// - /// The lookup index. - /// The node at the specified index. - /// - /// If the specified is greater than the - /// number of objects within the list. - /// - private Node GetNode(int index) - { - ValidateIndex(index); - Node node = _rootNode; - for (int i = 0; i <= index; i++) - { - node = node.NextNode; - } - return node; - } - - /// - /// Returns the node (and index) of the first node that contains - /// the specified value. - /// - /// The value to search for. - /// - /// The node, or if not found. - /// - private NodeHolder GetNode(object value) - { - int i = 0; - if (value == null) - { - - for (Node n = _rootNode.NextNode; n != _rootNode; n = n.NextNode) - { - if (n.Value == null) - { - return new NodeHolder(n, i); - } - i++; - } - } - else - { - - for (Node n = _rootNode.NextNode; n != _rootNode; n = n.NextNode) - { - if (value.Equals(n.Value)) - { - return new NodeHolder(n, i); - } - i++; - } - } - return null; - } - - /// - /// Removes the specified node. - /// - /// The node to be removed. - private void RemoveNode(Node node) - { - Node previousNode = node.PreviousNode; - previousNode.NextNode = node.NextNode; - node.NextNode.PreviousNode = previousNode; - node.PreviousNode = null; - node.NextNode = null; - _nodeIndex--; - _modId++; - } - - #endregion - - #region ICollection Members - - /// - /// Returns if the list is synchronized across - /// threads. - /// - /// - /// - /// This implementation always returns . - /// - ///

- /// Note that enumeration is inherently not thread-safe. Use the - /// to lock the object during enumeration. - ///

- ///
- public bool IsSynchronized - { - get { return false; } - } - - /// - /// The number of objects within the list. - /// - public int Count - { - get { return _nodeIndex; } - } - - /// - /// Copies the elements in this list to an array. - /// - /// - ///

- /// The type of array needs to be compatible with the objects in this - /// list, obviously. - ///

- ///
- /// - /// An array that will be the target of the copy operation. - /// - /// - /// The zero-based index where copying will start. - /// - /// - /// If the supplied is . - /// - /// - /// If the supplied is less than zero - /// or is greater than the length of . - /// - /// - /// If the supplied is of insufficient size. - /// - public void CopyTo(Array array, int index) - { - if (array == null) - { - throw new ArgumentNullException("array"); - } - if ((index < 0) || (index > array.Length)) - { - throw new ArgumentOutOfRangeException("index", String.Format("Index {0} is out of range.", index)); - } - if ((array.Length - index) < this._nodeIndex) - { - throw new ArgumentException("Array is of insufficient size."); - } - - Node node = this._rootNode; - for (int i = 0, pos = index; i < this._nodeIndex; i++, pos++) - { - node = node.NextNode; - array.SetValue(node.Value, pos); - } - } - - /// - /// An object that can be used to synchronize this - /// to make it thread-safe. - /// - /// - /// An object that can be used to synchronize this - /// to make it thread-safe. - /// - public object SyncRoot - { - get { return this; } - } - - #endregion - - #region IEnumerable Members - - /// - /// Gets an enumerator for the elements in the - /// . - /// - /// - ///

- /// Enumerators are fail fast. - ///

- ///
- /// - /// An over the elements - /// in the . - /// - public IEnumerator GetEnumerator() - { - return new LinkedListEnumerator(this); - } - - #endregion - - #region Inner Classes - - [Serializable] - private class Node - { - private object _value; - private Node _next; - private Node _previous; - - public object Value - { - get { return _value; } - set { _value = value; } - } - - public Node NextNode - { - get { return _next; } - set { this._next = value; } - } - - public Node PreviousNode - { - get { return _previous; } - set { this._previous = value; } - } - - public Node(object val, Node previous, Node next) - { - this._value = val; - this._next = next; - this._previous = previous; - } - } - - private class NodeHolder - { - private int _index; - private Node _node; - - public int Index - { - get { return _index; } - } - - public Node Node - { - get { return _node; } - } - - public NodeHolder(Node node, int index) - { - this._node = node; - this._index = index; - } - } - - private class LinkedListEnumerator : IEnumerator - { - private LinkedList _ll; - private Node _current; - private int _modId; - - public object Current - { - get { return _current.Value; } - } - - public LinkedListEnumerator(LinkedList ll) - { - this._ll = ll; - this._modId = ll._modId; - this._current = _ll._rootNode; - } - - public bool MoveNext() - { - if (this._modId != this._ll._modId) - { - throw new InvalidOperationException("LinkedList has been modified."); - } - - _current = _current.NextNode; - return (_current == _ll._rootNode ? false : true); - } - - public void Reset() - { - _current = _ll._rootNode; - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// Simple linked list implementation. + /// + /// Simon White + [Serializable] + public class LinkedList : IList + { + private int _nodeIndex; + private Node _rootNode; + private int _modId; + + #region Constructors + + /// + /// Creates a new instance of the + /// class. + /// + public LinkedList() + { + _rootNode = new Node(null, null, null); + _rootNode.PreviousNode = _rootNode; + _rootNode.NextNode = _rootNode; + } + + /// + /// Creates a new instance of the + /// class that contains all + /// elements of the specified list. + /// + /// + /// A list of elements that defines the initial contents. + /// + public LinkedList(IList list) : this() + { + AddAll(list); + } + + #endregion + + #region IList Members + + /// + /// Is list read only? + /// + /// + /// if the list is read only. + /// + public bool IsReadOnly + { + get { return false; } + } + + /// + /// Returns the node at the specified index. + /// + /// + ///

+ /// This is the indexer for the + /// class. + ///

+ ///
+ /// + public object this[int index] + { + get { return GetNode(index).Value; } + set { GetNode(index).Value = value; } + } + + /// + /// Removes the object at the specified index. + /// + /// The lookup index. + /// + /// If the specified is greater than the + /// number of objects within the list. + /// + public void RemoveAt(int index) + { + CheckUpdateState(); + RemoveNode(GetNode(index)); + } + + /// + /// Inserts an object at the specified index. + /// + /// The lookup index. + /// The object to be inserted. + /// + /// If the specified is greater than the + /// number of objects within the list. + /// + public void Insert(int index, object value) + { + CheckUpdateState(); + + Node node = null; + if (index == _nodeIndex) + { + node = new Node(value, _rootNode.PreviousNode, _rootNode); + } + else + { + Node insert = GetNode(index); + node = new Node(value, insert.PreviousNode, insert); + } + node.PreviousNode.NextNode = node; + node.NextNode.PreviousNode = node; + _nodeIndex++; + _modId++; + } + + /// + /// Removes the first instance of the specified object found. + /// + /// The object to remove + public void Remove(object value) + { + CheckUpdateState(); + NodeHolder nh = GetNode(value); + RemoveNode(nh.Node); + } + + /// + /// Returns if this list contains the specified + /// element. + /// + /// The element to look for. + /// + /// if this list contains the specified element. + /// + public bool Contains(object value) + { + return GetNode(value) != null; + } + + /// + /// Removes all objects from the list. + /// + public void Clear() + { + _rootNode = new Node(null, null, null); + _nodeIndex = 0; + _modId++; + } + + /// + /// Returns the index of the first instance of the specified + /// found. + /// + /// The object to search for + /// + /// The index of the first instance found, or -1 if the element was not + /// found. + /// + public int IndexOf(object value) + { + NodeHolder nh = GetNode(value); + if (nh == null) + { + return -1; + } + return nh.Index; + } + + /// + /// Adds the specified object to the end of the list. + /// + /// The object to add + /// The index that the object was added at. + public int Add(object value) + { + Insert(_nodeIndex, value); + return _nodeIndex - 1; + } + + /// + /// Adds all of the elements of the supplied + /// list to the end of this list. + /// + /// The list of objects to add. + public void AddAll(IList elements) + { + foreach (object obj in elements) + { + Add(obj); + } + } + + /// + /// Is the list a fixed size? + /// + /// + /// if the list is a fixed size list. + /// + public bool IsFixedSize + { + get { return false; } + } + + #endregion + + #region Private Methods + + /// + /// Checks whether the list can be modified. + /// + /// + /// If the list cannot be modified. + /// + private void CheckUpdateState() + { + if (IsReadOnly || IsFixedSize) + { + throw new NotSupportedException("LinkedList cannot be modified."); + } + } + + /// + /// Validates the specified index. + /// + /// The lookup index. + /// + /// If the index is invalid. + /// + private void ValidateIndex(int index) + { + if (index < 0 || index >= _nodeIndex) + { + throw new ArgumentOutOfRangeException("index"); + } + } + + /// + /// Returns the node at the specified index. + /// + /// The lookup index. + /// The node at the specified index. + /// + /// If the specified is greater than the + /// number of objects within the list. + /// + private Node GetNode(int index) + { + ValidateIndex(index); + Node node = _rootNode; + for (int i = 0; i <= index; i++) + { + node = node.NextNode; + } + return node; + } + + /// + /// Returns the node (and index) of the first node that contains + /// the specified value. + /// + /// The value to search for. + /// + /// The node, or if not found. + /// + private NodeHolder GetNode(object value) + { + int i = 0; + if (value == null) + { + + for (Node n = _rootNode.NextNode; n != _rootNode; n = n.NextNode) + { + if (n.Value == null) + { + return new NodeHolder(n, i); + } + i++; + } + } + else + { + + for (Node n = _rootNode.NextNode; n != _rootNode; n = n.NextNode) + { + if (value.Equals(n.Value)) + { + return new NodeHolder(n, i); + } + i++; + } + } + return null; + } + + /// + /// Removes the specified node. + /// + /// The node to be removed. + private void RemoveNode(Node node) + { + Node previousNode = node.PreviousNode; + previousNode.NextNode = node.NextNode; + node.NextNode.PreviousNode = previousNode; + node.PreviousNode = null; + node.NextNode = null; + _nodeIndex--; + _modId++; + } + + #endregion + + #region ICollection Members + + /// + /// Returns if the list is synchronized across + /// threads. + /// + /// + /// + /// This implementation always returns . + /// + ///

+ /// Note that enumeration is inherently not thread-safe. Use the + /// to lock the object during enumeration. + ///

+ ///
+ public bool IsSynchronized + { + get { return false; } + } + + /// + /// The number of objects within the list. + /// + public int Count + { + get { return _nodeIndex; } + } + + /// + /// Copies the elements in this list to an array. + /// + /// + ///

+ /// The type of array needs to be compatible with the objects in this + /// list, obviously. + ///

+ ///
+ /// + /// An array that will be the target of the copy operation. + /// + /// + /// The zero-based index where copying will start. + /// + /// + /// If the supplied is . + /// + /// + /// If the supplied is less than zero + /// or is greater than the length of . + /// + /// + /// If the supplied is of insufficient size. + /// + public void CopyTo(Array array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + if ((index < 0) || (index > array.Length)) + { + throw new ArgumentOutOfRangeException("index", String.Format("Index {0} is out of range.", index)); + } + if ((array.Length - index) < this._nodeIndex) + { + throw new ArgumentException("Array is of insufficient size."); + } + + Node node = this._rootNode; + for (int i = 0, pos = index; i < this._nodeIndex; i++, pos++) + { + node = node.NextNode; + array.SetValue(node.Value, pos); + } + } + + /// + /// An object that can be used to synchronize this + /// to make it thread-safe. + /// + /// + /// An object that can be used to synchronize this + /// to make it thread-safe. + /// + public object SyncRoot + { + get { return this; } + } + + #endregion + + #region IEnumerable Members + + /// + /// Gets an enumerator for the elements in the + /// . + /// + /// + ///

+ /// Enumerators are fail fast. + ///

+ ///
+ /// + /// An over the elements + /// in the . + /// + public IEnumerator GetEnumerator() + { + return new LinkedListEnumerator(this); + } + + #endregion + + #region Inner Classes + + [Serializable] + private class Node + { + private object _value; + private Node _next; + private Node _previous; + + public object Value + { + get { return _value; } + set { _value = value; } + } + + public Node NextNode + { + get { return _next; } + set { this._next = value; } + } + + public Node PreviousNode + { + get { return _previous; } + set { this._previous = value; } + } + + public Node(object val, Node previous, Node next) + { + this._value = val; + this._next = next; + this._previous = previous; + } + } + + private class NodeHolder + { + private int _index; + private Node _node; + + public int Index + { + get { return _index; } + } + + public Node Node + { + get { return _node; } + } + + public NodeHolder(Node node, int index) + { + this._node = node; + this._index = index; + } + } + + private class LinkedListEnumerator : IEnumerator + { + private LinkedList _ll; + private Node _current; + private int _modId; + + public object Current + { + get { return _current.Value; } + } + + public LinkedListEnumerator(LinkedList ll) + { + this._ll = ll; + this._modId = ll._modId; + this._current = _ll._rootNode; + } + + public bool MoveNext() + { + if (this._modId != this._ll._modId) + { + throw new InvalidOperationException("LinkedList has been modified."); + } + + _current = _current.NextNode; + return (_current == _ll._rootNode ? false : true); + } + + public void Reset() + { + _current = _ll._rootNode; + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/ListSet.cs b/src/Spring/Spring.Core/Collections/ListSet.cs index ace9afc2..87e90277 100644 --- a/src/Spring/Spring.Core/Collections/ListSet.cs +++ b/src/Spring/Spring.Core/Collections/ListSet.cs @@ -1,70 +1,70 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; - -#endregion - -namespace Spring.Collections -{ - /// - /// Implements a based on a list. - /// - /// - ///

- /// Performance is much better for very small lists than either - /// or . - /// However, performance degrades rapidly as the data-set gets bigger. Use a - /// instead if you are not sure your data-set - /// will always remain very small. Iteration produces elements in the order they were added. - /// However, element order is not guaranteed to be maintained by the various - /// mathematical operators. - ///

- ///
- [Serializable] - public class ListSet : DictionarySet - { - /// - /// Creates a new set instance based on a list. - /// - public ListSet() - { - InternalDictionary = new ListDictionary(); - } - - /// - /// Creates a new set instance based on a list and initializes it based on a - /// collection of elements. - /// - /// - /// A collection of elements that defines the initial set contents. - /// - public ListSet(ICollection initialValues) : this() - { - this.AddAll(initialValues); - } - } -} +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; + +#endregion + +namespace Spring.Collections +{ + /// + /// Implements a based on a list. + /// + /// + ///

+ /// Performance is much better for very small lists than either + /// or . + /// However, performance degrades rapidly as the data-set gets bigger. Use a + /// instead if you are not sure your data-set + /// will always remain very small. Iteration produces elements in the order they were added. + /// However, element order is not guaranteed to be maintained by the various + /// mathematical operators. + ///

+ ///
+ [Serializable] + public class ListSet : DictionarySet + { + /// + /// Creates a new set instance based on a list. + /// + public ListSet() + { + InternalDictionary = new ListDictionary(); + } + + /// + /// Creates a new set instance based on a list and initializes it based on a + /// collection of elements. + /// + /// + /// A collection of elements that defines the initial set contents. + /// + public ListSet(ICollection initialValues) : this() + { + this.AddAll(initialValues); + } + } +} diff --git a/src/Spring/Spring.Core/Collections/NoElementsException.cs b/src/Spring/Spring.Core/Collections/NoElementsException.cs index af54bfe1..ac86c39c 100644 --- a/src/Spring/Spring.Core/Collections/NoElementsException.cs +++ b/src/Spring/Spring.Core/Collections/NoElementsException.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Collections -{ - /// - /// Thrown when an element is requested from an empty . - /// - /// Griffin Caprio - /// $Id: NoElementsException.cs,v 1.4 2006/04/09 07:18:37 markpollack Exp $ - [Serializable] - public class NoElementsException : ApplicationException - { - /// - /// Creates a new instance of the - /// class. - /// - public NoElementsException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NoElementsException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - public NoElementsException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NoElementsException(string message, Exception rootCause) - : base(message, rootCause) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Collections +{ + /// + /// Thrown when an element is requested from an empty . + /// + /// Griffin Caprio + [Serializable] + public class NoElementsException : ApplicationException + { + /// + /// Creates a new instance of the + /// class. + /// + public NoElementsException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NoElementsException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + public NoElementsException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NoElementsException(string message, Exception rootCause) + : base(message, rootCause) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/PriorityQueue.cs b/src/Spring/Spring.Core/Collections/PriorityQueue.cs index 338141c0..52086f2f 100644 --- a/src/Spring/Spring.Core/Collections/PriorityQueue.cs +++ b/src/Spring/Spring.Core/Collections/PriorityQueue.cs @@ -1,833 +1,833 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Diagnostics; -using System.Reflection; -using System.Runtime.Serialization; - -namespace Spring.Collections -{ - /// - /// An unbounded priority based on a priority - /// heap. This queue orders elements according to an order specified - /// at construction time, which is specified either according to their - /// natural order (see , or according to a - /// , depending on which constructor is - /// used. A priority queue does not permit elements. - /// A priority queue relying on natural ordering also does not - /// permit insertion of non-comparable objects (doing so will result - /// . - /// - ///

- /// The head of this queue is the lowest element - /// with respect to the specified ordering. If multiple elements are - /// tied for lowest value, the head is one of those elements -- ties are - /// broken arbitrarily. - /// - ///

- /// A priority queue is unbounded, but has an internal - /// capacity governing the size of an array used to store the - /// elements on the queue. It is always at least as large as the queue - /// size. As elements are added to a priority queue, its capacity - /// grows automatically. The details of the growth policy are not - /// specified. - /// - ///

- /// This class and its enumerator implement all of the - /// optional methods of the and - /// interfaces. - /// The enumerator provided in method - /// is not guaranteed to traverse the elements of the PriorityQueue in any - /// particular order. - /// - ///

- /// Note that this implementation is NOT synchronized. - /// Multiple threads should not access a - /// instance concurrently if any of the threads modifies the list - /// structurally. Instead, use the thread-safe PriorityBlockingQueue. - ///

- /// Josh Bloch - /// Griffin Caprio (.NET) - [Serializable] - public class PriorityQueue : AbstractQueue, ISerializable - { - private class PriorityQueueEnumerator : IEnumerator - { - private PriorityQueue _enclosingInstance; - - public PriorityQueueEnumerator(PriorityQueue enclosingInstance) - { - _enclosingInstance = enclosingInstance; - } - - public Object Current - { - get - { - Object result = null; - if (_cursorIndex <= _enclosingInstance._priorityQueueSize) - { - result = _enclosingInstance._queue[_cursorIndex]; - } - return result; - } - - } - - /// - /// Index (into queue array) of element to be returned by subsequent call to next. - /// - private int _cursorIndex = 0; - - public bool MoveNext() - { - if ( _cursorIndex < _enclosingInstance._priorityQueueSize ) - { - _cursorIndex++; - return true; - } - return false; - } - - public void Reset() - { - _cursorIndex = 0; - } - } - - - #region Private Fields - - private const int DEFAULT_INITIAL_CAPACITY = 11; - - /// - /// Priority queue represented as a balanced binary heap: the two children - /// of queue[n] are queue[2*n] and queue[2*n + 1]. The priority queue is - /// ordered by comparator, or by the elements' natural ordering, if - /// comparator is null: For each node n in the heap and each descendant d - /// of n, n <= d. - /// - /// The element with the lowest value is in queue[1], assuming the queue is - /// nonempty. (A one-based array is used in preference to the traditional - /// zero-based array to simplify parent and child calculations.) - /// - /// queue.length must be >= 2, even if size == 0. - /// - [NonSerialized] private object[] _queue; - - /// The number of elements in the priority queue. - private int _priorityQueueSize = 0; - - /// - /// The comparator, or null if priority queue uses elements' - /// natural ordering. - /// - private IComparer _comparator; - - /// - /// The number of times this priority queue has been - /// structurally modified. - /// - [NonSerialized] private int _queueModificationCount = 0; - - #endregion - - #region Constructors - - /// - /// Creates a with the default initial capacity - /// (11) that orders its elements according to their natural - /// ordering (using ). - /// - public PriorityQueue() : this(DEFAULT_INITIAL_CAPACITY, null) - { - } - - /// - /// Creates a with the specified initial capacity - /// that orders its elements according to their natural ordering - /// (using ). - /// - /// the initial capacity for this priority queue. - /// - /// if is less than 1. - public PriorityQueue(int initialCapacity) : this(initialCapacity, null) - { - } - - /// - /// Creates a with the specified initial capacity - /// that orders its elements according to the specified comparator. - /// - /// the initial capacity for this priority queue. - /// the comparator used to order this priority queue. - /// If then the order depends on the elements' natural ordering. - /// - /// if is less than 1. - public PriorityQueue(int initialCapacity, IComparer comparator) - { - if (initialCapacity < 1) - throw new ArgumentException("initialCapacity"); - _queue = new object[initialCapacity + 1]; - _comparator = comparator; - } - - /// - /// Creates a containing the elements in the - /// specified collection. The priority queue has an initial - /// capacity of 110% of the size of the specified collection or 1 - /// if the collection is empty. If the specified collection is an - /// instance of a , the priority queue will be sorted - /// according to the same comparator, or according to its elements' - /// natural order if the collection is sorted according to its - /// elements' natural order. Otherwise, the priority queue is - /// ordered according to its elements' natural order. - /// - /// the collection whose elements are to be placed into this priority queue. - /// if elements of cannot be - /// compared to one another according to the priority queue's ordering - /// if or any element with it is - /// - /// - public PriorityQueue(ICollection collection) - { - if ( null == collection ) - throw new ArgumentNullException("collection"); - initializeArray(collection); - if (collection is PriorityQueue) - { - PriorityQueue s = (PriorityQueue) collection; - _comparator = s.Comparator(); - fillFromSorted(s); - } - else - { - _comparator = null; - fillFromUnsorted(collection); - } - } - - #endregion - - #region Private Helper Methods - - /// - /// Common code to initialize underlying queue array across - /// constructors below. - /// - private void initializeArray(ICollection c) - { - int size = c.Count; - int initialCapacity = getQueueSizeBasedOnPercentage(size, 110); - if (initialCapacity < 1) - initialCapacity = 1; - - _queue = new Object[initialCapacity + 1]; - } - - /// - /// Performs an unsigned bitwise right shift with the specified number - /// - /// Number to operate on - /// Ammount of bits to shift - /// The resulting number from the shift operation - private int urShift(int number, int bits) - { - if (number >= 0) - return number >> bits; - else - return (number >> bits) + (2 << ~bits); - } - - /// - /// Establishes the heap invariant assuming the heap - /// satisfies the invariant except possibly for the leaf-node indexed by k - /// (which may have a nextExecutionTime less than its parent's). - /// - /// - /// This method functions by "promoting" queue[k] up the hierarchy - /// (by swapping it with its parent) repeatedly until queue[k] - /// is greater than or equal to its parent. - /// - private void fixUp(int k) - { - if (_comparator == null) - { - while (k > 1) - { - int j = k >> 1; - if (((IComparable) _queue[j]).CompareTo(_queue[k]) <= 0) - break; - Object tmp = _queue[j]; - _queue[j] = _queue[k]; - _queue[k] = tmp; - k = j; - } - } - else - { - while (k > 1) - { - int j = urShift(k, 1); - if (_comparator.Compare(_queue[j], _queue[k]) <= 0) - break; - Object tmp = _queue[j]; - _queue[j] = _queue[k]; - _queue[k] = tmp; - k = j; - } - } - } - - /// - /// Establishes the heap invariant (described above) in the subtree - /// rooted at k, which is assumed to satisfy the heap invariant except - /// possibly for node k itself (which may be greater than its children). - /// - /// - /// This method functions by "demoting" queue[k] down the hierarchy - /// (by swapping it with its smaller child) repeatedly until queue[k] - /// is less than or equal to its children. - /// - private void fixDown(int k) - { - int j; - if (_comparator == null) - { - while ((j = k << 1) <= _priorityQueueSize && (j > 0)) - { - if (j < _priorityQueueSize && ((IComparable) _queue[j]).CompareTo(_queue[j + 1]) > 0) - j++; // j indexes smallest kid - - if (((IComparable) _queue[k]).CompareTo(_queue[j]) <= 0) - break; - Object tmp = _queue[j]; - _queue[j] = _queue[k]; - _queue[k] = tmp; - k = j; - } - } - else - { - while ((j = k << 1) <= _priorityQueueSize && (j > 0)) - { - if (j < _priorityQueueSize && _comparator.Compare(_queue[j], _queue[j + 1]) > 0) - j++; // j indexes smallest kid - if (_comparator.Compare(_queue[k], _queue[j]) <= 0) - break; - Object tmp = _queue[j]; - _queue[j] = _queue[k]; - _queue[k] = tmp; - k = j; - } - } - } - - /// - /// Establishes the heap invariant in the entire tree, - /// assuming nothing about the order of the elements prior to the call. - /// - private void heapify() - { - for (int i = _priorityQueueSize/2; i >= 1; i--) - fixDown(i); - } - - /// - /// Returns the of or - 1, - /// whichever is smaller. - /// - /// base size - /// percentage to return - /// of - private int getQueueSizeBasedOnPercentage(int size, long percentage) - { - return (int) Math.Min((size*percentage)/100, Int32.MaxValue - 1); - } - - /// - /// Initially fill elements of the queue array under the - /// knowledge that it is sorted or is another , in which - /// case we can just place the elements in the order presented. - /// - private void fillFromSorted(ICollection collection) - { - fillArray(collection, true); - } - - private void fillArray(ICollection collection, bool sorted) - { - foreach (object currentObject in collection) - { - if (null == currentObject ) - throw new ArgumentNullException("collection", "Cannot add null elements to queue."); - _queue[++_priorityQueueSize] = currentObject; - } - if (! sorted) - { - heapify(); - } - } - - /// - /// Initially fill elements of the queue array that is not to our knowledge - /// sorted, so we must rearrange the elements to guarantee the heap - /// invariant. - /// - private void fillFromUnsorted(ICollection collection) - { - fillArray(collection, false); - } - - /// - /// Removes and returns element located at from queue. (Recall that the queue - /// is one-based, so 1 <= i <= size.) - /// - /// - /// Normally this method leaves the elements at positions from 1 up to i-1, - /// inclusive, untouched. Under these circumstances, it returns . - /// Occasionally, in order to maintain the heap invariant, it must move - /// the last element of the list to some index in the range [2, i-1], - /// and move the element previously at position (i/2) to position i. - /// Under these circumstances, this method returns the element that was - /// previously at the end of the list and is now at some position between - /// 2 and i-1 inclusive. - /// - private Object removeAt(int index) - { - Debug.Assert(index > 0 && index <= _priorityQueueSize); - _queueModificationCount++; - - Object moved = _queue[_priorityQueueSize]; - _queue[index] = moved; - _queue[_priorityQueueSize--] = null; - if (index <= _priorityQueueSize) - { - fixDown(index); - if (_queue[index] == moved) - { - fixUp(index); - if (_queue[index] != moved) - return moved; - } - } - return null; - } - - /// Resize array, if necessary, to be able to hold given index - private void grow(int index) - { - int newLength = _queue.Length; - if (index < newLength) - return; - if (index == Int32.MaxValue) - throw new InvalidOperationException("Cannot grow queue to accomdate index " + index + ". Doing so would result in a memory overflow."); - while (newLength <= index) - { - if (newLength >= Int32.MaxValue/2) - { - newLength = Int32.MaxValue; - } - else - { - newLength <<= 2; - } - } - Object[] newQueue = new Object[newLength]; - Array.Copy(_queue, 0, newQueue, 0, _queue.Length); - _queue = newQueue; - } - - #endregion - - #region Public Methods - /// - /// Gets the Capacity of this queue. Will equal - /// - public override int Capacity - { - get - { - return _queue.Length; - } - } - - /// - /// Returns the queue count. - /// - public override int Count - { - get { return _priorityQueueSize; } - } - - /// - /// Inserts the specified element into this queue if it is possible to do - /// so immediately without violating capacity restrictions. - /// - /// - ///

- /// When using a capacity-restricted queue, this method is generally - /// preferable to , - /// which can fail to insert an element only by throwing an exception. - ///

- ///
- /// - /// The element to add. - /// - /// - /// if the element was added to this queue. - /// - /// - /// if the specified element cannot be compared - /// with elements currently in the priority queue according - /// to the priority queue's ordering. - /// - /// - /// If the element cannot be added at this time due to capacity restrictions. - /// - /// - /// If the supplied is - /// and this queue does not permit - /// elements. - /// - /// - /// If some property of the supplied prevents - /// it from being added to this queue. - /// - public override bool Offer(Object objectToAdd) - { - if (objectToAdd == null) - throw new ArgumentNullException("objectToAdd"); - _queueModificationCount++; - ++_priorityQueueSize; - - if (_priorityQueueSize >= _queue.Length) - { - grow(_priorityQueueSize); - } - _queue[_priorityQueueSize] = objectToAdd; - fixUp(_priorityQueueSize); - return true; - } - - /// - /// Retrieves, but does not remove, the head of this queue, - /// or returns if this queue is empty. - /// - /// - /// The head of this queue, or if this queue is empty. - /// - public override Object Peek() - { - if (_priorityQueueSize == 0) - return null; - return _queue[1]; - } - - // Collection Methods - the first two override to update docs - /// - /// Inserts the specified element into this queue if it is possible to do so - /// immediately without violating capacity restrictions, returning - /// upon success and throwing an - /// if no space is - /// currently available. - /// - /// - /// The element to add. - /// - /// - /// if successful. - /// - /// - /// If the element cannot be added at this time due to capacity restrictions. - /// - /// - /// If the specified element is and this queue does not - /// permit elements. - /// - /// - /// If some property of the supplied prevents - /// it from being added to this queue. - /// - /// - /// if the specified element cannot be compared - /// with elements currently in the priority queue according - /// to the priority queue's ordering. - /// - public override bool Add(Object objectToAdd) - { - return Offer(objectToAdd); - } - - /// - /// Removes a single instance of the specified element from this - /// queue, if it is present. - /// - public virtual bool Remove(Object objectToRemove) - { - if (objectToRemove == null) - { - return false; - } - - if (_comparator == null) - { - for (int i = 1; i <= _priorityQueueSize; i++) - { - if (((IComparable) _queue[i]).CompareTo(objectToRemove) == 0) - { - removeAt(i); - return true; - } - } - } - else - { - for (int i = 1; i <= _priorityQueueSize; i++) - { - if (_comparator.Compare(_queue[i], objectToRemove) == 0) - { - removeAt(i); - return true; - } - } - } - return false; - } - - /// - /// Returns an over the elements in this queue. - /// The enumeratoar does not return the elements in any particular order. - /// - /// an enumerator over the elements in this queue. - public override IEnumerator GetEnumerator() - { - return new PriorityQueueEnumerator(this); - } - - - /// - /// Removes all elements from the priority queue. - /// The queue will be empty after this call returns. - /// - public override void Clear() - { - _queueModificationCount++; - - for (int i = 1; i <= _priorityQueueSize; i++) - _queue[i] = null; - - _priorityQueueSize = 0; - } - - /// - /// Retrieves and removes the head of this queue, - /// or returns if this queue is empty. - /// - /// - /// The head of this queue, or if this queue is empty. - /// - public override Object Poll() - { - if (_priorityQueueSize == 0) - return null; - _queueModificationCount++; - - Object result = _queue[1]; - _queue[1] = _queue[_priorityQueueSize]; - _queue[_priorityQueueSize--] = null; - if (_priorityQueueSize > 1) - fixDown(1); - return result; - } - /// - /// Queries the queue to see if it contains the specified - /// - /// element to look for. - /// if the queue contains the , - /// otherwise. - public bool Contains( object element ) - { - if (element == null) - { - for (int num1 = 0; num1 < Capacity; num1++) - { - if (_queue[num1] == null) - { - return true; - } - } - return false; - } - for (int num2 = 0; num2 < Capacity; num2++) - { - if (element.Equals(_queue[num2])) - { - return true; - } - } - return false; - } - - - /// Returns the comparator used to order this collection, or - /// if this collection is sorted according to its elements natural ordering - /// (using ). - /// - /// - /// the comparator used to order this collection, or - /// if this collection is sorted according to its elements natural ordering. - /// - public virtual IComparer Comparator() - { - return _comparator; - } - #endregion - - #region ISerializable Implementation - /// - /// Save the state of the instance to a stream (that - /// is, serialize it). - /// - /// The length of the array backing the instance is - /// emitted (int), followed by all of its elements (each an - /// ) in the proper order. - /// - /// the stream - /// the context - public virtual void GetObjectData(SerializationInfo serializationInfo, StreamingContext context) - { - Type thisType = this.GetType(); - MemberInfo[] mi = FormatterServices.GetSerializableMembers(thisType, context); - for (int i = 0; i < mi.Length; i++) - { - serializationInfo.AddValue(mi[i].Name, ((FieldInfo) mi[i]).GetValue(this)); - } - - // Write out array length - serializationInfo.AddValue("Spring.Collections.PriorityQueuedata1", _queue.Length); - - // Write out all elements in the proper order. - for (int i = 1; i <= _priorityQueueSize; i++) - { - serializationInfo.AddValue("Spring.Collections.PriorityQueueData" + i, _queue[i]); - } - } - - /// - /// Reconstitute the instance from a stream (that is, - /// deserialize it). - /// - /// the stream - /// the context - protected PriorityQueue(SerializationInfo serializationInfo, StreamingContext context) - { - Type thisType = this.GetType(); - MemberInfo[] mi = FormatterServices.GetSerializableMembers(thisType, context); - for (int i = 0; i < mi.Length; i++) - { - FieldInfo fi = (FieldInfo) mi[i]; - fi.SetValue(this, serializationInfo.GetValue(fi.Name, fi.FieldType)); - } - int arrayLength = serializationInfo.GetInt32("Spring.Collections.PriorityQueuedata1"); - _queue = new Object[arrayLength]; - - for (int i = 1; i <= _priorityQueueSize; i++) - { - _queue[i] = serializationInfo.GetValue("Spring.Collections.PriorityQueueData" + i, typeof (Object)); - } - } - #endregion - - #region ICollection Implementation - - /// - ///Copies the elements of the to an , starting at a particular index. - /// - ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - ///The zero-based index in array at which copying begins. - ///array is null. - ///index is less than zero. - ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. - ///The type of the source cannot be cast automatically to the type of the destination array. 2 - public override void CopyTo(Array array,Int32 index) - { - if ( _priorityQueueSize > array.Length ) throw new ArgumentException("Destination array too small.", "array"); - if ( index > array.Length - 1 ) throw new ArgumentException("Starting index outside bounds of target array.", "index"); - if ( index + _priorityQueueSize > array.Length ) throw new IndexOutOfRangeException("Destination array not long enough to begin copying at index " + index + "."); - - for ( int queueElementCount = 1; queueElementCount <= _priorityQueueSize; queueElementCount++) - { - array.SetValue(_queue[queueElementCount], index ); - index++; - } - Array.Sort(array); - } - - /// - ///Copies the elements of the to an , starting at index 0. - /// - ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - ///array is null. - ///index is less than zero. - ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. - ///The type of the source cannot be cast automatically to the type of the destination array. 2 - public void CopyTo(Array array) - { - CopyTo(array, 0); - } - - /// - ///Gets an object that can be used to synchronize access to the . - /// - /// - ///An object that can be used to synchronize access to the . - /// - public override Object SyncRoot - { - get { return null; } - - } - - /// - ///Gets a value indicating whether access to the is synchronized (thread safe). - /// - /// - ///true if access to the is synchronized (thread safe); otherwise, false. - /// - public override Boolean IsSynchronized - { - get { return false; } - - } - - /// - /// Returns if there are no elements in the , otherwise. - /// - public override bool IsEmpty - { - get { return _priorityQueueSize == 0; } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Spring.Collections +{ + /// + /// An unbounded priority based on a priority + /// heap. This queue orders elements according to an order specified + /// at construction time, which is specified either according to their + /// natural order (see , or according to a + /// , depending on which constructor is + /// used. A priority queue does not permit elements. + /// A priority queue relying on natural ordering also does not + /// permit insertion of non-comparable objects (doing so will result + /// . + /// + ///

+ /// The head of this queue is the lowest element + /// with respect to the specified ordering. If multiple elements are + /// tied for lowest value, the head is one of those elements -- ties are + /// broken arbitrarily. + /// + ///

+ /// A priority queue is unbounded, but has an internal + /// capacity governing the size of an array used to store the + /// elements on the queue. It is always at least as large as the queue + /// size. As elements are added to a priority queue, its capacity + /// grows automatically. The details of the growth policy are not + /// specified. + /// + ///

+ /// This class and its enumerator implement all of the + /// optional methods of the and + /// interfaces. + /// The enumerator provided in method + /// is not guaranteed to traverse the elements of the PriorityQueue in any + /// particular order. + /// + ///

+ /// Note that this implementation is NOT synchronized. + /// Multiple threads should not access a + /// instance concurrently if any of the threads modifies the list + /// structurally. Instead, use the thread-safe PriorityBlockingQueue. + ///

+ /// Josh Bloch + /// Griffin Caprio (.NET) + [Serializable] + public class PriorityQueue : AbstractQueue, ISerializable + { + private class PriorityQueueEnumerator : IEnumerator + { + private PriorityQueue _enclosingInstance; + + public PriorityQueueEnumerator(PriorityQueue enclosingInstance) + { + _enclosingInstance = enclosingInstance; + } + + public Object Current + { + get + { + Object result = null; + if (_cursorIndex <= _enclosingInstance._priorityQueueSize) + { + result = _enclosingInstance._queue[_cursorIndex]; + } + return result; + } + + } + + /// + /// Index (into queue array) of element to be returned by subsequent call to next. + /// + private int _cursorIndex = 0; + + public bool MoveNext() + { + if ( _cursorIndex < _enclosingInstance._priorityQueueSize ) + { + _cursorIndex++; + return true; + } + return false; + } + + public void Reset() + { + _cursorIndex = 0; + } + } + + + #region Private Fields + + private const int DEFAULT_INITIAL_CAPACITY = 11; + + /// + /// Priority queue represented as a balanced binary heap: the two children + /// of queue[n] are queue[2*n] and queue[2*n + 1]. The priority queue is + /// ordered by comparator, or by the elements' natural ordering, if + /// comparator is null: For each node n in the heap and each descendant d + /// of n, n <= d. + /// + /// The element with the lowest value is in queue[1], assuming the queue is + /// nonempty. (A one-based array is used in preference to the traditional + /// zero-based array to simplify parent and child calculations.) + /// + /// queue.length must be >= 2, even if size == 0. + /// + [NonSerialized] private object[] _queue; + + /// The number of elements in the priority queue. + private int _priorityQueueSize = 0; + + /// + /// The comparator, or null if priority queue uses elements' + /// natural ordering. + /// + private IComparer _comparator; + + /// + /// The number of times this priority queue has been + /// structurally modified. + /// + [NonSerialized] private int _queueModificationCount = 0; + + #endregion + + #region Constructors + + /// + /// Creates a with the default initial capacity + /// (11) that orders its elements according to their natural + /// ordering (using ). + /// + public PriorityQueue() : this(DEFAULT_INITIAL_CAPACITY, null) + { + } + + /// + /// Creates a with the specified initial capacity + /// that orders its elements according to their natural ordering + /// (using ). + /// + /// the initial capacity for this priority queue. + /// + /// if is less than 1. + public PriorityQueue(int initialCapacity) : this(initialCapacity, null) + { + } + + /// + /// Creates a with the specified initial capacity + /// that orders its elements according to the specified comparator. + /// + /// the initial capacity for this priority queue. + /// the comparator used to order this priority queue. + /// If then the order depends on the elements' natural ordering. + /// + /// if is less than 1. + public PriorityQueue(int initialCapacity, IComparer comparator) + { + if (initialCapacity < 1) + throw new ArgumentException("initialCapacity"); + _queue = new object[initialCapacity + 1]; + _comparator = comparator; + } + + /// + /// Creates a containing the elements in the + /// specified collection. The priority queue has an initial + /// capacity of 110% of the size of the specified collection or 1 + /// if the collection is empty. If the specified collection is an + /// instance of a , the priority queue will be sorted + /// according to the same comparator, or according to its elements' + /// natural order if the collection is sorted according to its + /// elements' natural order. Otherwise, the priority queue is + /// ordered according to its elements' natural order. + /// + /// the collection whose elements are to be placed into this priority queue. + /// if elements of cannot be + /// compared to one another according to the priority queue's ordering + /// if or any element with it is + /// + /// + public PriorityQueue(ICollection collection) + { + if ( null == collection ) + throw new ArgumentNullException("collection"); + initializeArray(collection); + if (collection is PriorityQueue) + { + PriorityQueue s = (PriorityQueue) collection; + _comparator = s.Comparator(); + fillFromSorted(s); + } + else + { + _comparator = null; + fillFromUnsorted(collection); + } + } + + #endregion + + #region Private Helper Methods + + /// + /// Common code to initialize underlying queue array across + /// constructors below. + /// + private void initializeArray(ICollection c) + { + int size = c.Count; + int initialCapacity = getQueueSizeBasedOnPercentage(size, 110); + if (initialCapacity < 1) + initialCapacity = 1; + + _queue = new Object[initialCapacity + 1]; + } + + /// + /// Performs an unsigned bitwise right shift with the specified number + /// + /// Number to operate on + /// Ammount of bits to shift + /// The resulting number from the shift operation + private int urShift(int number, int bits) + { + if (number >= 0) + return number >> bits; + else + return (number >> bits) + (2 << ~bits); + } + + /// + /// Establishes the heap invariant assuming the heap + /// satisfies the invariant except possibly for the leaf-node indexed by k + /// (which may have a nextExecutionTime less than its parent's). + /// + /// + /// This method functions by "promoting" queue[k] up the hierarchy + /// (by swapping it with its parent) repeatedly until queue[k] + /// is greater than or equal to its parent. + /// + private void fixUp(int k) + { + if (_comparator == null) + { + while (k > 1) + { + int j = k >> 1; + if (((IComparable) _queue[j]).CompareTo(_queue[k]) <= 0) + break; + Object tmp = _queue[j]; + _queue[j] = _queue[k]; + _queue[k] = tmp; + k = j; + } + } + else + { + while (k > 1) + { + int j = urShift(k, 1); + if (_comparator.Compare(_queue[j], _queue[k]) <= 0) + break; + Object tmp = _queue[j]; + _queue[j] = _queue[k]; + _queue[k] = tmp; + k = j; + } + } + } + + /// + /// Establishes the heap invariant (described above) in the subtree + /// rooted at k, which is assumed to satisfy the heap invariant except + /// possibly for node k itself (which may be greater than its children). + /// + /// + /// This method functions by "demoting" queue[k] down the hierarchy + /// (by swapping it with its smaller child) repeatedly until queue[k] + /// is less than or equal to its children. + /// + private void fixDown(int k) + { + int j; + if (_comparator == null) + { + while ((j = k << 1) <= _priorityQueueSize && (j > 0)) + { + if (j < _priorityQueueSize && ((IComparable) _queue[j]).CompareTo(_queue[j + 1]) > 0) + j++; // j indexes smallest kid + + if (((IComparable) _queue[k]).CompareTo(_queue[j]) <= 0) + break; + Object tmp = _queue[j]; + _queue[j] = _queue[k]; + _queue[k] = tmp; + k = j; + } + } + else + { + while ((j = k << 1) <= _priorityQueueSize && (j > 0)) + { + if (j < _priorityQueueSize && _comparator.Compare(_queue[j], _queue[j + 1]) > 0) + j++; // j indexes smallest kid + if (_comparator.Compare(_queue[k], _queue[j]) <= 0) + break; + Object tmp = _queue[j]; + _queue[j] = _queue[k]; + _queue[k] = tmp; + k = j; + } + } + } + + /// + /// Establishes the heap invariant in the entire tree, + /// assuming nothing about the order of the elements prior to the call. + /// + private void heapify() + { + for (int i = _priorityQueueSize/2; i >= 1; i--) + fixDown(i); + } + + /// + /// Returns the of or - 1, + /// whichever is smaller. + /// + /// base size + /// percentage to return + /// of + private int getQueueSizeBasedOnPercentage(int size, long percentage) + { + return (int) Math.Min((size*percentage)/100, Int32.MaxValue - 1); + } + + /// + /// Initially fill elements of the queue array under the + /// knowledge that it is sorted or is another , in which + /// case we can just place the elements in the order presented. + /// + private void fillFromSorted(ICollection collection) + { + fillArray(collection, true); + } + + private void fillArray(ICollection collection, bool sorted) + { + foreach (object currentObject in collection) + { + if (null == currentObject ) + throw new ArgumentNullException("collection", "Cannot add null elements to queue."); + _queue[++_priorityQueueSize] = currentObject; + } + if (! sorted) + { + heapify(); + } + } + + /// + /// Initially fill elements of the queue array that is not to our knowledge + /// sorted, so we must rearrange the elements to guarantee the heap + /// invariant. + /// + private void fillFromUnsorted(ICollection collection) + { + fillArray(collection, false); + } + + /// + /// Removes and returns element located at from queue. (Recall that the queue + /// is one-based, so 1 <= i <= size.) + /// + /// + /// Normally this method leaves the elements at positions from 1 up to i-1, + /// inclusive, untouched. Under these circumstances, it returns . + /// Occasionally, in order to maintain the heap invariant, it must move + /// the last element of the list to some index in the range [2, i-1], + /// and move the element previously at position (i/2) to position i. + /// Under these circumstances, this method returns the element that was + /// previously at the end of the list and is now at some position between + /// 2 and i-1 inclusive. + /// + private Object removeAt(int index) + { + Debug.Assert(index > 0 && index <= _priorityQueueSize); + _queueModificationCount++; + + Object moved = _queue[_priorityQueueSize]; + _queue[index] = moved; + _queue[_priorityQueueSize--] = null; + if (index <= _priorityQueueSize) + { + fixDown(index); + if (_queue[index] == moved) + { + fixUp(index); + if (_queue[index] != moved) + return moved; + } + } + return null; + } + + /// Resize array, if necessary, to be able to hold given index + private void grow(int index) + { + int newLength = _queue.Length; + if (index < newLength) + return; + if (index == Int32.MaxValue) + throw new InvalidOperationException("Cannot grow queue to accomdate index " + index + ". Doing so would result in a memory overflow."); + while (newLength <= index) + { + if (newLength >= Int32.MaxValue/2) + { + newLength = Int32.MaxValue; + } + else + { + newLength <<= 2; + } + } + Object[] newQueue = new Object[newLength]; + Array.Copy(_queue, 0, newQueue, 0, _queue.Length); + _queue = newQueue; + } + + #endregion + + #region Public Methods + /// + /// Gets the Capacity of this queue. Will equal + /// + public override int Capacity + { + get + { + return _queue.Length; + } + } + + /// + /// Returns the queue count. + /// + public override int Count + { + get { return _priorityQueueSize; } + } + + /// + /// Inserts the specified element into this queue if it is possible to do + /// so immediately without violating capacity restrictions. + /// + /// + ///

+ /// When using a capacity-restricted queue, this method is generally + /// preferable to , + /// which can fail to insert an element only by throwing an exception. + ///

+ ///
+ /// + /// The element to add. + /// + /// + /// if the element was added to this queue. + /// + /// + /// if the specified element cannot be compared + /// with elements currently in the priority queue according + /// to the priority queue's ordering. + /// + /// + /// If the element cannot be added at this time due to capacity restrictions. + /// + /// + /// If the supplied is + /// and this queue does not permit + /// elements. + /// + /// + /// If some property of the supplied prevents + /// it from being added to this queue. + /// + public override bool Offer(Object objectToAdd) + { + if (objectToAdd == null) + throw new ArgumentNullException("objectToAdd"); + _queueModificationCount++; + ++_priorityQueueSize; + + if (_priorityQueueSize >= _queue.Length) + { + grow(_priorityQueueSize); + } + _queue[_priorityQueueSize] = objectToAdd; + fixUp(_priorityQueueSize); + return true; + } + + /// + /// Retrieves, but does not remove, the head of this queue, + /// or returns if this queue is empty. + /// + /// + /// The head of this queue, or if this queue is empty. + /// + public override Object Peek() + { + if (_priorityQueueSize == 0) + return null; + return _queue[1]; + } + + // Collection Methods - the first two override to update docs + /// + /// Inserts the specified element into this queue if it is possible to do so + /// immediately without violating capacity restrictions, returning + /// upon success and throwing an + /// if no space is + /// currently available. + /// + /// + /// The element to add. + /// + /// + /// if successful. + /// + /// + /// If the element cannot be added at this time due to capacity restrictions. + /// + /// + /// If the specified element is and this queue does not + /// permit elements. + /// + /// + /// If some property of the supplied prevents + /// it from being added to this queue. + /// + /// + /// if the specified element cannot be compared + /// with elements currently in the priority queue according + /// to the priority queue's ordering. + /// + public override bool Add(Object objectToAdd) + { + return Offer(objectToAdd); + } + + /// + /// Removes a single instance of the specified element from this + /// queue, if it is present. + /// + public virtual bool Remove(Object objectToRemove) + { + if (objectToRemove == null) + { + return false; + } + + if (_comparator == null) + { + for (int i = 1; i <= _priorityQueueSize; i++) + { + if (((IComparable) _queue[i]).CompareTo(objectToRemove) == 0) + { + removeAt(i); + return true; + } + } + } + else + { + for (int i = 1; i <= _priorityQueueSize; i++) + { + if (_comparator.Compare(_queue[i], objectToRemove) == 0) + { + removeAt(i); + return true; + } + } + } + return false; + } + + /// + /// Returns an over the elements in this queue. + /// The enumeratoar does not return the elements in any particular order. + /// + /// an enumerator over the elements in this queue. + public override IEnumerator GetEnumerator() + { + return new PriorityQueueEnumerator(this); + } + + + /// + /// Removes all elements from the priority queue. + /// The queue will be empty after this call returns. + /// + public override void Clear() + { + _queueModificationCount++; + + for (int i = 1; i <= _priorityQueueSize; i++) + _queue[i] = null; + + _priorityQueueSize = 0; + } + + /// + /// Retrieves and removes the head of this queue, + /// or returns if this queue is empty. + /// + /// + /// The head of this queue, or if this queue is empty. + /// + public override Object Poll() + { + if (_priorityQueueSize == 0) + return null; + _queueModificationCount++; + + Object result = _queue[1]; + _queue[1] = _queue[_priorityQueueSize]; + _queue[_priorityQueueSize--] = null; + if (_priorityQueueSize > 1) + fixDown(1); + return result; + } + /// + /// Queries the queue to see if it contains the specified + /// + /// element to look for. + /// if the queue contains the , + /// otherwise. + public bool Contains( object element ) + { + if (element == null) + { + for (int num1 = 0; num1 < Capacity; num1++) + { + if (_queue[num1] == null) + { + return true; + } + } + return false; + } + for (int num2 = 0; num2 < Capacity; num2++) + { + if (element.Equals(_queue[num2])) + { + return true; + } + } + return false; + } + + + /// Returns the comparator used to order this collection, or + /// if this collection is sorted according to its elements natural ordering + /// (using ). + /// + /// + /// the comparator used to order this collection, or + /// if this collection is sorted according to its elements natural ordering. + /// + public virtual IComparer Comparator() + { + return _comparator; + } + #endregion + + #region ISerializable Implementation + /// + /// Save the state of the instance to a stream (that + /// is, serialize it). + /// + /// The length of the array backing the instance is + /// emitted (int), followed by all of its elements (each an + /// ) in the proper order. + /// + /// the stream + /// the context + public virtual void GetObjectData(SerializationInfo serializationInfo, StreamingContext context) + { + Type thisType = this.GetType(); + MemberInfo[] mi = FormatterServices.GetSerializableMembers(thisType, context); + for (int i = 0; i < mi.Length; i++) + { + serializationInfo.AddValue(mi[i].Name, ((FieldInfo) mi[i]).GetValue(this)); + } + + // Write out array length + serializationInfo.AddValue("Spring.Collections.PriorityQueuedata1", _queue.Length); + + // Write out all elements in the proper order. + for (int i = 1; i <= _priorityQueueSize; i++) + { + serializationInfo.AddValue("Spring.Collections.PriorityQueueData" + i, _queue[i]); + } + } + + /// + /// Reconstitute the instance from a stream (that is, + /// deserialize it). + /// + /// the stream + /// the context + protected PriorityQueue(SerializationInfo serializationInfo, StreamingContext context) + { + Type thisType = this.GetType(); + MemberInfo[] mi = FormatterServices.GetSerializableMembers(thisType, context); + for (int i = 0; i < mi.Length; i++) + { + FieldInfo fi = (FieldInfo) mi[i]; + fi.SetValue(this, serializationInfo.GetValue(fi.Name, fi.FieldType)); + } + int arrayLength = serializationInfo.GetInt32("Spring.Collections.PriorityQueuedata1"); + _queue = new Object[arrayLength]; + + for (int i = 1; i <= _priorityQueueSize; i++) + { + _queue[i] = serializationInfo.GetValue("Spring.Collections.PriorityQueueData" + i, typeof (Object)); + } + } + #endregion + + #region ICollection Implementation + + /// + ///Copies the elements of the to an , starting at a particular index. + /// + ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + ///The zero-based index in array at which copying begins. + ///array is null. + ///index is less than zero. + ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. + ///The type of the source cannot be cast automatically to the type of the destination array. 2 + public override void CopyTo(Array array,Int32 index) + { + if ( _priorityQueueSize > array.Length ) throw new ArgumentException("Destination array too small.", "array"); + if ( index > array.Length - 1 ) throw new ArgumentException("Starting index outside bounds of target array.", "index"); + if ( index + _priorityQueueSize > array.Length ) throw new IndexOutOfRangeException("Destination array not long enough to begin copying at index " + index + "."); + + for ( int queueElementCount = 1; queueElementCount <= _priorityQueueSize; queueElementCount++) + { + array.SetValue(_queue[queueElementCount], index ); + index++; + } + Array.Sort(array); + } + + /// + ///Copies the elements of the to an , starting at index 0. + /// + ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + ///array is null. + ///index is less than zero. + ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. + ///The type of the source cannot be cast automatically to the type of the destination array. 2 + public void CopyTo(Array array) + { + CopyTo(array, 0); + } + + /// + ///Gets an object that can be used to synchronize access to the . + /// + /// + ///An object that can be used to synchronize access to the . + /// + public override Object SyncRoot + { + get { return null; } + + } + + /// + ///Gets a value indicating whether access to the is synchronized (thread safe). + /// + /// + ///true if access to the is synchronized (thread safe); otherwise, false. + /// + public override Boolean IsSynchronized + { + get { return false; } + + } + + /// + /// Returns if there are no elements in the , otherwise. + /// + public override bool IsEmpty + { + get { return _priorityQueueSize == 0; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/Set.cs b/src/Spring/Spring.Core/Collections/Set.cs index ff6ca5eb..ff936230 100644 --- a/src/Spring/Spring.Core/Collections/Set.cs +++ b/src/Spring/Spring.Core/Collections/Set.cs @@ -1,568 +1,567 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// A collection that contains no duplicate elements. - /// - /// - /// $Id: Set.cs,v 1.7 2007/03/16 04:01:28 aseovic Exp $ - [Serializable] - public abstract class Set : ISet - { - /// - /// Performs a "union" of the two sets, where all the elements - /// in both sets are present. - /// - /// A collection of elements. - /// - /// A new containing the union of - /// this with the specified - /// collection. Neither of the input objects is modified by the union. - /// - /// - public virtual ISet Union(ISet setOne) - { - ISet resultSet = (ISet) this.Clone(); - if (setOne != null) - { - resultSet.AddAll(setOne); - } - return resultSet; - } - - /// - /// Performs a "union" of two sets, where all the elements in both are - /// present. - /// - /// - ///

- /// That is, the element is included if it is in either - /// or . The return - /// value is a clone of one of the sets ( - /// if it is not ) with elements of the other set - /// added in. Neither of the input sets is modified by the operation. - ///

- ///
- /// A set of elements. - /// A set of elements. - /// - /// A set containing the union of the input sets; - /// if both sets are . - /// - public static ISet Union(ISet setOne, ISet anotherSet) - { - if (setOne == null && anotherSet == null) - { - return null; - } - else if (setOne == null) - { - return (ISet) anotherSet.Clone(); - } - else if (anotherSet == null) - { - return (ISet) setOne.Clone(); - } - else - { - return setOne.Union(anotherSet); - } - } - - /// - /// Performs a "union" of two sets, where all the elements in both are - /// present. - /// - /// A set of elements. - /// A set of elements. - /// - /// A set containing the union of the input sets; - /// if both sets are . - /// - /// - public static Set operator |(Set setOne, Set anotherSet) - { - return (Set) Union(setOne, anotherSet); - } - - /// - /// Performs an "intersection" of the two sets, where only the elements - /// that are present in both sets remain. - /// - /// A set of elements. - /// - /// The intersection of this set with . - /// - /// - public virtual ISet Intersect(ISet setOne) - { - ISet resultSet = (ISet) this.Clone(); - if (setOne != null) - { - resultSet.RetainAll(setOne); - } - else - { - resultSet.Clear(); - } - return resultSet; - } - - /// - /// Performs an "intersection" of the two sets, where only the elements - /// that are present in both sets remain. - /// - /// - ///

- /// That is, the element is included only if it exists in both - /// and . Neither input - /// object is modified by the operation. The result object is a - /// clone of one of the input objects ( - /// if it is not ) containing the elements from - /// the intersect operation. - ///

- ///
- /// A set of elements. - /// A set of elements. - /// - /// The intersection of the two input sets; if - /// both sets are . - /// - public static ISet Intersect(ISet setOne, ISet anotherSet) - { - if (setOne == null && anotherSet == null) - { - return null; - } - else if (setOne == null) - { - return anotherSet.Intersect(setOne); - } - else - { - return setOne.Intersect(anotherSet); - } - } - - /// - /// Performs an "intersection" of the two sets, where only the elements - /// that are present in both sets remain. - /// - /// A set of elements. - /// A set of elements. - /// - /// The intersection of the two input sets; if - /// both sets are . - /// - /// - public static Set operator &(Set setOne, Set anotherSet) - { - return (Set) Intersect(setOne, anotherSet); - } - - /// - /// Performs a "minus" of this set from the - /// set. - /// - /// A set of elements. - /// - /// A set containing the elements from this set with the elements in - /// removed. - /// - /// - public virtual ISet Minus(ISet setOne) - { - ISet resultSet = (ISet) this.Clone(); - if (setOne != null) - { - resultSet.RemoveAll(setOne); - } - return resultSet; - } - - /// - /// Performs a "minus" of set from set - /// . - /// - /// - ///

- /// This returns a set of all the elements in set - /// , removing the elements that are also in - /// set . The original sets are not modified - /// during this operation. The result set is a clone of set - /// containing the elements from the operation. - ///

- ///
- /// A set of elements. - /// A set of elements. - /// - /// A set containing - /// - elements. - /// if is - /// . - /// - public static ISet Minus(ISet setOne, ISet anotherSet) - { - if (setOne == null) - { - return null; - } - else - { - return setOne.Minus(anotherSet); - } - } - - /// - /// Performs a "minus" of set from set - /// . - /// - /// A set of elements. - /// A set of elements. - /// - /// A set containing - /// - elements. - /// if is - /// . - /// - /// - public static Set operator -(Set setOne, Set anotherSet) - { - return (Set) Minus(setOne, anotherSet); - } - - - /// - /// Performs an "exclusive-or" of the two sets, keeping only those - /// elements that are in one of the sets, but not in both. - /// - /// A set of elements. - /// - /// A set containing the result of - /// ^ this. - /// - /// - public virtual ISet ExclusiveOr(ISet setOne) - { - ISet resultSet = (ISet) this.Clone(); - foreach (object element in setOne) - { - if (resultSet.Contains(element)) - { - resultSet.Remove(element); - } - else - { - resultSet.Add(element); - } - } - return resultSet; - } - - /// - /// Performs an "exclusive-or" of the two sets, keeping only those - /// elements that are in one of the sets, but not in both. - /// - /// - ///

- /// The original sets are not modified during this operation. The - /// result set is a clone of one of the sets ( - /// if it is not ) - /// containing the elements from the exclusive-or operation. - ///

- ///
- /// A set of elements. - /// A set of elements. - /// - /// A set containing the result of - /// ^ . - /// if both sets are . - /// - public static ISet ExclusiveOr(ISet setOne, ISet anotherSet) - { - if (setOne == null && anotherSet == null) - { - return null; - } - else if (setOne == null) - { - return (Set) anotherSet.Clone(); - } - else if (anotherSet == null) - { - return (Set) setOne.Clone(); - } - else - { - return setOne.ExclusiveOr(anotherSet); - } - } - - /// - /// Performs an "exclusive-or" of the two sets, keeping only those - /// elements that are in one of the sets, but not in both. - /// - /// A set of elements. - /// A set of elements. - /// - /// A set containing the result of - /// ^ . - /// if both sets are . - /// - /// - public static Set operator ^(Set setOne, Set anotherSet) - { - return (Set) ExclusiveOr(setOne, anotherSet); - } - - /// - /// Adds the specified element to this set if it is not already present. - /// - /// The object to add to the set. - /// - /// is the object was added, - /// if the object was already present. - /// - public abstract bool Add(object element); - - /// - /// Adds all the elements in the specified collection to the set if - /// they are not already present. - /// - /// A collection of objects to add to the set. - /// - /// is the set changed as a result of this - /// operation. - /// - public abstract bool AddAll(ICollection collection); - - /// - /// Removes all objects from this set. - /// - public abstract void Clear(); - - /// - /// Returns if this set contains the specified - /// element. - /// - /// The element to look for. - /// - /// if this set contains the specified element. - /// - public abstract bool Contains(object element); - - /// - /// Returns if the set contains all the - /// elements in the specified collection. - /// - /// A collection of objects. - /// - /// if the set contains all the elements in the - /// specified collection. - /// - public abstract bool ContainsAll(ICollection collection); - - /// - /// Returns if this set contains no elements. - /// - public abstract bool IsEmpty { get; } - - /// - /// Removes the specified element from the set. - /// - /// The element to be removed. - /// - /// if the set contained the specified element. - /// - public abstract bool Remove(object element); - - /// - /// Remove all the specified elements from this set, if they exist in - /// this set. - /// - /// A collection of elements to remove. - /// - /// if the set was modified as a result of this - /// operation. - /// - public abstract bool RemoveAll(ICollection collection); - - /// - /// Retains only the elements in this set that are contained in the - /// specified collection. - /// - /// - /// The collection that defines the set of elements to be retained. - /// - /// - /// if this set changed as a result of this - /// operation. - /// - public abstract bool RetainAll(ICollection collection); - - /// - /// Returns a clone of the - /// instance. - /// - /// - ///

- /// This will work for derived - /// classes if the derived class implements a constructor that takes no - /// arguments. - ///

- ///
- /// A clone of this object. - public virtual object Clone() - { - Set newSet = (Set) Activator.CreateInstance(this.GetType()); - newSet.AddAll(this); - return newSet; - } - - /// - /// Copies the elements in the to - /// an array. - /// - /// - ///

- /// The type of array needs to be compatible with the objects in the - /// , obviously. - ///

- ///
- /// - /// An array that will be the target of the copy operation. - /// - /// - /// The zero-based index where copying will start. - /// - public abstract void CopyTo(Array array, int index); - - /// - /// The number of elements currently contained in this collection. - /// - public abstract int Count { get; } - - /// - /// Returns if the - /// is synchronized across - /// threads. - /// - /// - ///

- /// Note that enumeration is inherently not thread-safe. Use the - /// to lock the object during enumeration. - ///

- ///
- public abstract bool IsSynchronized { get; } - - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - /// - ///

- /// When implementing this, if your object uses a base object, like an - /// , or anything that has - /// a SyncRoot, return that object instead of "this". - ///

- ///
- /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - public abstract object SyncRoot { get; } - - /// - /// Gets an enumerator for the elements in the - /// . - /// - /// - /// An over the elements - /// in the . - /// - public abstract IEnumerator GetEnumerator(); - - /// - /// This method will test the - /// against another for - /// "equality". - /// - /// - ///

- /// In this case, "equality" means that the two sets contain the same - /// elements. The "==" and "!=" operators are not overridden by design. - /// If you wish to check for "equivalent" - /// instances, use - /// Equals(). If you wish to check to see if two references are - /// actually the same object, use "==" and "!=". - ///

- ///
- /// - /// A object to compare to. - /// - /// - /// if the two sets contain the same elements. - /// - public override bool Equals(object obj) - { - Set theOtherSet = obj as Set; - if (theOtherSet == null || theOtherSet.Count != Count) - { - return false; - } - else - { - foreach (object element in theOtherSet) - { - if (!this.Contains(element)) - { - return false; - } - } - return true; - } - } - - /// - /// Gets the hashcode for the object. - /// - public override int GetHashCode() - { - int hashCode = 0, count = 0; - foreach (object element in this) - { - hashCode += element.GetHashCode(); - count++; - } - return count + hashCode; - } - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// A collection that contains no duplicate elements. + /// + /// + [Serializable] + public abstract class Set : ISet + { + /// + /// Performs a "union" of the two sets, where all the elements + /// in both sets are present. + /// + /// A collection of elements. + /// + /// A new containing the union of + /// this with the specified + /// collection. Neither of the input objects is modified by the union. + /// + /// + public virtual ISet Union(ISet setOne) + { + ISet resultSet = (ISet) this.Clone(); + if (setOne != null) + { + resultSet.AddAll(setOne); + } + return resultSet; + } + + /// + /// Performs a "union" of two sets, where all the elements in both are + /// present. + /// + /// + ///

+ /// That is, the element is included if it is in either + /// or . The return + /// value is a clone of one of the sets ( + /// if it is not ) with elements of the other set + /// added in. Neither of the input sets is modified by the operation. + ///

+ ///
+ /// A set of elements. + /// A set of elements. + /// + /// A set containing the union of the input sets; + /// if both sets are . + /// + public static ISet Union(ISet setOne, ISet anotherSet) + { + if (setOne == null && anotherSet == null) + { + return null; + } + else if (setOne == null) + { + return (ISet) anotherSet.Clone(); + } + else if (anotherSet == null) + { + return (ISet) setOne.Clone(); + } + else + { + return setOne.Union(anotherSet); + } + } + + /// + /// Performs a "union" of two sets, where all the elements in both are + /// present. + /// + /// A set of elements. + /// A set of elements. + /// + /// A set containing the union of the input sets; + /// if both sets are . + /// + /// + public static Set operator |(Set setOne, Set anotherSet) + { + return (Set) Union(setOne, anotherSet); + } + + /// + /// Performs an "intersection" of the two sets, where only the elements + /// that are present in both sets remain. + /// + /// A set of elements. + /// + /// The intersection of this set with . + /// + /// + public virtual ISet Intersect(ISet setOne) + { + ISet resultSet = (ISet) this.Clone(); + if (setOne != null) + { + resultSet.RetainAll(setOne); + } + else + { + resultSet.Clear(); + } + return resultSet; + } + + /// + /// Performs an "intersection" of the two sets, where only the elements + /// that are present in both sets remain. + /// + /// + ///

+ /// That is, the element is included only if it exists in both + /// and . Neither input + /// object is modified by the operation. The result object is a + /// clone of one of the input objects ( + /// if it is not ) containing the elements from + /// the intersect operation. + ///

+ ///
+ /// A set of elements. + /// A set of elements. + /// + /// The intersection of the two input sets; if + /// both sets are . + /// + public static ISet Intersect(ISet setOne, ISet anotherSet) + { + if (setOne == null && anotherSet == null) + { + return null; + } + else if (setOne == null) + { + return anotherSet.Intersect(setOne); + } + else + { + return setOne.Intersect(anotherSet); + } + } + + /// + /// Performs an "intersection" of the two sets, where only the elements + /// that are present in both sets remain. + /// + /// A set of elements. + /// A set of elements. + /// + /// The intersection of the two input sets; if + /// both sets are . + /// + /// + public static Set operator &(Set setOne, Set anotherSet) + { + return (Set) Intersect(setOne, anotherSet); + } + + /// + /// Performs a "minus" of this set from the + /// set. + /// + /// A set of elements. + /// + /// A set containing the elements from this set with the elements in + /// removed. + /// + /// + public virtual ISet Minus(ISet setOne) + { + ISet resultSet = (ISet) this.Clone(); + if (setOne != null) + { + resultSet.RemoveAll(setOne); + } + return resultSet; + } + + /// + /// Performs a "minus" of set from set + /// . + /// + /// + ///

+ /// This returns a set of all the elements in set + /// , removing the elements that are also in + /// set . The original sets are not modified + /// during this operation. The result set is a clone of set + /// containing the elements from the operation. + ///

+ ///
+ /// A set of elements. + /// A set of elements. + /// + /// A set containing + /// - elements. + /// if is + /// . + /// + public static ISet Minus(ISet setOne, ISet anotherSet) + { + if (setOne == null) + { + return null; + } + else + { + return setOne.Minus(anotherSet); + } + } + + /// + /// Performs a "minus" of set from set + /// . + /// + /// A set of elements. + /// A set of elements. + /// + /// A set containing + /// - elements. + /// if is + /// . + /// + /// + public static Set operator -(Set setOne, Set anotherSet) + { + return (Set) Minus(setOne, anotherSet); + } + + + /// + /// Performs an "exclusive-or" of the two sets, keeping only those + /// elements that are in one of the sets, but not in both. + /// + /// A set of elements. + /// + /// A set containing the result of + /// ^ this. + /// + /// + public virtual ISet ExclusiveOr(ISet setOne) + { + ISet resultSet = (ISet) this.Clone(); + foreach (object element in setOne) + { + if (resultSet.Contains(element)) + { + resultSet.Remove(element); + } + else + { + resultSet.Add(element); + } + } + return resultSet; + } + + /// + /// Performs an "exclusive-or" of the two sets, keeping only those + /// elements that are in one of the sets, but not in both. + /// + /// + ///

+ /// The original sets are not modified during this operation. The + /// result set is a clone of one of the sets ( + /// if it is not ) + /// containing the elements from the exclusive-or operation. + ///

+ ///
+ /// A set of elements. + /// A set of elements. + /// + /// A set containing the result of + /// ^ . + /// if both sets are . + /// + public static ISet ExclusiveOr(ISet setOne, ISet anotherSet) + { + if (setOne == null && anotherSet == null) + { + return null; + } + else if (setOne == null) + { + return (Set) anotherSet.Clone(); + } + else if (anotherSet == null) + { + return (Set) setOne.Clone(); + } + else + { + return setOne.ExclusiveOr(anotherSet); + } + } + + /// + /// Performs an "exclusive-or" of the two sets, keeping only those + /// elements that are in one of the sets, but not in both. + /// + /// A set of elements. + /// A set of elements. + /// + /// A set containing the result of + /// ^ . + /// if both sets are . + /// + /// + public static Set operator ^(Set setOne, Set anotherSet) + { + return (Set) ExclusiveOr(setOne, anotherSet); + } + + /// + /// Adds the specified element to this set if it is not already present. + /// + /// The object to add to the set. + /// + /// is the object was added, + /// if the object was already present. + /// + public abstract bool Add(object element); + + /// + /// Adds all the elements in the specified collection to the set if + /// they are not already present. + /// + /// A collection of objects to add to the set. + /// + /// is the set changed as a result of this + /// operation. + /// + public abstract bool AddAll(ICollection collection); + + /// + /// Removes all objects from this set. + /// + public abstract void Clear(); + + /// + /// Returns if this set contains the specified + /// element. + /// + /// The element to look for. + /// + /// if this set contains the specified element. + /// + public abstract bool Contains(object element); + + /// + /// Returns if the set contains all the + /// elements in the specified collection. + /// + /// A collection of objects. + /// + /// if the set contains all the elements in the + /// specified collection. + /// + public abstract bool ContainsAll(ICollection collection); + + /// + /// Returns if this set contains no elements. + /// + public abstract bool IsEmpty { get; } + + /// + /// Removes the specified element from the set. + /// + /// The element to be removed. + /// + /// if the set contained the specified element. + /// + public abstract bool Remove(object element); + + /// + /// Remove all the specified elements from this set, if they exist in + /// this set. + /// + /// A collection of elements to remove. + /// + /// if the set was modified as a result of this + /// operation. + /// + public abstract bool RemoveAll(ICollection collection); + + /// + /// Retains only the elements in this set that are contained in the + /// specified collection. + /// + /// + /// The collection that defines the set of elements to be retained. + /// + /// + /// if this set changed as a result of this + /// operation. + /// + public abstract bool RetainAll(ICollection collection); + + /// + /// Returns a clone of the + /// instance. + /// + /// + ///

+ /// This will work for derived + /// classes if the derived class implements a constructor that takes no + /// arguments. + ///

+ ///
+ /// A clone of this object. + public virtual object Clone() + { + Set newSet = (Set) Activator.CreateInstance(this.GetType()); + newSet.AddAll(this); + return newSet; + } + + /// + /// Copies the elements in the to + /// an array. + /// + /// + ///

+ /// The type of array needs to be compatible with the objects in the + /// , obviously. + ///

+ ///
+ /// + /// An array that will be the target of the copy operation. + /// + /// + /// The zero-based index where copying will start. + /// + public abstract void CopyTo(Array array, int index); + + /// + /// The number of elements currently contained in this collection. + /// + public abstract int Count { get; } + + /// + /// Returns if the + /// is synchronized across + /// threads. + /// + /// + ///

+ /// Note that enumeration is inherently not thread-safe. Use the + /// to lock the object during enumeration. + ///

+ ///
+ public abstract bool IsSynchronized { get; } + + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + /// + ///

+ /// When implementing this, if your object uses a base object, like an + /// , or anything that has + /// a SyncRoot, return that object instead of "this". + ///

+ ///
+ /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + public abstract object SyncRoot { get; } + + /// + /// Gets an enumerator for the elements in the + /// . + /// + /// + /// An over the elements + /// in the . + /// + public abstract IEnumerator GetEnumerator(); + + /// + /// This method will test the + /// against another for + /// "equality". + /// + /// + ///

+ /// In this case, "equality" means that the two sets contain the same + /// elements. The "==" and "!=" operators are not overridden by design. + /// If you wish to check for "equivalent" + /// instances, use + /// Equals(). If you wish to check to see if two references are + /// actually the same object, use "==" and "!=". + ///

+ ///
+ /// + /// A object to compare to. + /// + /// + /// if the two sets contain the same elements. + /// + public override bool Equals(object obj) + { + Set theOtherSet = obj as Set; + if (theOtherSet == null || theOtherSet.Count != Count) + { + return false; + } + else + { + foreach (object element in theOtherSet) + { + if (!this.Contains(element)) + { + return false; + } + } + return true; + } + } + + /// + /// Gets the hashcode for the object. + /// + public override int GetHashCode() + { + int hashCode = 0, count = 0; + foreach (object element in this) + { + hashCode += element.GetHashCode(); + count++; + } + return count + hashCode; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/SortedSet.cs b/src/Spring/Spring.Core/Collections/SortedSet.cs index 55bd6558..f2628fd7 100644 --- a/src/Spring/Spring.Core/Collections/SortedSet.cs +++ b/src/Spring/Spring.Core/Collections/SortedSet.cs @@ -1,79 +1,78 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// Implements an based on a sorted - /// tree. - /// - /// - ///

- /// This gives good performance for operations on very large data-sets, - /// though not as good - asymptotically - as a - /// . However, iteration occurs - /// in order. - ///

- ///

- /// Elements that you put into this type of collection must implement - /// , and they must actually be comparable. - /// You can't mix and - /// values, for example. - ///

- ///

- /// This implementation does - /// not support elements that are . - ///

- ///
- /// - /// $Id: SortedSet.cs,v 1.6 2007/03/16 04:01:29 aseovic Exp $ - [Serializable] - public class SortedSet : DictionarySet - { - /// - /// Creates a new set instance based on a sorted tree. - /// - public SortedSet() - { - InternalDictionary = new SortedList(); - } - - /// - /// Creates a new set instance based on a sorted tree and initializes - /// it based on a collection of elements. - /// - /// - /// A collection of elements that defines the initial set contents. - /// - public SortedSet(ICollection initialValues) : this() - { - this.AddAll(initialValues); - } - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// Implements an based on a sorted + /// tree. + /// + /// + ///

+ /// This gives good performance for operations on very large data-sets, + /// though not as good - asymptotically - as a + /// . However, iteration occurs + /// in order. + ///

+ ///

+ /// Elements that you put into this type of collection must implement + /// , and they must actually be comparable. + /// You can't mix and + /// values, for example. + ///

+ ///

+ /// This implementation does + /// not support elements that are . + ///

+ ///
+ /// + [Serializable] + public class SortedSet : DictionarySet + { + /// + /// Creates a new set instance based on a sorted tree. + /// + public SortedSet() + { + InternalDictionary = new SortedList(); + } + + /// + /// Creates a new set instance based on a sorted tree and initializes + /// it based on a collection of elements. + /// + /// + /// A collection of elements that defines the initial set contents. + /// + public SortedSet(ICollection initialValues) : this() + { + this.AddAll(initialValues); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/SynchronizedDictionaryEnumerator.cs b/src/Spring/Spring.Core/Collections/SynchronizedDictionaryEnumerator.cs index f6061e71..11a62b09 100644 --- a/src/Spring/Spring.Core/Collections/SynchronizedDictionaryEnumerator.cs +++ b/src/Spring/Spring.Core/Collections/SynchronizedDictionaryEnumerator.cs @@ -1,76 +1,75 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Collections -{ - /// - /// Synchronized that should be returned by synchronized - /// dictionary implementations in order to ensure that the enumeration is thread safe. - /// - /// Aleksandar Seovic - /// $Id: SynchronizedDictionaryEnumerator.cs,v 1.1 2006/05/03 01:13:41 aseovic Exp $ - internal class SynchronizedDictionaryEnumerator : SynchronizedEnumerator, IDictionaryEnumerator - { - public SynchronizedDictionaryEnumerator(object syncRoot, IDictionaryEnumerator enumerator) - : base(syncRoot, enumerator) - { - } - - protected IDictionaryEnumerator Enumerator - { - get { return (IDictionaryEnumerator) enumerator; } - } - - public object Key - { - get - { - lock (syncRoot) - { - return Enumerator.Key; - } - } - } - - public object Value - { - get - { - lock (syncRoot) - { - return Enumerator.Value; - } - } - } - - public DictionaryEntry Entry - { - get - { - lock (syncRoot) - { - return Enumerator.Entry; - } - } - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Collections +{ + /// + /// Synchronized that should be returned by synchronized + /// dictionary implementations in order to ensure that the enumeration is thread safe. + /// + /// Aleksandar Seovic + internal class SynchronizedDictionaryEnumerator : SynchronizedEnumerator, IDictionaryEnumerator + { + public SynchronizedDictionaryEnumerator(object syncRoot, IDictionaryEnumerator enumerator) + : base(syncRoot, enumerator) + { + } + + protected IDictionaryEnumerator Enumerator + { + get { return (IDictionaryEnumerator) enumerator; } + } + + public object Key + { + get + { + lock (syncRoot) + { + return Enumerator.Key; + } + } + } + + public object Value + { + get + { + lock (syncRoot) + { + return Enumerator.Value; + } + } + } + + public DictionaryEntry Entry + { + get + { + lock (syncRoot) + { + return Enumerator.Entry; + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/SynchronizedEnumerator.cs b/src/Spring/Spring.Core/Collections/SynchronizedEnumerator.cs index 5060853b..e62be05f 100644 --- a/src/Spring/Spring.Core/Collections/SynchronizedEnumerator.cs +++ b/src/Spring/Spring.Core/Collections/SynchronizedEnumerator.cs @@ -1,69 +1,68 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Collections -{ - /// - /// Synchronized that should be returned by synchronized - /// collections in order to ensure that the enumeration is thread safe. - /// - /// Aleksandar Seovic - /// $Id: SynchronizedEnumerator.cs,v 1.1 2006/05/03 01:13:41 aseovic Exp $ - internal class SynchronizedEnumerator : IEnumerator - { - protected object syncRoot; - protected IEnumerator enumerator; - - public SynchronizedEnumerator(object syncRoot, IEnumerator enumerator) - { - this.syncRoot = syncRoot; - this.enumerator = enumerator; - } - - public bool MoveNext() - { - lock (syncRoot) - { - return enumerator.MoveNext(); - } - } - - public void Reset() - { - lock (syncRoot) - { - enumerator.Reset(); - } - } - - public object Current - { - get - { - lock (syncRoot) - { - return enumerator.Current; - } - } - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Collections +{ + /// + /// Synchronized that should be returned by synchronized + /// collections in order to ensure that the enumeration is thread safe. + /// + /// Aleksandar Seovic + internal class SynchronizedEnumerator : IEnumerator + { + protected object syncRoot; + protected IEnumerator enumerator; + + public SynchronizedEnumerator(object syncRoot, IEnumerator enumerator) + { + this.syncRoot = syncRoot; + this.enumerator = enumerator; + } + + public bool MoveNext() + { + lock (syncRoot) + { + return enumerator.MoveNext(); + } + } + + public void Reset() + { + lock (syncRoot) + { + enumerator.Reset(); + } + } + + public object Current + { + get + { + lock (syncRoot) + { + return enumerator.Current; + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/SynchronizedHashtable.cs b/src/Spring/Spring.Core/Collections/SynchronizedHashtable.cs index 4b754c36..c8ba2cc8 100644 --- a/src/Spring/Spring.Core/Collections/SynchronizedHashtable.cs +++ b/src/Spring/Spring.Core/Collections/SynchronizedHashtable.cs @@ -1,367 +1,366 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Spring.Util; - -namespace Spring.Collections -{ - /// - /// Synchronized that, unlike hashtable created - /// using method, synchronizes - /// reads from the underlying hashtable in addition to writes. - /// - /// - ///

- /// In addition to synchronizing reads, this implementation also fixes - /// IEnumerator/ICollection issue described at - /// http://msdn.microsoft.com/netframework/programming/breakingchanges/runtime/clr.aspx - /// (search for SynchronizedHashtable for issue description), by implementing - /// interface explicitly, and returns thread safe enumerator - /// implementations as well. - ///

- ///

- /// This class should be used whenever a truly synchronized - /// is needed. - ///

- ///
- /// Aleksandar Seovic - /// $Id: SynchronizedHashtable.cs,v 1.2 2007/08/27 13:57:17 oakinger Exp $ - [Serializable] - public class SynchronizedHashtable : IDictionary, ICollection, IEnumerable, ICloneable - { - private readonly Hashtable _table; - - #region Constructors - - /// - /// Initializes a new instance of - /// - public SynchronizedHashtable() - { - this._table = new Hashtable(); - } - - /// - /// Initializes a new instance of , copying inital entries from . - /// - public SynchronizedHashtable(IDictionary dictionary) - { - AssertUtils.ArgumentNotNull(dictionary, "dictionary"); - this._table = new Hashtable(dictionary); - } - - #endregion - - #region Properties - - /// - ///Gets a value indicating whether the object is read-only. - /// - /// - ///true if the object is read-only; otherwise, false. - /// - public bool IsReadOnly - { - get - { - lock (SyncRoot) - { - return _table.IsReadOnly; - } - } - } - - /// - ///Gets a value indicating whether the object has a fixed size. - /// - /// - ///true if the object has a fixed size; otherwise, false. - /// - public bool IsFixedSize - { - get - { - lock (SyncRoot) - { - return _table.IsFixedSize; - } - } - } - - /// - ///Gets a value indicating whether access to the is synchronized (thread safe). - /// - /// - ///true if access to the is synchronized (thread safe); otherwise, false. - /// - public bool IsSynchronized - { - get { return true; } - } - - /// - ///Gets an object containing the keys of the object. - /// - /// - ///An object containing the keys of the object. - /// - public ICollection Keys - { - get - { - lock (SyncRoot) - { - return _table.Keys; - } - } - } - - /// - ///Gets an object containing the values in the object. - /// - /// - ///An object containing the values in the object. - /// - public ICollection Values - { - get - { - lock (SyncRoot) - { - return _table.Values; - } - } - } - - /// - ///Gets an object that can be used to synchronize access to the . - /// - /// - ///An object that can be used to synchronize access to the . - /// - public object SyncRoot - { - get { return _table.SyncRoot; } - } - - /// - ///Gets the number of elements contained in the . - /// - /// - ///The number of elements contained in the . - /// - public int Count - { - get - { - lock (SyncRoot) - { - return _table.Count; - } - } - } - - #endregion - - #region Methods - - /// - ///Adds an element with the provided key and value to the object. - /// - ///The to use as the value of the element to add. - ///The to use as the key of the element to add. - ///An element with the same key already exists in the object. - ///key is null. - ///The is read-only.-or- The has a fixed size. 2 - public void Add(object key, object value) - { - lock (SyncRoot) - { - _table.Add(key, value); - } - } - - /// - ///Removes all elements from the object. - /// - ///The object is read-only. 2 - public void Clear() - { - lock (SyncRoot) - { - _table.Clear(); - } - } - - /// - ///Creates a new object that is a copy of the current instance. - /// - /// - ///A new object that is a copy of this instance. - /// - public object Clone() - { - lock (SyncRoot) - { - return new SynchronizedHashtable(this); - } - } - - /// - ///Determines whether the object contains an element with the specified key. - /// - /// - ///true if the contains an element with the key; otherwise, false. - /// - ///The key to locate in the object. - ///key is null. 2 - public bool Contains(object key) - { - lock (SyncRoot) - { - return _table.Contains(key); - } - } - - /// - /// Returns, whether this contains an entry with the specified . - /// - ///The key to look for - ///, if this contains an entry with this - public bool ContainsKey(object key) - { - lock (SyncRoot) - { - return _table.ContainsKey(key); - } - } - - /// - /// Returns, whether this contains an entry with the specified . - /// - ///The valúe to look for - ///, if this contains an entry with this - public bool ContainsValue(object value) - { - lock (SyncRoot) - { - return _table.ContainsValue(value); - } - } - - /// - ///Copies the elements of the to an , starting at a particular index. - /// - ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - ///The zero-based index in array at which copying begins. - ///array is null. - ///The type of the source cannot be cast automatically to the type of the destination array. - ///index is less than zero. - ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. 2 - public void CopyTo(Array array, int index) - { - lock (SyncRoot) - { - _table.CopyTo(array, index); - } - } - - /// - ///Returns an object for the object. - /// - /// - ///An object for the object. - /// - public IDictionaryEnumerator GetEnumerator() - { - lock (SyncRoot) - { - return new SynchronizedDictionaryEnumerator(SyncRoot, _table.GetEnumerator()); - } - } - - /// - ///Removes the element with the specified key from the object. - /// - ///The key of the element to remove. - ///The object is read-only.-or- The has a fixed size. - ///key is null. 2 - public void Remove(object key) - { - lock (SyncRoot) - { - _table.Remove(key); - } - } - - #endregion - - #region IEnumerable implementation - - /// - ///Returns an enumerator that iterates through a collection. - /// - /// - ///An object that can be used to iterate through the collection. - /// - IEnumerator IEnumerable.GetEnumerator() - { - lock (SyncRoot) - { - return new SynchronizedEnumerator(SyncRoot, ((IEnumerable) _table).GetEnumerator()); - } - } - - #endregion - - #region Indexer - - /// - ///Gets or sets the element with the specified key. - /// - /// - ///The element with the specified key. - /// - ///The key of the element to get or set. - ///The property is set and the object is read-only.-or- The property is set, key does not exist in the collection, and the has a fixed size. - ///key is null. 2 - public object this[object key] - { - get - { - lock (SyncRoot) - { - return _table[key]; - } - } - set - { - lock (SyncRoot) - { - _table[key] = value; - } - } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Spring.Util; + +namespace Spring.Collections +{ + /// + /// Synchronized that, unlike hashtable created + /// using method, synchronizes + /// reads from the underlying hashtable in addition to writes. + /// + /// + ///

+ /// In addition to synchronizing reads, this implementation also fixes + /// IEnumerator/ICollection issue described at + /// http://msdn.microsoft.com/en-us/netframework/aa570326.aspx + /// (search for SynchronizedHashtable for issue description), by implementing + /// interface explicitly, and returns thread safe enumerator + /// implementations as well. + ///

+ ///

+ /// This class should be used whenever a truly synchronized + /// is needed. + ///

+ ///
+ /// Aleksandar Seovic + [Serializable] + public class SynchronizedHashtable : IDictionary, ICollection, IEnumerable, ICloneable + { + private readonly Hashtable _table; + + #region Constructors + + /// + /// Initializes a new instance of + /// + public SynchronizedHashtable() + { + this._table = new Hashtable(); + } + + /// + /// Initializes a new instance of , copying inital entries from . + /// + public SynchronizedHashtable(IDictionary dictionary) + { + AssertUtils.ArgumentNotNull(dictionary, "dictionary"); + this._table = new Hashtable(dictionary); + } + + #endregion + + #region Properties + + /// + ///Gets a value indicating whether the object is read-only. + /// + /// + ///true if the object is read-only; otherwise, false. + /// + public bool IsReadOnly + { + get + { + lock (SyncRoot) + { + return _table.IsReadOnly; + } + } + } + + /// + ///Gets a value indicating whether the object has a fixed size. + /// + /// + ///true if the object has a fixed size; otherwise, false. + /// + public bool IsFixedSize + { + get + { + lock (SyncRoot) + { + return _table.IsFixedSize; + } + } + } + + /// + ///Gets a value indicating whether access to the is synchronized (thread safe). + /// + /// + ///true if access to the is synchronized (thread safe); otherwise, false. + /// + public bool IsSynchronized + { + get { return true; } + } + + /// + ///Gets an object containing the keys of the object. + /// + /// + ///An object containing the keys of the object. + /// + public ICollection Keys + { + get + { + lock (SyncRoot) + { + return _table.Keys; + } + } + } + + /// + ///Gets an object containing the values in the object. + /// + /// + ///An object containing the values in the object. + /// + public ICollection Values + { + get + { + lock (SyncRoot) + { + return _table.Values; + } + } + } + + /// + ///Gets an object that can be used to synchronize access to the . + /// + /// + ///An object that can be used to synchronize access to the . + /// + public object SyncRoot + { + get { return _table.SyncRoot; } + } + + /// + ///Gets the number of elements contained in the . + /// + /// + ///The number of elements contained in the . + /// + public int Count + { + get + { + lock (SyncRoot) + { + return _table.Count; + } + } + } + + #endregion + + #region Methods + + /// + ///Adds an element with the provided key and value to the object. + /// + ///The to use as the value of the element to add. + ///The to use as the key of the element to add. + ///An element with the same key already exists in the object. + ///key is null. + ///The is read-only.-or- The has a fixed size. 2 + public void Add(object key, object value) + { + lock (SyncRoot) + { + _table.Add(key, value); + } + } + + /// + ///Removes all elements from the object. + /// + ///The object is read-only. 2 + public void Clear() + { + lock (SyncRoot) + { + _table.Clear(); + } + } + + /// + ///Creates a new object that is a copy of the current instance. + /// + /// + ///A new object that is a copy of this instance. + /// + public object Clone() + { + lock (SyncRoot) + { + return new SynchronizedHashtable(this); + } + } + + /// + ///Determines whether the object contains an element with the specified key. + /// + /// + ///true if the contains an element with the key; otherwise, false. + /// + ///The key to locate in the object. + ///key is null. 2 + public bool Contains(object key) + { + lock (SyncRoot) + { + return _table.Contains(key); + } + } + + /// + /// Returns, whether this contains an entry with the specified . + /// + ///The key to look for + ///, if this contains an entry with this + public bool ContainsKey(object key) + { + lock (SyncRoot) + { + return _table.ContainsKey(key); + } + } + + /// + /// Returns, whether this contains an entry with the specified . + /// + ///The valúe to look for + ///, if this contains an entry with this + public bool ContainsValue(object value) + { + lock (SyncRoot) + { + return _table.ContainsValue(value); + } + } + + /// + ///Copies the elements of the to an , starting at a particular index. + /// + ///The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + ///The zero-based index in array at which copying begins. + ///array is null. + ///The type of the source cannot be cast automatically to the type of the destination array. + ///index is less than zero. + ///array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. 2 + public void CopyTo(Array array, int index) + { + lock (SyncRoot) + { + _table.CopyTo(array, index); + } + } + + /// + ///Returns an object for the object. + /// + /// + ///An object for the object. + /// + public IDictionaryEnumerator GetEnumerator() + { + lock (SyncRoot) + { + return new SynchronizedDictionaryEnumerator(SyncRoot, _table.GetEnumerator()); + } + } + + /// + ///Removes the element with the specified key from the object. + /// + ///The key of the element to remove. + ///The object is read-only.-or- The has a fixed size. + ///key is null. 2 + public void Remove(object key) + { + lock (SyncRoot) + { + _table.Remove(key); + } + } + + #endregion + + #region IEnumerable implementation + + /// + ///Returns an enumerator that iterates through a collection. + /// + /// + ///An object that can be used to iterate through the collection. + /// + IEnumerator IEnumerable.GetEnumerator() + { + lock (SyncRoot) + { + return new SynchronizedEnumerator(SyncRoot, ((IEnumerable) _table).GetEnumerator()); + } + } + + #endregion + + #region Indexer + + /// + ///Gets or sets the element with the specified key. + /// + /// + ///The element with the specified key. + /// + ///The key of the element to get or set. + ///The property is set and the object is read-only.-or- The property is set, key does not exist in the collection, and the has a fixed size. + ///key is null. 2 + public object this[object key] + { + get + { + lock (SyncRoot) + { + return _table[key]; + } + } + set + { + lock (SyncRoot) + { + _table[key] = value; + } + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Collections/SynchronizedSet.cs b/src/Spring/Spring.Core/Collections/SynchronizedSet.cs index cfc216c5..bef35716 100644 --- a/src/Spring/Spring.Core/Collections/SynchronizedSet.cs +++ b/src/Spring/Spring.Core/Collections/SynchronizedSet.cs @@ -1,331 +1,330 @@ -/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ - -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Collections -{ - /// - /// Implements a thread-safe wrapper. - /// - /// - ///

- /// The implementation is extremely conservative, serializing critical - /// sections to prevent possible deadlocks, and locking on everything. The - /// one exception is for enumeration, which is inherently not thread-safe. - /// For this, you have to lock the SyncRoot object for the - /// duration of the enumeration. - ///

- ///
- /// - /// $Id: SynchronizedSet.cs,v 1.6 2007/03/16 04:01:29 aseovic Exp $ - [Serializable] - public sealed class SynchronizedSet : Set - { - private ISet _mBasisSet; - private object _mSyncRoot; - - /// - /// Constructs a thread-safe - /// wrapper. - /// - /// - /// The object that this object - /// will wrap. - /// - /// - /// If the supplied ecposes a - /// SyncRoot value. - /// - public SynchronizedSet(ISet basisSet) - { - _mBasisSet = basisSet; - _mSyncRoot = basisSet.SyncRoot; - if (_mSyncRoot == null) - { - throw new NullReferenceException( - "The Set you specified returned a null SyncRoot."); - } - } - - /// - /// Adds the specified element to this set if it is not already present. - /// - /// The object to add to the set. - /// - /// is the object was added, - /// if the object was already present. - /// - public override sealed bool Add(object element) - { - lock (_mSyncRoot) - { - return _mBasisSet.Add(element); - } - } - - /// - /// Adds all the elements in the specified collection to the set if - /// they are not already present. - /// - /// A collection of objects to add to the set. - /// - /// is the set changed as a result of this - /// operation. - /// - public override sealed bool AddAll(ICollection collection) - { - if(collection == null) - { - return false; - } - Set temp; - lock (collection.SyncRoot) - { - temp = new HybridSet(collection); - } - lock (_mSyncRoot) - { - return _mBasisSet.AddAll(temp); - } - } - - /// - /// Removes all objects from this set. - /// - public override sealed void Clear() - { - lock (_mSyncRoot) - { - _mBasisSet.Clear(); - } - } - - /// - /// Returns if this set contains the specified - /// element. - /// - /// The element to look for. - /// - /// if this set contains the specified element. - /// - public override sealed bool Contains(object element) - { - lock (_mSyncRoot) - { - return _mBasisSet.Contains(element); - } - } - - /// - /// Returns if the set contains all the - /// elements in the specified collection. - /// - /// A collection of objects. - /// - /// if the set contains all the elements in the - /// specified collection; also if the - /// supplied is . - /// - public override sealed bool ContainsAll(ICollection collection) - { - if(collection == null) - { - return false; - } - Set temp; - lock (collection.SyncRoot) - { - temp = new HybridSet(collection); - } - lock (_mSyncRoot) - { - return _mBasisSet.ContainsAll(temp); - } - } - - /// - /// Returns if this set contains no elements. - /// - public override sealed bool IsEmpty - { - get - { - lock (_mSyncRoot) - { - return _mBasisSet.IsEmpty; - } - } - } - - /// - /// Removes the specified element from the set. - /// - /// The element to be removed. - /// - /// if the set contained the specified element. - /// - public override sealed bool Remove(object element) - { - lock (_mSyncRoot) - { - return _mBasisSet.Remove(element); - } - } - - /// - /// Remove all the specified elements from this set, if they exist in - /// this set. - /// - /// A collection of elements to remove. - /// - /// if the set was modified as a result of this - /// operation. - /// - public override sealed bool RemoveAll(ICollection collection) - { - Set temp; - lock (collection.SyncRoot) - { - temp = new HybridSet(collection); - } - lock (_mSyncRoot) - { - return _mBasisSet.RemoveAll(temp); - } - } - - /// - /// Retains only the elements in this set that are contained in the - /// specified collection. - /// - /// - /// The collection that defines the set of elements to be retained. - /// - /// - /// if this set changed as a result of this - /// operation. - /// - public override sealed bool RetainAll(ICollection c) - { - Set temp; - lock (c.SyncRoot) - { - temp = new HybridSet(c); - } - lock (_mSyncRoot) - { - return _mBasisSet.RetainAll(temp); - } - } - - /// - /// Copies the elements in the to - /// an array. - /// - /// - ///

- /// The type of array needs to be compatible with the objects in the - /// , obviously. - ///

- ///
- /// - /// An array that will be the target of the copy operation. - /// - /// - /// The zero-based index where copying will start. - /// - public override sealed void CopyTo(Array array, int index) - { - lock (_mSyncRoot) - { - _mBasisSet.CopyTo(array, index); - } - } - - /// - /// The number of elements currently contained in this collection. - /// - public override sealed int Count - { - get - { - lock (_mSyncRoot) - { - return _mBasisSet.Count; - } - } - } - - /// - /// Returns if the - /// is synchronized across - /// threads. - /// - /// - public override sealed bool IsSynchronized - { - get { return true; } - } - - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - /// - /// An object that can be used to synchronize this collection to make - /// it thread-safe. - /// - /// - public override sealed object SyncRoot - { - get { return _mSyncRoot; } - } - - /// - /// Gets an enumerator for the elements in the - /// . - /// - /// - /// An over the elements - /// in the . - /// - public override sealed IEnumerator GetEnumerator() - { - return _mBasisSet.GetEnumerator(); - } - - /// - /// Returns a clone of the instance. - /// - /// A clone of this object. - public override object Clone() - { - return new SynchronizedSet((ISet) _mBasisSet.Clone()); - } - } +/* Copyright © 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */ + +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Collections +{ + /// + /// Implements a thread-safe wrapper. + /// + /// + ///

+ /// The implementation is extremely conservative, serializing critical + /// sections to prevent possible deadlocks, and locking on everything. The + /// one exception is for enumeration, which is inherently not thread-safe. + /// For this, you have to lock the SyncRoot object for the + /// duration of the enumeration. + ///

+ ///
+ /// + [Serializable] + public sealed class SynchronizedSet : Set + { + private ISet _mBasisSet; + private object _mSyncRoot; + + /// + /// Constructs a thread-safe + /// wrapper. + /// + /// + /// The object that this object + /// will wrap. + /// + /// + /// If the supplied ecposes a + /// SyncRoot value. + /// + public SynchronizedSet(ISet basisSet) + { + _mBasisSet = basisSet; + _mSyncRoot = basisSet.SyncRoot; + if (_mSyncRoot == null) + { + throw new NullReferenceException( + "The Set you specified returned a null SyncRoot."); + } + } + + /// + /// Adds the specified element to this set if it is not already present. + /// + /// The object to add to the set. + /// + /// is the object was added, + /// if the object was already present. + /// + public override sealed bool Add(object element) + { + lock (_mSyncRoot) + { + return _mBasisSet.Add(element); + } + } + + /// + /// Adds all the elements in the specified collection to the set if + /// they are not already present. + /// + /// A collection of objects to add to the set. + /// + /// is the set changed as a result of this + /// operation. + /// + public override sealed bool AddAll(ICollection collection) + { + if(collection == null) + { + return false; + } + Set temp; + lock (collection.SyncRoot) + { + temp = new HybridSet(collection); + } + lock (_mSyncRoot) + { + return _mBasisSet.AddAll(temp); + } + } + + /// + /// Removes all objects from this set. + /// + public override sealed void Clear() + { + lock (_mSyncRoot) + { + _mBasisSet.Clear(); + } + } + + /// + /// Returns if this set contains the specified + /// element. + /// + /// The element to look for. + /// + /// if this set contains the specified element. + /// + public override sealed bool Contains(object element) + { + lock (_mSyncRoot) + { + return _mBasisSet.Contains(element); + } + } + + /// + /// Returns if the set contains all the + /// elements in the specified collection. + /// + /// A collection of objects. + /// + /// if the set contains all the elements in the + /// specified collection; also if the + /// supplied is . + /// + public override sealed bool ContainsAll(ICollection collection) + { + if(collection == null) + { + return false; + } + Set temp; + lock (collection.SyncRoot) + { + temp = new HybridSet(collection); + } + lock (_mSyncRoot) + { + return _mBasisSet.ContainsAll(temp); + } + } + + /// + /// Returns if this set contains no elements. + /// + public override sealed bool IsEmpty + { + get + { + lock (_mSyncRoot) + { + return _mBasisSet.IsEmpty; + } + } + } + + /// + /// Removes the specified element from the set. + /// + /// The element to be removed. + /// + /// if the set contained the specified element. + /// + public override sealed bool Remove(object element) + { + lock (_mSyncRoot) + { + return _mBasisSet.Remove(element); + } + } + + /// + /// Remove all the specified elements from this set, if they exist in + /// this set. + /// + /// A collection of elements to remove. + /// + /// if the set was modified as a result of this + /// operation. + /// + public override sealed bool RemoveAll(ICollection collection) + { + Set temp; + lock (collection.SyncRoot) + { + temp = new HybridSet(collection); + } + lock (_mSyncRoot) + { + return _mBasisSet.RemoveAll(temp); + } + } + + /// + /// Retains only the elements in this set that are contained in the + /// specified collection. + /// + /// + /// The collection that defines the set of elements to be retained. + /// + /// + /// if this set changed as a result of this + /// operation. + /// + public override sealed bool RetainAll(ICollection c) + { + Set temp; + lock (c.SyncRoot) + { + temp = new HybridSet(c); + } + lock (_mSyncRoot) + { + return _mBasisSet.RetainAll(temp); + } + } + + /// + /// Copies the elements in the to + /// an array. + /// + /// + ///

+ /// The type of array needs to be compatible with the objects in the + /// , obviously. + ///

+ ///
+ /// + /// An array that will be the target of the copy operation. + /// + /// + /// The zero-based index where copying will start. + /// + public override sealed void CopyTo(Array array, int index) + { + lock (_mSyncRoot) + { + _mBasisSet.CopyTo(array, index); + } + } + + /// + /// The number of elements currently contained in this collection. + /// + public override sealed int Count + { + get + { + lock (_mSyncRoot) + { + return _mBasisSet.Count; + } + } + } + + /// + /// Returns if the + /// is synchronized across + /// threads. + /// + /// + public override sealed bool IsSynchronized + { + get { return true; } + } + + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + /// + /// An object that can be used to synchronize this collection to make + /// it thread-safe. + /// + /// + public override sealed object SyncRoot + { + get { return _mSyncRoot; } + } + + /// + /// Gets an enumerator for the elements in the + /// . + /// + /// + /// An over the elements + /// in the . + /// + public override sealed IEnumerator GetEnumerator() + { + return _mBasisSet.GetEnumerator(); + } + + /// + /// Returns a clone of the instance. + /// + /// A clone of this object. + public override object Clone() + { + return new SynchronizedSet((ISet) _mBasisSet.Clone()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/ApplicationContextException.cs b/src/Spring/Spring.Core/Context/ApplicationContextException.cs index d57d1bdb..f7eeb9b9 100644 --- a/src/Spring/Spring.Core/Context/ApplicationContextException.cs +++ b/src/Spring/Spring.Core/Context/ApplicationContextException.cs @@ -1,87 +1,86 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Objects; - -#endregion - -namespace Spring.Context -{ - /// Exception thrown during application context initialization. - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: ApplicationContextException.cs,v 1.5 2006/04/09 07:18:38 markpollack Exp $ - [Serializable] - public class ApplicationContextException : FatalObjectException - { - /// - /// Creates a new instance of the - /// class. - /// - public ApplicationContextException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ApplicationContextException( SerializationInfo info, StreamingContext context ) - : base( info, context ) {} - - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - public ApplicationContextException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ApplicationContextException(string message, Exception rootCause) - : base(message, rootCause) - { - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Objects; + +#endregion + +namespace Spring.Context +{ + /// Exception thrown during application context initialization. + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class ApplicationContextException : FatalObjectException + { + /// + /// Creates a new instance of the + /// class. + /// + public ApplicationContextException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ApplicationContextException( SerializationInfo info, StreamingContext context ) + : base( info, context ) {} + + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + public ApplicationContextException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ApplicationContextException(string message, Exception rootCause) + : base(message, rootCause) + { + } + } +} diff --git a/src/Spring/Spring.Core/Context/ApplicationEventArgs.cs b/src/Spring/Spring.Core/Context/ApplicationEventArgs.cs index 99e51ecc..6a3198b5 100644 --- a/src/Spring/Spring.Core/Context/ApplicationEventArgs.cs +++ b/src/Spring/Spring.Core/Context/ApplicationEventArgs.cs @@ -1,71 +1,70 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Context -{ - /// - /// Encapsulates the data associated with an event raised by an - /// . - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// Griffin Caprio (.NET) - /// - /// $Id: ApplicationEventArgs.cs,v 1.5 2006/04/09 07:18:38 markpollack Exp $ - [Serializable] - public class ApplicationEventArgs : EventArgs - { - private const long TicksAtEpoch = 621355968000000000; - private DateTime _timestamp; - - /// - /// Creates a new instance of the - /// class. - /// - public ApplicationEventArgs() - { - _timestamp = DateTime.Now; - } - - /// - /// The date and time when the event occured. - /// - /// - /// The date and time when the event occured. - /// - public DateTime TimeStamp - { - get { return _timestamp; } - } - - /// - /// The system time in milliseconds when the event happened. - /// - /// - /// The system time in milliseconds when the event happened. - /// - public long EventTimeMilliseconds - { - get { return ( _timestamp.Ticks - TicksAtEpoch ) / 10000; } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Context +{ + /// + /// Encapsulates the data associated with an event raised by an + /// . + /// + /// Rod Johnson + /// Mark Pollack (.NET) + /// Griffin Caprio (.NET) + /// + [Serializable] + public class ApplicationEventArgs : EventArgs + { + private const long TicksAtEpoch = 621355968000000000; + private DateTime _timestamp; + + /// + /// Creates a new instance of the + /// class. + /// + public ApplicationEventArgs() + { + _timestamp = DateTime.Now; + } + + /// + /// The date and time when the event occured. + /// + /// + /// The date and time when the event occured. + /// + public DateTime TimeStamp + { + get { return _timestamp; } + } + + /// + /// The system time in milliseconds when the event happened. + /// + /// + /// The system time in milliseconds when the event happened. + /// + public long EventTimeMilliseconds + { + get { return ( _timestamp.Ticks - TicksAtEpoch ) / 10000; } + } + } +} diff --git a/src/Spring/Spring.Core/Context/EventListenerAttribute.cs b/src/Spring/Spring.Core/Context/EventListenerAttribute.cs index 86c8d0b4..644d823c 100644 --- a/src/Spring/Spring.Core/Context/EventListenerAttribute.cs +++ b/src/Spring/Spring.Core/Context/EventListenerAttribute.cs @@ -1,44 +1,43 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Context -{ - /// - /// Marks an interface as being an application event listener. - /// - /// Griffin Caprio - /// $Id: EventListenerAttribute.cs,v 1.5 2006/04/09 07:18:38 markpollack Exp $ - /// - [AttributeUsage(AttributeTargets.Interface)] - public sealed class EventListenerAttribute : Attribute - { - /// - /// Creates a new instance of the - /// class. - /// - public EventListenerAttribute() {} - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Context +{ + /// + /// Marks an interface as being an application event listener. + /// + /// Griffin Caprio + /// + [AttributeUsage(AttributeTargets.Interface)] + public sealed class EventListenerAttribute : Attribute + { + /// + /// Creates a new instance of the + /// class. + /// + public EventListenerAttribute() {} + } +} diff --git a/src/Spring/Spring.Core/Context/Events/ConsoleListener.cs b/src/Spring/Spring.Core/Context/Events/ConsoleListener.cs index fb050fc3..0e0ac539 100644 --- a/src/Spring/Spring.Core/Context/Events/ConsoleListener.cs +++ b/src/Spring/Spring.Core/Context/Events/ConsoleListener.cs @@ -1,66 +1,65 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Context.Events -{ - /// - /// Simple listener that logs application events to the console. - /// - /// - ///

- /// Intended for use during debugging only. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: ConsoleListener.cs,v 1.6 2006/04/09 07:18:38 markpollack Exp $ - /// - public sealed class ConsoleListener : IApplicationEventListener - { - /// - /// Creates a new instance of the - /// class. - /// - public ConsoleListener() - { - } - - /// - /// Handle an application event. - /// - /// - /// The source of the event. - /// - /// - /// The event that is to be handled. - /// - public void HandleApplicationEvent(object sender, ApplicationEventArgs e) - { - Console.WriteLine("Source : " + sender); - Console.WriteLine("Event fired : " + e.TimeStamp); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Context.Events +{ + /// + /// Simple listener that logs application events to the console. + /// + /// + ///

+ /// Intended for use during debugging only. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + /// + public sealed class ConsoleListener : IApplicationEventListener + { + /// + /// Creates a new instance of the + /// class. + /// + public ConsoleListener() + { + } + + /// + /// Handle an application event. + /// + /// + /// The source of the event. + /// + /// + /// The event that is to be handled. + /// + public void HandleApplicationEvent(object sender, ApplicationEventArgs e) + { + Console.WriteLine("Source : " + sender); + Console.WriteLine("Event fired : " + e.TimeStamp); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Events/ContextEventArgs.cs b/src/Spring/Spring.Core/Context/Events/ContextEventArgs.cs index 5f06af9a..b8fea4ac 100644 --- a/src/Spring/Spring.Core/Context/Events/ContextEventArgs.cs +++ b/src/Spring/Spring.Core/Context/Events/ContextEventArgs.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Globalization; - -namespace Spring.Context.Events -{ - /// - /// Event object sent to listeners registered with an - /// to inform them of - /// context lifecycle events. - /// - /// Griffin Caprio (.NET) - /// $Id: ContextEventArgs.cs,v 1.8 2007/07/31 08:18:11 markpollack Exp $ - /// - /// - /// - public class ContextEventArgs : ApplicationEventArgs - { - /// - /// The various context event types. - /// - public enum ContextEvent - { - /// - /// The event type when the context is refreshed or created. - /// - Refreshed, - - /// - /// The event type when the context is closed. - /// - Closed - } ; - - private ContextEvent _contextEvent; - - /// - /// Creates a new instance of the ContextEventArgs class to represent the - /// supplied context event. - /// - /// The type of context event. - public ContextEventArgs(ContextEvent e) - { - _contextEvent = e; - } - - /// - /// The event type. - /// - public ContextEvent Event - { - get { return _contextEvent; } - } - - /// - /// Returns a string representation of this object. - /// - /// A string representation of this object. - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} [{1}]", GetType().Name, Event); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Globalization; + +namespace Spring.Context.Events +{ + /// + /// Event object sent to listeners registered with an + /// to inform them of + /// context lifecycle events. + /// + /// Griffin Caprio (.NET) + /// + /// + /// + public class ContextEventArgs : ApplicationEventArgs + { + /// + /// The various context event types. + /// + public enum ContextEvent + { + /// + /// The event type when the context is refreshed or created. + /// + Refreshed, + + /// + /// The event type when the context is closed. + /// + Closed + } ; + + private ContextEvent _contextEvent; + + /// + /// Creates a new instance of the ContextEventArgs class to represent the + /// supplied context event. + /// + /// The type of context event. + public ContextEventArgs(ContextEvent e) + { + _contextEvent = e; + } + + /// + /// The event type. + /// + public ContextEvent Event + { + get { return _contextEvent; } + } + + /// + /// Returns a string representation of this object. + /// + /// A string representation of this object. + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} [{1}]", GetType().Name, Event); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/IApplicationContext.cs b/src/Spring/Spring.Core/Context/IApplicationContext.cs index fc745fb1..d6185cc3 100644 --- a/src/Spring/Spring.Core/Context/IApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/IApplicationContext.cs @@ -1,164 +1,163 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Core.IO; -using Spring.Objects.Events; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Context -{ - /// - /// The central interface to Spring.NET's IoC container. - /// - /// - ///

- /// implementations - /// provide: - /// - /// - /// - /// Object factory functionality inherited from the - /// - /// and - /// interfaces. - /// - /// - /// - /// - /// The ability to resolve messages, supporting internationalization. - /// Inherited from the - /// interface. - /// - /// - /// - /// - /// The ability to load file resources in a generic fashion. - /// Inherited from the - /// interface. - /// - /// - /// - /// - /// Acts an an event registry for supporting loosely coupled eventing - /// between objecs. Inherited from the - /// interface. - /// - /// - /// - /// - /// The ability to raise events related to the context lifecycle. Inherited - /// from the - /// interface. - /// - /// - /// - /// - /// Inheritance from a parent context. Definitions in a descendant context - /// will always take priority. - /// - /// - /// - ///

- ///

- /// In addition to standard object factory lifecycle capabilities, - /// implementations need - /// to detect - /// , - /// , and - /// objects and supply - /// their attendant dependencies accordingly. - ///

- ///

- /// This interface is the central client interface in Spring.NET's IoC - /// container implementation. As such it does inherit a quite sizeable - /// number of interfaces; implementations are strongly encouraged to use - /// composition to satisfy each of the inherited interfaces (where - /// appropriate of course). - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// - /// - /// - /// - /// $Id: IApplicationContext.cs,v 1.15 2007/08/08 17:46:37 bbaia Exp $ - public interface IApplicationContext - : IListableObjectFactory, IHierarchicalObjectFactory, IMessageSource, - IApplicationEventPublisher, IResourceLoader, IEventRegistry, IDisposable - { - /// - /// Raised in response to an application context event. - /// - event ApplicationEventHandler ContextEvent; - - /// - /// Returns the date and time this context was loaded. - /// - /// - ///

- /// This is to be set immediately after an - /// has been - /// instantiated and its configuration has been loaded. Implementations - /// are permitted to update this value if the context is reset or - /// refreshed in some way. - ///

- ///
- /// - /// The representing when this context - /// was loaded. - /// - /// - DateTime StartupDate { get; } - - /// - /// Gets the parent context, or if there is no - /// parent context. - /// - /// - ///

- /// If the parent context is , then this context - /// is the root of any context hierarchy. - ///

- ///
- /// - /// The parent context, or if there is no - /// parent. - /// - IApplicationContext ParentContext { get; } - - /// - /// Gets and sets a name for this context. - /// - /// - /// A name for this context. - /// - string Name { get; set; } - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Core.IO; +using Spring.Objects.Events; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Context +{ + /// + /// The central interface to Spring.NET's IoC container. + /// + /// + ///

+ /// implementations + /// provide: + /// + /// + /// + /// Object factory functionality inherited from the + /// + /// and + /// interfaces. + /// + /// + /// + /// + /// The ability to resolve messages, supporting internationalization. + /// Inherited from the + /// interface. + /// + /// + /// + /// + /// The ability to load file resources in a generic fashion. + /// Inherited from the + /// interface. + /// + /// + /// + /// + /// Acts an an event registry for supporting loosely coupled eventing + /// between objecs. Inherited from the + /// interface. + /// + /// + /// + /// + /// The ability to raise events related to the context lifecycle. Inherited + /// from the + /// interface. + /// + /// + /// + /// + /// Inheritance from a parent context. Definitions in a descendant context + /// will always take priority. + /// + /// + /// + ///

+ ///

+ /// In addition to standard object factory lifecycle capabilities, + /// implementations need + /// to detect + /// , + /// , and + /// objects and supply + /// their attendant dependencies accordingly. + ///

+ ///

+ /// This interface is the central client interface in Spring.NET's IoC + /// container implementation. As such it does inherit a quite sizeable + /// number of interfaces; implementations are strongly encouraged to use + /// composition to satisfy each of the inherited interfaces (where + /// appropriate of course). + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + /// + /// + /// + /// + public interface IApplicationContext + : IListableObjectFactory, IHierarchicalObjectFactory, IMessageSource, + IApplicationEventPublisher, IResourceLoader, IEventRegistry, IDisposable + { + /// + /// Raised in response to an application context event. + /// + event ApplicationEventHandler ContextEvent; + + /// + /// Returns the date and time this context was loaded. + /// + /// + ///

+ /// This is to be set immediately after an + /// has been + /// instantiated and its configuration has been loaded. Implementations + /// are permitted to update this value if the context is reset or + /// refreshed in some way. + ///

+ ///
+ /// + /// The representing when this context + /// was loaded. + /// + /// + DateTime StartupDate { get; } + + /// + /// Gets the parent context, or if there is no + /// parent context. + /// + /// + ///

+ /// If the parent context is , then this context + /// is the root of any context hierarchy. + ///

+ ///
+ /// + /// The parent context, or if there is no + /// parent. + /// + IApplicationContext ParentContext { get; } + + /// + /// Gets and sets a name for this context. + /// + /// + /// A name for this context. + /// + string Name { get; set; } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/IApplicationContextAware.cs b/src/Spring/Spring.Core/Context/IApplicationContextAware.cs index f82fe311..cec4a134 100644 --- a/src/Spring/Spring.Core/Context/IApplicationContextAware.cs +++ b/src/Spring/Spring.Core/Context/IApplicationContextAware.cs @@ -1,99 +1,97 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Context -{ - /// - /// To be implemented by any object that wishes to be notified - /// of the that it runs in. - /// - /// - ///

- /// Implementing this interface makes sense when an object requires access - /// to a set of collaborating objects. Note that configuration via object - /// references is preferable to implementing this interface just for object - /// lookup purposes. - ///

- ///

- /// This interface can also be implemented if an object needs access to - /// file resources, i.e. wants to call - /// , or access to - /// the . However, it is - /// preferable to implement the more specific - /// - /// interface to receive a reference to the - /// object in that scenario. - ///

- ///

- /// Note that dependencies can also - /// be exposed as object properties of the - /// type, populated via strings with - /// automatic type conversion performed by an object factory. This obviates - /// the need for implementing any callback interface just for the purpose - /// of accessing a specific file resource. - ///

- ///

- /// - /// is a convenience implementation of this interface for your - /// application objects. - ///

- ///

- /// For a list of all object lifecycle methods, see the overview for the - /// interface. - ///

- ///
- /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: IApplicationContextAware.cs,v 1.8 2007/08/08 17:46:37 bbaia Exp $ - /// - /// - /// - /// $Id: IApplicationContextAware.cs,v 1.8 2007/08/08 17:46:37 bbaia Exp $ - public interface IApplicationContextAware - { - /// - /// Set the that this - /// object runs in. - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - IApplicationContext ApplicationContext { set; get; } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Context +{ + /// + /// To be implemented by any object that wishes to be notified + /// of the that it runs in. + /// + /// + ///

+ /// Implementing this interface makes sense when an object requires access + /// to a set of collaborating objects. Note that configuration via object + /// references is preferable to implementing this interface just for object + /// lookup purposes. + ///

+ ///

+ /// This interface can also be implemented if an object needs access to + /// file resources, i.e. wants to call + /// , or access to + /// the . However, it is + /// preferable to implement the more specific + /// + /// interface to receive a reference to the + /// object in that scenario. + ///

+ ///

+ /// Note that dependencies can also + /// be exposed as object properties of the + /// type, populated via strings with + /// automatic type conversion performed by an object factory. This obviates + /// the need for implementing any callback interface just for the purpose + /// of accessing a specific file resource. + ///

+ ///

+ /// + /// is a convenience implementation of this interface for your + /// application objects. + ///

+ ///

+ /// For a list of all object lifecycle methods, see the overview for the + /// interface. + ///

+ ///
+ /// Rod Johnson + /// Mark Pollack (.NET) + /// + /// + /// + public interface IApplicationContextAware + { + /// + /// Set the that this + /// object runs in. + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + IApplicationContext ApplicationContext { set; get; } + } +} diff --git a/src/Spring/Spring.Core/Context/IApplicationEventListener.cs b/src/Spring/Spring.Core/Context/IApplicationEventListener.cs index d6d65803..b0701b06 100644 --- a/src/Spring/Spring.Core/Context/IApplicationEventListener.cs +++ b/src/Spring/Spring.Core/Context/IApplicationEventListener.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Context -{ - /// - /// The callback for application events. - /// - public delegate void ApplicationEventHandler(object sender, ApplicationEventArgs e); - - /// - /// A listener for application events. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: IApplicationEventListener.cs,v 1.2 2006/04/09 07:18:38 markpollack Exp $ - [EventListener] - public interface IApplicationEventListener - { - /// - /// Handle an application event. - /// - /// - /// The source of the event. - /// - /// - /// The event that is to be handled. - /// - void HandleApplicationEvent(object sender, ApplicationEventArgs e); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Context +{ + /// + /// The callback for application events. + /// + public delegate void ApplicationEventHandler(object sender, ApplicationEventArgs e); + + /// + /// A listener for application events. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [EventListener] + public interface IApplicationEventListener + { + /// + /// Handle an application event. + /// + /// + /// The source of the event. + /// + /// + /// The event that is to be handled. + /// + void HandleApplicationEvent(object sender, ApplicationEventArgs e); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/IApplicationEventPublisher.cs b/src/Spring/Spring.Core/Context/IApplicationEventPublisher.cs index c8fc9941..2a13b0f6 100644 --- a/src/Spring/Spring.Core/Context/IApplicationEventPublisher.cs +++ b/src/Spring/Spring.Core/Context/IApplicationEventPublisher.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Context { - - /// - /// Encapsulates event publication functionality. - /// - /// - ///

- /// Serves as a super-interface for the - /// interface. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IApplicationEventPublisher.cs,v 1.2 2006/04/09 07:18:38 markpollack Exp $ - public interface IApplicationEventPublisher - { - /// - /// Publishes an application context event. - /// - /// - /// The source of the event. May be . - /// - /// - /// The event that is to be raised. - /// - void PublishEvent(object sender, ApplicationEventArgs e); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Context { + + /// + /// Encapsulates event publication functionality. + /// + /// + ///

+ /// Serves as a super-interface for the + /// interface. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IApplicationEventPublisher + { + /// + /// Publishes an application context event. + /// + /// + /// The source of the event. May be . + /// + /// + /// The event that is to be raised. + /// + void PublishEvent(object sender, ApplicationEventArgs e); + } +} diff --git a/src/Spring/Spring.Core/Context/IConfigurableApplicationContext.cs b/src/Spring/Spring.Core/Context/IConfigurableApplicationContext.cs index f9fc53fb..a45ad274 100644 --- a/src/Spring/Spring.Core/Context/IConfigurableApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/IConfigurableApplicationContext.cs @@ -1,132 +1,131 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Context -{ - /// - /// Provides the means to configure an application context in addition to - /// the methods exposed on the - /// interface. - /// - /// - ///

- /// This interface is to be implemented by most (if not all) - /// implementations. - ///

- ///

- /// Configuration and lifecycle methods are encapsulated here to avoid - /// making them obvious to - /// client code. - ///

- ///

- /// Calling will close this - /// application context, releasing all resources and locks that the - /// implementation might hold. This includes disposing all cached - /// singleton objects. - ///

- /// - /// does not invoke the - /// attendant on any parent - /// context. - /// - ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: IConfigurableApplicationContext.cs,v 1.10 2006/04/09 07:18:38 markpollack Exp $ - /// - /// - public interface IConfigurableApplicationContext : IApplicationContext - { - /// - /// Return the internal object factory of this application context. - /// - /// - ///

- /// Can be used to access specific functionality of the factory. - ///

- /// - /// This is just guaranteed to return an instance that is not - /// after the context has been refreshed - /// at least once. - /// - /// - /// Do not use this to post-process the object factory; singletons - /// will already have been instantiated. Use an - /// - /// to intercept the object factory setup process before objects even - /// get touched. - /// - ///
- /// - IConfigurableListableObjectFactory ObjectFactory { get; } - - /// - /// Add an - /// - /// that will get applied to the internal object factory of this - /// application context on refresh, before any of the object - /// definitions are evaluated. - /// - /// - ///

- /// To be invoked during context configuration. - ///

- ///
- /// - /// The factory processor to register. - /// - /// - void AddObjectFactoryPostProcessor( - IObjectFactoryPostProcessor objectFactoryPostProcessor); - - /// - /// Load or refresh the persistent representation of the configuration, - /// which might an XML file, properties file, or relational database schema. - /// - /// - /// If the configuration cannot be loaded. - /// - /// - /// If the object factory could not be initialized. - /// - void Refresh(); - - /// - /// Sets the parent of this application context. - /// - /// - /// - /// The parent should not be changed: it should only be set - /// outside a constructor if it isn't available when an instance of - /// this class is created. - /// - /// - /// - /// The parent context. - /// - new IApplicationContext ParentContext { get; set; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Context +{ + /// + /// Provides the means to configure an application context in addition to + /// the methods exposed on the + /// interface. + /// + /// + ///

+ /// This interface is to be implemented by most (if not all) + /// implementations. + ///

+ ///

+ /// Configuration and lifecycle methods are encapsulated here to avoid + /// making them obvious to + /// client code. + ///

+ ///

+ /// Calling will close this + /// application context, releasing all resources and locks that the + /// implementation might hold. This includes disposing all cached + /// singleton objects. + ///

+ /// + /// does not invoke the + /// attendant on any parent + /// context. + /// + ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + /// + /// + public interface IConfigurableApplicationContext : IApplicationContext + { + /// + /// Return the internal object factory of this application context. + /// + /// + ///

+ /// Can be used to access specific functionality of the factory. + ///

+ /// + /// This is just guaranteed to return an instance that is not + /// after the context has been refreshed + /// at least once. + /// + /// + /// Do not use this to post-process the object factory; singletons + /// will already have been instantiated. Use an + /// + /// to intercept the object factory setup process before objects even + /// get touched. + /// + ///
+ /// + IConfigurableListableObjectFactory ObjectFactory { get; } + + /// + /// Add an + /// + /// that will get applied to the internal object factory of this + /// application context on refresh, before any of the object + /// definitions are evaluated. + /// + /// + ///

+ /// To be invoked during context configuration. + ///

+ ///
+ /// + /// The factory processor to register. + /// + /// + void AddObjectFactoryPostProcessor( + IObjectFactoryPostProcessor objectFactoryPostProcessor); + + /// + /// Load or refresh the persistent representation of the configuration, + /// which might an XML file, properties file, or relational database schema. + /// + /// + /// If the configuration cannot be loaded. + /// + /// + /// If the object factory could not be initialized. + /// + void Refresh(); + + /// + /// Sets the parent of this application context. + /// + /// + /// + /// The parent should not be changed: it should only be set + /// outside a constructor if it isn't available when an instance of + /// this class is created. + /// + /// + /// + /// The parent context. + /// + new IApplicationContext ParentContext { get; set; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/IHierarchicalMessageSource.cs b/src/Spring/Spring.Core/Context/IHierarchicalMessageSource.cs index e28c1654..8c208f71 100644 --- a/src/Spring/Spring.Core/Context/IHierarchicalMessageSource.cs +++ b/src/Spring/Spring.Core/Context/IHierarchicalMessageSource.cs @@ -1,46 +1,45 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Context -{ - /// - /// Sub-interface of to be - /// implemented by objects that can resolve messages hierarchically. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: IHierarchicalMessageSource.cs,v 1.6 2006/04/09 07:18:38 markpollack Exp $ - /// - public interface IHierarchicalMessageSource : IMessageSource - { - /// - /// The parent message source used to try and resolve messages that - /// this object can't resolve. - /// - /// - ///

- /// If the value of this property is then no - /// further resolution is possible. - ///

- ///
- IMessageSource ParentMessageSource { get; set; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Context +{ + /// + /// Sub-interface of to be + /// implemented by objects that can resolve messages hierarchically. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + /// + public interface IHierarchicalMessageSource : IMessageSource + { + /// + /// The parent message source used to try and resolve messages that + /// this object can't resolve. + /// + /// + ///

+ /// If the value of this property is then no + /// further resolution is possible. + ///

+ ///
+ IMessageSource ParentMessageSource { get; set; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/IMessageSource.cs b/src/Spring/Spring.Core/Context/IMessageSource.cs index b87cf616..a9950987 100644 --- a/src/Spring/Spring.Core/Context/IMessageSource.cs +++ b/src/Spring/Spring.Core/Context/IMessageSource.cs @@ -1,308 +1,307 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Globalization; - -namespace Spring.Context { - /// - /// Describes an object that can resolve messages. - /// - /// - ///

- /// This enables the parameterization and internationalization of messages. - ///

- ///

- /// Spring.NET provides one out-of-the-box implementation for production - /// use: - ///

    - ///
  • .
  • - ///
- ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// Aleksandar Seovic (.NET) - /// $Id: IMessageSource.cs,v 1.13 2007/07/02 21:24:39 markpollack Exp $ - /// - public interface IMessageSource { - /// - /// Resolve the message identified by the supplied - /// . - /// - /// - ///

- /// If the lookup is not successful, implementations are permitted to - /// take one of two actions. - ///

- /// - /// - /// Throw an exception. - /// - /// - /// - /// Return the supplied as is. - /// - /// - /// - ///
- /// The name of the message to resolve. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - string GetMessage(string name); - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// - ///

- /// If the lookup is not successful, implementations are permitted to - /// take one of two actions. - ///

- /// - /// - /// Throw an exception. - /// - /// - /// - /// Return the supplied as is. - /// - /// - /// - ///
- /// The name of the message to resolve. - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - string GetMessage(string name, params object[] arguments); - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - ///

- /// If the lookup is not successful, implementations are permitted to - /// take one of two actions. - ///

- /// - /// - /// Throw an exception. - /// - /// - /// - /// Return the supplied as is. - /// - /// - /// - ///
- /// The name of the message to resolve. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - string GetMessage(string name, CultureInfo culture); - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - ///

- /// If the lookup is not successful, implementations are permitted to - /// take one of two actions. - ///

- /// - /// - /// Throw an exception. - /// - /// - /// - /// Return the supplied as is. - /// - /// - /// - ///
- /// The name of the message to resolve. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - string GetMessage(string name, CultureInfo culture, params object[] arguments); - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - ///

- /// If the lookup is not successful, implementations are permitted to - /// take one of two actions. - ///

- /// - /// - /// Throw an exception. - /// - /// - /// - /// Return the supplied as is. - /// - /// - /// - ///
- /// The name of the message to resolve. - /// The default message if name is not found. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments); - - /// - /// Resolve the message using all of the attributes contained within - /// the supplied - /// argument. - /// - /// - /// The value object storing those attributes that are required to - /// properly resolve a message. - /// - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture); - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - ///

- /// This method must use the - /// - /// value to obtain a resource. - ///

- ///

- /// Examples of resources that may be resolved by this method include - /// (but are not limited to) objects such as icons and bitmaps. - ///

- ///
- /// - /// The name of the resource object to resolve. - /// - /// - /// The resolved object, or if not found. - /// - object GetResourceObject(string name); - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - ///

- /// Examples of resources that may be resolved by this method include - /// (but are not limited to) objects such as icons and bitmaps. - ///

- ///
- /// - /// The name of the resource object to resolve. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - /// The resolved object, or if not found. - /// - object GetResourceObject(string name, CultureInfo culture); - - /// - /// Applies resources to object properties. - /// - /// - ///

- /// Resource key names are of the form objectName.propertyName. - ///

- ///
- /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - void ApplyResources(object value, string objectName, CultureInfo culture); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Globalization; + +namespace Spring.Context { + /// + /// Describes an object that can resolve messages. + /// + /// + ///

+ /// This enables the parameterization and internationalization of messages. + ///

+ ///

+ /// Spring.NET provides one out-of-the-box implementation for production + /// use: + ///

    + ///
  • .
  • + ///
+ ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + /// Aleksandar Seovic (.NET) + /// + public interface IMessageSource { + /// + /// Resolve the message identified by the supplied + /// . + /// + /// + ///

+ /// If the lookup is not successful, implementations are permitted to + /// take one of two actions. + ///

+ /// + /// + /// Throw an exception. + /// + /// + /// + /// Return the supplied as is. + /// + /// + /// + ///
+ /// The name of the message to resolve. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + string GetMessage(string name); + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// + ///

+ /// If the lookup is not successful, implementations are permitted to + /// take one of two actions. + ///

+ /// + /// + /// Throw an exception. + /// + /// + /// + /// Return the supplied as is. + /// + /// + /// + ///
+ /// The name of the message to resolve. + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + string GetMessage(string name, params object[] arguments); + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + ///

+ /// If the lookup is not successful, implementations are permitted to + /// take one of two actions. + ///

+ /// + /// + /// Throw an exception. + /// + /// + /// + /// Return the supplied as is. + /// + /// + /// + ///
+ /// The name of the message to resolve. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + string GetMessage(string name, CultureInfo culture); + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + ///

+ /// If the lookup is not successful, implementations are permitted to + /// take one of two actions. + ///

+ /// + /// + /// Throw an exception. + /// + /// + /// + /// Return the supplied as is. + /// + /// + /// + ///
+ /// The name of the message to resolve. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + string GetMessage(string name, CultureInfo culture, params object[] arguments); + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + ///

+ /// If the lookup is not successful, implementations are permitted to + /// take one of two actions. + ///

+ /// + /// + /// Throw an exception. + /// + /// + /// + /// Return the supplied as is. + /// + /// + /// + ///
+ /// The name of the message to resolve. + /// The default message if name is not found. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments); + + /// + /// Resolve the message using all of the attributes contained within + /// the supplied + /// argument. + /// + /// + /// The value object storing those attributes that are required to + /// properly resolve a message. + /// + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture); + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + ///

+ /// This method must use the + /// + /// value to obtain a resource. + ///

+ ///

+ /// Examples of resources that may be resolved by this method include + /// (but are not limited to) objects such as icons and bitmaps. + ///

+ ///
+ /// + /// The name of the resource object to resolve. + /// + /// + /// The resolved object, or if not found. + /// + object GetResourceObject(string name); + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + ///

+ /// Examples of resources that may be resolved by this method include + /// (but are not limited to) objects such as icons and bitmaps. + ///

+ ///
+ /// + /// The name of the resource object to resolve. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + /// The resolved object, or if not found. + /// + object GetResourceObject(string name, CultureInfo culture); + + /// + /// Applies resources to object properties. + /// + /// + ///

+ /// Resource key names are of the form objectName.propertyName. + ///

+ ///
+ /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + void ApplyResources(object value, string objectName, CultureInfo culture); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/IMessageSourceAware.cs b/src/Spring/Spring.Core/Context/IMessageSourceAware.cs index 9407c0b2..0438de0e 100644 --- a/src/Spring/Spring.Core/Context/IMessageSourceAware.cs +++ b/src/Spring/Spring.Core/Context/IMessageSourceAware.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Context { - - /// - /// To be implemented by any object that wishes to be notified - /// of the associated with it. - /// - /// - ///

- /// In the current implementation, the - /// will typically be the - /// associated that - /// spawned the implementing object. - ///

- ///

- /// The can usually also be - /// passed on as an object reference to arbitrary object properties or - /// constructor arguments, because a - /// is typically defined as an - /// object with the well known name "messageSource" in the - /// associated application context. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IMessageSourceAware.cs,v 1.4 2006/04/09 07:18:38 markpollack Exp $ - /// - public interface IMessageSourceAware - { - /// - /// Sets the associated - /// with this object. - /// - /// - ///

- /// Invoked after population of normal object properties but - /// before an initializing callback such as the - /// - /// method of the - /// interface - /// or a custom init-method. - ///

- ///

- /// It is also invoked before the - /// - /// property of any - /// - /// implementation. - ///

- ///
- /// - /// The associated - /// with this object. - /// - IMessageSource MessageSource - { - set; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Context { + + /// + /// To be implemented by any object that wishes to be notified + /// of the associated with it. + /// + /// + ///

+ /// In the current implementation, the + /// will typically be the + /// associated that + /// spawned the implementing object. + ///

+ ///

+ /// The can usually also be + /// passed on as an object reference to arbitrary object properties or + /// constructor arguments, because a + /// is typically defined as an + /// object with the well known name "messageSource" in the + /// associated application context. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// + public interface IMessageSourceAware + { + /// + /// Sets the associated + /// with this object. + /// + /// + ///

+ /// Invoked after population of normal object properties but + /// before an initializing callback such as the + /// + /// method of the + /// interface + /// or a custom init-method. + ///

+ ///

+ /// It is also invoked before the + /// + /// property of any + /// + /// implementation. + ///

+ ///
+ /// + /// The associated + /// with this object. + /// + IMessageSource MessageSource + { + set; + } + } +} diff --git a/src/Spring/Spring.Core/Context/IMessageSourceResolvable.cs b/src/Spring/Spring.Core/Context/IMessageSourceResolvable.cs index 01473015..4f48b6de 100644 --- a/src/Spring/Spring.Core/Context/IMessageSourceResolvable.cs +++ b/src/Spring/Spring.Core/Context/IMessageSourceResolvable.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; - -#endregion - -namespace Spring.Context -{ - /// - /// Describes objects that are suitable for message resolution in a - /// . - /// - /// - ///

- /// Spring.NET's own validation error classes implement this interface. - ///

- ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: IMessageSourceResolvable.cs,v 1.6 2006/04/09 07:18:38 markpollack Exp $ - /// - /// - public interface IMessageSourceResolvable - { - /// - /// Return the codes to be used to resolve this message, in the order - /// that they are to be tried. - /// - /// - ///

- /// The last code will therefore be the default one. - ///

- ///
- /// - /// A array of codes which are associated - /// with this message. - /// - string[] GetCodes(); - - /// - /// Return the array of arguments to be used to resolve this message. - /// - /// - /// An array of objects to be used as parameters to replace - /// placeholders within the message text. - /// - object[] GetArguments(); - - /// - /// Return the default message to be used to resolve this message. - /// - /// - /// The default message, or if there is no - /// default. - /// - string DefaultMessage { get; } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; + +#endregion + +namespace Spring.Context +{ + /// + /// Describes objects that are suitable for message resolution in a + /// . + /// + /// + ///

+ /// Spring.NET's own validation error classes implement this interface. + ///

+ ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + /// + /// + public interface IMessageSourceResolvable + { + /// + /// Return the codes to be used to resolve this message, in the order + /// that they are to be tried. + /// + /// + ///

+ /// The last code will therefore be the default one. + ///

+ ///
+ /// + /// A array of codes which are associated + /// with this message. + /// + string[] GetCodes(); + + /// + /// Return the array of arguments to be used to resolve this message. + /// + /// + /// An array of objects to be used as parameters to replace + /// placeholders within the message text. + /// + object[] GetArguments(); + + /// + /// Return the default message to be used to resolve this message. + /// + /// + /// The default message, or if there is no + /// default. + /// + string DefaultMessage { get; } + } +} diff --git a/src/Spring/Spring.Core/Context/IResourceLoaderAware.cs b/src/Spring/Spring.Core/Context/IResourceLoaderAware.cs index f8006c7b..b18d3ed1 100644 --- a/src/Spring/Spring.Core/Context/IResourceLoaderAware.cs +++ b/src/Spring/Spring.Core/Context/IResourceLoaderAware.cs @@ -1,83 +1,82 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Core.IO; - -#endregion - -namespace Spring.Context -{ - /// - /// Interface to be implemented by any object that wishes to be notified - /// of the (typically the - /// ) that it runs in. - /// - /// - ///

- /// Note that dependencies can also - /// be exposed as object properties of type - /// , populated via strings with - /// automatic type conversion by the object factory. This obviates the - /// need for implementing any callback interface just for the purpose of - /// accessing a specific resource. - ///

- ///

- /// You typically need an - /// when your application object has to access a variety of file resources - /// whose names are calculated. A good strategy is to make the object use - /// a default resource loader but still implement the - /// interface to allow - /// for overriding when running in an - /// . - ///

- ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: IResourceLoaderAware.cs,v 1.8 2007/08/08 17:46:37 bbaia Exp $ - /// - /// - /// - public interface IResourceLoaderAware - { - /// - /// Gets and sets the - /// that this object runs in. - /// - /// - ///

- /// Invoked after population of normal objects properties but - /// before an init callback such as - /// 's - /// - /// or a custom init-method. Invoked before setting - /// 's - /// - /// property. - ///

- ///
- IResourceLoader ResourceLoader - { - set; - get; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Core.IO; + +#endregion + +namespace Spring.Context +{ + /// + /// Interface to be implemented by any object that wishes to be notified + /// of the (typically the + /// ) that it runs in. + /// + /// + ///

+ /// Note that dependencies can also + /// be exposed as object properties of type + /// , populated via strings with + /// automatic type conversion by the object factory. This obviates the + /// need for implementing any callback interface just for the purpose of + /// accessing a specific resource. + ///

+ ///

+ /// You typically need an + /// when your application object has to access a variety of file resources + /// whose names are calculated. A good strategy is to make the object use + /// a default resource loader but still implement the + /// interface to allow + /// for overriding when running in an + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + /// + /// + /// + public interface IResourceLoaderAware + { + /// + /// Gets and sets the + /// that this object runs in. + /// + /// + ///

+ /// Invoked after population of normal objects properties but + /// before an init callback such as + /// 's + /// + /// or a custom init-method. Invoked before setting + /// 's + /// + /// property. + ///

+ ///
+ IResourceLoader ResourceLoader + { + set; + get; + } + } +} diff --git a/src/Spring/Spring.Core/Context/NoSuchMessageException.cs b/src/Spring/Spring.Core/Context/NoSuchMessageException.cs index b2eb9026..aa51d6eb 100644 --- a/src/Spring/Spring.Core/Context/NoSuchMessageException.cs +++ b/src/Spring/Spring.Core/Context/NoSuchMessageException.cs @@ -1,115 +1,114 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Context -{ - /// - /// Thrown when a message cannot be resolved. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// - /// - /// $Id: NoSuchMessageException.cs,v 1.8 2007/07/17 14:51:13 oakinger Exp $ - [Serializable] - public class NoSuchMessageException : ApplicationException - { - /// - /// Creates a new instance of the - /// class. - /// - public NoSuchMessageException() - { - } - - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NoSuchMessageException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being - /// thrown. - /// - /// - /// The - /// that contains contextual information about the source or - /// destination. - /// - protected NoSuchMessageException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The code that could not be resolved for given culture. - /// - /// - /// The that was used - /// to search for the code. - /// - public NoSuchMessageException(string code, CultureInfo culture) - : base(string.Format("No message found under code '{0}' for locale '{1}'.", - code, culture)) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The code that could not be resolved for the current UI culture. - /// - public NoSuchMessageException(string code) - : this(code, CultureInfo.CurrentUICulture) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Context +{ + /// + /// Thrown when a message cannot be resolved. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + /// + /// + [Serializable] + public class NoSuchMessageException : ApplicationException + { + /// + /// Creates a new instance of the + /// class. + /// + public NoSuchMessageException() + { + } + + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NoSuchMessageException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being + /// thrown. + /// + /// + /// The + /// that contains contextual information about the source or + /// destination. + /// + protected NoSuchMessageException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The code that could not be resolved for given culture. + /// + /// + /// The that was used + /// to search for the code. + /// + public NoSuchMessageException(string code, CultureInfo culture) + : base(string.Format("No message found under code '{0}' for locale '{1}'.", + code, culture)) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The code that could not be resolved for the current UI culture. + /// + public NoSuchMessageException(string code) + : this(code, CultureInfo.CurrentUICulture) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs index ed7ab560..acf1052d 100644 --- a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs @@ -1,1754 +1,1753 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Diagnostics; -using System.Globalization; -using Common.Logging; -using Spring.Context.Events; -using Spring.Core; -using Spring.Core.IO; -using Spring.Objects; -using Spring.Objects.Events; -using Spring.Objects.Events.Support; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Partial implementation of the - /// interface. - /// - /// - ///

- /// Does not mandate the type of storage used for configuration, but does - /// implement common functionality. Uses the Template Method design - /// pattern, requiring concrete subclasses to implement - /// methods. - ///

- ///

- /// In contrast to a plain vanilla - /// , an - /// is supposed - /// to detect special objects defined in its object factory: therefore, - /// this class automatically registers - /// s, - /// s - /// and s that are - /// defined as objects in the context. - ///

- ///

- /// An may be also supplied as - /// an object in the context, with the special, well-known-name of - /// "messageSource". Else, message resolution is delegated to the - /// parent context. - ///

- ///
- /// Rod Johnson - /// Juergan Hoeller - /// Griffin Caprio (.NET) - /// $Id: AbstractApplicationContext.cs,v 1.74 2007/08/27 09:38:28 oakinger Exp $ - /// - /// - public abstract class AbstractApplicationContext - : ConfigurableResourceLoader, IConfigurableApplicationContext - { - #region Constants - - /// - /// Name of the .Net config section that contains Spring.Net context definition. - /// - public const string ContextSectionName = "spring/context"; - - /// - /// Default name of the root context. - /// - public const string DefaultRootContextName = "spring.root"; - - #endregion - - #region Fields - - private const long TicksAtEpoch = 621355968000000000; - - /// - /// The special, well-known-name of the default - /// in the context. - /// - /// - ///

- /// If no can be found - /// in the context using this lookup key, then message resolution - /// will be delegated to the parent context (if any). - ///

- ///
- public static readonly string MessageSourceObjectName = "messageSource"; - - /// - /// The special, well-known-name of the default - /// in the context. - /// - /// - ///

- /// If no can be found - /// in the context using this lookup key, then a default - /// will be used. - ///

- ///
- public static readonly string EventRegistryObjectName = "eventRegistry"; - - /// - /// The instance for this class. - /// - private static readonly ILog log = LogManager.GetLogger(typeof(AbstractApplicationContext)); - - /// - /// The instance we delegate - /// our implementation of said interface to. - /// - private IMessageSource _messageSource; - - /// - /// The instance we - /// delegate our implementation of said interface to. - /// - private IEventRegistry _eventRegistry; - - private IApplicationContext _parentApplicationContext; - private readonly IList _objectFactoryPostProcessors; - private IList _defaultObjectPostProcessors; - private string _name; - private DateTime _startupDate; - private readonly bool _caseSensitive; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// with no parent context. - /// - /// - ///

- /// This is an class, and as such exposes - /// no public constructors. - ///

- ///
- protected AbstractApplicationContext() : this(null, true, null) - { - } - - /// - /// Creates a new instance of the - /// with no parent context. - /// - /// - ///

- /// This is an class, and as such exposes - /// no public constructors. - ///

- ///
- /// Flag specifying whether to make this context case sensitive or not. - protected AbstractApplicationContext(bool caseSensitive) : this(null, caseSensitive, null) - { - } - - /// - /// Creates a new instance of the - /// with the supplied parent context. - /// - /// - ///

- /// This is an class, and as such exposes - /// no public constructors. - ///

- ///
- /// The application context name. - /// Flag specifying whether to make this context case sensitive or not. - /// The parent application context. - protected AbstractApplicationContext(string name, bool caseSensitive, - IApplicationContext parentApplicationContext) - { - _name = (StringUtils.IsNullOrEmpty(name)) ? DefaultRootContextName : name; - _caseSensitive = caseSensitive; - _parentApplicationContext = parentApplicationContext; - _objectFactoryPostProcessors = new ArrayList(); - _defaultObjectPostProcessors = new ArrayList(); - AddDefaultObjectPostProcessor(new ObjectPostProcessorChecker()); - AddDefaultObjectPostProcessor(new ApplicationContextAwareProcessor(this)); - } - - /// - /// Adds the given to the list of standard - /// processors being added to the underlying - /// - /// - /// Each time is called on this context, the context ensures, that - /// all default s are registered with the underlying . - /// - /// The instance. - protected void AddDefaultObjectPostProcessor(IObjectPostProcessor defaultObjectPostProcessor) - { - _defaultObjectPostProcessors.Add(defaultObjectPostProcessor); - } - - /// - /// Closes this context and disposes of any resources (such as - /// singleton objects in the wrapped - /// ). - /// - public virtual void Dispose() - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Closing application context [{0}].", - Name)); - } - - #endregion - - new DefensiveEventRaiser().Raise( - ContextEvent, this, - new ContextEventArgs(ContextEventArgs.ContextEvent.Closed)); - ObjectFactory.Dispose(); - } - - #endregion - - #region Abstract Methods - - /// - /// Subclasses must implement this method to perform the actual - /// configuration loading. - /// - /// - ///

- /// This method is invoked by - /// , - /// before any other initialization occurs. - ///

- ///
- /// - /// In the case of errors encountered while refreshing the object factory. - /// - protected abstract void RefreshObjectFactory(); - - #endregion - - /// - /// An object that can be used to synchronize access to the - /// - public object SyncRoot - { - get { return this; } - } - - /// - /// The timestamp when this context was first loaded. - /// - /// - /// The timestamp (milliseconds) when this context was first loaded. - /// - public long StartupDateMilliseconds - { - get { return (StartupDate.Ticks - TicksAtEpoch)/10000; } - } - - - /// - /// Gets a flag indicating whether context should be case sensitive. - /// - /// true if object lookups are case sensitive; otherwise, false. - protected bool CaseSensitive - { - get { return _caseSensitive; } - } - - /// - /// The for this context. - /// - /// - /// If the context has not been initialized yet. - /// - public IMessageSource MessageSource - { - get - { - if (_messageSource == null) - { - throw new InvalidOperationException( - "MessageSource not initialized - call 'Refresh()' " + - "before accessing messages via the context: " + this); - } - return _messageSource; - } - } - - /// - /// The for this context. - /// - /// - /// If the context has not been initialized yet. - /// - public IEventRegistry EventRegistry - { - get - { - if (_eventRegistry == null) - { - throw new InvalidOperationException( - "EventRegistry not initialized - call 'Refresh()' " + - "before accessing the event registry via the context: " + this); - } - return _eventRegistry; - } - } - - /// - /// Returns the internal object factory of the parent context if it implements - /// ; else, - /// returns the parent context itself. - /// - /// - /// The parent context's object factory, or the parent itself. - /// - protected IObjectFactory GetInternalParentObjectFactory() - { - IConfigurableApplicationContext configContext - = _parentApplicationContext as IConfigurableApplicationContext; - if (configContext != null) - { - return ((IConfigurableApplicationContext) - _parentApplicationContext).ObjectFactory; - } - else - { - return _parentApplicationContext; - } - } - - /// - /// Raises an application context event. - /// - /// - /// Any arguments to the event. May be . - /// - protected virtual void OnContextEvent(ApplicationEventArgs e) - { - OnContextEvent(this, e); - } - - /// - /// Raises an application context event. - /// - /// - /// The source of the event. - /// - /// - /// Any arguments to the event. May be . - /// - protected virtual void OnContextEvent(object source, ApplicationEventArgs e) - { - new DefensiveEventRaiser().Raise(ContextEvent, source, e); - } - - /// - /// Modify the application context's internal object factory after its standard - /// initialization. - /// - /// - ///

- /// All object definitions will have been loaded, but no objects - /// will have been instantiated yet. This allows for the registration - /// of special - /// s - /// in certain - /// implementations. - ///

- ///
- /// - /// The object factory used by the application context. - /// - /// - /// In the case of errors. - /// . - protected virtual void PostProcessObjectFactory( - IConfigurableListableObjectFactory objectFactory) - { - } - - /// - /// Template method which can be overridden to add context-specific - /// refresh work. - /// - /// - ///

- /// Called on initialization of special objects, before instantiation - /// of singletons. - ///

- ///
- protected virtual void OnRefresh() - { - } - - /// - /// Instantiate and invoke all registered - /// - /// objects, respecting any explicit ordering. - /// - /// - /// - /// Must be called before singleton instantiation. - /// - /// - /// In the case of errors. - private void InvokeObjectFactoryPostProcessors() - { - // do NOT include IFactoryObjects; they (typically) need to be instantiated - // to determine the Type of object that they create, and if they are instantiated - // then we won't be able to do any factory post processin' on 'em... - string[] factoryProcessorNames - = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false); - ArrayList orderedFactoryProcessors = new ArrayList(); - IList nonOrderedFactoryProcessorNames = new ArrayList(); - for (int i = 0; i < factoryProcessorNames.Length; ++i) - { - string processorName = factoryProcessorNames[i]; - object processor = GetObject(processorName); - if (typeof(IOrdered).IsAssignableFrom(GetType(processorName))) - { - orderedFactoryProcessors.Add(processor); - } - else - { - nonOrderedFactoryProcessorNames.Add(processor); - } - } - // first, invoke those IObjectFactoryPostProcessors that implement IOrdered... - orderedFactoryProcessors.Sort(new OrderComparator()); - ProcessObjectFactoryPostProcessors(orderedFactoryProcessors); - // and then the unordered ones... - ProcessObjectFactoryPostProcessors(nonOrderedFactoryProcessorNames); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "processed {0} IFactoryObjectPostProcessors defined in application context [{1}].", - factoryProcessorNames.Length, - Name)); - } - - #endregion - } - - private void ProcessObjectFactoryPostProcessors(IList orderedFactoryProcessors) - { - foreach (IObjectFactoryPostProcessor processor in orderedFactoryProcessors) - { - processor.PostProcessObjectFactory(ObjectFactory); - } - } - - private void RegisterObjectPostProcessors(IConfigurableListableObjectFactory objectFactory) - { - RegisterObjectPostProcessorChecker(objectFactory); - IDictionary dict = GetObjectsOfType(typeof(IObjectPostProcessor), true, false); - ArrayList objectProcessors = new ArrayList(dict.Values); - objectProcessors.Sort(new OrderComparator()); - foreach (IObjectPostProcessor objectPostProcessor in objectProcessors) - { - ObjectFactory.AddObjectPostProcessor(objectPostProcessor); - } - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "processed {0} IObjectPostProcessors defined in application context [{1}].", - objectProcessors.Count, - Name)); - } - } - - /// - /// Register an IObjectPostProcessorChecker that logs an info - /// message when an object is created during IObjectPostProcessor - /// instantiation, i.e. when an object is not eligible for being - /// processed by all IObjectPostProcessors. - /// - private void RegisterObjectPostProcessorChecker(IConfigurableListableObjectFactory objectFactory) - { - int objectPostProcessorCount - = ObjectFactory.ObjectPostProcessorCount + 1 - + GetObjectNamesForType(typeof(IObjectPostProcessor), true, false).Length; -// ObjectFactory.AddObjectPostProcessor( -// new ObjectPostProcessorChecker(objectFactory, objectPostProcessorCount)); - ((ObjectPostProcessorChecker) _defaultObjectPostProcessors[0]).Reset(objectFactory, objectPostProcessorCount); - } - - /// - /// Initializes the default event registry for this context. - /// - private void InitEventRegistry() - { - if (ContainsObject(EventRegistryObjectName)) - { - object candidateRegistry = GetObject(EventRegistryObjectName); - if (candidateRegistry is IEventRegistry) - { - _eventRegistry = (IEventRegistry) candidateRegistry; - - #region Instrumentation - - log.Debug(StringUtils.Surround( - "Using IEventRegistry [", EventRegistry, "]")); - - #endregion - } - else - { - _eventRegistry = new EventRegistry(); - - #region Instrumentation - - if (log.IsWarnEnabled) - { - log.Warn(string.Format( - "Found object in context named '{0}' : this name " + - "is typically reserved for IEventRegistry objects. " + - "Falling back to default '{1}'.", - EventRegistryObjectName, EventRegistry)); - } - - #endregion - } - } - else - { - _eventRegistry = new EventRegistry(); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - "No IEventRegistry found with name '{0}' : using default '{1}'.", - EventRegistryObjectName, EventRegistry)); - } - - #endregion - } - ICollection interestedParties - = GetObjectsOfType(typeof(IEventRegistryAware), true, false).Values; - foreach (IEventRegistryAware party in interestedParties) - { - party.EventRegistry = EventRegistry; - } - EventRegistry.PublishEvents(this); - } - - /// - /// Returns the internal message source of the parent context if said - /// parent context is an , else - /// simply the parent context itself. - /// - /// - /// The internal message source of the parent context if said - /// parent context is an , else - /// simply the parent context itself. - /// - protected virtual IMessageSource GetInternalParentMessageSource() - { - AbstractApplicationContext parent - = ParentContext as AbstractApplicationContext; - return parent == null ? ParentContext : parent._messageSource; - } - - /// - /// Initializes the default message source for this context. - /// - /// - ///

- /// Uses any parent context's message source if one is not available - /// in this context. - ///

- ///
- private void InitMessageSource() - { - if (ContainsObject(MessageSourceObjectName)) - { - object candidateSource = GetObject(MessageSourceObjectName); - if (candidateSource is IMessageSource) - { - _messageSource - = (IMessageSource) GetObject(MessageSourceObjectName); - - // make IMessageSource aware of any parent IMessageSource... - if (ParentContext != null) - { - IHierarchicalMessageSource hierSource - = MessageSource as IHierarchicalMessageSource; - if (hierSource != null) - { - IMessageSource parentMessageSource - = GetInternalParentMessageSource(); - hierSource.ParentMessageSource = parentMessageSource; - } - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(StringUtils.Surround( - "Using MessageSource [", MessageSource, "]")); - } - - #endregion - } - else - { - _messageSource = new DelegatingMessageSource( - GetInternalParentMessageSource()); - - #region Instrumentation - - if (log.IsWarnEnabled) - { - log.Warn(string.Format( - "Found object in context named '{0}' : this name " + - "is typically reserved for IMessageSource objects. " + - "Falling back to default '{1}'.", - MessageSourceObjectName, MessageSource)); - } - - #endregion - } - } - else if (ParentContext != null) - { - _messageSource = new DelegatingMessageSource( - GetInternalParentMessageSource()); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - "No message source found in the current context: using parent context's message source '{0}'.", - MessageSource)); - } - - #endregion - } - else - { - _messageSource = new StaticMessageSource(); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - "No IMessageSource found with name '{0}' : using default '{1}'.", - MessageSourceObjectName, MessageSource)); - } - - #endregion - } - } - - private void RefreshApplicationEventListeners() - { - ICollection listeners - = GetObjectsOfType( - typeof(IApplicationEventListener), true, false).Values; - foreach (IApplicationEventListener applicationListener in listeners) - { - EventRegistry.Subscribe(applicationListener); - } - } - - /// - /// Returns the list of the - /// s - /// that will be applied to the objects created with this factory. - /// - /// - ///

- /// The elements of this list are instances of implementations of the - /// - /// interface. - ///

- ///
- /// - /// The list of the - /// s - /// that will be applied to the objects created with this factory. - /// - private IList ObjectFactoryPostProcessors - { - get { return _objectFactoryPostProcessors; } - } - - #region IConfigurableApplicationContext Members - - /// - /// Return the internal object factory of this application context. - /// - public abstract IConfigurableListableObjectFactory ObjectFactory { get; } - - /// - /// Add a new - /// that will get applied to the internal object factory of this application context - /// on refresh, before any of the object definitions are evaluated. - /// - /// - /// The factory processor to register. - /// - public void AddObjectFactoryPostProcessor( - IObjectFactoryPostProcessor objectFactoryPostProcessor) - { - _objectFactoryPostProcessors.Add(objectFactoryPostProcessor); - } - - /// - /// Load or refresh the persistent representation of the configuration, - /// which might an XML file, properties file, or relational database schema. - /// - /// - /// If the configuration cannot be loaded. - /// - /// - /// If the object factory could not be initialized. - /// - public virtual void Refresh() - { - lock (SyncRoot) - { - - /* - #region Instrumentation - - if (log.IsDebugEnabled) - { - StackTrace stackTrace = new StackTrace(1, true); - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Refreshing application context [{0}]. Called from:{1}", - Name, stackTrace)); - } - - #endregion - */ - - _startupDate = DateTime.Now; - - RefreshObjectFactory(); - IConfigurableListableObjectFactory objectFactory = ObjectFactory; - - EnsureKnownObjectPostProcessors(objectFactory); - objectFactory.IgnoreDependencyType(typeof(IResourceLoader)); - objectFactory.IgnoreDependencyType(typeof(IApplicationContext)); - - PostProcessObjectFactory(objectFactory); - foreach (IObjectFactoryPostProcessor factoryProcessor in ObjectFactoryPostProcessors) - { - factoryProcessor.PostProcessObjectFactory(objectFactory); - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "{0} objects defined in application context [{1}].", - ObjectDefinitionCount == 0 ? "No" : ObjectDefinitionCount.ToString(), - Name)); - } - - #endregion - - InvokeObjectFactoryPostProcessors(); - RegisterObjectPostProcessors(objectFactory); - InitEventRegistry(); - InitMessageSource(); - OnRefresh(); - RefreshApplicationEventListeners(); - - objectFactory.PreInstantiateSingletons(); - - new DefensiveEventRaiser().Raise( - ContextEvent, this, - new ContextEventArgs(ContextEventArgs.ContextEvent.Refreshed)); - } - } - - /// - /// Ensures, that predefined ObjectPostProcessors are registered with this ObjectFactory - /// - /// - protected void EnsureKnownObjectPostProcessors(IConfigurableListableObjectFactory objectFactory) - { - // index 0 contains the ObjectPostProcessorChecker that is handled separately! - for (int i = 1; i < _defaultObjectPostProcessors.Count; i++) - { - objectFactory.AddObjectPostProcessor((IObjectPostProcessor) this._defaultObjectPostProcessors[i]); - } - } - - /// - /// Gets the parent context, or if there is no - /// parent context. - /// - /// - /// The parent context, or if there is no - /// parent. - /// - /// - public virtual IApplicationContext ParentContext - { - get { return _parentApplicationContext; } - set { _parentApplicationContext = value; } - } - - #endregion - - #region IApplicationContext Members - - /// - /// Raised in response to an implementation-dependant application - /// context event. - /// - public event ApplicationEventHandler ContextEvent; - - /// - /// The date and time this context was first loaded. - /// - /// - /// The representing when this context - /// was first loaded. - /// - public DateTime StartupDate - { - get { return _startupDate; } - } - - /// - /// A name for this context. - /// - /// - /// A name for this context. - /// - public string Name - { - get { return _name; } - set { _name = value; } - } - - - - #endregion - - #region IListableObjectFactory Members - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectNamesForType(Type type) - { - return ObjectFactory.GetObjectNamesForType(type); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectNamesForType( - Type type, bool includePrototypes, bool includeFactoryObjects) - { - return ObjectFactory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects); - } - - /// - /// Return the names of all objects defined in this factory. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectDefinitionNames() - { - return ObjectFactory.GetObjectDefinitionNames(); - } - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - public virtual IObjectDefinition GetObjectDefinition(string name) - { - return ObjectFactory.GetObjectDefinition(name); - } - - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// Whether to search parent object factories. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - public IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) - { - return ObjectFactory.GetObjectDefinition(name, includeAncestors); - } - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - /// The (class or interface) to match. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - /// - public IDictionary GetObjectsOfType(Type type) - { - return GetObjectsOfType(type, true, true); - } - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - /// The (class or interface) to match. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - /// - public IDictionary GetObjectsOfType( - Type type, bool includePrototypes, bool includeFactoryObjects) - { - return ObjectFactory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects); - } - - /// - /// Return the number of objects defined in the factory. - /// - /// - /// The number of objects defined in the factory. - /// - /// - public int ObjectDefinitionCount - { - get { return ObjectFactory.ObjectDefinitionCount; } - } - - /// - /// Check if this object factory contains an object definition with the given name. - /// - /// The name of the object to look for. - /// - /// True if this object factory contains an object definition with the given name. - /// - /// - public bool ContainsObjectDefinition(string name) - { - return ObjectFactory.ContainsObjectDefinition(name); - } - - #endregion - - #region IObjectFactory Members - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - public object this[string name] - { - get { return ObjectFactory.GetObject(name); } - } - - /// - /// Does this object factory contain an object with the given name? - /// - /// The name of the object to query. - /// - /// if an object with the given name is defined. - /// - /// - public bool ContainsObject(string name) - { - return ObjectFactory.ContainsObject(name); - } - - /// - /// Return the aliases for the given object name, if defined. - /// - /// The object name to check for aliases. - /// The aliases, or an empty array if none. - /// - /// If there's no such object definition. - /// - /// - public string[] GetAliases(string name) - { - return ObjectFactory.GetAliases(name); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// - /// the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the object is not of the required type. - /// - /// - public object GetObject(string name, Type requiredType) - { - return ObjectFactory.GetObject(name, requiredType); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - public object GetObject(string name) - { - return ObjectFactory.GetObject(name); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to return. - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. If there is no factory method and the - /// arguments are not null, then match the argument values by type and - /// call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the supplied is . - /// - public object GetObject(string name, object[] arguments) - { - return ObjectFactory.GetObject(name, arguments); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// - /// The the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a factory method. If there is no factory method and the - /// supplied array is not , then - /// match the argument values by type and call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the object is not of the required type. - /// - /// - /// If the supplied is . - /// - /// - public object GetObject(string name, Type requiredType, object[] arguments) - { - return ObjectFactory.GetObject(name, requiredType, arguments); - } - - /// - /// Is this object a singleton? - /// - /// The name of the object to query. - /// True if the named object is a singleton. - /// - /// If there's no such object definition. - /// - /// - public bool IsSingleton(string name) - { - return ObjectFactory.IsSingleton(name); - } - - /// - /// Determines whether the specified object name is prototype. That is, will GetObject - /// always return independent instances? - /// - /// The name of the object to query - /// - /// true if the specified object name will always deliver independent instances; otherwise, false. - /// - /// This method returning false does not clearly indicate a singleton object. - /// It indicated non-independent instances, which may correspond to a scoped object as - /// well. use the IsSingleton property to explicitly check for a shared - /// singleton instance. - /// Translates aliases back to the corresponding canonical object name. Will ask the - /// parent factory if the object can not be found in this factory instance. - /// - /// - /// if there is no object with the given name. - public bool IsPrototype(string name) - { - return ObjectFactory.IsPrototype(name); - } - - - /// - /// Determines whether the object with the given name matches the specified type. - /// - /// More specifically, check whether a GetObject call for the given name - /// would return an object that is assignable to the specified target type. - /// Translates aliases back to the corresponding canonical bean name. - /// Will ask the parent factory if the bean cannot be found in this factory instance. - /// - /// The name of the object to query. - /// Type of the target to match against. - /// - /// true if the object type matches; otherwise, false - /// if it doesn't match or cannot be determined yet. - /// - /// Ff there is no object with the given name - /// - public bool IsTypeMatch(string name, Type targetType) - { - return ObjectFactory.IsTypeMatch(name, targetType); - } - - /// - /// Determine the of the object with the - /// given name. - /// - /// The name of the object to query. - /// - /// The of the object, or - /// if not determinable. - /// - /// - public Type GetType(string name) - { - return ObjectFactory.GetType(name); - } - - /// - /// Injects dependencies into the supplied instance - /// using the named object definition. - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - public object ConfigureObject(object target, string name) - { - return ObjectFactory.ConfigureObject(target, name); - } - - /// - /// Injects dependencies into the supplied instance - /// using the supplied . - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// An object definition that should be used to configure object. - /// - /// - public object ConfigureObject(object target, string name, IObjectDefinition definition) - { - return ObjectFactory.ConfigureObject(target, name, definition); - } - - #endregion - - #region IHierarchicalObjectFactory Members - - /// - /// Return the parent object factory, or if there is none. - /// - /// - /// The parent object factory, or if there is none. - /// - /// - public IObjectFactory ParentObjectFactory - { - get { return _parentApplicationContext; } - } - - #endregion - - #region IMessageSource Members - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If no message could be resolved. - /// - /// - /// If the supplied is . - /// - /// - public string GetMessage( - string name, CultureInfo culture, params object[] arguments) - { - return MessageSource.GetMessage(name, culture, arguments); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// The default message. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If no message could be resolved. - /// - /// - /// If the supplied is . - /// - /// - public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) - { - return MessageSource.GetMessage(name, defaultMessage, culture, arguments); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The resolved message if the lookup was successful. - /// - /// - /// If no message could be resolved. - /// - /// - public string GetMessage(string name) - { - return MessageSource.GetMessage(name); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful. - /// - /// - /// If no message could be resolved. - /// - /// - /// If the supplied is . - /// - /// - public string GetMessage(string name, params object[] arguments) - { - return MessageSource.GetMessage(name, arguments); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If no message could be resolved. - /// - /// - /// If the supplied is . - /// - /// - public string GetMessage(string name, CultureInfo culture) - { - return MessageSource.GetMessage(name, culture); - } - - /// - /// Resolve the message using all of the attributes contained within - /// the supplied - /// argument. - /// - /// - /// The value object storing those attributes that are required to - /// properly resolve a message. - /// - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) - { - return MessageSource.GetMessage(resolvable, culture); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - /// The resolved object, or if not found. - /// - /// - object IMessageSource.GetResourceObject(string name, CultureInfo culture) - { - return GetResourceObject(name, culture); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The resolved object, or if not found. - /// - /// - object IMessageSource.GetResourceObject(string name) - { - return GetResourceObject(name); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - /// The resolved object, or if not found. - /// - /// - public object GetResourceObject(string name, CultureInfo culture) - { - return MessageSource.GetResourceObject(name, culture); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The resolved object, or if not found. - /// - /// - public object GetResourceObject(string name) - { - return MessageSource.GetResourceObject(name); - } - - /// - /// Applies resources to object properties. - /// - /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - public void ApplyResources(object value, string objectName, CultureInfo culture) - { - MessageSource.ApplyResources(value, objectName, culture); - } - - #endregion - - #region IEventRegistry Members - - /// - /// Publishes all events of the source object. - /// - /// - /// The source object containing events to publish. - /// - /// - public void PublishEvents(object sourceObject) - { - _eventRegistry.PublishEvents(sourceObject); - } - - /// - /// Subscribes to all events published, if the subscriber - /// implements compatible handler methods. - /// - /// The subscriber to use. - /// - public void Subscribe(object subscriber) - { - _eventRegistry.Subscribe(subscriber); - } - - /// - /// Subscribes to published events of a all objects of a given - /// , if the subscriber implements - /// compatible handler methods. - /// - /// The subscriber to use. - /// - /// The target to subscribe to. - /// - /// - public void Subscribe(object subscriber, Type targetSourceType) - { - _eventRegistry.Subscribe(subscriber, targetSourceType); - } - - #endregion - - /// - /// Publishes an application context event. - /// - /// - ///

- /// - ///

- ///
- /// - /// The source of the event. May be . - /// - /// - /// The event that is to be raised. - /// - /// - public void PublishEvent(object sender, ApplicationEventArgs e) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Publishing event in context [{0}] : {1}", - Name, e)); - } - - #endregion - - OnContextEvent(sender, e); - - if (ParentContext != null) - { - ParentContext.PublishEvent(sender, e); - } - } - - #region IPostProcessor implementation - - private sealed class ObjectPostProcessorChecker : IObjectPostProcessor - { - private int _objectPostProcessorTargetCount; - private IConfigurableListableObjectFactory _objectFactory; - - - public ObjectPostProcessorChecker() - { - } - -// public ObjectPostProcessorChecker( -// IConfigurableListableObjectFactory objectFactory, int objectPostProcessorTargetCount) -// { -// _objectFactory = objectFactory; -// _objectPostProcessorTargetCount = objectPostProcessorTargetCount; -// } - - public void Reset(IConfigurableListableObjectFactory objectFactory, int objectPostProcessorTargetCount) - { - _objectFactory = objectFactory; - _objectPostProcessorTargetCount = objectPostProcessorTargetCount; - } - - public object PostProcessBeforeInitialization(object obj, string name) - { - return obj; - } - - public object PostProcessAfterInitialization(object obj, string objectName) - { - if (_objectFactory.ObjectPostProcessorCount < _objectPostProcessorTargetCount) - { - #region Instrumentation - - if (log.IsInfoEnabled) - { - log.Info(string.Format( - "Object '{0}' is not eligible for being processed by all " + - "IObjectPostProcessors (for example: not eligible for auto-proxying).", objectName)); - } - - #endregion - } - return obj; - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Diagnostics; +using System.Globalization; +using Common.Logging; +using Spring.Context.Events; +using Spring.Core; +using Spring.Core.IO; +using Spring.Objects; +using Spring.Objects.Events; +using Spring.Objects.Events.Support; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Partial implementation of the + /// interface. + /// + /// + ///

+ /// Does not mandate the type of storage used for configuration, but does + /// implement common functionality. Uses the Template Method design + /// pattern, requiring concrete subclasses to implement + /// methods. + ///

+ ///

+ /// In contrast to a plain vanilla + /// , an + /// is supposed + /// to detect special objects defined in its object factory: therefore, + /// this class automatically registers + /// s, + /// s + /// and s that are + /// defined as objects in the context. + ///

+ ///

+ /// An may be also supplied as + /// an object in the context, with the special, well-known-name of + /// "messageSource". Else, message resolution is delegated to the + /// parent context. + ///

+ ///
+ /// Rod Johnson + /// Juergan Hoeller + /// Griffin Caprio (.NET) + /// + /// + public abstract class AbstractApplicationContext + : ConfigurableResourceLoader, IConfigurableApplicationContext + { + #region Constants + + /// + /// Name of the .Net config section that contains Spring.Net context definition. + /// + public const string ContextSectionName = "spring/context"; + + /// + /// Default name of the root context. + /// + public const string DefaultRootContextName = "spring.root"; + + #endregion + + #region Fields + + private const long TicksAtEpoch = 621355968000000000; + + /// + /// The special, well-known-name of the default + /// in the context. + /// + /// + ///

+ /// If no can be found + /// in the context using this lookup key, then message resolution + /// will be delegated to the parent context (if any). + ///

+ ///
+ public static readonly string MessageSourceObjectName = "messageSource"; + + /// + /// The special, well-known-name of the default + /// in the context. + /// + /// + ///

+ /// If no can be found + /// in the context using this lookup key, then a default + /// will be used. + ///

+ ///
+ public static readonly string EventRegistryObjectName = "eventRegistry"; + + /// + /// The instance for this class. + /// + private static readonly ILog log = LogManager.GetLogger(typeof(AbstractApplicationContext)); + + /// + /// The instance we delegate + /// our implementation of said interface to. + /// + private IMessageSource _messageSource; + + /// + /// The instance we + /// delegate our implementation of said interface to. + /// + private IEventRegistry _eventRegistry; + + private IApplicationContext _parentApplicationContext; + private readonly IList _objectFactoryPostProcessors; + private IList _defaultObjectPostProcessors; + private string _name; + private DateTime _startupDate; + private readonly bool _caseSensitive; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// with no parent context. + /// + /// + ///

+ /// This is an class, and as such exposes + /// no public constructors. + ///

+ ///
+ protected AbstractApplicationContext() : this(null, true, null) + { + } + + /// + /// Creates a new instance of the + /// with no parent context. + /// + /// + ///

+ /// This is an class, and as such exposes + /// no public constructors. + ///

+ ///
+ /// Flag specifying whether to make this context case sensitive or not. + protected AbstractApplicationContext(bool caseSensitive) : this(null, caseSensitive, null) + { + } + + /// + /// Creates a new instance of the + /// with the supplied parent context. + /// + /// + ///

+ /// This is an class, and as such exposes + /// no public constructors. + ///

+ ///
+ /// The application context name. + /// Flag specifying whether to make this context case sensitive or not. + /// The parent application context. + protected AbstractApplicationContext(string name, bool caseSensitive, + IApplicationContext parentApplicationContext) + { + _name = (StringUtils.IsNullOrEmpty(name)) ? DefaultRootContextName : name; + _caseSensitive = caseSensitive; + _parentApplicationContext = parentApplicationContext; + _objectFactoryPostProcessors = new ArrayList(); + _defaultObjectPostProcessors = new ArrayList(); + AddDefaultObjectPostProcessor(new ObjectPostProcessorChecker()); + AddDefaultObjectPostProcessor(new ApplicationContextAwareProcessor(this)); + } + + /// + /// Adds the given to the list of standard + /// processors being added to the underlying + /// + /// + /// Each time is called on this context, the context ensures, that + /// all default s are registered with the underlying . + /// + /// The instance. + protected void AddDefaultObjectPostProcessor(IObjectPostProcessor defaultObjectPostProcessor) + { + _defaultObjectPostProcessors.Add(defaultObjectPostProcessor); + } + + /// + /// Closes this context and disposes of any resources (such as + /// singleton objects in the wrapped + /// ). + /// + public virtual void Dispose() + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Closing application context [{0}].", + Name)); + } + + #endregion + + new DefensiveEventRaiser().Raise( + ContextEvent, this, + new ContextEventArgs(ContextEventArgs.ContextEvent.Closed)); + ObjectFactory.Dispose(); + } + + #endregion + + #region Abstract Methods + + /// + /// Subclasses must implement this method to perform the actual + /// configuration loading. + /// + /// + ///

+ /// This method is invoked by + /// , + /// before any other initialization occurs. + ///

+ ///
+ /// + /// In the case of errors encountered while refreshing the object factory. + /// + protected abstract void RefreshObjectFactory(); + + #endregion + + /// + /// An object that can be used to synchronize access to the + /// + public object SyncRoot + { + get { return this; } + } + + /// + /// The timestamp when this context was first loaded. + /// + /// + /// The timestamp (milliseconds) when this context was first loaded. + /// + public long StartupDateMilliseconds + { + get { return (StartupDate.Ticks - TicksAtEpoch)/10000; } + } + + + /// + /// Gets a flag indicating whether context should be case sensitive. + /// + /// true if object lookups are case sensitive; otherwise, false. + protected bool CaseSensitive + { + get { return _caseSensitive; } + } + + /// + /// The for this context. + /// + /// + /// If the context has not been initialized yet. + /// + public IMessageSource MessageSource + { + get + { + if (_messageSource == null) + { + throw new InvalidOperationException( + "MessageSource not initialized - call 'Refresh()' " + + "before accessing messages via the context: " + this); + } + return _messageSource; + } + } + + /// + /// The for this context. + /// + /// + /// If the context has not been initialized yet. + /// + public IEventRegistry EventRegistry + { + get + { + if (_eventRegistry == null) + { + throw new InvalidOperationException( + "EventRegistry not initialized - call 'Refresh()' " + + "before accessing the event registry via the context: " + this); + } + return _eventRegistry; + } + } + + /// + /// Returns the internal object factory of the parent context if it implements + /// ; else, + /// returns the parent context itself. + /// + /// + /// The parent context's object factory, or the parent itself. + /// + protected IObjectFactory GetInternalParentObjectFactory() + { + IConfigurableApplicationContext configContext + = _parentApplicationContext as IConfigurableApplicationContext; + if (configContext != null) + { + return ((IConfigurableApplicationContext) + _parentApplicationContext).ObjectFactory; + } + else + { + return _parentApplicationContext; + } + } + + /// + /// Raises an application context event. + /// + /// + /// Any arguments to the event. May be . + /// + protected virtual void OnContextEvent(ApplicationEventArgs e) + { + OnContextEvent(this, e); + } + + /// + /// Raises an application context event. + /// + /// + /// The source of the event. + /// + /// + /// Any arguments to the event. May be . + /// + protected virtual void OnContextEvent(object source, ApplicationEventArgs e) + { + new DefensiveEventRaiser().Raise(ContextEvent, source, e); + } + + /// + /// Modify the application context's internal object factory after its standard + /// initialization. + /// + /// + ///

+ /// All object definitions will have been loaded, but no objects + /// will have been instantiated yet. This allows for the registration + /// of special + /// s + /// in certain + /// implementations. + ///

+ ///
+ /// + /// The object factory used by the application context. + /// + /// + /// In the case of errors. + /// . + protected virtual void PostProcessObjectFactory( + IConfigurableListableObjectFactory objectFactory) + { + } + + /// + /// Template method which can be overridden to add context-specific + /// refresh work. + /// + /// + ///

+ /// Called on initialization of special objects, before instantiation + /// of singletons. + ///

+ ///
+ protected virtual void OnRefresh() + { + } + + /// + /// Instantiate and invoke all registered + /// + /// objects, respecting any explicit ordering. + /// + /// + /// + /// Must be called before singleton instantiation. + /// + /// + /// In the case of errors. + private void InvokeObjectFactoryPostProcessors() + { + // do NOT include IFactoryObjects; they (typically) need to be instantiated + // to determine the Type of object that they create, and if they are instantiated + // then we won't be able to do any factory post processin' on 'em... + string[] factoryProcessorNames + = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false); + ArrayList orderedFactoryProcessors = new ArrayList(); + IList nonOrderedFactoryProcessorNames = new ArrayList(); + for (int i = 0; i < factoryProcessorNames.Length; ++i) + { + string processorName = factoryProcessorNames[i]; + object processor = GetObject(processorName); + if (typeof(IOrdered).IsAssignableFrom(GetType(processorName))) + { + orderedFactoryProcessors.Add(processor); + } + else + { + nonOrderedFactoryProcessorNames.Add(processor); + } + } + // first, invoke those IObjectFactoryPostProcessors that implement IOrdered... + orderedFactoryProcessors.Sort(new OrderComparator()); + ProcessObjectFactoryPostProcessors(orderedFactoryProcessors); + // and then the unordered ones... + ProcessObjectFactoryPostProcessors(nonOrderedFactoryProcessorNames); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "processed {0} IFactoryObjectPostProcessors defined in application context [{1}].", + factoryProcessorNames.Length, + Name)); + } + + #endregion + } + + private void ProcessObjectFactoryPostProcessors(IList orderedFactoryProcessors) + { + foreach (IObjectFactoryPostProcessor processor in orderedFactoryProcessors) + { + processor.PostProcessObjectFactory(ObjectFactory); + } + } + + private void RegisterObjectPostProcessors(IConfigurableListableObjectFactory objectFactory) + { + RegisterObjectPostProcessorChecker(objectFactory); + IDictionary dict = GetObjectsOfType(typeof(IObjectPostProcessor), true, false); + ArrayList objectProcessors = new ArrayList(dict.Values); + objectProcessors.Sort(new OrderComparator()); + foreach (IObjectPostProcessor objectPostProcessor in objectProcessors) + { + ObjectFactory.AddObjectPostProcessor(objectPostProcessor); + } + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "processed {0} IObjectPostProcessors defined in application context [{1}].", + objectProcessors.Count, + Name)); + } + } + + /// + /// Register an IObjectPostProcessorChecker that logs an info + /// message when an object is created during IObjectPostProcessor + /// instantiation, i.e. when an object is not eligible for being + /// processed by all IObjectPostProcessors. + /// + private void RegisterObjectPostProcessorChecker(IConfigurableListableObjectFactory objectFactory) + { + int objectPostProcessorCount + = ObjectFactory.ObjectPostProcessorCount + 1 + + GetObjectNamesForType(typeof(IObjectPostProcessor), true, false).Length; +// ObjectFactory.AddObjectPostProcessor( +// new ObjectPostProcessorChecker(objectFactory, objectPostProcessorCount)); + ((ObjectPostProcessorChecker) _defaultObjectPostProcessors[0]).Reset(objectFactory, objectPostProcessorCount); + } + + /// + /// Initializes the default event registry for this context. + /// + private void InitEventRegistry() + { + if (ContainsObject(EventRegistryObjectName)) + { + object candidateRegistry = GetObject(EventRegistryObjectName); + if (candidateRegistry is IEventRegistry) + { + _eventRegistry = (IEventRegistry) candidateRegistry; + + #region Instrumentation + + log.Debug(StringUtils.Surround( + "Using IEventRegistry [", EventRegistry, "]")); + + #endregion + } + else + { + _eventRegistry = new EventRegistry(); + + #region Instrumentation + + if (log.IsWarnEnabled) + { + log.Warn(string.Format( + "Found object in context named '{0}' : this name " + + "is typically reserved for IEventRegistry objects. " + + "Falling back to default '{1}'.", + EventRegistryObjectName, EventRegistry)); + } + + #endregion + } + } + else + { + _eventRegistry = new EventRegistry(); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + "No IEventRegistry found with name '{0}' : using default '{1}'.", + EventRegistryObjectName, EventRegistry)); + } + + #endregion + } + ICollection interestedParties + = GetObjectsOfType(typeof(IEventRegistryAware), true, false).Values; + foreach (IEventRegistryAware party in interestedParties) + { + party.EventRegistry = EventRegistry; + } + EventRegistry.PublishEvents(this); + } + + /// + /// Returns the internal message source of the parent context if said + /// parent context is an , else + /// simply the parent context itself. + /// + /// + /// The internal message source of the parent context if said + /// parent context is an , else + /// simply the parent context itself. + /// + protected virtual IMessageSource GetInternalParentMessageSource() + { + AbstractApplicationContext parent + = ParentContext as AbstractApplicationContext; + return parent == null ? ParentContext : parent._messageSource; + } + + /// + /// Initializes the default message source for this context. + /// + /// + ///

+ /// Uses any parent context's message source if one is not available + /// in this context. + ///

+ ///
+ private void InitMessageSource() + { + if (ContainsObject(MessageSourceObjectName)) + { + object candidateSource = GetObject(MessageSourceObjectName); + if (candidateSource is IMessageSource) + { + _messageSource + = (IMessageSource) GetObject(MessageSourceObjectName); + + // make IMessageSource aware of any parent IMessageSource... + if (ParentContext != null) + { + IHierarchicalMessageSource hierSource + = MessageSource as IHierarchicalMessageSource; + if (hierSource != null) + { + IMessageSource parentMessageSource + = GetInternalParentMessageSource(); + hierSource.ParentMessageSource = parentMessageSource; + } + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(StringUtils.Surround( + "Using MessageSource [", MessageSource, "]")); + } + + #endregion + } + else + { + _messageSource = new DelegatingMessageSource( + GetInternalParentMessageSource()); + + #region Instrumentation + + if (log.IsWarnEnabled) + { + log.Warn(string.Format( + "Found object in context named '{0}' : this name " + + "is typically reserved for IMessageSource objects. " + + "Falling back to default '{1}'.", + MessageSourceObjectName, MessageSource)); + } + + #endregion + } + } + else if (ParentContext != null) + { + _messageSource = new DelegatingMessageSource( + GetInternalParentMessageSource()); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + "No message source found in the current context: using parent context's message source '{0}'.", + MessageSource)); + } + + #endregion + } + else + { + _messageSource = new StaticMessageSource(); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + "No IMessageSource found with name '{0}' : using default '{1}'.", + MessageSourceObjectName, MessageSource)); + } + + #endregion + } + } + + private void RefreshApplicationEventListeners() + { + ICollection listeners + = GetObjectsOfType( + typeof(IApplicationEventListener), true, false).Values; + foreach (IApplicationEventListener applicationListener in listeners) + { + EventRegistry.Subscribe(applicationListener); + } + } + + /// + /// Returns the list of the + /// s + /// that will be applied to the objects created with this factory. + /// + /// + ///

+ /// The elements of this list are instances of implementations of the + /// + /// interface. + ///

+ ///
+ /// + /// The list of the + /// s + /// that will be applied to the objects created with this factory. + /// + private IList ObjectFactoryPostProcessors + { + get { return _objectFactoryPostProcessors; } + } + + #region IConfigurableApplicationContext Members + + /// + /// Return the internal object factory of this application context. + /// + public abstract IConfigurableListableObjectFactory ObjectFactory { get; } + + /// + /// Add a new + /// that will get applied to the internal object factory of this application context + /// on refresh, before any of the object definitions are evaluated. + /// + /// + /// The factory processor to register. + /// + public void AddObjectFactoryPostProcessor( + IObjectFactoryPostProcessor objectFactoryPostProcessor) + { + _objectFactoryPostProcessors.Add(objectFactoryPostProcessor); + } + + /// + /// Load or refresh the persistent representation of the configuration, + /// which might an XML file, properties file, or relational database schema. + /// + /// + /// If the configuration cannot be loaded. + /// + /// + /// If the object factory could not be initialized. + /// + public virtual void Refresh() + { + lock (SyncRoot) + { + + /* + #region Instrumentation + + if (log.IsDebugEnabled) + { + StackTrace stackTrace = new StackTrace(1, true); + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Refreshing application context [{0}]. Called from:{1}", + Name, stackTrace)); + } + + #endregion + */ + + _startupDate = DateTime.Now; + + RefreshObjectFactory(); + IConfigurableListableObjectFactory objectFactory = ObjectFactory; + + EnsureKnownObjectPostProcessors(objectFactory); + objectFactory.IgnoreDependencyType(typeof(IResourceLoader)); + objectFactory.IgnoreDependencyType(typeof(IApplicationContext)); + + PostProcessObjectFactory(objectFactory); + foreach (IObjectFactoryPostProcessor factoryProcessor in ObjectFactoryPostProcessors) + { + factoryProcessor.PostProcessObjectFactory(objectFactory); + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "{0} objects defined in application context [{1}].", + ObjectDefinitionCount == 0 ? "No" : ObjectDefinitionCount.ToString(), + Name)); + } + + #endregion + + InvokeObjectFactoryPostProcessors(); + RegisterObjectPostProcessors(objectFactory); + InitEventRegistry(); + InitMessageSource(); + OnRefresh(); + RefreshApplicationEventListeners(); + + objectFactory.PreInstantiateSingletons(); + + new DefensiveEventRaiser().Raise( + ContextEvent, this, + new ContextEventArgs(ContextEventArgs.ContextEvent.Refreshed)); + } + } + + /// + /// Ensures, that predefined ObjectPostProcessors are registered with this ObjectFactory + /// + /// + protected void EnsureKnownObjectPostProcessors(IConfigurableListableObjectFactory objectFactory) + { + // index 0 contains the ObjectPostProcessorChecker that is handled separately! + for (int i = 1; i < _defaultObjectPostProcessors.Count; i++) + { + objectFactory.AddObjectPostProcessor((IObjectPostProcessor) this._defaultObjectPostProcessors[i]); + } + } + + /// + /// Gets the parent context, or if there is no + /// parent context. + /// + /// + /// The parent context, or if there is no + /// parent. + /// + /// + public virtual IApplicationContext ParentContext + { + get { return _parentApplicationContext; } + set { _parentApplicationContext = value; } + } + + #endregion + + #region IApplicationContext Members + + /// + /// Raised in response to an implementation-dependant application + /// context event. + /// + public event ApplicationEventHandler ContextEvent; + + /// + /// The date and time this context was first loaded. + /// + /// + /// The representing when this context + /// was first loaded. + /// + public DateTime StartupDate + { + get { return _startupDate; } + } + + /// + /// A name for this context. + /// + /// + /// A name for this context. + /// + public string Name + { + get { return _name; } + set { _name = value; } + } + + + + #endregion + + #region IListableObjectFactory Members + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectNamesForType(Type type) + { + return ObjectFactory.GetObjectNamesForType(type); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectNamesForType( + Type type, bool includePrototypes, bool includeFactoryObjects) + { + return ObjectFactory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects); + } + + /// + /// Return the names of all objects defined in this factory. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectDefinitionNames() + { + return ObjectFactory.GetObjectDefinitionNames(); + } + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + public virtual IObjectDefinition GetObjectDefinition(string name) + { + return ObjectFactory.GetObjectDefinition(name); + } + + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// Whether to search parent object factories. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + public IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) + { + return ObjectFactory.GetObjectDefinition(name, includeAncestors); + } + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + /// The (class or interface) to match. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + /// + public IDictionary GetObjectsOfType(Type type) + { + return GetObjectsOfType(type, true, true); + } + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + /// The (class or interface) to match. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + /// + public IDictionary GetObjectsOfType( + Type type, bool includePrototypes, bool includeFactoryObjects) + { + return ObjectFactory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects); + } + + /// + /// Return the number of objects defined in the factory. + /// + /// + /// The number of objects defined in the factory. + /// + /// + public int ObjectDefinitionCount + { + get { return ObjectFactory.ObjectDefinitionCount; } + } + + /// + /// Check if this object factory contains an object definition with the given name. + /// + /// The name of the object to look for. + /// + /// True if this object factory contains an object definition with the given name. + /// + /// + public bool ContainsObjectDefinition(string name) + { + return ObjectFactory.ContainsObjectDefinition(name); + } + + #endregion + + #region IObjectFactory Members + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + public object this[string name] + { + get { return ObjectFactory.GetObject(name); } + } + + /// + /// Does this object factory contain an object with the given name? + /// + /// The name of the object to query. + /// + /// if an object with the given name is defined. + /// + /// + public bool ContainsObject(string name) + { + return ObjectFactory.ContainsObject(name); + } + + /// + /// Return the aliases for the given object name, if defined. + /// + /// The object name to check for aliases. + /// The aliases, or an empty array if none. + /// + /// If there's no such object definition. + /// + /// + public string[] GetAliases(string name) + { + return ObjectFactory.GetAliases(name); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// + /// the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the object is not of the required type. + /// + /// + public object GetObject(string name, Type requiredType) + { + return ObjectFactory.GetObject(name, requiredType); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + public object GetObject(string name) + { + return ObjectFactory.GetObject(name); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to return. + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. If there is no factory method and the + /// arguments are not null, then match the argument values by type and + /// call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the supplied is . + /// + public object GetObject(string name, object[] arguments) + { + return ObjectFactory.GetObject(name, arguments); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// + /// The the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a factory method. If there is no factory method and the + /// supplied array is not , then + /// match the argument values by type and call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the object is not of the required type. + /// + /// + /// If the supplied is . + /// + /// + public object GetObject(string name, Type requiredType, object[] arguments) + { + return ObjectFactory.GetObject(name, requiredType, arguments); + } + + /// + /// Is this object a singleton? + /// + /// The name of the object to query. + /// True if the named object is a singleton. + /// + /// If there's no such object definition. + /// + /// + public bool IsSingleton(string name) + { + return ObjectFactory.IsSingleton(name); + } + + /// + /// Determines whether the specified object name is prototype. That is, will GetObject + /// always return independent instances? + /// + /// The name of the object to query + /// + /// true if the specified object name will always deliver independent instances; otherwise, false. + /// + /// This method returning false does not clearly indicate a singleton object. + /// It indicated non-independent instances, which may correspond to a scoped object as + /// well. use the IsSingleton property to explicitly check for a shared + /// singleton instance. + /// Translates aliases back to the corresponding canonical object name. Will ask the + /// parent factory if the object can not be found in this factory instance. + /// + /// + /// if there is no object with the given name. + public bool IsPrototype(string name) + { + return ObjectFactory.IsPrototype(name); + } + + + /// + /// Determines whether the object with the given name matches the specified type. + /// + /// More specifically, check whether a GetObject call for the given name + /// would return an object that is assignable to the specified target type. + /// Translates aliases back to the corresponding canonical bean name. + /// Will ask the parent factory if the bean cannot be found in this factory instance. + /// + /// The name of the object to query. + /// Type of the target to match against. + /// + /// true if the object type matches; otherwise, false + /// if it doesn't match or cannot be determined yet. + /// + /// Ff there is no object with the given name + /// + public bool IsTypeMatch(string name, Type targetType) + { + return ObjectFactory.IsTypeMatch(name, targetType); + } + + /// + /// Determine the of the object with the + /// given name. + /// + /// The name of the object to query. + /// + /// The of the object, or + /// if not determinable. + /// + /// + public Type GetType(string name) + { + return ObjectFactory.GetType(name); + } + + /// + /// Injects dependencies into the supplied instance + /// using the named object definition. + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + public object ConfigureObject(object target, string name) + { + return ObjectFactory.ConfigureObject(target, name); + } + + /// + /// Injects dependencies into the supplied instance + /// using the supplied . + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// An object definition that should be used to configure object. + /// + /// + public object ConfigureObject(object target, string name, IObjectDefinition definition) + { + return ObjectFactory.ConfigureObject(target, name, definition); + } + + #endregion + + #region IHierarchicalObjectFactory Members + + /// + /// Return the parent object factory, or if there is none. + /// + /// + /// The parent object factory, or if there is none. + /// + /// + public IObjectFactory ParentObjectFactory + { + get { return _parentApplicationContext; } + } + + #endregion + + #region IMessageSource Members + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If no message could be resolved. + /// + /// + /// If the supplied is . + /// + /// + public string GetMessage( + string name, CultureInfo culture, params object[] arguments) + { + return MessageSource.GetMessage(name, culture, arguments); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// The default message. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If no message could be resolved. + /// + /// + /// If the supplied is . + /// + /// + public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) + { + return MessageSource.GetMessage(name, defaultMessage, culture, arguments); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The resolved message if the lookup was successful. + /// + /// + /// If no message could be resolved. + /// + /// + public string GetMessage(string name) + { + return MessageSource.GetMessage(name); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful. + /// + /// + /// If no message could be resolved. + /// + /// + /// If the supplied is . + /// + /// + public string GetMessage(string name, params object[] arguments) + { + return MessageSource.GetMessage(name, arguments); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If no message could be resolved. + /// + /// + /// If the supplied is . + /// + /// + public string GetMessage(string name, CultureInfo culture) + { + return MessageSource.GetMessage(name, culture); + } + + /// + /// Resolve the message using all of the attributes contained within + /// the supplied + /// argument. + /// + /// + /// The value object storing those attributes that are required to + /// properly resolve a message. + /// + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) + { + return MessageSource.GetMessage(resolvable, culture); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + /// The resolved object, or if not found. + /// + /// + object IMessageSource.GetResourceObject(string name, CultureInfo culture) + { + return GetResourceObject(name, culture); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The resolved object, or if not found. + /// + /// + object IMessageSource.GetResourceObject(string name) + { + return GetResourceObject(name); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + /// The resolved object, or if not found. + /// + /// + public object GetResourceObject(string name, CultureInfo culture) + { + return MessageSource.GetResourceObject(name, culture); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The resolved object, or if not found. + /// + /// + public object GetResourceObject(string name) + { + return MessageSource.GetResourceObject(name); + } + + /// + /// Applies resources to object properties. + /// + /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + public void ApplyResources(object value, string objectName, CultureInfo culture) + { + MessageSource.ApplyResources(value, objectName, culture); + } + + #endregion + + #region IEventRegistry Members + + /// + /// Publishes all events of the source object. + /// + /// + /// The source object containing events to publish. + /// + /// + public void PublishEvents(object sourceObject) + { + _eventRegistry.PublishEvents(sourceObject); + } + + /// + /// Subscribes to all events published, if the subscriber + /// implements compatible handler methods. + /// + /// The subscriber to use. + /// + public void Subscribe(object subscriber) + { + _eventRegistry.Subscribe(subscriber); + } + + /// + /// Subscribes to published events of a all objects of a given + /// , if the subscriber implements + /// compatible handler methods. + /// + /// The subscriber to use. + /// + /// The target to subscribe to. + /// + /// + public void Subscribe(object subscriber, Type targetSourceType) + { + _eventRegistry.Subscribe(subscriber, targetSourceType); + } + + #endregion + + /// + /// Publishes an application context event. + /// + /// + ///

+ /// + ///

+ ///
+ /// + /// The source of the event. May be . + /// + /// + /// The event that is to be raised. + /// + /// + public void PublishEvent(object sender, ApplicationEventArgs e) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Publishing event in context [{0}] : {1}", + Name, e)); + } + + #endregion + + OnContextEvent(sender, e); + + if (ParentContext != null) + { + ParentContext.PublishEvent(sender, e); + } + } + + #region IPostProcessor implementation + + private sealed class ObjectPostProcessorChecker : IObjectPostProcessor + { + private int _objectPostProcessorTargetCount; + private IConfigurableListableObjectFactory _objectFactory; + + + public ObjectPostProcessorChecker() + { + } + +// public ObjectPostProcessorChecker( +// IConfigurableListableObjectFactory objectFactory, int objectPostProcessorTargetCount) +// { +// _objectFactory = objectFactory; +// _objectPostProcessorTargetCount = objectPostProcessorTargetCount; +// } + + public void Reset(IConfigurableListableObjectFactory objectFactory, int objectPostProcessorTargetCount) + { + _objectFactory = objectFactory; + _objectPostProcessorTargetCount = objectPostProcessorTargetCount; + } + + public object PostProcessBeforeInitialization(object obj, string name) + { + return obj; + } + + public object PostProcessAfterInitialization(object obj, string objectName) + { + if (_objectFactory.ObjectPostProcessorCount < _objectPostProcessorTargetCount) + { + #region Instrumentation + + if (log.IsInfoEnabled) + { + log.Info(string.Format( + "Object '{0}' is not eligible for being processed by all " + + "IObjectPostProcessors (for example: not eligible for auto-proxying).", objectName)); + } + + #endregion + } + return obj; + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/AbstractMessageSource.cs b/src/Spring/Spring.Core/Context/Support/AbstractMessageSource.cs index 0c426817..ec211c66 100644 --- a/src/Spring/Spring.Core/Context/Support/AbstractMessageSource.cs +++ b/src/Spring/Spring.Core/Context/Support/AbstractMessageSource.cs @@ -1,617 +1,616 @@ -#region License - -/* - * Copyright 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; -using Common.Logging; - -namespace Spring.Context.Support -{ - /// - /// Abstract implementation of the interface, - /// implementing common handling of message variants, making it easy - /// to implement a specific strategy for a concrete . - /// - /// - ///

Subclasses must implement the abstract ResolveObject - /// method.

- ///

Note: By default, message texts are only parsed through - /// String.Format if arguments have been passed in for the message. In case - /// of no arguments, message texts will be returned as-is. As a consequence, - /// you should only use String.Format escaping for messages with actual - /// arguments, and keep all other messages unescaped. - ///

- ///

Supports not only IMessageSourceResolvables as primary messages - /// but also resolution of message arguments that are in turn - /// IMessageSourceResolvables themselves. - ///

- ///

This class does not implement caching of messages per code, thus - /// subclasses can dynamically change messages over time. Subclasses are - /// encouraged to cache their messages in a modification-aware fashion, - /// allowing for hot deployment of updated messages. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Harald Radi (.NET) - /// $Id: AbstractMessageSource.cs,v 1.23 2007/08/28 14:16:15 oakinger Exp $ - /// - /// - /// - public abstract class AbstractMessageSource : IHierarchicalMessageSource - { - #region Fields - - /// - /// holds the logger instance shared with subclasses. - /// - protected readonly ILog log; - - private IMessageSource parentMessageSource; - private bool useCodeAsDefaultMessage = false; - - #endregion - - #region Constructor - - /// - /// Initializes this instance. - /// - protected AbstractMessageSource() - { - log = LogManager.GetLogger(GetType()); - } - - #endregion - - #region Properties - - - /// Gets or Sets a value indicating whether to use the message code as - /// default message instead of throwing a NoSuchMessageException. - /// Useful for development and debugging. Default is "false". - /// - /// - ///

Note: In case of a IMessageSourceResolvable with multiple codes - /// (like a FieldError) and a MessageSource that has a parent MessageSource, - /// do not activate "UseCodeAsDefaultMessage" in the parent: - /// Else, you'll get the first code returned as message by the parent, - /// without attempts to check further codes.

- ///

To be able to work with "UseCodeAsDefaultMessage" turned on in the parent, - /// AbstractMessageSource contains special checks - /// to delegate to the internal GetMessageInternal method if available. - /// In general, it is recommended to just use "UseCodeAsDefaultMessage" during - /// development and not rely on it in production in the first place, though.

- ///

Alternatively, consider overriding the GetDefaultMessage - /// method to return a custom fallback message for an unresolvable code.

- ///
- /// - /// true if use the message code as default message instead of - /// throwing a NoSuchMessageException; otherwise, false. - /// - public bool UseCodeAsDefaultMessage - { - get { return useCodeAsDefaultMessage; } - set { useCodeAsDefaultMessage = value; } - } - - #endregion - - #region IHierarchicalMessageSource Members - - /// - /// The parent message source used to try and resolve messages that - /// this object can't resolve. - /// - /// - /// - ///

- /// If the value of this property is then no - /// further resolution is possible. - ///

- ///
- public IMessageSource ParentMessageSource - { - get { return parentMessageSource; } - set { parentMessageSource = value; } - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the lookup is not successful throw NoSuchMessageException - /// - public string GetMessage(string name) - { - return GetMessage(name, CultureInfo.CurrentUICulture, null); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// The that represents - /// the culture for which the resource is localized. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - ///

- /// If the lookup is not successful, implementations are permitted to - /// take one of two actions. - ///

- /// If the lookup is not successful throw NoSuchMessageException - ///
- public string GetMessage(string name, CultureInfo culture) - { - return GetMessage(name, culture, null); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the lookup is not successful throw NoSuchMessageException - /// - public string GetMessage(string name, params object[] arguments) - { - return GetMessage(name, CultureInfo.CurrentUICulture, arguments); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// The that represents - /// the culture for which the resource is localized. - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - ///

- /// If the lookup is not successful throw NoSuchMessageException. - ///

- ///
- public string GetMessage(string name, CultureInfo culture, params object[] arguments) - { - string msg = GetMessageInternal(name, arguments, culture); - if (msg != null) return msg; - string fallback = GetDefaultMessage(name); - if (fallback != null) return fallback; - throw new NoSuchMessageException(name, culture); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// The default message if name is not found. - /// The that represents - /// the culture for which the resource is localized. - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - ///

- /// If the lookup is not successful throw NoSuchMessageException - ///

- ///
- public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) - { - string msg = GetMessageInternal(name, arguments, culture); - if (msg != null) return msg; - if (defaultMessage == null) - { - string fallback = GetDefaultMessage(name); - if (fallback != null) return fallback; - } - return RenderDefaultMessage(defaultMessage, arguments, culture); - } - - /// - /// Resolve the message using all of the attributes contained within - /// the supplied - /// argument. - /// - /// The value object storing those attributes that are required to - /// properly resolve a message. - /// The that represents - /// the culture for which the resource is localized. - /// - /// The resolved message if the lookup was successful. - /// - /// - /// If the message could not be resolved. - /// - public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) - { - string[] codes = resolvable.GetCodes(); - if (codes == null) codes = new string[0]; - for (int i = 0; i < codes.Length; i++) - { - string msg = GetMessageInternal(codes[i], resolvable.GetArguments(), culture); - if (msg != null) return msg; - } - if (resolvable.DefaultMessage != null) - return RenderDefaultMessage(resolvable.DefaultMessage, resolvable.GetArguments(), culture); - if (codes.Length > 0) - { - string fallback = GetDefaultMessage(codes[0]); - if (fallback != null) return fallback; - } - throw new NoSuchMessageException(codes.Length > 0 ? codes[codes.Length - 1] : null, culture); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The resolved object, or if not found. - /// - /// - public object GetResourceObject(string name) - { - object resource = GetResourceInternal(name, CultureInfo.CurrentUICulture); - if (resource != null) return resource; - if (ParentMessageSource != null) - return ParentMessageSource.GetResourceObject(name, CultureInfo.CurrentUICulture); - return null; - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// Note that the fallback behavior based on CultureInfo seem to - /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - /// The resolved object, or if not found. If - /// the resource name resolves to null, then in .NET 1.1 the return - /// value will be String.Empty whereas in .NET 2.0 it will return - /// null. - /// - /// - public object GetResourceObject(string name, CultureInfo culture) - { - object resource = GetResourceInternal(name, culture); - if (resource != null) return resource; - if (ParentMessageSource != null) return ParentMessageSource.GetResourceObject(name, culture); - return null; - } - - /// - /// Applies resources to object properties. - /// - /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - public void ApplyResources( - object value, string objectName, CultureInfo culture) - { - ApplyResourcesInternal(value, objectName, culture); - if (ParentMessageSource != null) ParentMessageSource.ApplyResources(value, objectName, culture); - } - - #endregion - - #region Protected Methods - - /// Resolve the given code and arguments as message in the given culture, - /// returning null if not found. Does not fall back to the code - /// as default message. Invoked by GetMessage methods. - /// - /// The code to lookup up, such as 'calculator.noRateSet'. - /// array of arguments that will be filled in for params - /// within the message. - /// The with which the - /// resource is associated. - /// - /// The resolved message if the lookup was successful. - /// - protected string GetMessageInternal(string code, object[] args, CultureInfo culture) - { - if (code == null) return null; - if (culture == null) culture = CultureInfo.CurrentUICulture; - - if ((args != null && args.Length > 0)) - { - // Resolve arguments eagerly, for the case where the message - // is defined in a parent MessageSource but resolvable arguments - // are defined in the child MessageSource. - args = ResolveArguments(args, culture); - } - - string message = ResolveMessage(code, culture); - - if (message != null) return FormatMessage(message, args, culture); - - // Not found -> check parent, if any. - return GetMessageFromParent(code, args, culture); - } - - - /// - /// Try to retrieve the given message from the parent MessageSource, if any. - /// - /// The code to lookup up, such as 'calculator.noRateSet'. - /// array of arguments that will be filled in for params - /// within the message. - /// The with which the - /// resource is associated. - /// - /// The resolved message if the lookup was successful. - /// - protected string GetMessageFromParent(string code, object[] args, CultureInfo culture) - { - if (ParentMessageSource != null) - { - AbstractMessageSource parent = ParentMessageSource as AbstractMessageSource; - if (parent != null) - { - // Call internal method to avoid getting the default code back - // in case of "useCodeAsDefaultMessage" being activated. - return parent.GetMessageInternal(code, args, culture); - } - else - { - // Check parent MessageSource, returning null if not found there. - return ParentMessageSource.GetMessage(code, null, culture, args); - } - } - // Not found in parent either. - return null; - } - - - /// - /// Return a fallback default message for the given code, if any. - /// - /// - /// Default is to return the code itself if "UseCodeAsDefaultMessage" - /// is activated, or return no fallback else. In case of no fallback, - /// the caller will usually receive a NoSuchMessageException from GetMessage - /// - /// The code to lookup up, such as 'calculator.noRateSet'. - /// The default message to use, or null if none. - protected virtual string GetDefaultMessage(string code) - { - if (UseCodeAsDefaultMessage) return code; - return null; - } - - - - /// - /// Renders the default message string. The default message is passed in as specified by the - /// caller and can be rendered into a fully formatted default message shown to the user. - /// - /// Default implementation passed he String for String.Format resolving any - /// argument placeholders found in them. Subclasses may override this method to plug - /// in custom processing of default messages. - /// - /// The default message. - /// The array of agruments that will be filled in for parameter - /// placeholders within the message, or null if none. - /// The with which the - /// resource is associated. - /// The rendered default message (with resolved arguments) - protected virtual string RenderDefaultMessage(string defaultMessage, object[] args, CultureInfo culture) - { - return FormatMessage(defaultMessage, args, culture); - } - - /// - /// Format the given default message String resolving any - /// agrument placeholders found in them. - /// - /// The message to format. - /// The array of agruments that will be filled in for parameter - /// placeholders within the message, or null if none. - /// The with which the - /// resource is associated. - /// The formatted message (with resolved arguments) - protected virtual string FormatMessage(string msg, object[] args, CultureInfo culture) - { - if (msg == null || ((args == null || args.Length == 0))) return msg; - return String.Format(culture, msg, args); - } - - - /// - /// Search through the given array of objects, find any - /// MessageSourceResolvable objects and resolve them. - /// - /// - /// Allows for messages to have MessageSourceResolvables as arguments. - /// - /// - /// The array of arguments for a message. - /// The with which the - /// resource is associated. - /// An array of arguments with any IMessageSourceResolvables resolved - protected virtual object[] ResolveArguments(object[] args, CultureInfo culture) - { - if (args == null) return new object[0]; - object[] resolvedArgs = new object[args.Length]; - - for (int i = 0; i < args.Length; i++) - { - IMessageSourceResolvable resolvable = args[i] as IMessageSourceResolvable; - if (resolvable != null) resolvedArgs[i] = GetMessage(resolvable, culture); - else resolvedArgs[i] = args[i]; - } - - return resolvedArgs; - } - - /// - /// Gets the specified resource (e.g. Icon or Bitmap). - /// - /// The name of the resource to resolve. - /// - /// The to resolve the - /// code for. - /// - /// The resource if found. otherwise. - protected object GetResourceInternal(string name, CultureInfo cultureInfo) - { - if (cultureInfo == null) cultureInfo = CultureInfo.CurrentUICulture; - if (name == null) return null; - return ResolveObject(name, cultureInfo); - } - - /// - /// Applies resources from the given name on the specified object. - /// - /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - protected void ApplyResourcesInternal(object value, string objectName, CultureInfo cultureInfo) - { - if (cultureInfo == null) cultureInfo = CultureInfo.CurrentUICulture; - ApplyResourcesToObject(value, objectName, cultureInfo); - } - - #endregion - - #region Protected Abstract Methods - - /// - /// Subclasses must implement this method to resolve a message. - /// - /// The code to lookup up, such as 'calculator.noRateSet'. - /// The with which the - /// resource is associated. - /// The resolved message from the backing store of message data. - protected abstract string ResolveMessage(string code, CultureInfo cultureInfo); - - /// - /// Resolves an object (typically an icon or bitmap). - /// - /// - ///

- /// Subclasses must implement this method to resolve an object. - ///

- ///
- /// The code of the object to resolve. - /// - /// The to resolve the - /// code for. - /// - /// - /// The resolved object or if not found. - /// - protected abstract object ResolveObject(string code, CultureInfo cultureInfo); - - /// - /// Applies resources to object properties. - /// - /// - ///

- /// Subclasses must implement this method to apply resources - /// to an arbitrary object. - ///

- ///
- /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - protected abstract void ApplyResourcesToObject(object value, string objectName, CultureInfo cultureInfo); - - - #endregion - - } +#region License + +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; +using Common.Logging; + +namespace Spring.Context.Support +{ + /// + /// Abstract implementation of the interface, + /// implementing common handling of message variants, making it easy + /// to implement a specific strategy for a concrete . + /// + /// + ///

Subclasses must implement the abstract ResolveObject + /// method.

+ ///

Note: By default, message texts are only parsed through + /// String.Format if arguments have been passed in for the message. In case + /// of no arguments, message texts will be returned as-is. As a consequence, + /// you should only use String.Format escaping for messages with actual + /// arguments, and keep all other messages unescaped. + ///

+ ///

Supports not only IMessageSourceResolvables as primary messages + /// but also resolution of message arguments that are in turn + /// IMessageSourceResolvables themselves. + ///

+ ///

This class does not implement caching of messages per code, thus + /// subclasses can dynamically change messages over time. Subclasses are + /// encouraged to cache their messages in a modification-aware fashion, + /// allowing for hot deployment of updated messages. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Harald Radi (.NET) + /// + /// + /// + public abstract class AbstractMessageSource : IHierarchicalMessageSource + { + #region Fields + + /// + /// holds the logger instance shared with subclasses. + /// + protected readonly ILog log; + + private IMessageSource parentMessageSource; + private bool useCodeAsDefaultMessage = false; + + #endregion + + #region Constructor + + /// + /// Initializes this instance. + /// + protected AbstractMessageSource() + { + log = LogManager.GetLogger(GetType()); + } + + #endregion + + #region Properties + + + /// Gets or Sets a value indicating whether to use the message code as + /// default message instead of throwing a NoSuchMessageException. + /// Useful for development and debugging. Default is "false". + /// + /// + ///

Note: In case of a IMessageSourceResolvable with multiple codes + /// (like a FieldError) and a MessageSource that has a parent MessageSource, + /// do not activate "UseCodeAsDefaultMessage" in the parent: + /// Else, you'll get the first code returned as message by the parent, + /// without attempts to check further codes.

+ ///

To be able to work with "UseCodeAsDefaultMessage" turned on in the parent, + /// AbstractMessageSource contains special checks + /// to delegate to the internal GetMessageInternal method if available. + /// In general, it is recommended to just use "UseCodeAsDefaultMessage" during + /// development and not rely on it in production in the first place, though.

+ ///

Alternatively, consider overriding the GetDefaultMessage + /// method to return a custom fallback message for an unresolvable code.

+ ///
+ /// + /// true if use the message code as default message instead of + /// throwing a NoSuchMessageException; otherwise, false. + /// + public bool UseCodeAsDefaultMessage + { + get { return useCodeAsDefaultMessage; } + set { useCodeAsDefaultMessage = value; } + } + + #endregion + + #region IHierarchicalMessageSource Members + + /// + /// The parent message source used to try and resolve messages that + /// this object can't resolve. + /// + /// + /// + ///

+ /// If the value of this property is then no + /// further resolution is possible. + ///

+ ///
+ public IMessageSource ParentMessageSource + { + get { return parentMessageSource; } + set { parentMessageSource = value; } + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the lookup is not successful throw NoSuchMessageException + /// + public string GetMessage(string name) + { + return GetMessage(name, CultureInfo.CurrentUICulture, null); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// The that represents + /// the culture for which the resource is localized. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + ///

+ /// If the lookup is not successful, implementations are permitted to + /// take one of two actions. + ///

+ /// If the lookup is not successful throw NoSuchMessageException + ///
+ public string GetMessage(string name, CultureInfo culture) + { + return GetMessage(name, culture, null); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the lookup is not successful throw NoSuchMessageException + /// + public string GetMessage(string name, params object[] arguments) + { + return GetMessage(name, CultureInfo.CurrentUICulture, arguments); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// The that represents + /// the culture for which the resource is localized. + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + ///

+ /// If the lookup is not successful throw NoSuchMessageException. + ///

+ ///
+ public string GetMessage(string name, CultureInfo culture, params object[] arguments) + { + string msg = GetMessageInternal(name, arguments, culture); + if (msg != null) return msg; + string fallback = GetDefaultMessage(name); + if (fallback != null) return fallback; + throw new NoSuchMessageException(name, culture); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// The default message if name is not found. + /// The that represents + /// the culture for which the resource is localized. + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + ///

+ /// If the lookup is not successful throw NoSuchMessageException + ///

+ ///
+ public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) + { + string msg = GetMessageInternal(name, arguments, culture); + if (msg != null) return msg; + if (defaultMessage == null) + { + string fallback = GetDefaultMessage(name); + if (fallback != null) return fallback; + } + return RenderDefaultMessage(defaultMessage, arguments, culture); + } + + /// + /// Resolve the message using all of the attributes contained within + /// the supplied + /// argument. + /// + /// The value object storing those attributes that are required to + /// properly resolve a message. + /// The that represents + /// the culture for which the resource is localized. + /// + /// The resolved message if the lookup was successful. + /// + /// + /// If the message could not be resolved. + /// + public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) + { + string[] codes = resolvable.GetCodes(); + if (codes == null) codes = new string[0]; + for (int i = 0; i < codes.Length; i++) + { + string msg = GetMessageInternal(codes[i], resolvable.GetArguments(), culture); + if (msg != null) return msg; + } + if (resolvable.DefaultMessage != null) + return RenderDefaultMessage(resolvable.DefaultMessage, resolvable.GetArguments(), culture); + if (codes.Length > 0) + { + string fallback = GetDefaultMessage(codes[0]); + if (fallback != null) return fallback; + } + throw new NoSuchMessageException(codes.Length > 0 ? codes[codes.Length - 1] : null, culture); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The resolved object, or if not found. + /// + /// + public object GetResourceObject(string name) + { + object resource = GetResourceInternal(name, CultureInfo.CurrentUICulture); + if (resource != null) return resource; + if (ParentMessageSource != null) + return ParentMessageSource.GetResourceObject(name, CultureInfo.CurrentUICulture); + return null; + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// Note that the fallback behavior based on CultureInfo seem to + /// have a bug that is fixed by installed .NET 1.1 Service Pack 1. + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + /// The resolved object, or if not found. If + /// the resource name resolves to null, then in .NET 1.1 the return + /// value will be String.Empty whereas in .NET 2.0 it will return + /// null. + /// + /// + public object GetResourceObject(string name, CultureInfo culture) + { + object resource = GetResourceInternal(name, culture); + if (resource != null) return resource; + if (ParentMessageSource != null) return ParentMessageSource.GetResourceObject(name, culture); + return null; + } + + /// + /// Applies resources to object properties. + /// + /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + public void ApplyResources( + object value, string objectName, CultureInfo culture) + { + ApplyResourcesInternal(value, objectName, culture); + if (ParentMessageSource != null) ParentMessageSource.ApplyResources(value, objectName, culture); + } + + #endregion + + #region Protected Methods + + /// Resolve the given code and arguments as message in the given culture, + /// returning null if not found. Does not fall back to the code + /// as default message. Invoked by GetMessage methods. + /// + /// The code to lookup up, such as 'calculator.noRateSet'. + /// array of arguments that will be filled in for params + /// within the message. + /// The with which the + /// resource is associated. + /// + /// The resolved message if the lookup was successful. + /// + protected string GetMessageInternal(string code, object[] args, CultureInfo culture) + { + if (code == null) return null; + if (culture == null) culture = CultureInfo.CurrentUICulture; + + if ((args != null && args.Length > 0)) + { + // Resolve arguments eagerly, for the case where the message + // is defined in a parent MessageSource but resolvable arguments + // are defined in the child MessageSource. + args = ResolveArguments(args, culture); + } + + string message = ResolveMessage(code, culture); + + if (message != null) return FormatMessage(message, args, culture); + + // Not found -> check parent, if any. + return GetMessageFromParent(code, args, culture); + } + + + /// + /// Try to retrieve the given message from the parent MessageSource, if any. + /// + /// The code to lookup up, such as 'calculator.noRateSet'. + /// array of arguments that will be filled in for params + /// within the message. + /// The with which the + /// resource is associated. + /// + /// The resolved message if the lookup was successful. + /// + protected string GetMessageFromParent(string code, object[] args, CultureInfo culture) + { + if (ParentMessageSource != null) + { + AbstractMessageSource parent = ParentMessageSource as AbstractMessageSource; + if (parent != null) + { + // Call internal method to avoid getting the default code back + // in case of "useCodeAsDefaultMessage" being activated. + return parent.GetMessageInternal(code, args, culture); + } + else + { + // Check parent MessageSource, returning null if not found there. + return ParentMessageSource.GetMessage(code, null, culture, args); + } + } + // Not found in parent either. + return null; + } + + + /// + /// Return a fallback default message for the given code, if any. + /// + /// + /// Default is to return the code itself if "UseCodeAsDefaultMessage" + /// is activated, or return no fallback else. In case of no fallback, + /// the caller will usually receive a NoSuchMessageException from GetMessage + /// + /// The code to lookup up, such as 'calculator.noRateSet'. + /// The default message to use, or null if none. + protected virtual string GetDefaultMessage(string code) + { + if (UseCodeAsDefaultMessage) return code; + return null; + } + + + + /// + /// Renders the default message string. The default message is passed in as specified by the + /// caller and can be rendered into a fully formatted default message shown to the user. + /// + /// Default implementation passed he String for String.Format resolving any + /// argument placeholders found in them. Subclasses may override this method to plug + /// in custom processing of default messages. + /// + /// The default message. + /// The array of agruments that will be filled in for parameter + /// placeholders within the message, or null if none. + /// The with which the + /// resource is associated. + /// The rendered default message (with resolved arguments) + protected virtual string RenderDefaultMessage(string defaultMessage, object[] args, CultureInfo culture) + { + return FormatMessage(defaultMessage, args, culture); + } + + /// + /// Format the given default message String resolving any + /// agrument placeholders found in them. + /// + /// The message to format. + /// The array of agruments that will be filled in for parameter + /// placeholders within the message, or null if none. + /// The with which the + /// resource is associated. + /// The formatted message (with resolved arguments) + protected virtual string FormatMessage(string msg, object[] args, CultureInfo culture) + { + if (msg == null || ((args == null || args.Length == 0))) return msg; + return String.Format(culture, msg, args); + } + + + /// + /// Search through the given array of objects, find any + /// MessageSourceResolvable objects and resolve them. + /// + /// + /// Allows for messages to have MessageSourceResolvables as arguments. + /// + /// + /// The array of arguments for a message. + /// The with which the + /// resource is associated. + /// An array of arguments with any IMessageSourceResolvables resolved + protected virtual object[] ResolveArguments(object[] args, CultureInfo culture) + { + if (args == null) return new object[0]; + object[] resolvedArgs = new object[args.Length]; + + for (int i = 0; i < args.Length; i++) + { + IMessageSourceResolvable resolvable = args[i] as IMessageSourceResolvable; + if (resolvable != null) resolvedArgs[i] = GetMessage(resolvable, culture); + else resolvedArgs[i] = args[i]; + } + + return resolvedArgs; + } + + /// + /// Gets the specified resource (e.g. Icon or Bitmap). + /// + /// The name of the resource to resolve. + /// + /// The to resolve the + /// code for. + /// + /// The resource if found. otherwise. + protected object GetResourceInternal(string name, CultureInfo cultureInfo) + { + if (cultureInfo == null) cultureInfo = CultureInfo.CurrentUICulture; + if (name == null) return null; + return ResolveObject(name, cultureInfo); + } + + /// + /// Applies resources from the given name on the specified object. + /// + /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + protected void ApplyResourcesInternal(object value, string objectName, CultureInfo cultureInfo) + { + if (cultureInfo == null) cultureInfo = CultureInfo.CurrentUICulture; + ApplyResourcesToObject(value, objectName, cultureInfo); + } + + #endregion + + #region Protected Abstract Methods + + /// + /// Subclasses must implement this method to resolve a message. + /// + /// The code to lookup up, such as 'calculator.noRateSet'. + /// The with which the + /// resource is associated. + /// The resolved message from the backing store of message data. + protected abstract string ResolveMessage(string code, CultureInfo cultureInfo); + + /// + /// Resolves an object (typically an icon or bitmap). + /// + /// + ///

+ /// Subclasses must implement this method to resolve an object. + ///

+ ///
+ /// The code of the object to resolve. + /// + /// The to resolve the + /// code for. + /// + /// + /// The resolved object or if not found. + /// + protected abstract object ResolveObject(string code, CultureInfo cultureInfo); + + /// + /// Applies resources to object properties. + /// + /// + ///

+ /// Subclasses must implement this method to apply resources + /// to an arbitrary object. + ///

+ ///
+ /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + protected abstract void ApplyResourcesToObject(object value, string objectName, CultureInfo cultureInfo); + + + #endregion + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/AbstractXmlApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/AbstractXmlApplicationContext.cs index 75025375..860279fe 100644 --- a/src/Spring/Spring.Core/Context/Support/AbstractXmlApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/Support/AbstractXmlApplicationContext.cs @@ -1,293 +1,292 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using Common.Logging; -using Spring.Objects; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Convenient abstract superclass for - /// implementations that - /// draw their configuration from XML documents containing object - /// definitions as understood by an - /// . - /// - /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: AbstractXmlApplicationContext.cs,v 1.20 2007/07/20 11:37:55 oakinger Exp $ - public abstract class AbstractXmlApplicationContext : AbstractApplicationContext - { - /// - /// The instance for this class. - /// - private static readonly ILog log = LogManager.GetLogger(typeof(AbstractXmlApplicationContext)); - - private DefaultListableObjectFactory _objectFactory; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes - /// no public constructors. - ///

- ///
- protected AbstractXmlApplicationContext() : this(null, true, null) - {} - - /// - /// Creates a new instance of the - /// class - /// with the given parent context. - /// - /// - ///

- /// This is an class, and as such exposes - /// no public constructors. - ///

- ///
- /// The application context name. - /// Flag specifying whether to make this context case sensitive or not. - /// The parent context. - protected AbstractXmlApplicationContext(string name, bool caseSensitive, - IApplicationContext parentContext) : base(name, caseSensitive, parentContext) - {} - - /// - /// An array of resource locations, referring to the XML object - /// definition files that this context is to be built with. - /// - /// - ///

- /// Examples of the format of the various strings that would be - /// returned by accessing this property can be found in the overview - /// documentation of with the - /// class. - ///

- ///
- /// - /// An array of resource locations, or if none. - /// - protected abstract string[] ConfigurationLocations { get; } - - /// - /// Instantiates and populates the underlying - /// with the object - /// definitions yielded up by the - /// method. - /// - /// - /// In the case of errors encountered while refreshing the object factory. - /// - /// - /// In the case of errors encountered reading any of the resources - /// yielded by the method. - /// - /// - protected override void RefreshObjectFactory() - { - // Shut down previous object factory, if any. - IConfigurableListableObjectFactory oldObjectFactory = null; - oldObjectFactory = _objectFactory; - - if (oldObjectFactory != null) - { - _objectFactory = null; - oldObjectFactory.Dispose(); - } - - try - { - DefaultListableObjectFactory objectFactory = CreateObjectFactory(); - LoadObjectDefinitions(objectFactory); - - _objectFactory = objectFactory; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - "Refreshed ObjectFactory for application context '{0}'.", - Name)); - } - - #endregion - } - catch (IOException ex) - { - throw new ApplicationContextException( - string.Format( - "I/O error parsing XML resource for application context '{0}'.", - Name), ex); - } - catch (UriFormatException ex) - { - throw new ApplicationContextException( - string.Format( - "Error parsing resource locations [{0}] for application context '{1}'.", - StringUtils.ArrayToCommaDelimitedString(ConfigurationLocations), - Name), ex); - } - } - - - /// - /// Initialize the object definition reader used for loading the object - /// definitions of this context. - /// - /// - ///

- /// The default implementation of this method is a no-op; i.e. it does - /// nothing. Can be overridden in subclasses to provide custom - /// initialization of the supplied - /// ; for example, a derived - /// class may want to turn off XML validation. - ///

- ///
- /// - /// The object definition reader used by this context. - /// - protected virtual void InitObjectDefinitionReader( - XmlObjectDefinitionReader objectDefinitionReader) - {} - - /// - /// Load the object definitions with the given - /// . - /// - /// - ///

- /// The lifecycle of the object factory is handled by - /// ; - /// therefore this method is just supposed to load and / or register - /// object definitions. - ///

- ///
- /// - /// The reader containing object definitions. - /// - /// In case of object registration errors. - /// - /// - /// In the case of errors encountered reading any of the resources - /// yielded by the method. - /// - protected virtual void LoadObjectDefinitions( - XmlObjectDefinitionReader objectDefinitionReader) - { - string[] locations = ConfigurationLocations; - if (locations != null) - { - objectDefinitionReader.LoadObjectDefinitions(ConfigurationLocations); - } - } - - - /// - /// Loads the object definitions into the given object factory, typically through - /// delegating to one or more object definition readers. - /// - /// The object factory to lead object definitions into - /// - /// - protected virtual void LoadObjectDefinitions(DefaultListableObjectFactory objectFactory) - { - //Create a new XmlObjectDefinitionReader for the given ObjectFactory - XmlObjectDefinitionReader objectDefinitionReader = new XmlObjectDefinitionReader(objectFactory); - - // Configure the bean definition reader with this context's - // resource loading environment. - objectDefinitionReader.ResourceLoader = this; - - // Allow a subclass to provide custom initialization of the reader, - // then proceed with actually loading the object definitions. - InitObjectDefinitionReader(objectDefinitionReader); - LoadObjectDefinitions(objectDefinitionReader); - } - - /// - /// Customizes the internal object factory used by this context. - /// - /// Called for each attempt. - ///

- /// The default implementation is empty. Can be overriden in subclassses to customize - /// DefaultListableBeanFatory's standard settings. - ///

- /// The newly created object factory for this context - protected virtual void CustomizeObjectFactory(DefaultListableObjectFactory objectFactory) - { - - } - - /// - /// Create an internal object factory for this context. - /// - /// - ///

- /// Called for each attempt. - /// This default implementation creates a - /// - /// with the internal object factory of this context's parent serving - /// as the parent object factory. Can be overridden in subclasse,s - /// for example to customize DefaultListableBeanFactory's settings. - ///

- ///
- /// The object factory for this context. - protected virtual DefaultListableObjectFactory CreateObjectFactory() - { - return new DefaultListableObjectFactory(CaseSensitive, GetInternalParentObjectFactory()); - } - - /// - /// Subclasses must return their internal object factory here. - /// - /// - /// The internal object factory for the application context. - /// - /// - public override IConfigurableListableObjectFactory ObjectFactory - { - get - { - lock(SyncRoot) - { - return _objectFactory; - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using Common.Logging; +using Spring.Objects; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Convenient abstract superclass for + /// implementations that + /// draw their configuration from XML documents containing object + /// definitions as understood by an + /// . + /// + /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + public abstract class AbstractXmlApplicationContext : AbstractApplicationContext + { + /// + /// The instance for this class. + /// + private static readonly ILog log = LogManager.GetLogger(typeof(AbstractXmlApplicationContext)); + + private DefaultListableObjectFactory _objectFactory; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes + /// no public constructors. + ///

+ ///
+ protected AbstractXmlApplicationContext() : this(null, true, null) + {} + + /// + /// Creates a new instance of the + /// class + /// with the given parent context. + /// + /// + ///

+ /// This is an class, and as such exposes + /// no public constructors. + ///

+ ///
+ /// The application context name. + /// Flag specifying whether to make this context case sensitive or not. + /// The parent context. + protected AbstractXmlApplicationContext(string name, bool caseSensitive, + IApplicationContext parentContext) : base(name, caseSensitive, parentContext) + {} + + /// + /// An array of resource locations, referring to the XML object + /// definition files that this context is to be built with. + /// + /// + ///

+ /// Examples of the format of the various strings that would be + /// returned by accessing this property can be found in the overview + /// documentation of with the + /// class. + ///

+ ///
+ /// + /// An array of resource locations, or if none. + /// + protected abstract string[] ConfigurationLocations { get; } + + /// + /// Instantiates and populates the underlying + /// with the object + /// definitions yielded up by the + /// method. + /// + /// + /// In the case of errors encountered while refreshing the object factory. + /// + /// + /// In the case of errors encountered reading any of the resources + /// yielded by the method. + /// + /// + protected override void RefreshObjectFactory() + { + // Shut down previous object factory, if any. + IConfigurableListableObjectFactory oldObjectFactory = null; + oldObjectFactory = _objectFactory; + + if (oldObjectFactory != null) + { + _objectFactory = null; + oldObjectFactory.Dispose(); + } + + try + { + DefaultListableObjectFactory objectFactory = CreateObjectFactory(); + LoadObjectDefinitions(objectFactory); + + _objectFactory = objectFactory; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + "Refreshed ObjectFactory for application context '{0}'.", + Name)); + } + + #endregion + } + catch (IOException ex) + { + throw new ApplicationContextException( + string.Format( + "I/O error parsing XML resource for application context '{0}'.", + Name), ex); + } + catch (UriFormatException ex) + { + throw new ApplicationContextException( + string.Format( + "Error parsing resource locations [{0}] for application context '{1}'.", + StringUtils.ArrayToCommaDelimitedString(ConfigurationLocations), + Name), ex); + } + } + + + /// + /// Initialize the object definition reader used for loading the object + /// definitions of this context. + /// + /// + ///

+ /// The default implementation of this method is a no-op; i.e. it does + /// nothing. Can be overridden in subclasses to provide custom + /// initialization of the supplied + /// ; for example, a derived + /// class may want to turn off XML validation. + ///

+ ///
+ /// + /// The object definition reader used by this context. + /// + protected virtual void InitObjectDefinitionReader( + XmlObjectDefinitionReader objectDefinitionReader) + {} + + /// + /// Load the object definitions with the given + /// . + /// + /// + ///

+ /// The lifecycle of the object factory is handled by + /// ; + /// therefore this method is just supposed to load and / or register + /// object definitions. + ///

+ ///
+ /// + /// The reader containing object definitions. + /// + /// In case of object registration errors. + /// + /// + /// In the case of errors encountered reading any of the resources + /// yielded by the method. + /// + protected virtual void LoadObjectDefinitions( + XmlObjectDefinitionReader objectDefinitionReader) + { + string[] locations = ConfigurationLocations; + if (locations != null) + { + objectDefinitionReader.LoadObjectDefinitions(ConfigurationLocations); + } + } + + + /// + /// Loads the object definitions into the given object factory, typically through + /// delegating to one or more object definition readers. + /// + /// The object factory to lead object definitions into + /// + /// + protected virtual void LoadObjectDefinitions(DefaultListableObjectFactory objectFactory) + { + //Create a new XmlObjectDefinitionReader for the given ObjectFactory + XmlObjectDefinitionReader objectDefinitionReader = new XmlObjectDefinitionReader(objectFactory); + + // Configure the bean definition reader with this context's + // resource loading environment. + objectDefinitionReader.ResourceLoader = this; + + // Allow a subclass to provide custom initialization of the reader, + // then proceed with actually loading the object definitions. + InitObjectDefinitionReader(objectDefinitionReader); + LoadObjectDefinitions(objectDefinitionReader); + } + + /// + /// Customizes the internal object factory used by this context. + /// + /// Called for each attempt. + ///

+ /// The default implementation is empty. Can be overriden in subclassses to customize + /// DefaultListableBeanFatory's standard settings. + ///

+ /// The newly created object factory for this context + protected virtual void CustomizeObjectFactory(DefaultListableObjectFactory objectFactory) + { + + } + + /// + /// Create an internal object factory for this context. + /// + /// + ///

+ /// Called for each attempt. + /// This default implementation creates a + /// + /// with the internal object factory of this context's parent serving + /// as the parent object factory. Can be overridden in subclasse,s + /// for example to customize DefaultListableBeanFactory's settings. + ///

+ ///
+ /// The object factory for this context. + protected virtual DefaultListableObjectFactory CreateObjectFactory() + { + return new DefaultListableObjectFactory(CaseSensitive, GetInternalParentObjectFactory()); + } + + /// + /// Subclasses must return their internal object factory here. + /// + /// + /// The internal object factory for the application context. + /// + /// + public override IConfigurableListableObjectFactory ObjectFactory + { + get + { + lock(SyncRoot) + { + return _objectFactory; + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/ApplicationContextAwareProcessor.cs b/src/Spring/Spring.Core/Context/Support/ApplicationContextAwareProcessor.cs index 3d8a45ac..408b7828 100644 --- a/src/Spring/Spring.Core/Context/Support/ApplicationContextAwareProcessor.cs +++ b/src/Spring/Spring.Core/Context/Support/ApplicationContextAwareProcessor.cs @@ -1,149 +1,148 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Remoting; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// - /// implementation that passes the application context to object that - /// implement the - /// , - /// , and - /// interfaces. - /// - /// - ///

- /// If an object's class implements more than one of the - /// , - /// , and - /// interfaces, then the - /// order in which the interfaces are satisfied is as follows... - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///

- ///

- /// Application contexts will automatically register this with their - /// underlying object factory. Applications should thus never need to use - /// this class directly. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: ApplicationContextAwareProcessor.cs,v 1.8 2007/08/22 08:49:26 markpollack Exp $ - public class ApplicationContextAwareProcessor : IObjectPostProcessor - { - private IApplicationContext _applicationContext; - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The that this - /// instance will work with. - /// - public ApplicationContextAwareProcessor( - IApplicationContext applicationContext) - { - _applicationContext = applicationContext; - } - - /// - /// Apply this - /// to the given new object instance before any object - /// initialization callbacks. - /// - /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The the object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - /// - public object PostProcessAfterInitialization(object obj, string objectName) - { - return obj; - } - - /// - /// Apply this to the - /// given new object instance after any object initialization - /// callbacks. - /// - /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - /// - public object PostProcessBeforeInitialization(object obj, string name) - { - if(!RemotingServices.IsTransparentProxy(obj)) - { - if (typeof (IResourceLoaderAware).IsInstanceOfType(obj)) - { - ((IResourceLoaderAware) obj).ResourceLoader - = _applicationContext; - } - if (typeof (IMessageSourceAware).IsInstanceOfType(obj)) - { - ((IMessageSourceAware) obj).MessageSource - = _applicationContext; - } - if (typeof (IApplicationContextAware).IsInstanceOfType(obj)) - { - ((IApplicationContextAware) obj).ApplicationContext - = _applicationContext; - } - } - return obj; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Remoting; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// + /// implementation that passes the application context to object that + /// implement the + /// , + /// , and + /// interfaces. + /// + /// + ///

+ /// If an object's class implements more than one of the + /// , + /// , and + /// interfaces, then the + /// order in which the interfaces are satisfied is as follows... + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ///

+ ///

+ /// Application contexts will automatically register this with their + /// underlying object factory. Applications should thus never need to use + /// this class directly. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + public class ApplicationContextAwareProcessor : IObjectPostProcessor + { + private IApplicationContext _applicationContext; + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The that this + /// instance will work with. + /// + public ApplicationContextAwareProcessor( + IApplicationContext applicationContext) + { + _applicationContext = applicationContext; + } + + /// + /// Apply this + /// to the given new object instance before any object + /// initialization callbacks. + /// + /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The the object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + /// + public object PostProcessAfterInitialization(object obj, string objectName) + { + return obj; + } + + /// + /// Apply this to the + /// given new object instance after any object initialization + /// callbacks. + /// + /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + /// + public object PostProcessBeforeInitialization(object obj, string name) + { + if(!RemotingServices.IsTransparentProxy(obj)) + { + if (typeof (IResourceLoaderAware).IsInstanceOfType(obj)) + { + ((IResourceLoaderAware) obj).ResourceLoader + = _applicationContext; + } + if (typeof (IMessageSourceAware).IsInstanceOfType(obj)) + { + ((IMessageSourceAware) obj).MessageSource + = _applicationContext; + } + if (typeof (IApplicationContextAware).IsInstanceOfType(obj)) + { + ((IApplicationContextAware) obj).ApplicationContext + = _applicationContext; + } + } + return obj; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/ApplicationObjectSupport.cs b/src/Spring/Spring.Core/Context/Support/ApplicationObjectSupport.cs index f6807649..2aea4955 100644 --- a/src/Spring/Spring.Core/Context/Support/ApplicationObjectSupport.cs +++ b/src/Spring/Spring.Core/Context/Support/ApplicationObjectSupport.cs @@ -1,210 +1,209 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Spring.Objects; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Convenient superclass for application objects that want to be aware of - /// the application context, e.g. for custom lookup of collaborating object - /// or for context-specific resource access. - /// - /// - ///

- /// It saves the application context reference and provides an - /// initialization callback method. Furthermore, it offers numerous - /// convenience methods for message lookup. - ///

- ///

- /// There is no requirement to subclass this class: it just makes things - /// a little easier if you need access to the context, e.g. for access to - /// file resources or to the message source. Note that many application - /// objects do not need to be aware of the application context at all, - /// as they can receive collaborating objects via object references. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: ApplicationObjectSupport.cs,v 1.8 2007/07/17 14:51:14 oakinger Exp $ - public abstract class ApplicationObjectSupport : IApplicationContextAware - { - private IApplicationContext _applicationContext; - private MessageSourceAccessor _messageSourceAccessor; - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected ApplicationObjectSupport() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- /// - /// The that this - /// object runs in. - /// - protected ApplicationObjectSupport( - IApplicationContext applicationContext) - { - _applicationContext = applicationContext; - } - - /// - /// The context class that any context passed to the - /// - /// must be an instance of. - /// - /// - /// The - /// . - /// - protected virtual Type RequiredType - { - get { return typeof (IApplicationContext); } - } - - /// - /// Intializes the wrapped - /// . - /// - /// - ///

- /// This is a template method that subclasses can override for custom - /// initialization behavior. - ///

- ///

- /// Gets called by the - /// - /// instance directly after setting the context instance. - ///

- /// - /// Does not get called on reinitialization of the context. - /// - ///
- /// - /// In the case of any initialization errors. - /// - /// - /// If thrown by application context methods. - /// - protected virtual void InitApplicationContext() - { - } - - /// - /// Return a for the - /// application context used by this object, for easy message access. - /// - public MessageSourceAccessor MessageSourceAccessor - { - get { return _messageSourceAccessor; } - } - - #region IApplicationContextAware Members - - /// - /// Set the that this - /// object runs in. - /// - /// - /// When passed an unexpected - /// implementation - /// instance that is not compatible with the - /// defined by the value of the - /// . - /// property. Also, thrown when trying to re-initialize with a - /// different than was - /// originally used. - /// - /// - /// If thrown by any application context methods. - /// - /// - /// - public IApplicationContext ApplicationContext - { - get { return _applicationContext; } - set - { - if (_applicationContext == null) - { - if (! isValueOfRequiredType(value)) - { - throw new ApplicationContextException( - "Invalid application context: needs to by of type '" + RequiredType.DeclaringType + "'"); - } - _applicationContext = value; - _messageSourceAccessor = new MessageSourceAccessor(value); - InitApplicationContext(); - } - else - { - if (_applicationContext != value) - { - throw new ApplicationContextException("Cannot reinitialize with different application context"); - } - } - } - } - - private bool isValueOfRequiredType(IApplicationContext value) - { - if (value.GetType() == RequiredType) - { - return true; - } - Type[] implementedTypes = value.GetType().GetInterfaces(); - for (int i = 0; i < implementedTypes.Length; i++) - { - if (implementedTypes[i] == RequiredType) - { - return true; - } - } - return false; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Spring.Objects; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Convenient superclass for application objects that want to be aware of + /// the application context, e.g. for custom lookup of collaborating object + /// or for context-specific resource access. + /// + /// + ///

+ /// It saves the application context reference and provides an + /// initialization callback method. Furthermore, it offers numerous + /// convenience methods for message lookup. + ///

+ ///

+ /// There is no requirement to subclass this class: it just makes things + /// a little easier if you need access to the context, e.g. for access to + /// file resources or to the message source. Note that many application + /// objects do not need to be aware of the application context at all, + /// as they can receive collaborating objects via object references. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + public abstract class ApplicationObjectSupport : IApplicationContextAware + { + private IApplicationContext _applicationContext; + private MessageSourceAccessor _messageSourceAccessor; + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected ApplicationObjectSupport() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ /// + /// The that this + /// object runs in. + /// + protected ApplicationObjectSupport( + IApplicationContext applicationContext) + { + _applicationContext = applicationContext; + } + + /// + /// The context class that any context passed to the + /// + /// must be an instance of. + /// + /// + /// The + /// . + /// + protected virtual Type RequiredType + { + get { return typeof (IApplicationContext); } + } + + /// + /// Intializes the wrapped + /// . + /// + /// + ///

+ /// This is a template method that subclasses can override for custom + /// initialization behavior. + ///

+ ///

+ /// Gets called by the + /// + /// instance directly after setting the context instance. + ///

+ /// + /// Does not get called on reinitialization of the context. + /// + ///
+ /// + /// In the case of any initialization errors. + /// + /// + /// If thrown by application context methods. + /// + protected virtual void InitApplicationContext() + { + } + + /// + /// Return a for the + /// application context used by this object, for easy message access. + /// + public MessageSourceAccessor MessageSourceAccessor + { + get { return _messageSourceAccessor; } + } + + #region IApplicationContextAware Members + + /// + /// Set the that this + /// object runs in. + /// + /// + /// When passed an unexpected + /// implementation + /// instance that is not compatible with the + /// defined by the value of the + /// . + /// property. Also, thrown when trying to re-initialize with a + /// different than was + /// originally used. + /// + /// + /// If thrown by any application context methods. + /// + /// + /// + public IApplicationContext ApplicationContext + { + get { return _applicationContext; } + set + { + if (_applicationContext == null) + { + if (! isValueOfRequiredType(value)) + { + throw new ApplicationContextException( + "Invalid application context: needs to by of type '" + RequiredType.DeclaringType + "'"); + } + _applicationContext = value; + _messageSourceAccessor = new MessageSourceAccessor(value); + InitApplicationContext(); + } + else + { + if (_applicationContext != value) + { + throw new ApplicationContextException("Cannot reinitialize with different application context"); + } + } + } + } + + private bool isValueOfRequiredType(IApplicationContext value) + { + if (value.GetType() == RequiredType) + { + return true; + } + Type[] implementedTypes = value.GetType().GetInterfaces(); + for (int i = 0; i < implementedTypes.Length; i++) + { + if (implementedTypes[i] == RequiredType) + { + return true; + } + } + return false; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/ContextHandler.cs b/src/Spring/Spring.Core/Context/Support/ContextHandler.cs index 3d613f4c..f0018d4a 100644 --- a/src/Spring/Spring.Core/Context/Support/ContextHandler.cs +++ b/src/Spring/Spring.Core/Context/Support/ContextHandler.cs @@ -1,642 +1,641 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Configuration; -using System.Reflection; -using System.Xml; - -using Common.Logging; -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Objects; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Creates an instance - /// using context definitions supplied in a custom configuration and - /// configures the with that instance. - /// - /// - /// Implementations of the - /// interface must provide the following two constructors: - /// - /// - /// - /// A constructor that takes a string array of resource locations. - /// - /// - /// - /// - /// A constructor that takes a reference to a parent application context - /// and a string array of resource locations (and in that order). - /// - /// - /// - ///

- /// Note that if the type attribute is not present in the declaration - /// of a particular context, then a default - /// - /// is assumed. This default - /// - /// is currently the - /// ; please note the exact - /// of this default is an - /// implementation detail, that, while unlikely, may do so in the future. - /// to - ///

- ///
- /// - ///

- /// This is an example of specifying a context that reads its resources from - /// an embedded Spring.NET XML object configuration file... - ///

- /// - /// - /// - /// - ///
- /// - /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// This is an example of specifying a context that reads its resources from - /// a custom configuration section within the same application / web - /// configuration file and uses case insensitive object lookups. - ///

- ///

- /// Please note that you must adhere to the naming - /// of the various sections (i.e. '<sectionGroup name="spring">' and - /// '<section name="context">'. - ///

- /// - /// - /// - /// - ///
- ///
- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// And this is an example of specifying a hierarchy of contexts. The - /// hierarchy in this case is only a simple parent->child hierarchy, but - /// hopefully it illustrates the nesting of context configurations. This - /// nesting of contexts can be arbitrarily deep, and is one way... child - /// contexts know about their parent contexts, but parent contexts do not - /// know how many child contexts they have (if any), or have references - /// to any such child contexts. - ///

- /// - /// - /// - /// - ///
- ///
- /// - ///
- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Mark Pollack - /// Aleksandar Seovic - /// Rick Evans - /// $Id: ContextHandler.cs,v 1.36 2008/03/13 20:07:33 bbaia Exp $ - /// - public class ContextHandler : IConfigurationSectionHandler - { - private readonly ILog Log = LogManager.GetLogger(typeof(ContextHandler)); - - /// - /// The of - /// created if no type attribute is specified on a context element. - /// - /// - protected virtual Type DefaultApplicationContextType - { - get { return typeof (XmlApplicationContext); } - } - - /// - /// Get the context's case-sensitivity to use if none is specified - /// - /// - ///

- /// Derived handlers may override this property to change their default case-sensitivity. - ///

- ///

- /// Defaults to 'true'. - ///

- ///
- protected virtual bool DefaultCaseSensitivity - { - get { return true; } - } - - /// - /// Creates an instance - /// using the context definitions supplied in a custom - /// configuration section. - /// - /// - ///

- /// This instance is - /// also used to configure the . - ///

- ///
- /// - /// The configuration settings in a corresponding parent - /// configuration section. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is . - /// - /// - /// The for the section. - /// - /// - /// An instance - /// populated with the object definitions supplied in the configuration - /// section. - /// - public object Create(object parent, object configContext, XmlNode section) - { - XmlElement contextElement = section as XmlElement; - - #region Sanity Checks - - if (contextElement == null) - { - throw ConfigurationUtils.CreateConfigurationException( - "Context configuration section must be an XmlElement."); - } - - // sanity check on parent - if ( (parent != null) && !(parent is IApplicationContext) ) - { - throw ConfigurationUtils.CreateConfigurationException( - String.Format("Parent context must be of type IApplicationContext, but was '{0}'", parent.GetType().FullName)); - } - - #endregion - - // determine name of context to be created - string contextName = GetContextName(configContext, contextElement); - if (!StringUtils.HasLength(contextName)) - { - contextName = AbstractApplicationContext.DefaultRootContextName; - } - - #region Instrumentation - if (Log.IsDebugEnabled) Log.Debug(string.Format("creating context '{0}'", contextName ) ); - #endregion - - IApplicationContext context = null; - try - { - IApplicationContext parentContext = parent as IApplicationContext; - - // determine context type - Type contextType = GetContextType(contextElement, parentContext); - - // determine case-sensitivity - bool caseSensitive = GetCaseSensitivity(contextElement); - - // get resource-list - string[] resources = GetResources(contextElement); - - // finally create the context instance - context = InstantiateContext(parentContext, configContext, contextName, contextType, caseSensitive, resources); - - // get and create child context definitions - XmlNode[] childContexts = GetChildContexts(contextElement); - CreateChildContexts(context, configContext, childContexts); - - if (Log.IsDebugEnabled) Log.Debug( string.Format("context '{0}' created for name '{1}'", context, contextName) ); - } - catch (Exception ex) - { - if (!ConfigurationUtils.IsConfigurationException(ex)) - { - throw ConfigurationUtils.CreateConfigurationException( - String.Format("Error creating context '{0}': {1}", - contextName, ReflectionUtils.GetExplicitBaseException(ex).Message), ex); - } - throw; - } - return context; - } - - /// - /// Create all child-contexts in the given for the given context. - /// - /// The parent context to use - /// The current configContext - /// The list of child context elements - protected virtual void CreateChildContexts(IApplicationContext parentContext, object configContext, XmlNode[] childContexts) - { - // create child contexts for 'the most recently created context'... - foreach (XmlNode childContext in childContexts) - { - this.Create(parentContext, configContext, childContext); - } - } - - /// - /// Instantiates a new context. - /// - protected virtual IApplicationContext InstantiateContext(IApplicationContext parentContext, object configContext, string contextName, Type contextType, bool caseSensitive, string[] resources) - { - IApplicationContext context; - ContextInstantiator instantiator; - - if (parentContext == null) - { - instantiator = new RootContextInstantiator(contextType, contextName, caseSensitive, resources); - } - else - { - instantiator = new DescendantContextInstantiator(parentContext, contextType, contextName, caseSensitive, resources); - } - - if (IsLazy) - { - // TODO - } - context = instantiator.InstantiateContext(); - return context; - } - - /// - /// Gets the context's name specified in the name attribute of the context element. - /// - /// The current configContext - /// The context element - protected virtual string GetContextName(object configContext, XmlElement contextElement) - { - string contextName; - contextName = contextElement.GetAttribute(ContextSchema.NameAttribute); - return contextName; - } - - /// - /// Extracts the context-type from the context element. - /// If none is specified, returns the parent's type. - /// - private Type GetContextType(XmlElement contextElement, IApplicationContext parentContext) - { - Type contextType; - if (parentContext != null) - { - // set default context type to parent's type (allows for type inheritance) - contextType = GetConfiguredContextType(contextElement, parentContext.GetType()); - } - else - { - contextType = GetConfiguredContextType(contextElement, this.DefaultApplicationContextType); - } - return contextType; - } - - /// - /// Extracts the case-sensitivity attribute from the context element - /// - private bool GetCaseSensitivity(XmlElement contextElement) - { - bool caseSensitive = DefaultCaseSensitivity; - - string caseSensitiveAttr = contextElement.GetAttribute(ContextSchema.CaseSensitiveAttribute); - if (StringUtils.HasText(caseSensitiveAttr)) - { - caseSensitive = Boolean.Parse(caseSensitiveAttr); - } - return caseSensitive; - } - - /// - /// Gets the context specified in the type - /// attribute of the context element. - /// - /// - ///

- /// If this attribute is not defined it defaults to the - /// type. - ///

- ///
- /// - /// If the context type does not implement the - /// interface. - /// - private Type GetConfiguredContextType(XmlElement contextElement, Type defaultContextType) - { - string typeName = contextElement.GetAttribute(ContextSchema.TypeAttribute); - - if (StringUtils.IsNullOrEmpty(typeName)) - { - return defaultContextType; - } - else - { - Type type = TypeResolutionUtils.ResolveType(typeName); - if (typeof(IApplicationContext).IsAssignableFrom(type)) - { - return type; - } - else - { - throw new TypeMismatchException( type.Name + " does not implement IApplicationContext."); - } - } - } - - /// - /// Returns if the context should be lazily - /// initialized. - /// - private bool IsLazy - { - get { return false; } - } - - /// - /// Returns the array of resources containing object definitions for - /// this context. - /// - private string[] GetResources( XmlElement contextElement ) - { - ArrayList resourceNodes = new ArrayList(contextElement.ChildNodes.Count); - foreach (XmlNode possibleResourceNode in contextElement.ChildNodes) - { - XmlElement possibleResourceElement = possibleResourceNode as XmlElement; - if(possibleResourceElement != null && - possibleResourceElement.LocalName == ContextSchema.ResourceElement) - { - string resourceName = possibleResourceElement.GetAttribute(ContextSchema.URIAttribute); - if(StringUtils.HasText(resourceName)) - { - resourceNodes.Add(resourceName); - } - } - } - return (string[]) resourceNodes.ToArray(typeof(string)); - } - - /// - /// Returns the array of child contexts for this context. - /// - private XmlNode[] GetChildContexts(XmlElement contextElement) - { - ArrayList contextNodes = new ArrayList(contextElement.ChildNodes.Count); - foreach (XmlNode possibleContextNode in contextElement.ChildNodes) - { - XmlElement possibleContextElement = possibleContextNode as XmlElement; - if (possibleContextElement != null && - possibleContextElement.LocalName == ContextSchema.ContextElement) - { - contextNodes.Add(possibleContextElement); - } - } - return (XmlNode[])contextNodes.ToArray(typeof(XmlNode)); - } - - #region Inner Class : ContextInstantiator - - private abstract class ContextInstantiator - { - protected ContextInstantiator( - Type contextType, string contextName, bool caseSensitive, string[] resources) - { - _contextType = contextType; - _contextName = contextName; - _caseSensitive = caseSensitive; - _resources = resources; - } - - public IApplicationContext InstantiateContext() - { - ConstructorInfo ctor = GetContextConstructor(); - if (ctor == null) - { - string errorMessage = "No constructor with string[] argument found for context type [" + ContextType.Name + "]"; - throw ConfigurationUtils.CreateConfigurationException(errorMessage); - } - IApplicationContext context = InvokeContextConstructor(ctor); - ContextRegistry.RegisterContext(context); - return context; - } - - protected abstract ConstructorInfo GetContextConstructor(); - - protected abstract IApplicationContext InvokeContextConstructor( - ConstructorInfo ctor); - - protected Type ContextType - { - get { return _contextType; } - } - - protected string ContextName - { - get { return _contextName; } - } - - protected bool CaseSensitive - { - get { return _caseSensitive; } - } - - protected string[] Resources - { - get { return _resources; } - } - - private Type _contextType; - private string _contextName; - private bool _caseSensitive; - private string[] _resources; - } - - #endregion - - #region Inner Class : RootContextInstantiator - - private sealed class RootContextInstantiator : ContextInstantiator - { - public RootContextInstantiator( - Type contextType, string contextName, bool caseSensitive, string[] resources) - : base(contextType, contextName, caseSensitive, resources) - { - } - - protected override ConstructorInfo GetContextConstructor() - { - return ContextType.GetConstructor(new Type[] {typeof(string), typeof(bool), typeof(string[])}); - } - - protected override IApplicationContext InvokeContextConstructor( - ConstructorInfo ctor) - { - return (IApplicationContext) ObjectUtils.InstantiateType( - ctor, new object[] {ContextName, CaseSensitive, Resources}); - } - } - - #endregion - - #region Inner Class : DescendantContextInstantiator - - private sealed class DescendantContextInstantiator : ContextInstantiator - { - public DescendantContextInstantiator( - IApplicationContext parentContext, Type contextType, - string contextName, bool caseSensitive, string[] resources) - : base(contextType, contextName, caseSensitive, resources) - { - this.parentContext = parentContext; - } - - protected override ConstructorInfo GetContextConstructor() - { - return ContextType.GetConstructor( - new Type[] {typeof(string), typeof(bool), typeof(IApplicationContext), typeof(string[])}); - } - - protected override IApplicationContext InvokeContextConstructor( - ConstructorInfo ctor) - { - return (IApplicationContext) ObjectUtils.InstantiateType( - ctor, new object[] {ContextName, CaseSensitive, this.parentContext, Resources}); - } - - private IApplicationContext parentContext; - } - - #endregion - - #region Context Schema Constants - - /// - /// Constants defining the structure and values associated with the - /// schema for laying out Spring.NET contexts in XML. - /// - private sealed class ContextSchema - { - /// - /// Defines a single - /// . - /// - public const string ContextElement = "context"; - - /// - /// Specifies a context name. - /// - public const string NameAttribute = "name"; - - /// - /// Specifies if context should be case sensitive or not. Default is true. - /// - public const string CaseSensitiveAttribute = "caseSensitive"; - - /// - /// Specifies a . - /// - /// - ///

- /// Does not have to be fully assembly qualified, but its generally regarded - /// as better form if the names of one's objects - /// are specified explicitly. - ///

- ///
- public const string TypeAttribute = "type"; - - /// - /// Specifies whether context should be lazy initialized. - /// - public const string LazyAttribute = "lazy"; - - /// - /// Defines an - /// - public const string ResourceElement = "resource"; - - /// - /// Specifies the URI for an - /// . - /// - public const string URIAttribute = "uri"; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Configuration; +using System.Reflection; +using System.Xml; + +using Common.Logging; +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Objects; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Creates an instance + /// using context definitions supplied in a custom configuration and + /// configures the with that instance. + /// + /// + /// Implementations of the + /// interface must provide the following two constructors: + /// + /// + /// + /// A constructor that takes a string array of resource locations. + /// + /// + /// + /// + /// A constructor that takes a reference to a parent application context + /// and a string array of resource locations (and in that order). + /// + /// + /// + ///

+ /// Note that if the type attribute is not present in the declaration + /// of a particular context, then a default + /// + /// is assumed. This default + /// + /// is currently the + /// ; please note the exact + /// of this default is an + /// implementation detail, that, while unlikely, may do so in the future. + /// to + ///

+ ///
+ /// + ///

+ /// This is an example of specifying a context that reads its resources from + /// an embedded Spring.NET XML object configuration file... + ///

+ /// + /// + /// + /// + ///
+ /// + /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// This is an example of specifying a context that reads its resources from + /// a custom configuration section within the same application / web + /// configuration file and uses case insensitive object lookups. + ///

+ ///

+ /// Please note that you must adhere to the naming + /// of the various sections (i.e. '<sectionGroup name="spring">' and + /// '<section name="context">'. + ///

+ /// + /// + /// + /// + ///
+ ///
+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// And this is an example of specifying a hierarchy of contexts. The + /// hierarchy in this case is only a simple parent->child hierarchy, but + /// hopefully it illustrates the nesting of context configurations. This + /// nesting of contexts can be arbitrarily deep, and is one way... child + /// contexts know about their parent contexts, but parent contexts do not + /// know how many child contexts they have (if any), or have references + /// to any such child contexts. + ///

+ /// + /// + /// + /// + ///
+ ///
+ /// + ///
+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Mark Pollack + /// Aleksandar Seovic + /// Rick Evans + /// + public class ContextHandler : IConfigurationSectionHandler + { + private readonly ILog Log = LogManager.GetLogger(typeof(ContextHandler)); + + /// + /// The of + /// created if no type attribute is specified on a context element. + /// + /// + protected virtual Type DefaultApplicationContextType + { + get { return typeof (XmlApplicationContext); } + } + + /// + /// Get the context's case-sensitivity to use if none is specified + /// + /// + ///

+ /// Derived handlers may override this property to change their default case-sensitivity. + ///

+ ///

+ /// Defaults to 'true'. + ///

+ ///
+ protected virtual bool DefaultCaseSensitivity + { + get { return true; } + } + + /// + /// Creates an instance + /// using the context definitions supplied in a custom + /// configuration section. + /// + /// + ///

+ /// This instance is + /// also used to configure the . + ///

+ ///
+ /// + /// The configuration settings in a corresponding parent + /// configuration section. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is . + /// + /// + /// The for the section. + /// + /// + /// An instance + /// populated with the object definitions supplied in the configuration + /// section. + /// + public object Create(object parent, object configContext, XmlNode section) + { + XmlElement contextElement = section as XmlElement; + + #region Sanity Checks + + if (contextElement == null) + { + throw ConfigurationUtils.CreateConfigurationException( + "Context configuration section must be an XmlElement."); + } + + // sanity check on parent + if ( (parent != null) && !(parent is IApplicationContext) ) + { + throw ConfigurationUtils.CreateConfigurationException( + String.Format("Parent context must be of type IApplicationContext, but was '{0}'", parent.GetType().FullName)); + } + + #endregion + + // determine name of context to be created + string contextName = GetContextName(configContext, contextElement); + if (!StringUtils.HasLength(contextName)) + { + contextName = AbstractApplicationContext.DefaultRootContextName; + } + + #region Instrumentation + if (Log.IsDebugEnabled) Log.Debug(string.Format("creating context '{0}'", contextName ) ); + #endregion + + IApplicationContext context = null; + try + { + IApplicationContext parentContext = parent as IApplicationContext; + + // determine context type + Type contextType = GetContextType(contextElement, parentContext); + + // determine case-sensitivity + bool caseSensitive = GetCaseSensitivity(contextElement); + + // get resource-list + string[] resources = GetResources(contextElement); + + // finally create the context instance + context = InstantiateContext(parentContext, configContext, contextName, contextType, caseSensitive, resources); + + // get and create child context definitions + XmlNode[] childContexts = GetChildContexts(contextElement); + CreateChildContexts(context, configContext, childContexts); + + if (Log.IsDebugEnabled) Log.Debug( string.Format("context '{0}' created for name '{1}'", context, contextName) ); + } + catch (Exception ex) + { + if (!ConfigurationUtils.IsConfigurationException(ex)) + { + throw ConfigurationUtils.CreateConfigurationException( + String.Format("Error creating context '{0}': {1}", + contextName, ReflectionUtils.GetExplicitBaseException(ex).Message), ex); + } + throw; + } + return context; + } + + /// + /// Create all child-contexts in the given for the given context. + /// + /// The parent context to use + /// The current configContext + /// The list of child context elements + protected virtual void CreateChildContexts(IApplicationContext parentContext, object configContext, XmlNode[] childContexts) + { + // create child contexts for 'the most recently created context'... + foreach (XmlNode childContext in childContexts) + { + this.Create(parentContext, configContext, childContext); + } + } + + /// + /// Instantiates a new context. + /// + protected virtual IApplicationContext InstantiateContext(IApplicationContext parentContext, object configContext, string contextName, Type contextType, bool caseSensitive, string[] resources) + { + IApplicationContext context; + ContextInstantiator instantiator; + + if (parentContext == null) + { + instantiator = new RootContextInstantiator(contextType, contextName, caseSensitive, resources); + } + else + { + instantiator = new DescendantContextInstantiator(parentContext, contextType, contextName, caseSensitive, resources); + } + + if (IsLazy) + { + // TODO + } + context = instantiator.InstantiateContext(); + return context; + } + + /// + /// Gets the context's name specified in the name attribute of the context element. + /// + /// The current configContext + /// The context element + protected virtual string GetContextName(object configContext, XmlElement contextElement) + { + string contextName; + contextName = contextElement.GetAttribute(ContextSchema.NameAttribute); + return contextName; + } + + /// + /// Extracts the context-type from the context element. + /// If none is specified, returns the parent's type. + /// + private Type GetContextType(XmlElement contextElement, IApplicationContext parentContext) + { + Type contextType; + if (parentContext != null) + { + // set default context type to parent's type (allows for type inheritance) + contextType = GetConfiguredContextType(contextElement, parentContext.GetType()); + } + else + { + contextType = GetConfiguredContextType(contextElement, this.DefaultApplicationContextType); + } + return contextType; + } + + /// + /// Extracts the case-sensitivity attribute from the context element + /// + private bool GetCaseSensitivity(XmlElement contextElement) + { + bool caseSensitive = DefaultCaseSensitivity; + + string caseSensitiveAttr = contextElement.GetAttribute(ContextSchema.CaseSensitiveAttribute); + if (StringUtils.HasText(caseSensitiveAttr)) + { + caseSensitive = Boolean.Parse(caseSensitiveAttr); + } + return caseSensitive; + } + + /// + /// Gets the context specified in the type + /// attribute of the context element. + /// + /// + ///

+ /// If this attribute is not defined it defaults to the + /// type. + ///

+ ///
+ /// + /// If the context type does not implement the + /// interface. + /// + private Type GetConfiguredContextType(XmlElement contextElement, Type defaultContextType) + { + string typeName = contextElement.GetAttribute(ContextSchema.TypeAttribute); + + if (StringUtils.IsNullOrEmpty(typeName)) + { + return defaultContextType; + } + else + { + Type type = TypeResolutionUtils.ResolveType(typeName); + if (typeof(IApplicationContext).IsAssignableFrom(type)) + { + return type; + } + else + { + throw new TypeMismatchException( type.Name + " does not implement IApplicationContext."); + } + } + } + + /// + /// Returns if the context should be lazily + /// initialized. + /// + private bool IsLazy + { + get { return false; } + } + + /// + /// Returns the array of resources containing object definitions for + /// this context. + /// + private string[] GetResources( XmlElement contextElement ) + { + ArrayList resourceNodes = new ArrayList(contextElement.ChildNodes.Count); + foreach (XmlNode possibleResourceNode in contextElement.ChildNodes) + { + XmlElement possibleResourceElement = possibleResourceNode as XmlElement; + if(possibleResourceElement != null && + possibleResourceElement.LocalName == ContextSchema.ResourceElement) + { + string resourceName = possibleResourceElement.GetAttribute(ContextSchema.URIAttribute); + if(StringUtils.HasText(resourceName)) + { + resourceNodes.Add(resourceName); + } + } + } + return (string[]) resourceNodes.ToArray(typeof(string)); + } + + /// + /// Returns the array of child contexts for this context. + /// + private XmlNode[] GetChildContexts(XmlElement contextElement) + { + ArrayList contextNodes = new ArrayList(contextElement.ChildNodes.Count); + foreach (XmlNode possibleContextNode in contextElement.ChildNodes) + { + XmlElement possibleContextElement = possibleContextNode as XmlElement; + if (possibleContextElement != null && + possibleContextElement.LocalName == ContextSchema.ContextElement) + { + contextNodes.Add(possibleContextElement); + } + } + return (XmlNode[])contextNodes.ToArray(typeof(XmlNode)); + } + + #region Inner Class : ContextInstantiator + + private abstract class ContextInstantiator + { + protected ContextInstantiator( + Type contextType, string contextName, bool caseSensitive, string[] resources) + { + _contextType = contextType; + _contextName = contextName; + _caseSensitive = caseSensitive; + _resources = resources; + } + + public IApplicationContext InstantiateContext() + { + ConstructorInfo ctor = GetContextConstructor(); + if (ctor == null) + { + string errorMessage = "No constructor with string[] argument found for context type [" + ContextType.Name + "]"; + throw ConfigurationUtils.CreateConfigurationException(errorMessage); + } + IApplicationContext context = InvokeContextConstructor(ctor); + ContextRegistry.RegisterContext(context); + return context; + } + + protected abstract ConstructorInfo GetContextConstructor(); + + protected abstract IApplicationContext InvokeContextConstructor( + ConstructorInfo ctor); + + protected Type ContextType + { + get { return _contextType; } + } + + protected string ContextName + { + get { return _contextName; } + } + + protected bool CaseSensitive + { + get { return _caseSensitive; } + } + + protected string[] Resources + { + get { return _resources; } + } + + private Type _contextType; + private string _contextName; + private bool _caseSensitive; + private string[] _resources; + } + + #endregion + + #region Inner Class : RootContextInstantiator + + private sealed class RootContextInstantiator : ContextInstantiator + { + public RootContextInstantiator( + Type contextType, string contextName, bool caseSensitive, string[] resources) + : base(contextType, contextName, caseSensitive, resources) + { + } + + protected override ConstructorInfo GetContextConstructor() + { + return ContextType.GetConstructor(new Type[] {typeof(string), typeof(bool), typeof(string[])}); + } + + protected override IApplicationContext InvokeContextConstructor( + ConstructorInfo ctor) + { + return (IApplicationContext) ObjectUtils.InstantiateType( + ctor, new object[] {ContextName, CaseSensitive, Resources}); + } + } + + #endregion + + #region Inner Class : DescendantContextInstantiator + + private sealed class DescendantContextInstantiator : ContextInstantiator + { + public DescendantContextInstantiator( + IApplicationContext parentContext, Type contextType, + string contextName, bool caseSensitive, string[] resources) + : base(contextType, contextName, caseSensitive, resources) + { + this.parentContext = parentContext; + } + + protected override ConstructorInfo GetContextConstructor() + { + return ContextType.GetConstructor( + new Type[] {typeof(string), typeof(bool), typeof(IApplicationContext), typeof(string[])}); + } + + protected override IApplicationContext InvokeContextConstructor( + ConstructorInfo ctor) + { + return (IApplicationContext) ObjectUtils.InstantiateType( + ctor, new object[] {ContextName, CaseSensitive, this.parentContext, Resources}); + } + + private IApplicationContext parentContext; + } + + #endregion + + #region Context Schema Constants + + /// + /// Constants defining the structure and values associated with the + /// schema for laying out Spring.NET contexts in XML. + /// + private sealed class ContextSchema + { + /// + /// Defines a single + /// . + /// + public const string ContextElement = "context"; + + /// + /// Specifies a context name. + /// + public const string NameAttribute = "name"; + + /// + /// Specifies if context should be case sensitive or not. Default is true. + /// + public const string CaseSensitiveAttribute = "caseSensitive"; + + /// + /// Specifies a . + /// + /// + ///

+ /// Does not have to be fully assembly qualified, but its generally regarded + /// as better form if the names of one's objects + /// are specified explicitly. + ///

+ ///
+ public const string TypeAttribute = "type"; + + /// + /// Specifies whether context should be lazy initialized. + /// + public const string LazyAttribute = "lazy"; + + /// + /// Defines an + /// + public const string ResourceElement = "resource"; + + /// + /// Specifies the URI for an + /// . + /// + public const string URIAttribute = "uri"; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs b/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs index c4f6d47e..0f4047b9 100644 --- a/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs +++ b/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs @@ -1,286 +1,285 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Configuration; -using Common.Logging; - -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Provides access to a central registry of - /// s. - /// - /// - ///

- /// A singleton implementation to access one or more application contexts. Application - /// context instances are cached. - ///

- ///

Note that the use of this class or similar is unnecessary except (sometimes) for - /// a small amount of glue code. Excessive usage will lead to code that is more tightly - /// coupled, and harder to modify or test. Consider refactoring your code to use standard - /// Dependency Injection techniques or implement the interface IApplicationContextAware to - /// obtain a reference to an application context.

- ///
- /// Mark Pollack - /// Aleksandar Seovic - /// - /// $Id: ContextRegistry.cs,v 1.28 2008/03/21 10:49:37 oakinger Exp $ - public sealed class ContextRegistry - { - /// - /// The shared instance for this class (and derived classes). - /// - private static readonly ILog log = LogManager.GetLogger(typeof(ContextRegistry)); - - private static readonly object syncRoot = new Object(); - private static readonly ContextRegistry instance = new ContextRegistry(); - private static string rootContextName = null; - - private IDictionary contextMap = CollectionsUtil.CreateCaseInsensitiveHashtable(); - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the ContextRegistry class. - /// - /// - ///

- /// Explicit static constructor to tell C# compiler - /// not to mark type as beforefieldinit. - ///

- ///
- static ContextRegistry() - {} - - // CLOVER:ON - - #endregion - - /// - /// This event is fired, if ContextRegistry.Clear() is called.
- /// Clients may register to get informed - ///
- /// - /// This event is fired while still holding a lock on the Registry.
- /// 'sender' parameter is sent as typeof(ContextRegistry), EventArgs are not used - ///
- public static event EventHandler Cleared; - - /// - /// Gets an object that should be used to synchronize access to ContextRegistry - /// from the calling code. - /// - public static object SyncRoot - { - get { return syncRoot; } - } - - /// - /// Registers an instance of an - /// . - /// - /// - ///

- /// This is usually called via a - /// inside a .NET - /// application configuration file. - ///

- ///
- /// The application context to be registered. - /// - /// If a context has previously been registered using the same name - /// - public static void RegisterContext(IApplicationContext context) - { - lock (syncRoot) - { - if (instance.contextMap.Contains(context.Name)) - { - IApplicationContext ctx = (IApplicationContext)instance.contextMap[context.Name]; - throw new ApplicationContextException( - string.Format("Existing context '{0}' already registered under name '{1}'.", - ctx, context.Name)); - } - instance.contextMap[context.Name] = context; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(String.Format( - "Registering context '{0}' under name '{1}'.", context, context.Name)); - } - - #endregion - - if (rootContextName == null) - { - rootContextName = context.Name; - } - } - } - - /// - /// Returns the root application context. - /// - /// - ///

- /// The first call to GetContext will create the context - /// as specified in the .NET application configuration file - /// under the location spring/context. - ///

- ///
- /// The root application context. - public static IApplicationContext GetContext() - { - lock (syncRoot) - { - InitializeContextIfNeeded(); - return GetContext(rootContextName); - } - } - - /// - /// Returns context based on specified name. - /// - /// - ///

- /// The first call to GetContext will create the context - /// as specified in the .NET application configuration file - /// under the location spring/context. - ///

- ///
- /// The context name. - /// The specified context, or null, if context with that name doesn't exists. - /// - /// If the context name is null or empty - /// - public static IApplicationContext GetContext(string name) - { - if (StringUtils.IsNullOrEmpty(name)) - { - throw new ArgumentException( - "The context name passed to the GetContext method cannot be null or empty."); - } - else - { - lock (syncRoot) - { - InitializeContextIfNeeded(); - IApplicationContext ctx = (IApplicationContext)instance.contextMap[name]; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - if (ctx == null) - { - log.Debug(String.Format( - "No context registered under name '{0}'.", name)); - } - else - { - log.Debug(String.Format( - "Returning context '{0}' registered under name '{1}'.", ctx, name)); - } - } - - #endregion - - return ctx; - } - } - } - - /// - /// Removes all registered - /// s from this - /// registry. - /// - /// - /// Raises the event while still holding a lock on - /// - public static void Clear() - { - lock (syncRoot) - { - foreach (IApplicationContext ctx in instance.contextMap.Values) - { - ctx.Dispose(); - } - instance.contextMap.Clear(); - rootContextName = null; - ConfigurationUtils.RefreshSection(AbstractApplicationContext.ContextSectionName); - if (Cleared != null) - { - Cleared(typeof(ContextRegistry), EventArgs.Empty); - } - } - } - - /// - /// Allows to check, if a context is already registered - /// - /// The context name. - /// true, if the context is already registered. false otherwise - public static bool IsContextRegistered( string name ) - { - lock (instance) - { - return (instance.contextMap[name] != null); - } - } - - private static bool rootContextCurrentlyInCreation; - - private static void InitializeContextIfNeeded() - { - if (rootContextName == null) - { - if (rootContextCurrentlyInCreation) - { - throw new InvalidOperationException("root context is currently in creation. You must not call ContextRegistry.GetContext() from e.g. constructors of your singleton objects"); - } - - rootContextCurrentlyInCreation = true; - try - { - ConfigurationUtils.GetSection(AbstractApplicationContext.ContextSectionName); - } - finally - { - rootContextCurrentlyInCreation = false; - } - } - } - } -} - +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Configuration; +using Common.Logging; + +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Provides access to a central registry of + /// s. + /// + /// + ///

+ /// A singleton implementation to access one or more application contexts. Application + /// context instances are cached. + ///

+ ///

Note that the use of this class or similar is unnecessary except (sometimes) for + /// a small amount of glue code. Excessive usage will lead to code that is more tightly + /// coupled, and harder to modify or test. Consider refactoring your code to use standard + /// Dependency Injection techniques or implement the interface IApplicationContextAware to + /// obtain a reference to an application context.

+ ///
+ /// Mark Pollack + /// Aleksandar Seovic + /// + public sealed class ContextRegistry + { + /// + /// The shared instance for this class (and derived classes). + /// + private static readonly ILog log = LogManager.GetLogger(typeof(ContextRegistry)); + + private static readonly object syncRoot = new Object(); + private static readonly ContextRegistry instance = new ContextRegistry(); + private static string rootContextName = null; + + private IDictionary contextMap = CollectionsUtil.CreateCaseInsensitiveHashtable(); + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the ContextRegistry class. + /// + /// + ///

+ /// Explicit static constructor to tell C# compiler + /// not to mark type as beforefieldinit. + ///

+ ///
+ static ContextRegistry() + {} + + // CLOVER:ON + + #endregion + + /// + /// This event is fired, if ContextRegistry.Clear() is called.
+ /// Clients may register to get informed + ///
+ /// + /// This event is fired while still holding a lock on the Registry.
+ /// 'sender' parameter is sent as typeof(ContextRegistry), EventArgs are not used + ///
+ public static event EventHandler Cleared; + + /// + /// Gets an object that should be used to synchronize access to ContextRegistry + /// from the calling code. + /// + public static object SyncRoot + { + get { return syncRoot; } + } + + /// + /// Registers an instance of an + /// . + /// + /// + ///

+ /// This is usually called via a + /// inside a .NET + /// application configuration file. + ///

+ ///
+ /// The application context to be registered. + /// + /// If a context has previously been registered using the same name + /// + public static void RegisterContext(IApplicationContext context) + { + lock (syncRoot) + { + if (instance.contextMap.Contains(context.Name)) + { + IApplicationContext ctx = (IApplicationContext)instance.contextMap[context.Name]; + throw new ApplicationContextException( + string.Format("Existing context '{0}' already registered under name '{1}'.", + ctx, context.Name)); + } + instance.contextMap[context.Name] = context; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(String.Format( + "Registering context '{0}' under name '{1}'.", context, context.Name)); + } + + #endregion + + if (rootContextName == null) + { + rootContextName = context.Name; + } + } + } + + /// + /// Returns the root application context. + /// + /// + ///

+ /// The first call to GetContext will create the context + /// as specified in the .NET application configuration file + /// under the location spring/context. + ///

+ ///
+ /// The root application context. + public static IApplicationContext GetContext() + { + lock (syncRoot) + { + InitializeContextIfNeeded(); + return GetContext(rootContextName); + } + } + + /// + /// Returns context based on specified name. + /// + /// + ///

+ /// The first call to GetContext will create the context + /// as specified in the .NET application configuration file + /// under the location spring/context. + ///

+ ///
+ /// The context name. + /// The specified context, or null, if context with that name doesn't exists. + /// + /// If the context name is null or empty + /// + public static IApplicationContext GetContext(string name) + { + if (StringUtils.IsNullOrEmpty(name)) + { + throw new ArgumentException( + "The context name passed to the GetContext method cannot be null or empty."); + } + else + { + lock (syncRoot) + { + InitializeContextIfNeeded(); + IApplicationContext ctx = (IApplicationContext)instance.contextMap[name]; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + if (ctx == null) + { + log.Debug(String.Format( + "No context registered under name '{0}'.", name)); + } + else + { + log.Debug(String.Format( + "Returning context '{0}' registered under name '{1}'.", ctx, name)); + } + } + + #endregion + + return ctx; + } + } + } + + /// + /// Removes all registered + /// s from this + /// registry. + /// + /// + /// Raises the event while still holding a lock on + /// + public static void Clear() + { + lock (syncRoot) + { + foreach (IApplicationContext ctx in instance.contextMap.Values) + { + ctx.Dispose(); + } + instance.contextMap.Clear(); + rootContextName = null; + ConfigurationUtils.RefreshSection(AbstractApplicationContext.ContextSectionName); + if (Cleared != null) + { + Cleared(typeof(ContextRegistry), EventArgs.Empty); + } + } + } + + /// + /// Allows to check, if a context is already registered + /// + /// The context name. + /// true, if the context is already registered. false otherwise + public static bool IsContextRegistered( string name ) + { + lock (instance) + { + return (instance.contextMap[name] != null); + } + } + + private static bool rootContextCurrentlyInCreation; + + private static void InitializeContextIfNeeded() + { + if (rootContextName == null) + { + if (rootContextCurrentlyInCreation) + { + throw new InvalidOperationException("root context is currently in creation. You must not call ContextRegistry.GetContext() from e.g. constructors of your singleton objects"); + } + + rootContextCurrentlyInCreation = true; + try + { + ConfigurationUtils.GetSection(AbstractApplicationContext.ContextSectionName); + } + finally + { + rootContextCurrentlyInCreation = false; + } + } + } + } +} + diff --git a/src/Spring/Spring.Core/Context/Support/DefaultMessageSourceResolvable.cs b/src/Spring/Spring.Core/Context/Support/DefaultMessageSourceResolvable.cs index d91942a8..5a4b19f9 100644 --- a/src/Spring/Spring.Core/Context/Support/DefaultMessageSourceResolvable.cs +++ b/src/Spring/Spring.Core/Context/Support/DefaultMessageSourceResolvable.cs @@ -1,227 +1,226 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Default implementation of the - /// interface. - /// - /// - ///

- /// Provides easy ways to store all the necessary values needed to resolve - /// messages from an . - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: DefaultMessageSourceResolvable.cs,v 1.4 2007/07/02 21:24:39 markpollack Exp $ - /// - [Serializable] - public class DefaultMessageSourceResolvable : IMessageSourceResolvable - { - private string[] codes; - private object[] arguments; - private string defaultMessage; - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class - /// using a single code. - /// - /// The message code to be resolved. - public DefaultMessageSourceResolvable(string code) - : this(new string[] {code}, StringUtils.EmptyStrings, string.Empty) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The codes to be used to resolve this message - public DefaultMessageSourceResolvable(string[] codes) - : this(codes, StringUtils.EmptyStrings, string.Empty) - { - } - - /// - /// Creates a new instance of the - /// class - /// using multiple codes. - /// - /// The message codes to be resolved. - /// - /// The arguments used to resolve the supplied . - /// - public DefaultMessageSourceResolvable(string[] codes, object[] arguments) - : this(codes, arguments, string.Empty) - { - } - - /// - /// Creates a new instance of the - /// class - /// using multiple codes and a default message. - /// - /// The message codes to be resolved. - /// - /// The arguments used to resolve the supplied . - /// - /// - /// The default message used if no code could be resolved. - /// - public DefaultMessageSourceResolvable( - string[] codes, object[] arguments, string defaultMessage) - { - this.codes = codes; - this.arguments = arguments; - this.defaultMessage = defaultMessage; - } - - /// - /// Creates a new instance of the - /// class - /// from another resolvable. - /// - /// - ///

- /// This is the copy constructor for the - /// class. - ///

- ///
- /// - /// The to be copied. - /// - /// - /// If the supplied is . - /// - public DefaultMessageSourceResolvable(IMessageSourceResolvable resolvable) - : this(resolvable.GetCodes(), resolvable.GetArguments(), resolvable.DefaultMessage) - { - } - - #endregion - - /// - /// Return the default code for this resolvable. - /// - /// - /// The default code of this resolvable; this will be the last code in - /// the codes array, or if this instance has no - /// codes. - /// - /// - public string LastCode - { - get - { - if (codes != null && codes.Length > 0) - { - return codes[codes.Length - 1]; - } - else - { - return null; - } - } - } - - /// - /// Returns a representation of this - /// . - /// - /// - /// A representation of this - /// . - /// - public override string ToString() - { - return Accept(new MessageSourceResolvableVisitor()); - } - - /// - /// Calls the visit method on the supplied - /// to output a version of this class. - /// - /// The visitor to use. - /// - /// A representation of this - /// . - /// - public string Accept(MessageSourceResolvableVisitor visitor) - { - return visitor.VisitMessageSourceResolvableString(this); - } - - #region IMessageSourceResolvable Members - - /// - /// Return the codes to be used to resolve this message, in the order - /// that they are to be tried. - /// - /// - /// A array of codes which are associated - /// with this message. - /// - /// - public string[] GetCodes() - { - return codes; - } - - /// - /// Return the array of arguments to be used to resolve this message. - /// - /// - /// An array of objects to be used as parameters to replace - /// placeholders within the message text. - /// - /// - public object[] GetArguments() - { - return arguments; - } - - /// - /// Return the default message to be used to resolve this message. - /// - /// - /// The default message, or if there is no - /// default. - /// - /// - public string DefaultMessage - { - get { return defaultMessage; } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Default implementation of the + /// interface. + /// + /// + ///

+ /// Provides easy ways to store all the necessary values needed to resolve + /// messages from an . + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// + [Serializable] + public class DefaultMessageSourceResolvable : IMessageSourceResolvable + { + private string[] codes; + private object[] arguments; + private string defaultMessage; + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class + /// using a single code. + /// + /// The message code to be resolved. + public DefaultMessageSourceResolvable(string code) + : this(new string[] {code}, StringUtils.EmptyStrings, string.Empty) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The codes to be used to resolve this message + public DefaultMessageSourceResolvable(string[] codes) + : this(codes, StringUtils.EmptyStrings, string.Empty) + { + } + + /// + /// Creates a new instance of the + /// class + /// using multiple codes. + /// + /// The message codes to be resolved. + /// + /// The arguments used to resolve the supplied . + /// + public DefaultMessageSourceResolvable(string[] codes, object[] arguments) + : this(codes, arguments, string.Empty) + { + } + + /// + /// Creates a new instance of the + /// class + /// using multiple codes and a default message. + /// + /// The message codes to be resolved. + /// + /// The arguments used to resolve the supplied . + /// + /// + /// The default message used if no code could be resolved. + /// + public DefaultMessageSourceResolvable( + string[] codes, object[] arguments, string defaultMessage) + { + this.codes = codes; + this.arguments = arguments; + this.defaultMessage = defaultMessage; + } + + /// + /// Creates a new instance of the + /// class + /// from another resolvable. + /// + /// + ///

+ /// This is the copy constructor for the + /// class. + ///

+ ///
+ /// + /// The to be copied. + /// + /// + /// If the supplied is . + /// + public DefaultMessageSourceResolvable(IMessageSourceResolvable resolvable) + : this(resolvable.GetCodes(), resolvable.GetArguments(), resolvable.DefaultMessage) + { + } + + #endregion + + /// + /// Return the default code for this resolvable. + /// + /// + /// The default code of this resolvable; this will be the last code in + /// the codes array, or if this instance has no + /// codes. + /// + /// + public string LastCode + { + get + { + if (codes != null && codes.Length > 0) + { + return codes[codes.Length - 1]; + } + else + { + return null; + } + } + } + + /// + /// Returns a representation of this + /// . + /// + /// + /// A representation of this + /// . + /// + public override string ToString() + { + return Accept(new MessageSourceResolvableVisitor()); + } + + /// + /// Calls the visit method on the supplied + /// to output a version of this class. + /// + /// The visitor to use. + /// + /// A representation of this + /// . + /// + public string Accept(MessageSourceResolvableVisitor visitor) + { + return visitor.VisitMessageSourceResolvableString(this); + } + + #region IMessageSourceResolvable Members + + /// + /// Return the codes to be used to resolve this message, in the order + /// that they are to be tried. + /// + /// + /// A array of codes which are associated + /// with this message. + /// + /// + public string[] GetCodes() + { + return codes; + } + + /// + /// Return the array of arguments to be used to resolve this message. + /// + /// + /// An array of objects to be used as parameters to replace + /// placeholders within the message text. + /// + /// + public object[] GetArguments() + { + return arguments; + } + + /// + /// Return the default message to be used to resolve this message. + /// + /// + /// The default message, or if there is no + /// default. + /// + /// + public string DefaultMessage + { + get { return defaultMessage; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/DefaultSectionHandler.cs b/src/Spring/Spring.Core/Context/Support/DefaultSectionHandler.cs index 4fccf4c2..4edd4f95 100644 --- a/src/Spring/Spring.Core/Context/Support/DefaultSectionHandler.cs +++ b/src/Spring/Spring.Core/Context/Support/DefaultSectionHandler.cs @@ -1,65 +1,64 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Configuration; -using System.Xml; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Default section handler that can handle any configuration section. - /// - /// - ///

- /// Simply returns the configuration section as an . - ///

- ///
- /// Aleksandar Seovic - /// $Id: DefaultSectionHandler.cs,v 1.4 2006/04/09 07:18:38 markpollack Exp $ - public class DefaultSectionHandler : IConfigurationSectionHandler - { - #region Methods - /// - /// Returns the configuration section as an - /// - /// - /// The configuration settings in a corresponding parent - /// configuration section. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is a null reference. - /// - /// - /// The for the section. - /// - /// Config section as XmlElement. - public object Create(object parent, object configContext, XmlNode section) - { - return section as XmlElement; - } - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Configuration; +using System.Xml; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Default section handler that can handle any configuration section. + /// + /// + ///

+ /// Simply returns the configuration section as an . + ///

+ ///
+ /// Aleksandar Seovic + public class DefaultSectionHandler : IConfigurationSectionHandler + { + #region Methods + /// + /// Returns the configuration section as an + /// + /// + /// The configuration settings in a corresponding parent + /// configuration section. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is a null reference. + /// + /// + /// The for the section. + /// + /// Config section as XmlElement. + public object Create(object parent, object configContext, XmlNode section) + { + return section as XmlElement; + } + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/DelegatingMessageSource.cs b/src/Spring/Spring.Core/Context/Support/DelegatingMessageSource.cs index da5a3f8a..ae36b50c 100644 --- a/src/Spring/Spring.Core/Context/Support/DelegatingMessageSource.cs +++ b/src/Spring/Spring.Core/Context/Support/DelegatingMessageSource.cs @@ -1,387 +1,386 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Globalization; - -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Empty implementation that - /// simply delegates all method calls to it's parent - /// . - /// - /// - ///

- /// If no parent is available, - /// no messages will be resolved (and a - /// will be thrown). - ///

- ///

- /// Used as placeholder by the - /// class, - /// if the context definition doesn't define its own - /// . Not intended for direct use - /// in applications. - ///

- ///
- /// Juergan Hoeller - /// Rick Evans (.NET) - /// $Id: DelegatingMessageSource.cs,v 1.5 2007/07/02 21:24:39 markpollack Exp $ - /// - public class DelegatingMessageSource : IHierarchicalMessageSource - { - #region Fields - - private IMessageSource _parentMessageSource; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public DelegatingMessageSource() - {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The parent message source used to try and resolve messages that - /// this object can't resolve. - /// - public DelegatingMessageSource(IMessageSource parentMessageSource) - { - ParentMessageSource = parentMessageSource; - } - - #endregion - - #region Properties - - /// - /// The parent message source used to try and resolve messages that - /// this object can't resolve. - /// - /// - public IMessageSource ParentMessageSource - { - get - { - if (_parentMessageSource == null) - { - _parentMessageSource = new SpecialCaseNullMessageSource(); - } - return _parentMessageSource; - } - set { _parentMessageSource = value; } - } - - #endregion - - #region Methods - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(string name) - { - return ParentMessageSource.GetMessage(name); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(string name, params object[] arguments) - { - return ParentMessageSource.GetMessage(name, arguments); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(string name, CultureInfo culture) - { - return ParentMessageSource.GetMessage(name, culture); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(string name, CultureInfo culture, params object[] arguments) - { - return ParentMessageSource.GetMessage(name, culture, arguments); - } - - /// - /// Resolve the message identified by the supplied - /// . - /// - /// The name of the message to resolve. - /// The default message. - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The array of arguments that will be filled in for parameters within - /// the message, or if there are no parameters - /// within the message. Parameters within a message should be - /// referenced using the same syntax as the format string for the - /// method. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) - { - return ParentMessageSource.GetMessage(name, defaultMessage, culture, arguments); - } - - /// - /// Resolve the message using all of the attributes contained within - /// the supplied - /// argument. - /// - /// - /// The value object storing those attributes that are required to - /// properly resolve a message. - /// - /// - /// The that represents - /// the culture for which the resource is localized. - /// - /// - /// The resolved message if the lookup was successful (see above for - /// the return value in the case of an unsuccessful lookup). - /// - /// - /// If the message could not be resolved. - /// - /// - /// If the message could not be resolved. - /// - /// - public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) - { - return ParentMessageSource.GetMessage(resolvable, culture); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The resolved object, or if not found. - /// - /// - public object GetResourceObject(string name) - { - return ParentMessageSource.GetResourceObject(name); - } - - /// - /// Gets a localized resource object identified by the supplied - /// . - /// - /// - /// The name of the resource object to resolve. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - /// The resolved object, or if not found. - /// - /// - public object GetResourceObject(string name, CultureInfo culture) - { - return ParentMessageSource.GetResourceObject(name, culture); - } - - /// - /// Applies resources to object properties. - /// - /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - public void ApplyResources(object value, string objectName, CultureInfo culture) - { - ParentMessageSource.ApplyResources(value, objectName, culture); - } - - #endregion - - #region Inner Class : SpecialCaseNullMessageSource - - private sealed class SpecialCaseNullMessageSource : IMessageSource - { - public string GetMessage(string name) - { - return GetMessage(name, (object[]) null); - } - - public string GetMessage(string name, params object[] arguments) - { - return GetMessage(name, CultureInfo.CurrentUICulture, null); - } - - public string GetMessage(string name, CultureInfo culture) - { - return GetMessage(name, culture, null); - } - - public string GetMessage(string name, CultureInfo culture, params object[] arguments) - { - throw new NoSuchMessageException(name, culture); - } - - public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) - { - throw new NoSuchMessageException(name, culture); - } - - - public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) - { - if (StringUtils.HasText(resolvable.DefaultMessage)) - { - return resolvable.DefaultMessage; - } - string[] codes = resolvable.GetCodes(); - string code = (codes != null && codes.Length > 0 ? codes[0] : string.Empty); - throw new NoSuchMessageException(code, culture); - } - - public object GetResourceObject(string name) - { - return GetResourceObject(name, CultureInfo.CurrentUICulture); - } - - public object GetResourceObject(string name, CultureInfo culture) - { - throw new ApplicationContextException( - string.Format( - "Cannot lookup the named resource '{0}' for locale '{1}' " + - ": no IMessageSource in context.", - name, culture)); - } - - public void ApplyResources(object value, string objectName, CultureInfo culture) - { - throw new ApplicationContextException( - string.Format( - "Cannot apply [{0}] resource to object '{1}' for locale '{2}' " + - ": no IMessageSource in context.", - value, objectName, culture)); - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Globalization; + +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Empty implementation that + /// simply delegates all method calls to it's parent + /// . + /// + /// + ///

+ /// If no parent is available, + /// no messages will be resolved (and a + /// will be thrown). + ///

+ ///

+ /// Used as placeholder by the + /// class, + /// if the context definition doesn't define its own + /// . Not intended for direct use + /// in applications. + ///

+ ///
+ /// Juergan Hoeller + /// Rick Evans (.NET) + /// + public class DelegatingMessageSource : IHierarchicalMessageSource + { + #region Fields + + private IMessageSource _parentMessageSource; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public DelegatingMessageSource() + {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The parent message source used to try and resolve messages that + /// this object can't resolve. + /// + public DelegatingMessageSource(IMessageSource parentMessageSource) + { + ParentMessageSource = parentMessageSource; + } + + #endregion + + #region Properties + + /// + /// The parent message source used to try and resolve messages that + /// this object can't resolve. + /// + /// + public IMessageSource ParentMessageSource + { + get + { + if (_parentMessageSource == null) + { + _parentMessageSource = new SpecialCaseNullMessageSource(); + } + return _parentMessageSource; + } + set { _parentMessageSource = value; } + } + + #endregion + + #region Methods + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(string name) + { + return ParentMessageSource.GetMessage(name); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(string name, params object[] arguments) + { + return ParentMessageSource.GetMessage(name, arguments); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(string name, CultureInfo culture) + { + return ParentMessageSource.GetMessage(name, culture); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(string name, CultureInfo culture, params object[] arguments) + { + return ParentMessageSource.GetMessage(name, culture, arguments); + } + + /// + /// Resolve the message identified by the supplied + /// . + /// + /// The name of the message to resolve. + /// The default message. + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The array of arguments that will be filled in for parameters within + /// the message, or if there are no parameters + /// within the message. Parameters within a message should be + /// referenced using the same syntax as the format string for the + /// method. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) + { + return ParentMessageSource.GetMessage(name, defaultMessage, culture, arguments); + } + + /// + /// Resolve the message using all of the attributes contained within + /// the supplied + /// argument. + /// + /// + /// The value object storing those attributes that are required to + /// properly resolve a message. + /// + /// + /// The that represents + /// the culture for which the resource is localized. + /// + /// + /// The resolved message if the lookup was successful (see above for + /// the return value in the case of an unsuccessful lookup). + /// + /// + /// If the message could not be resolved. + /// + /// + /// If the message could not be resolved. + /// + /// + public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) + { + return ParentMessageSource.GetMessage(resolvable, culture); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The resolved object, or if not found. + /// + /// + public object GetResourceObject(string name) + { + return ParentMessageSource.GetResourceObject(name); + } + + /// + /// Gets a localized resource object identified by the supplied + /// . + /// + /// + /// The name of the resource object to resolve. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + /// The resolved object, or if not found. + /// + /// + public object GetResourceObject(string name, CultureInfo culture) + { + return ParentMessageSource.GetResourceObject(name, culture); + } + + /// + /// Applies resources to object properties. + /// + /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + public void ApplyResources(object value, string objectName, CultureInfo culture) + { + ParentMessageSource.ApplyResources(value, objectName, culture); + } + + #endregion + + #region Inner Class : SpecialCaseNullMessageSource + + private sealed class SpecialCaseNullMessageSource : IMessageSource + { + public string GetMessage(string name) + { + return GetMessage(name, (object[]) null); + } + + public string GetMessage(string name, params object[] arguments) + { + return GetMessage(name, CultureInfo.CurrentUICulture, null); + } + + public string GetMessage(string name, CultureInfo culture) + { + return GetMessage(name, culture, null); + } + + public string GetMessage(string name, CultureInfo culture, params object[] arguments) + { + throw new NoSuchMessageException(name, culture); + } + + public string GetMessage(string name, string defaultMessage, CultureInfo culture, params object[] arguments) + { + throw new NoSuchMessageException(name, culture); + } + + + public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture) + { + if (StringUtils.HasText(resolvable.DefaultMessage)) + { + return resolvable.DefaultMessage; + } + string[] codes = resolvable.GetCodes(); + string code = (codes != null && codes.Length > 0 ? codes[0] : string.Empty); + throw new NoSuchMessageException(code, culture); + } + + public object GetResourceObject(string name) + { + return GetResourceObject(name, CultureInfo.CurrentUICulture); + } + + public object GetResourceObject(string name, CultureInfo culture) + { + throw new ApplicationContextException( + string.Format( + "Cannot lookup the named resource '{0}' for locale '{1}' " + + ": no IMessageSource in context.", + name, culture)); + } + + public void ApplyResources(object value, string objectName, CultureInfo culture) + { + throw new ApplicationContextException( + string.Format( + "Cannot apply [{0}] resource to object '{1}' for locale '{2}' " + + ": no IMessageSource in context.", + value, objectName, culture)); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs index 935382fa..eeb91b87 100644 --- a/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs @@ -1,259 +1,258 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Core.IO; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Util; - -namespace Spring.Context.Support -{ - /// - /// Generic ApplicationContext implementation that holds a single internal - /// instance and does not - /// assume a specific object definition format. - /// - /// - /// Implements the interface in order - /// to allow for aplying any object definition readers to it. - /// Typical usage is to register a variety of object definitions via the - /// interface and then call - /// to initialize those - /// objects with application context semantics (handling - /// , auto-detecting - /// ObjectFactoryPostProcessors, etc). - /// - /// In contrast to other IApplicationContext implementations that create a new internal - /// IObjectFactory instance for each refresh, the internal IObjectFactory of this context - /// is available right from the start, to be able to register object definitions on it. - /// may only be called once - /// Usage examples - /// - /// GenericApplicationContext ctx = new GenericApplicationContext(); - /// - /// - /// - /// Mark Pollack - /// $Id: GenericApplicationContext.cs,v 1.5 2008/02/17 13:34:44 markpollack Exp $ - public class GenericApplicationContext : AbstractApplicationContext, IObjectDefinitionRegistry - { - private DefaultListableObjectFactory objectFactory; - - private bool refreshed = false; - - - /// - /// Initializes a new instance of the class. - /// - public GenericApplicationContext() - { - objectFactory = new DefaultListableObjectFactory(); - } - - /// - /// Initializes a new instance of the class. - /// - /// if set to true names in the context are case sensitive. - public GenericApplicationContext(bool caseSensitive) - { - objectFactory = new DefaultListableObjectFactory(caseSensitive); - } - - - /// - /// Initializes a new instance of the class. - /// - /// The object factory instance to use for this context. - public GenericApplicationContext(DefaultListableObjectFactory objectFactory) - { - AssertUtils.ArgumentNotNull(objectFactory, "objectFactory", "ObjectFactory must not be null"); - this.objectFactory = objectFactory; - } - - - /// - /// Initializes a new instance of the class. - /// - /// The parent application context. - public GenericApplicationContext(IApplicationContext parent) - { - objectFactory = new DefaultListableObjectFactory(); - ParentContext = parent; - } - - - /// - /// Initializes a new instance of the class. - /// - /// The name of the application context. - /// if set to true names in the context are case sensitive. - /// The parent application context. - public GenericApplicationContext(string name, bool caseSensitive, IApplicationContext parent) : this(caseSensitive) - { - Name = name; - ParentContext = parent; - } - - - /// - /// Initializes a new instance of the class. - /// - /// The object factory to use for this context - /// The parent applicaiton context. - public GenericApplicationContext(DefaultListableObjectFactory objectFactory, IApplicationContext parent) : this(objectFactory) - { - ParentContext = parent; - } - - - - /// - /// Gets the parent context, or if there is no - /// parent context. Set the parent of this application context also setting - /// the parent of the interanl ObjectFactory accordingly. - /// - /// The parent context - /// - /// The parent context, or if there is no - /// parent. - /// - /// - public override IApplicationContext ParentContext - { - get - { - return base.ParentContext; - } - set { - base.ParentContext = value; - objectFactory.ParentObjectFactory = GetInternalParentObjectFactory(); - } - } - - - /// - /// Do nothing operation. We hold a single internal ObjectFactory and rely on callers - /// to register objects throug our public methods (or the ObjectFactory's). - /// - /// - /// In the case of errors encountered while refreshing the object factory. - /// - protected override void RefreshObjectFactory() - { - if (refreshed) - { - throw new InvalidOperationException( - "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); - } - - refreshed = true; - } - - /// - /// Return the internal object factory of this application context. - /// - /// - public override IConfigurableListableObjectFactory ObjectFactory - { - get { return objectFactory; } - } - - /// - /// Gets the underlying object factory of this context, available for - /// registering object definitions. - /// - /// You need to call Refresh to initialize the - /// objects factory and its contained objects with application context - /// semantics (autodecting IObjectFactoryPostProcessors, etc). - /// The internal object factory (as DefaultListableObjectFactory). - public DefaultListableObjectFactory DefaultListableObjectFactory - { - get { return objectFactory; } - } - - - - #region IObjectDefinitionRegistry Members - - /// - /// Returns the - /// - /// for the given object name. - /// - /// The name of the object to find a definition for. - /// - /// The for - /// the given name (never null). - /// - /// - /// If the object definition cannot be resolved. - /// - /// - /// In case of errors. - /// - public override IObjectDefinition GetObjectDefinition(string name) - { - return objectFactory.GetObjectDefinition(name); - } - - /// - /// Register a new object definition with this registry. - /// Must support - /// - /// and . - /// - /// The name of the object instance to register. - /// The definition of the object instance to register. - /// - ///

- /// Must support - /// and - /// . - ///

- ///
- /// - /// If the object definition is invalid. - /// - public void RegisterObjectDefinition(string name, IObjectDefinition definition) - { - objectFactory.RegisterObjectDefinition(name, definition); - } - - /// - /// Given a object name, create an alias. We typically use this method to - /// support names that are illegal within XML ids (used for object names). - /// - /// The name of the object. - /// The alias that will behave the same as the object name. - /// - /// If there is no object with the given name. - /// - /// - /// If the alias is already in use. - /// - public void RegisterAlias(string name, string theAlias) - { - objectFactory.RegisterAlias(name, theAlias); - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Core.IO; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Util; + +namespace Spring.Context.Support +{ + /// + /// Generic ApplicationContext implementation that holds a single internal + /// instance and does not + /// assume a specific object definition format. + /// + /// + /// Implements the interface in order + /// to allow for aplying any object definition readers to it. + /// Typical usage is to register a variety of object definitions via the + /// interface and then call + /// to initialize those + /// objects with application context semantics (handling + /// , auto-detecting + /// ObjectFactoryPostProcessors, etc). + /// + /// In contrast to other IApplicationContext implementations that create a new internal + /// IObjectFactory instance for each refresh, the internal IObjectFactory of this context + /// is available right from the start, to be able to register object definitions on it. + /// may only be called once + /// Usage examples + /// + /// GenericApplicationContext ctx = new GenericApplicationContext(); + /// + /// + /// + /// Mark Pollack + public class GenericApplicationContext : AbstractApplicationContext, IObjectDefinitionRegistry + { + private DefaultListableObjectFactory objectFactory; + + private bool refreshed = false; + + + /// + /// Initializes a new instance of the class. + /// + public GenericApplicationContext() + { + objectFactory = new DefaultListableObjectFactory(); + } + + /// + /// Initializes a new instance of the class. + /// + /// if set to true names in the context are case sensitive. + public GenericApplicationContext(bool caseSensitive) + { + objectFactory = new DefaultListableObjectFactory(caseSensitive); + } + + + /// + /// Initializes a new instance of the class. + /// + /// The object factory instance to use for this context. + public GenericApplicationContext(DefaultListableObjectFactory objectFactory) + { + AssertUtils.ArgumentNotNull(objectFactory, "objectFactory", "ObjectFactory must not be null"); + this.objectFactory = objectFactory; + } + + + /// + /// Initializes a new instance of the class. + /// + /// The parent application context. + public GenericApplicationContext(IApplicationContext parent) + { + objectFactory = new DefaultListableObjectFactory(); + ParentContext = parent; + } + + + /// + /// Initializes a new instance of the class. + /// + /// The name of the application context. + /// if set to true names in the context are case sensitive. + /// The parent application context. + public GenericApplicationContext(string name, bool caseSensitive, IApplicationContext parent) : this(caseSensitive) + { + Name = name; + ParentContext = parent; + } + + + /// + /// Initializes a new instance of the class. + /// + /// The object factory to use for this context + /// The parent applicaiton context. + public GenericApplicationContext(DefaultListableObjectFactory objectFactory, IApplicationContext parent) : this(objectFactory) + { + ParentContext = parent; + } + + + + /// + /// Gets the parent context, or if there is no + /// parent context. Set the parent of this application context also setting + /// the parent of the interanl ObjectFactory accordingly. + /// + /// The parent context + /// + /// The parent context, or if there is no + /// parent. + /// + /// + public override IApplicationContext ParentContext + { + get + { + return base.ParentContext; + } + set { + base.ParentContext = value; + objectFactory.ParentObjectFactory = GetInternalParentObjectFactory(); + } + } + + + /// + /// Do nothing operation. We hold a single internal ObjectFactory and rely on callers + /// to register objects throug our public methods (or the ObjectFactory's). + /// + /// + /// In the case of errors encountered while refreshing the object factory. + /// + protected override void RefreshObjectFactory() + { + if (refreshed) + { + throw new InvalidOperationException( + "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); + } + + refreshed = true; + } + + /// + /// Return the internal object factory of this application context. + /// + /// + public override IConfigurableListableObjectFactory ObjectFactory + { + get { return objectFactory; } + } + + /// + /// Gets the underlying object factory of this context, available for + /// registering object definitions. + /// + /// You need to call Refresh to initialize the + /// objects factory and its contained objects with application context + /// semantics (autodecting IObjectFactoryPostProcessors, etc). + /// The internal object factory (as DefaultListableObjectFactory). + public DefaultListableObjectFactory DefaultListableObjectFactory + { + get { return objectFactory; } + } + + + + #region IObjectDefinitionRegistry Members + + /// + /// Returns the + /// + /// for the given object name. + /// + /// The name of the object to find a definition for. + /// + /// The for + /// the given name (never null). + /// + /// + /// If the object definition cannot be resolved. + /// + /// + /// In case of errors. + /// + public override IObjectDefinition GetObjectDefinition(string name) + { + return objectFactory.GetObjectDefinition(name); + } + + /// + /// Register a new object definition with this registry. + /// Must support + /// + /// and . + /// + /// The name of the object instance to register. + /// The definition of the object instance to register. + /// + ///

+ /// Must support + /// and + /// . + ///

+ ///
+ /// + /// If the object definition is invalid. + /// + public void RegisterObjectDefinition(string name, IObjectDefinition definition) + { + objectFactory.RegisterObjectDefinition(name, definition); + } + + /// + /// Given a object name, create an alias. We typically use this method to + /// support names that are illegal within XML ids (used for object names). + /// + /// The name of the object. + /// The alias that will behave the same as the object name. + /// + /// If there is no object with the given name. + /// + /// + /// If the alias is already in use. + /// + public void RegisterAlias(string name, string theAlias) + { + objectFactory.RegisterAlias(name, theAlias); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/MessageSourceAccessor.cs b/src/Spring/Spring.Core/Context/Support/MessageSourceAccessor.cs index b44f50c8..0de33b21 100644 --- a/src/Spring/Spring.Core/Context/Support/MessageSourceAccessor.cs +++ b/src/Spring/Spring.Core/Context/Support/MessageSourceAccessor.cs @@ -1,188 +1,187 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Helper class for easy access to messages from an - /// , providing various - /// overloaded GetMessage methods. - /// - /// - ///

- /// Available from - /// , but also - /// reusable as a standalone helper to delegate to in application objects. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: MessageSourceAccessor.cs,v 1.8 2007/08/23 14:30:50 oakinger Exp $ - /// - /// - public class MessageSourceAccessor - { - private IMessageSource _messageSource; - private CultureInfo _defaultCultureInfo; - - /// - /// Creates a new instance of the - /// class - /// that uses the current - /// for all locale specific lookups. - /// - /// - /// The to use to locate messages. - /// - public MessageSourceAccessor(IMessageSource messageSource) - : this(messageSource, CultureInfo.CurrentUICulture) - { - } - - /// - /// Creates a new instance of the - /// class - /// - /// - /// The to use to locate - /// messages. - /// - /// - /// The to use for - /// locale specific messages. - /// - public MessageSourceAccessor( - IMessageSource messageSource, CultureInfo cultureInfo) - { - _messageSource = messageSource; - _defaultCultureInfo = cultureInfo; - } - - /// - /// Retrieve the message for the given code and the default - /// . - /// - /// The code of the message. - /// The message. - public string GetMessage(string code) - { - return _messageSource.GetMessage(code, _defaultCultureInfo); - } - - /// - /// Retrieve the message for the given code and the given - /// . - /// - /// The code of the message. - /// - /// The to use for - /// lookups. - /// - /// The message. - public string GetMessage(string code, CultureInfo cultureInfo) - { - return _messageSource.GetMessage(code, cultureInfo); - } - - /// - /// Retrieve the message for the given code and the default - /// . - /// - /// The code of the message. - /// - /// The arguments for the message, or if none. - /// - /// The message. - /// - /// If the message could not be found. - /// - public string GetMessage(string code, params object[] args) - { - return _messageSource.GetMessage(code, _defaultCultureInfo, args); - } - - /// - /// Retrieve the message for the given code and the given - /// . - /// - /// The code of the message. - /// - /// The to use for - /// lookups. - /// - /// - /// The arguments for the message, or if none. - /// - /// The message. - /// - /// If the message could not be found. - /// - public string GetMessage( - string code, CultureInfo cultureInfo, params object[] args) - { - return _messageSource.GetMessage(code, cultureInfo, args); - } - - /// - /// Retrieve a mesage using the given - /// . - /// - /// - /// The . - /// - /// The message. - /// - /// If the message could not be found. - /// - public string GetMessage(IMessageSourceResolvable resolvable) - { - return GetMessage(resolvable, _defaultCultureInfo); - } - - /// - /// Retrieve a mesage using the given - /// in the given - /// . - /// - /// - /// The . - /// - /// - /// The to use for - /// lookups. - /// - /// The message - /// - /// If the message could not be found. - /// - public string GetMessage( - IMessageSourceResolvable resolvable, CultureInfo cultureInfo) - { - return _messageSource.GetMessage(resolvable, cultureInfo); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Helper class for easy access to messages from an + /// , providing various + /// overloaded GetMessage methods. + /// + /// + ///

+ /// Available from + /// , but also + /// reusable as a standalone helper to delegate to in application objects. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// + /// + public class MessageSourceAccessor + { + private IMessageSource _messageSource; + private CultureInfo _defaultCultureInfo; + + /// + /// Creates a new instance of the + /// class + /// that uses the current + /// for all locale specific lookups. + /// + /// + /// The to use to locate messages. + /// + public MessageSourceAccessor(IMessageSource messageSource) + : this(messageSource, CultureInfo.CurrentUICulture) + { + } + + /// + /// Creates a new instance of the + /// class + /// + /// + /// The to use to locate + /// messages. + /// + /// + /// The to use for + /// locale specific messages. + /// + public MessageSourceAccessor( + IMessageSource messageSource, CultureInfo cultureInfo) + { + _messageSource = messageSource; + _defaultCultureInfo = cultureInfo; + } + + /// + /// Retrieve the message for the given code and the default + /// . + /// + /// The code of the message. + /// The message. + public string GetMessage(string code) + { + return _messageSource.GetMessage(code, _defaultCultureInfo); + } + + /// + /// Retrieve the message for the given code and the given + /// . + /// + /// The code of the message. + /// + /// The to use for + /// lookups. + /// + /// The message. + public string GetMessage(string code, CultureInfo cultureInfo) + { + return _messageSource.GetMessage(code, cultureInfo); + } + + /// + /// Retrieve the message for the given code and the default + /// . + /// + /// The code of the message. + /// + /// The arguments for the message, or if none. + /// + /// The message. + /// + /// If the message could not be found. + /// + public string GetMessage(string code, params object[] args) + { + return _messageSource.GetMessage(code, _defaultCultureInfo, args); + } + + /// + /// Retrieve the message for the given code and the given + /// . + /// + /// The code of the message. + /// + /// The to use for + /// lookups. + /// + /// + /// The arguments for the message, or if none. + /// + /// The message. + /// + /// If the message could not be found. + /// + public string GetMessage( + string code, CultureInfo cultureInfo, params object[] args) + { + return _messageSource.GetMessage(code, cultureInfo, args); + } + + /// + /// Retrieve a mesage using the given + /// . + /// + /// + /// The . + /// + /// The message. + /// + /// If the message could not be found. + /// + public string GetMessage(IMessageSourceResolvable resolvable) + { + return GetMessage(resolvable, _defaultCultureInfo); + } + + /// + /// Retrieve a mesage using the given + /// in the given + /// . + /// + /// + /// The . + /// + /// + /// The to use for + /// lookups. + /// + /// The message + /// + /// If the message could not be found. + /// + public string GetMessage( + IMessageSourceResolvable resolvable, CultureInfo cultureInfo) + { + return _messageSource.GetMessage(resolvable, cultureInfo); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/MessageSourceResolvableVisitor.cs b/src/Spring/Spring.Core/Context/Support/MessageSourceResolvableVisitor.cs index fb579548..afa02165 100644 --- a/src/Spring/Spring.Core/Context/Support/MessageSourceResolvableVisitor.cs +++ b/src/Spring/Spring.Core/Context/Support/MessageSourceResolvableVisitor.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Visitor class to represent - /// instances. - /// - /// - ///

- /// Used in the first instance to supply stringified versions of - /// instances. - ///

- ///

- /// Other methods can be added here to return different representations, - /// including XML, CSV, etc.. - ///

- ///
- /// Griffin Caprio (.NET) - /// $Id: MessageSourceResolvableVisitor.cs,v 1.6 2006/04/09 07:18:38 markpollack Exp $ - public class MessageSourceResolvableVisitor - { - /// - /// Creates a new instance of the - /// class. - /// - public MessageSourceResolvableVisitor() - { - } - - /// - /// Outputs the supplied - /// as a nicely formatted . - /// - /// - /// The to output. - /// - public string VisitMessageSourceResolvableString( - IMessageSourceResolvable resolvable) - { - StringBuilder builder = new StringBuilder(); - builder.Append("codes=["); - builder.Append(StringUtils.ArrayToDelimitedString(resolvable.GetCodes(), ",")); - builder.Append("]; arguments=["); - if (resolvable.GetArguments() == null) - { - builder.Append("null"); - } - else - { - object[] arguments = resolvable.GetArguments(); - for (int i = 0; i < arguments.Length; i++) - { - builder.Append("("); - builder.Append(arguments[i].GetType().Name); - builder.Append(")["); - builder.Append(arguments[i]); - builder.Append("]"); - if (i < arguments.Length - 1) - { - builder.Append(", "); - } - } - } - builder.Append("]; defaultMessage=["); - builder.Append(resolvable.DefaultMessage); - builder.Append("]"); - return builder.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Visitor class to represent + /// instances. + /// + /// + ///

+ /// Used in the first instance to supply stringified versions of + /// instances. + ///

+ ///

+ /// Other methods can be added here to return different representations, + /// including XML, CSV, etc.. + ///

+ ///
+ /// Griffin Caprio (.NET) + public class MessageSourceResolvableVisitor + { + /// + /// Creates a new instance of the + /// class. + /// + public MessageSourceResolvableVisitor() + { + } + + /// + /// Outputs the supplied + /// as a nicely formatted . + /// + /// + /// The to output. + /// + public string VisitMessageSourceResolvableString( + IMessageSourceResolvable resolvable) + { + StringBuilder builder = new StringBuilder(); + builder.Append("codes=["); + builder.Append(StringUtils.ArrayToDelimitedString(resolvable.GetCodes(), ",")); + builder.Append("]; arguments=["); + if (resolvable.GetArguments() == null) + { + builder.Append("null"); + } + else + { + object[] arguments = resolvable.GetArguments(); + for (int i = 0; i < arguments.Length; i++) + { + builder.Append("("); + builder.Append(arguments[i].GetType().Name); + builder.Append(")["); + builder.Append(arguments[i]); + builder.Append("]"); + if (i < arguments.Length - 1) + { + builder.Append(", "); + } + } + } + builder.Append("]; defaultMessage=["); + builder.Append(resolvable.DefaultMessage); + builder.Append("]"); + return builder.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/NamespaceParsersSectionHandler.cs b/src/Spring/Spring.Core/Context/Support/NamespaceParsersSectionHandler.cs index 0e7c7326..1dcbc5ac 100644 --- a/src/Spring/Spring.Core/Context/Support/NamespaceParsersSectionHandler.cs +++ b/src/Spring/Spring.Core/Context/Support/NamespaceParsersSectionHandler.cs @@ -1,139 +1,138 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Configuration; -using System.Globalization; -using System.Xml; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Objects; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Configuration section handler for the (recommended, Spring.NET standard) parsers - /// config section. - /// - /// - ///

- /// Spring.NET allows the registration of custom configuration parsers that - /// can be used to create simplified configuration schemas that better - /// describe object definitions. - ///

- ///

- /// For example, Spring.NET uses this facility internally in order to - /// define simplified schemas for various AOP, Data and Services definitions. - ///

- ///
- /// - ///

- /// The following example shows how to configure both this section handler - /// and how to define custom configuration parsers within a Spring.NET - /// config section. - ///

- /// - /// - /// - /// - ///
- /// - /// - /// - /// - /// - /// - /// ... - /// - /// ... - /// - /// - /// - /// - /// Aleksandar Seovic - /// $Id: NamespaceParsersSectionHandler.cs,v 1.1 2007/08/08 01:53:43 bbaia Exp $ - /// - public class NamespaceParsersSectionHandler : IConfigurationSectionHandler - { - private const string ParserElementName = "parser"; - private const string TypeAttributeName = "type"; - private const string NamespaceAttributeName = "namespace"; - private const string SchemaLocationAttributeName = "schemaLocation"; - - /// - /// Registers parsers specified in the (recommended, Spring.NET standard) - /// parsers config section with the . - /// - /// - /// The configuration settings in a corresponding parent - /// configuration section. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is . - /// - /// - /// The for the section. - /// - /// - /// This method always returns , because parsers - /// are registered as a side-effect of this object's execution and there - /// is thus no need to return anything. - /// - public object Create(object parent, object configContext, XmlNode section) - { - if (section != null) - { - XmlNodeList parsers = ((XmlElement)section).GetElementsByTagName(ParserElementName); - foreach (XmlElement parserElement in parsers) - { - string parserTypeName = GetRequiredAttributeValue(parserElement, TypeAttributeName, section); - string xmlNamespace = parserElement.GetAttribute(NamespaceAttributeName); - string schemaLocation = parserElement.GetAttribute(SchemaLocationAttributeName); - - Type parserType = TypeResolutionUtils.ResolveType(parserTypeName); - NamespaceParserRegistry.RegisterParser(parserType, xmlNamespace, schemaLocation); - } - } - return null; - } - - private static string GetRequiredAttributeValue( - XmlElement aliasElement, string requiredAttributeName, XmlNode section) - { - XmlAttribute attribute = aliasElement.GetAttributeNode(requiredAttributeName); - if (attribute == null) - { - string errorMessage = string.Format(CultureInfo.InvariantCulture, - "The '{0}' attribute is required for the element.", requiredAttributeName); - throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); - } - return attribute.Value; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Configuration; +using System.Globalization; +using System.Xml; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Objects; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Configuration section handler for the (recommended, Spring.NET standard) parsers + /// config section. + /// + /// + ///

+ /// Spring.NET allows the registration of custom configuration parsers that + /// can be used to create simplified configuration schemas that better + /// describe object definitions. + ///

+ ///

+ /// For example, Spring.NET uses this facility internally in order to + /// define simplified schemas for various AOP, Data and Services definitions. + ///

+ ///
+ /// + ///

+ /// The following example shows how to configure both this section handler + /// and how to define custom configuration parsers within a Spring.NET + /// config section. + ///

+ /// + /// + /// + /// + ///
+ /// + /// + /// + /// + /// + /// + /// ... + /// + /// ... + /// + /// + /// + /// + /// Aleksandar Seovic + /// + public class NamespaceParsersSectionHandler : IConfigurationSectionHandler + { + private const string ParserElementName = "parser"; + private const string TypeAttributeName = "type"; + private const string NamespaceAttributeName = "namespace"; + private const string SchemaLocationAttributeName = "schemaLocation"; + + /// + /// Registers parsers specified in the (recommended, Spring.NET standard) + /// parsers config section with the . + /// + /// + /// The configuration settings in a corresponding parent + /// configuration section. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is . + /// + /// + /// The for the section. + /// + /// + /// This method always returns , because parsers + /// are registered as a side-effect of this object's execution and there + /// is thus no need to return anything. + /// + public object Create(object parent, object configContext, XmlNode section) + { + if (section != null) + { + XmlNodeList parsers = ((XmlElement)section).GetElementsByTagName(ParserElementName); + foreach (XmlElement parserElement in parsers) + { + string parserTypeName = GetRequiredAttributeValue(parserElement, TypeAttributeName, section); + string xmlNamespace = parserElement.GetAttribute(NamespaceAttributeName); + string schemaLocation = parserElement.GetAttribute(SchemaLocationAttributeName); + + Type parserType = TypeResolutionUtils.ResolveType(parserTypeName); + NamespaceParserRegistry.RegisterParser(parserType, xmlNamespace, schemaLocation); + } + } + return null; + } + + private static string GetRequiredAttributeValue( + XmlElement aliasElement, string requiredAttributeName, XmlNode section) + { + XmlAttribute attribute = aliasElement.GetAttributeNode(requiredAttributeName); + if (attribute == null) + { + string errorMessage = string.Format(CultureInfo.InvariantCulture, + "The '{0}' attribute is required for the element.", requiredAttributeName); + throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); + } + return attribute.Value; + } + } +} diff --git a/src/Spring/Spring.Core/Context/Support/NullMessageSource.cs b/src/Spring/Spring.Core/Context/Support/NullMessageSource.cs index e9b691d7..9573aa1e 100644 --- a/src/Spring/Spring.Core/Context/Support/NullMessageSource.cs +++ b/src/Spring/Spring.Core/Context/Support/NullMessageSource.cs @@ -1,117 +1,116 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Globalization; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// An that doesn't do a whole lot. - /// - /// - ///

- /// is an implementation of - /// the NullObject pattern. It should be used in those situations where a - /// needs to be passed (say to a - /// method) but where the resolution of messages is not required. - ///

- ///

- /// There should not (typically) be a need to instantiate instances of this class; - /// does not maintan any state - /// and the instance is - /// thus safe to pass around. - ///

- ///
- /// Aleksandar Seovic - /// $Id: NullMessageSource.cs,v 1.5 2007/08/27 09:38:29 oakinger Exp $ - public sealed class NullMessageSource : AbstractMessageSource - { - /// - /// The canonical instance of the - /// class. - /// - public static readonly NullMessageSource Null = new NullMessageSource(); - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// Consider using - /// instead. - ///

- ///
- public NullMessageSource() - {} - - /// - /// Simply returns the supplied message as-is. - /// - /// The code of the message to resolve. - /// - /// The to resolve the - /// code for. - /// - /// - /// The supplied message as-is. - /// - protected override string ResolveMessage(string code, CultureInfo cultureInfo) - { - return code; - } - - /// - /// Always returns . - /// - /// The code of the object to resolve. - /// - /// The to resolve the - /// code for. - /// - /// - /// (always). - /// - protected override object ResolveObject(string code, CultureInfo cultureInfo) - { - return null; - } - - /// - /// Does nothing. - /// - /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - protected override void ApplyResourcesToObject( - object value, string objectName, CultureInfo cultureInfo) - {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Globalization; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// An that doesn't do a whole lot. + /// + /// + ///

+ /// is an implementation of + /// the NullObject pattern. It should be used in those situations where a + /// needs to be passed (say to a + /// method) but where the resolution of messages is not required. + ///

+ ///

+ /// There should not (typically) be a need to instantiate instances of this class; + /// does not maintan any state + /// and the instance is + /// thus safe to pass around. + ///

+ ///
+ /// Aleksandar Seovic + public sealed class NullMessageSource : AbstractMessageSource + { + /// + /// The canonical instance of the + /// class. + /// + public static readonly NullMessageSource Null = new NullMessageSource(); + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// Consider using + /// instead. + ///

+ ///
+ public NullMessageSource() + {} + + /// + /// Simply returns the supplied message as-is. + /// + /// The code of the message to resolve. + /// + /// The to resolve the + /// code for. + /// + /// + /// The supplied message as-is. + /// + protected override string ResolveMessage(string code, CultureInfo cultureInfo) + { + return code; + } + + /// + /// Always returns . + /// + /// The code of the object to resolve. + /// + /// The to resolve the + /// code for. + /// + /// + /// (always). + /// + protected override object ResolveObject(string code, CultureInfo cultureInfo) + { + return null; + } + + /// + /// Does nothing. + /// + /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + protected override void ApplyResourcesToObject( + object value, string objectName, CultureInfo cultureInfo) + {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/ResourceHandlersSectionHandler.cs b/src/Spring/Spring.Core/Context/Support/ResourceHandlersSectionHandler.cs index 872efe18..9783aff3 100644 --- a/src/Spring/Spring.Core/Context/Support/ResourceHandlersSectionHandler.cs +++ b/src/Spring/Spring.Core/Context/Support/ResourceHandlersSectionHandler.cs @@ -1,137 +1,136 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -#if ! NET_COMPACT_FRAMEWORK -#endif -using System.Configuration; -using System.Globalization; -using System.Xml; - -using Spring.Core.IO; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Handler for Spring.NET resourceHandlers config section. - /// - /// - ///

- /// Spring allows registration of custom resource handlers that can be used to load - /// object definitions from. - ///

- ///

- /// For example, if you wanted to store your object definitions in a database instead - /// of in the config file, you could write a custom implementation - /// and register it with Spring using 'db' as a protocol name. - ///

- ///

- /// Afterwards, you would simply specify resource URI within the context config element - /// using your custom resource handler. - ///

- ///
- /// - ///

- /// The following example shows how to configure both this section handler, - /// how to define custom resource within Spring config section, and how to load - /// object definitions using custom resource handler: - ///

- /// - /// - /// - /// - ///
- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Aleksandar Seovic - /// $Id: ResourceHandlersSectionHandler.cs,v 1.3 2007/08/08 17:46:37 bbaia Exp $ - /// - public class ResourceHandlersSectionHandler : IConfigurationSectionHandler - { - private const string HandlerElement = "handler"; - private const string ProtocolAttribute = "protocol"; - private const string TypeAttribute = "type"; - - /// - /// Registers resource handlers that are specified in - /// the resources config section with the . - /// - /// - /// The configuration settings in a corresponding parent - /// configuration section. Ignored. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is . - /// - /// - /// The for the section. - /// - /// - /// This method always returns null, because resource handlers are registered - /// as a sideffect of its execution and there is no need to return anything. - /// - public object Create(object parent, object configContext, XmlNode section) - { - if (section != null) - { - XmlNodeList resourceHandlers = ((XmlElement) section).GetElementsByTagName(HandlerElement); - - foreach (XmlElement handler in resourceHandlers) - { - string protocolName = GetRequiredAttributeValue(handler, ProtocolAttribute, section); - string typeName = GetRequiredAttributeValue(handler, TypeAttribute, section); - - ResourceHandlerRegistry.RegisterResourceHandler(protocolName, typeName); - } - } - return null; - } - - private static string GetRequiredAttributeValue(XmlElement resourceElement, string requiredAttributeName, XmlNode section) - { - XmlAttribute attribute = resourceElement.GetAttributeNode(requiredAttributeName); - if (attribute == null) - { - string errorMessage = - string.Format(CultureInfo.InvariantCulture, "The '{0}' attribute is required for the resource handler definition.", - requiredAttributeName); - throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); - } - return attribute.Value; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +#if ! NET_COMPACT_FRAMEWORK +#endif +using System.Configuration; +using System.Globalization; +using System.Xml; + +using Spring.Core.IO; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Handler for Spring.NET resourceHandlers config section. + /// + /// + ///

+ /// Spring allows registration of custom resource handlers that can be used to load + /// object definitions from. + ///

+ ///

+ /// For example, if you wanted to store your object definitions in a database instead + /// of in the config file, you could write a custom implementation + /// and register it with Spring using 'db' as a protocol name. + ///

+ ///

+ /// Afterwards, you would simply specify resource URI within the context config element + /// using your custom resource handler. + ///

+ ///
+ /// + ///

+ /// The following example shows how to configure both this section handler, + /// how to define custom resource within Spring config section, and how to load + /// object definitions using custom resource handler: + ///

+ /// + /// + /// + /// + ///
+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Aleksandar Seovic + /// + public class ResourceHandlersSectionHandler : IConfigurationSectionHandler + { + private const string HandlerElement = "handler"; + private const string ProtocolAttribute = "protocol"; + private const string TypeAttribute = "type"; + + /// + /// Registers resource handlers that are specified in + /// the resources config section with the . + /// + /// + /// The configuration settings in a corresponding parent + /// configuration section. Ignored. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is . + /// + /// + /// The for the section. + /// + /// + /// This method always returns null, because resource handlers are registered + /// as a sideffect of its execution and there is no need to return anything. + /// + public object Create(object parent, object configContext, XmlNode section) + { + if (section != null) + { + XmlNodeList resourceHandlers = ((XmlElement) section).GetElementsByTagName(HandlerElement); + + foreach (XmlElement handler in resourceHandlers) + { + string protocolName = GetRequiredAttributeValue(handler, ProtocolAttribute, section); + string typeName = GetRequiredAttributeValue(handler, TypeAttribute, section); + + ResourceHandlerRegistry.RegisterResourceHandler(protocolName, typeName); + } + } + return null; + } + + private static string GetRequiredAttributeValue(XmlElement resourceElement, string requiredAttributeName, XmlNode section) + { + XmlAttribute attribute = resourceElement.GetAttributeNode(requiredAttributeName); + if (attribute == null) + { + string errorMessage = + string.Format(CultureInfo.InvariantCulture, "The '{0}' attribute is required for the resource handler definition.", + requiredAttributeName); + throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); + } + return attribute.Value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/ResourceSetMessageSource.cs b/src/Spring/Spring.Core/Context/Support/ResourceSetMessageSource.cs index ac705f94..dedf9172 100644 --- a/src/Spring/Spring.Core/Context/Support/ResourceSetMessageSource.cs +++ b/src/Spring/Spring.Core/Context/Support/ResourceSetMessageSource.cs @@ -1,238 +1,237 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.ComponentModel; -using System.Globalization; -using System.Resources; -using System.Text; - -using Spring.Objects.Factory; -using Spring.Core.TypeConversion; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// An implementation that - /// accesses resources from .resx / .resource files. - /// - /// Note that for the method - /// GetResourceObject if the resource name resolves to null, then in - /// .NET 1.1 the return value will be String.Empty whereas - /// in .NET 2.0 it will return null. - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// Aleksandar Seovic (.NET) - /// $Id: ResourceSetMessageSource.cs,v 1.23 2007/07/31 18:15:50 bbaia Exp $ - public class ResourceSetMessageSource : AbstractMessageSource, IInitializingObject - { - #region Fields - - private Hashtable _cachedResources; - private IList _resourceManagers; - - #endregion - - /// - /// Creates a new instance of the - /// class. - /// - public ResourceSetMessageSource() - { - _cachedResources = new Hashtable(); - _resourceManagers = new ArrayList(); - } - - /// - /// The collection of s - /// in this . - /// - public IList ResourceManagers - { - get { return _resourceManagers; } - set { _resourceManagers = value; } - } - - /// - /// Resolves a given code by searching through each assembly name in - /// the base names array. - /// - /// The code to resolve. - /// - /// The to use for lookups. - /// - /// The message from the resource set. - protected override string ResolveMessage( - string code, CultureInfo cultureInfo) - { - string message = null; - for (int i = 0; message == null & i < _resourceManagers.Count; i++) - { - message = ResolveObject((ResourceManager) _resourceManagers[i], code, cultureInfo) as string; - } - return message; - } - - /// - /// Resolves a given code by searching through each assembly name in the array. - /// - /// The code to resolve. - /// - /// The to use for lookups. - /// - /// The object from the resource set. - protected override object ResolveObject(string code, CultureInfo cultureInfo) - { - object obj = null; - - for (int i = 0; obj == null & i < _resourceManagers.Count; i++) - { - obj = ResolveObject((ResourceManager) _resourceManagers[i], code, cultureInfo); - } - return obj; - } - - // *** NOTE Don't use cref for ComponentResourceManager as it doesn't - // exist on 1.0 - // - - /// - /// Uses a System.ComponentModel.ComponentResourceManager - /// to apply resources to object properties. - /// Resource key names are of the form objectName.propertyName - /// - /// - /// This feature is not currently supported on version 1.0 of the .NET platform. - /// - /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for the key lookup. - /// - /// - /// The to use for lookups. - /// If , uses the - /// value. - /// - /// - /// This feature is not currently supported on version 1.0 of the .NET platform. - /// - protected override void ApplyResourcesToObject(object value, string objectName, CultureInfo culture) - { -#if !NET_1_0 - if(value != null) - { - ComponentResourceManager crm = new ComponentResourceManager(value.GetType()); - crm.ApplyResources(value, objectName, culture); - } -#else - throw new NotSupportedException("Operation not supported in .NET 1.0 Release."); -#endif - } - - /// - /// Resolves a code into an object given a base name. - /// - /// The to search. - /// The code to resolve. - /// - /// The to use for lookups. - /// - /// The object from the resource file. - protected object ResolveObject(ResourceManager resourceManager, string code, CultureInfo cultureInfo) - { - string cacheKey = code + "." + cultureInfo.Name; - object resource = _cachedResources[cacheKey]; - - if (resource == null) - { - resource = resourceManager.GetObject(code, cultureInfo); - if (resource != null) - { - lock (_cachedResources) - { - _cachedResources[cacheKey] = resource; - } - } - } - - return resource; - } - - /// - /// Returns a representation of the - /// . - /// - /// A representation of the - /// . - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.Append(GetType().Name); - sb.Append(" with ResourceManagers of base names = ["); - foreach (ResourceManager rm in ResourceManagers) - { - sb.Append(rm.BaseName); - sb.Append(","); - } - string s = sb.ToString(); - return s.TrimEnd(new char[] {','}) + "]"; - } - - /// - /// Invoked by an - /// after it has set all object properties supplied. - /// - /// - ///

- /// The list may contain objects of type or - /// . types - /// are converted to instances using the notation - /// resourcename, assembly partial name. - ///

- ///
- /// - /// If the conversion from a to a - /// can't be performed. - /// - public void AfterPropertiesSet() - { - ResourceManagerConverter cvt = new ResourceManagerConverter(); - for (int i = 0; i < _resourceManagers.Count; i++) - { - object o = _resourceManagers[i]; - if (o is String) - { - _resourceManagers[i] = cvt.ConvertFrom((string) o); - } - else if (!(o is ResourceManager)) - { - throw new ArgumentException("Only Types of string and ResourceManager are allowed. Type " + o.GetType() + " was set instead."); - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Resources; +using System.Text; + +using Spring.Objects.Factory; +using Spring.Core.TypeConversion; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// An implementation that + /// accesses resources from .resx / .resource files. + /// + /// Note that for the method + /// GetResourceObject if the resource name resolves to null, then in + /// .NET 1.1 the return value will be String.Empty whereas + /// in .NET 2.0 it will return null. + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + /// Aleksandar Seovic (.NET) + public class ResourceSetMessageSource : AbstractMessageSource, IInitializingObject + { + #region Fields + + private Hashtable _cachedResources; + private IList _resourceManagers; + + #endregion + + /// + /// Creates a new instance of the + /// class. + /// + public ResourceSetMessageSource() + { + _cachedResources = new Hashtable(); + _resourceManagers = new ArrayList(); + } + + /// + /// The collection of s + /// in this . + /// + public IList ResourceManagers + { + get { return _resourceManagers; } + set { _resourceManagers = value; } + } + + /// + /// Resolves a given code by searching through each assembly name in + /// the base names array. + /// + /// The code to resolve. + /// + /// The to use for lookups. + /// + /// The message from the resource set. + protected override string ResolveMessage( + string code, CultureInfo cultureInfo) + { + string message = null; + for (int i = 0; message == null & i < _resourceManagers.Count; i++) + { + message = ResolveObject((ResourceManager) _resourceManagers[i], code, cultureInfo) as string; + } + return message; + } + + /// + /// Resolves a given code by searching through each assembly name in the array. + /// + /// The code to resolve. + /// + /// The to use for lookups. + /// + /// The object from the resource set. + protected override object ResolveObject(string code, CultureInfo cultureInfo) + { + object obj = null; + + for (int i = 0; obj == null & i < _resourceManagers.Count; i++) + { + obj = ResolveObject((ResourceManager) _resourceManagers[i], code, cultureInfo); + } + return obj; + } + + // *** NOTE Don't use cref for ComponentResourceManager as it doesn't + // exist on 1.0 + // + + /// + /// Uses a System.ComponentModel.ComponentResourceManager + /// to apply resources to object properties. + /// Resource key names are of the form objectName.propertyName + /// + /// + /// This feature is not currently supported on version 1.0 of the .NET platform. + /// + /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for the key lookup. + /// + /// + /// The to use for lookups. + /// If , uses the + /// value. + /// + /// + /// This feature is not currently supported on version 1.0 of the .NET platform. + /// + protected override void ApplyResourcesToObject(object value, string objectName, CultureInfo culture) + { +#if !NET_1_0 + if(value != null) + { + ComponentResourceManager crm = new ComponentResourceManager(value.GetType()); + crm.ApplyResources(value, objectName, culture); + } +#else + throw new NotSupportedException("Operation not supported in .NET 1.0 Release."); +#endif + } + + /// + /// Resolves a code into an object given a base name. + /// + /// The to search. + /// The code to resolve. + /// + /// The to use for lookups. + /// + /// The object from the resource file. + protected object ResolveObject(ResourceManager resourceManager, string code, CultureInfo cultureInfo) + { + string cacheKey = code + "." + cultureInfo.Name; + object resource = _cachedResources[cacheKey]; + + if (resource == null) + { + resource = resourceManager.GetObject(code, cultureInfo); + if (resource != null) + { + lock (_cachedResources) + { + _cachedResources[cacheKey] = resource; + } + } + } + + return resource; + } + + /// + /// Returns a representation of the + /// . + /// + /// A representation of the + /// . + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(GetType().Name); + sb.Append(" with ResourceManagers of base names = ["); + foreach (ResourceManager rm in ResourceManagers) + { + sb.Append(rm.BaseName); + sb.Append(","); + } + string s = sb.ToString(); + return s.TrimEnd(new char[] {','}) + "]"; + } + + /// + /// Invoked by an + /// after it has set all object properties supplied. + /// + /// + ///

+ /// The list may contain objects of type or + /// . types + /// are converted to instances using the notation + /// resourcename, assembly partial name. + ///

+ ///
+ /// + /// If the conversion from a to a + /// can't be performed. + /// + public void AfterPropertiesSet() + { + ResourceManagerConverter cvt = new ResourceManagerConverter(); + for (int i = 0; i < _resourceManagers.Count; i++) + { + object o = _resourceManagers[i]; + if (o is String) + { + _resourceManagers[i] = cvt.ConvertFrom((string) o); + } + else if (!(o is ResourceManager)) + { + throw new ArgumentException("Only Types of string and ResourceManager are allowed. Type " + o.GetType() + " was set instead."); + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/StaticApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/StaticApplicationContext.cs index 53cea4f0..c21c3d22 100644 --- a/src/Spring/Spring.Core/Context/Support/StaticApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/Support/StaticApplicationContext.cs @@ -1,102 +1,101 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Spring.Objects; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// that allows concrete registration of - /// objects and messages in code, rather than from external configuration sources. - /// - /// - ///

- /// Mainly useful for testing. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: StaticApplicationContext.cs,v 1.9 2007/07/10 05:48:03 markpollack Exp $ - public class StaticApplicationContext : GenericApplicationContext - { - /// - /// Creates a new instance of the StaticApplicationContext class. - /// - public StaticApplicationContext() : this( null ) {} - - /// - /// Creates a new instance of the StaticApplicationContext class. - /// - /// The parent application context. - public StaticApplicationContext( IApplicationContext parentContext ) - : base( null, true, parentContext ) - { - RegisterSingleton( MessageSourceObjectName, typeof( StaticMessageSource ), null ); - } - - /// - /// Do nothing: we rely on callers to update our public methods. - /// - protected override void RefreshObjectFactory() {} - - /// - /// Register a singleton object with the default object factory. - /// - /// The name of the object. - /// The of the object. - /// The property values for the singleton instance. - public void RegisterSingleton( string name, Type classType, MutablePropertyValues propertyValues ) - { - DefaultListableObjectFactory.RegisterObjectDefinition( name, new RootObjectDefinition( classType, propertyValues ) ); - } - - /// - /// Registers a prototype object with the default object factory. - /// - /// The name of the prototype object. - /// The of the prototype object. - /// The property values for the prototype instance. - public void RegisterPrototype( string name, Type classType, MutablePropertyValues propertyValues ) - { - DefaultListableObjectFactory.RegisterObjectDefinition(name, new RootObjectDefinition(classType, propertyValues, false)); - } - - /// - /// Associate the given message with the given code. - /// - /// The lookup code. - /// - /// The that the message should be found within. - /// - /// The message associated with the lookup code. - public void AddMessage( string code, CultureInfo cultureInfo, string defaultMessage ) - { - StaticMessageSource messageSource = (StaticMessageSource) GetObject( MessageSourceObjectName ); - messageSource.AddMessage( code, cultureInfo, defaultMessage ); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Spring.Objects; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// that allows concrete registration of + /// objects and messages in code, rather than from external configuration sources. + /// + /// + ///

+ /// Mainly useful for testing. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + public class StaticApplicationContext : GenericApplicationContext + { + /// + /// Creates a new instance of the StaticApplicationContext class. + /// + public StaticApplicationContext() : this( null ) {} + + /// + /// Creates a new instance of the StaticApplicationContext class. + /// + /// The parent application context. + public StaticApplicationContext( IApplicationContext parentContext ) + : base( null, true, parentContext ) + { + RegisterSingleton( MessageSourceObjectName, typeof( StaticMessageSource ), null ); + } + + /// + /// Do nothing: we rely on callers to update our public methods. + /// + protected override void RefreshObjectFactory() {} + + /// + /// Register a singleton object with the default object factory. + /// + /// The name of the object. + /// The of the object. + /// The property values for the singleton instance. + public void RegisterSingleton( string name, Type classType, MutablePropertyValues propertyValues ) + { + DefaultListableObjectFactory.RegisterObjectDefinition( name, new RootObjectDefinition( classType, propertyValues ) ); + } + + /// + /// Registers a prototype object with the default object factory. + /// + /// The name of the prototype object. + /// The of the prototype object. + /// The property values for the prototype instance. + public void RegisterPrototype( string name, Type classType, MutablePropertyValues propertyValues ) + { + DefaultListableObjectFactory.RegisterObjectDefinition(name, new RootObjectDefinition(classType, propertyValues, false)); + } + + /// + /// Associate the given message with the given code. + /// + /// The lookup code. + /// + /// The that the message should be found within. + /// + /// The message associated with the lookup code. + public void AddMessage( string code, CultureInfo cultureInfo, string defaultMessage ) + { + StaticMessageSource messageSource = (StaticMessageSource) GetObject( MessageSourceObjectName ); + messageSource.AddMessage( code, cultureInfo, defaultMessage ); + } + } +} diff --git a/src/Spring/Spring.Core/Context/Support/StaticMessageSource.cs b/src/Spring/Spring.Core/Context/Support/StaticMessageSource.cs index d56380b8..7d2bfc37 100644 --- a/src/Spring/Spring.Core/Context/Support/StaticMessageSource.cs +++ b/src/Spring/Spring.Core/Context/Support/StaticMessageSource.cs @@ -1,202 +1,201 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.ComponentModel; -using System.Globalization; -using System.Text; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Simple implementation of - /// that allows messages to be held in an object and added programmatically. - /// - /// - ///

- /// Mainly useful for testing. - ///

- ///

- /// This supports internationalization. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// - /// $Id: StaticMessageSource.cs,v 1.16 2007/08/27 13:57:27 oakinger Exp $ - public class StaticMessageSource : AbstractMessageSource - { - private Hashtable _messages; - private Hashtable _objects; - - /// - /// Creates a new instance of the - /// class. - /// - public StaticMessageSource() - { - _messages = new Hashtable(); - _objects = new Hashtable(); - } - - /// - /// Returns a format string. - /// - /// The code of the message to resolve. - /// - /// The to resolve the - /// code for. - /// - /// - /// A format string or if not found. - /// - /// - protected override string ResolveMessage(string code, CultureInfo cultureInfo) - { - return (string) _messages[GetLookupKey(code, cultureInfo)]; - } - - /// - /// Resolves an object (typically an icon or bitmap). - /// - /// The code of the object to resolve. - /// - /// The to resolve the - /// code for. - /// - /// - /// The resolved object or if not found. - /// - /// - protected override object ResolveObject(string code, CultureInfo cultureInfo) - { - return _objects[GetLookupKey(code, cultureInfo)]; - } - - - // *** NOTE Don't use cref for ComponentResourceManager as it doesn't - // exist on 1.0 - // - - /// - /// Applies resources to object properties. - /// - /// - ///

- /// Uses a System.ComponentModel.ComponentResourceManager - /// internally to apply resources to object properties. Resource key - /// names are of the form objectName.propertyName. - ///

- ///

- /// This feature is not currently supported on version 1.0 of the .NET platform. - ///

- ///
- /// - /// An object that contains the property values to be applied. - /// - /// - /// The base name of the object to use for key lookup. - /// - /// - /// The with which the - /// resource is associated. - /// - /// - /// This feature is not currently supported on version 1.0 of the .NET platform. - /// - /// - protected override void ApplyResourcesToObject(object value, string objectName, CultureInfo cultureInfo) - { -#if !NET_1_0 - if(value != null) - { - new ComponentResourceManager(value.GetType()).ApplyResources(value, objectName, cultureInfo); - } -#else - throw new System.NotSupportedException("Operation not supported in .NET 1.0 Release."); -#endif - } - - /// - /// Associate the supplied with the - /// supplied . - /// - /// The lookup code. - /// - /// The to resolve the - /// code for. - /// - /// - /// The message format associated with this lookup code. - /// - public void AddMessage( - string code, CultureInfo culture, string messageFormat) - { - _messages.Add(GetLookupKey(code, culture), messageFormat); - } - - /// - /// Associate the supplied with the - /// supplied . - /// - /// The lookup code. - /// - /// The to resolve the - /// code for. - /// - /// - /// The object associated with this lookup code. - /// - public void AddObject(string code, CultureInfo cultureInfo, object value) - { - _objects.Add(GetLookupKey(code, cultureInfo), value); - } - - /// - /// Returns a representation of this - /// message source. - /// - /// - /// A containing all of this message - /// source's messages. - /// - public override string ToString() - { - StringBuilder output = new StringBuilder(); - output.Append(GetType().Name); - output.Append(" : "); - foreach (string code in _messages.Keys) - { - output.AppendFormat("['{0}' : '{1}']", code, _messages[code]); - } - return output.ToString(); - } - - private static string GetLookupKey(string code, CultureInfo culture) - { - return new StringBuilder(code).Append("_").Append(culture).ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Text; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Simple implementation of + /// that allows messages to be held in an object and added programmatically. + /// + /// + ///

+ /// Mainly useful for testing. + ///

+ ///

+ /// This supports internationalization. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// + public class StaticMessageSource : AbstractMessageSource + { + private Hashtable _messages; + private Hashtable _objects; + + /// + /// Creates a new instance of the + /// class. + /// + public StaticMessageSource() + { + _messages = new Hashtable(); + _objects = new Hashtable(); + } + + /// + /// Returns a format string. + /// + /// The code of the message to resolve. + /// + /// The to resolve the + /// code for. + /// + /// + /// A format string or if not found. + /// + /// + protected override string ResolveMessage(string code, CultureInfo cultureInfo) + { + return (string) _messages[GetLookupKey(code, cultureInfo)]; + } + + /// + /// Resolves an object (typically an icon or bitmap). + /// + /// The code of the object to resolve. + /// + /// The to resolve the + /// code for. + /// + /// + /// The resolved object or if not found. + /// + /// + protected override object ResolveObject(string code, CultureInfo cultureInfo) + { + return _objects[GetLookupKey(code, cultureInfo)]; + } + + + // *** NOTE Don't use cref for ComponentResourceManager as it doesn't + // exist on 1.0 + // + + /// + /// Applies resources to object properties. + /// + /// + ///

+ /// Uses a System.ComponentModel.ComponentResourceManager + /// internally to apply resources to object properties. Resource key + /// names are of the form objectName.propertyName. + ///

+ ///

+ /// This feature is not currently supported on version 1.0 of the .NET platform. + ///

+ ///
+ /// + /// An object that contains the property values to be applied. + /// + /// + /// The base name of the object to use for key lookup. + /// + /// + /// The with which the + /// resource is associated. + /// + /// + /// This feature is not currently supported on version 1.0 of the .NET platform. + /// + /// + protected override void ApplyResourcesToObject(object value, string objectName, CultureInfo cultureInfo) + { +#if !NET_1_0 + if(value != null) + { + new ComponentResourceManager(value.GetType()).ApplyResources(value, objectName, cultureInfo); + } +#else + throw new System.NotSupportedException("Operation not supported in .NET 1.0 Release."); +#endif + } + + /// + /// Associate the supplied with the + /// supplied . + /// + /// The lookup code. + /// + /// The to resolve the + /// code for. + /// + /// + /// The message format associated with this lookup code. + /// + public void AddMessage( + string code, CultureInfo culture, string messageFormat) + { + _messages.Add(GetLookupKey(code, culture), messageFormat); + } + + /// + /// Associate the supplied with the + /// supplied . + /// + /// The lookup code. + /// + /// The to resolve the + /// code for. + /// + /// + /// The object associated with this lookup code. + /// + public void AddObject(string code, CultureInfo cultureInfo, object value) + { + _objects.Add(GetLookupKey(code, cultureInfo), value); + } + + /// + /// Returns a representation of this + /// message source. + /// + /// + /// A containing all of this message + /// source's messages. + /// + public override string ToString() + { + StringBuilder output = new StringBuilder(); + output.Append(GetType().Name); + output.Append(" : "); + foreach (string code in _messages.Keys) + { + output.AppendFormat("['{0}' : '{1}']", code, _messages[code]); + } + return output.ToString(); + } + + private static string GetLookupKey(string code, CultureInfo culture) + { + return new StringBuilder(code).Append("_").Append(culture).ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/TypeAliasesSectionHandler.cs b/src/Spring/Spring.Core/Context/Support/TypeAliasesSectionHandler.cs index 9ed6e7da..1518b40f 100644 --- a/src/Spring/Spring.Core/Context/Support/TypeAliasesSectionHandler.cs +++ b/src/Spring/Spring.Core/Context/Support/TypeAliasesSectionHandler.cs @@ -1,130 +1,129 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Configuration; -using System.Globalization; -using System.Xml; - -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Configuration section handler for the Spring.NET typeAliases - /// config section. - /// - /// - ///

- /// Type aliases can be used instead of fully qualified type names anywhere - /// a type name is expected in a Spring.NET configuration file. - ///

- ///

- /// This includes type names specified within an object definition, as well - /// as values of the properties or constructor arguments that expect - /// instances. - ///

- ///
- /// - ///

- /// The following example shows how to configure both this section handler and - /// how to define type aliases within a Spring.NET config section: - ///

- /// - /// - /// - /// - ///
- /// - /// - /// - /// - /// - /// - /// ... - /// - /// ... - /// - /// - /// - /// - /// Aleksandar Seovic - /// $Id: TypeAliasesSectionHandler.cs,v 1.8 2007/07/31 18:15:50 bbaia Exp $ - /// - public class TypeAliasesSectionHandler : IConfigurationSectionHandler - { - private const string AliasElementName = "alias"; - private const string NameAttributeName = "name"; - private const string TypeAttributeName = "type"; - - /// - /// Populates using values specified in - /// the typeAliases config section. - /// - /// - /// The configuration settings in a corresponding parent - /// configuration section. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is . - /// - /// - /// The for the section. - /// - /// - /// This method always returns , because the - /// is populated as a side-effect of this - /// object's execution and thus there is no need to return anything. - /// - public object Create(object parent, object configContext, XmlNode section) - { - if (section != null) - { - XmlNodeList aliases = ((XmlElement) section).GetElementsByTagName(AliasElementName); - foreach (XmlElement aliasElement in aliases) - { - string alias = GetRequiredAttributeValue(aliasElement, NameAttributeName, section); - string typeName = GetRequiredAttributeValue(aliasElement, TypeAttributeName, section); - TypeRegistry.RegisterType(alias, typeName); - } - } - return null; - } - - private static string GetRequiredAttributeValue( - XmlElement aliasElement, string requiredAttributeName, XmlNode section) - { - XmlAttribute attribute = aliasElement.GetAttributeNode(requiredAttributeName); - if (attribute == null) - { - string errorMessage = string.Format(CultureInfo.InvariantCulture, - "The '{0}' attribute is required for the (type) element.", requiredAttributeName); - throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); - } - return attribute.Value; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Configuration; +using System.Globalization; +using System.Xml; + +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Configuration section handler for the Spring.NET typeAliases + /// config section. + /// + /// + ///

+ /// Type aliases can be used instead of fully qualified type names anywhere + /// a type name is expected in a Spring.NET configuration file. + ///

+ ///

+ /// This includes type names specified within an object definition, as well + /// as values of the properties or constructor arguments that expect + /// instances. + ///

+ ///
+ /// + ///

+ /// The following example shows how to configure both this section handler and + /// how to define type aliases within a Spring.NET config section: + ///

+ /// + /// + /// + /// + ///
+ /// + /// + /// + /// + /// + /// + /// ... + /// + /// ... + /// + /// + /// + /// + /// Aleksandar Seovic + /// + public class TypeAliasesSectionHandler : IConfigurationSectionHandler + { + private const string AliasElementName = "alias"; + private const string NameAttributeName = "name"; + private const string TypeAttributeName = "type"; + + /// + /// Populates using values specified in + /// the typeAliases config section. + /// + /// + /// The configuration settings in a corresponding parent + /// configuration section. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is . + /// + /// + /// The for the section. + /// + /// + /// This method always returns , because the + /// is populated as a side-effect of this + /// object's execution and thus there is no need to return anything. + /// + public object Create(object parent, object configContext, XmlNode section) + { + if (section != null) + { + XmlNodeList aliases = ((XmlElement) section).GetElementsByTagName(AliasElementName); + foreach (XmlElement aliasElement in aliases) + { + string alias = GetRequiredAttributeValue(aliasElement, NameAttributeName, section); + string typeName = GetRequiredAttributeValue(aliasElement, TypeAttributeName, section); + TypeRegistry.RegisterType(alias, typeName); + } + } + return null; + } + + private static string GetRequiredAttributeValue( + XmlElement aliasElement, string requiredAttributeName, XmlNode section) + { + XmlAttribute attribute = aliasElement.GetAttributeNode(requiredAttributeName); + if (attribute == null) + { + string errorMessage = string.Format(CultureInfo.InvariantCulture, + "The '{0}' attribute is required for the (type) element.", requiredAttributeName); + throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); + } + return attribute.Value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/TypeConvertersSectionHandler.cs b/src/Spring/Spring.Core/Context/Support/TypeConvertersSectionHandler.cs index 941d7f87..32641de0 100644 --- a/src/Spring/Spring.Core/Context/Support/TypeConvertersSectionHandler.cs +++ b/src/Spring/Spring.Core/Context/Support/TypeConvertersSectionHandler.cs @@ -1,148 +1,147 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.ComponentModel; -using System.Configuration; -using System.Globalization; -using System.Xml; - -using Spring.Core.TypeConversion; -using Spring.Util; - -#endregion - -namespace Spring.Context.Support -{ - /// - /// Configuration section handler for the Spring.NET typeConverters - /// config section. - /// - /// - ///

- /// Type converters are used to convert objects from one type into another - /// when injecting property values, evaluating expressions, performing data - /// binding, etc. - ///

- ///

- /// They are a very powerful mechanism as they allow Spring.NET to automatically - /// convert string-based property values from the configuration file into the appropriate - /// type based on the target property's type or to convert string values submitted - /// via a web form into a type that is used by your data model when Spring.NET data - /// binding is used. Because they offer such tremendous help, you should always provide - /// a type converter implementation for your custom types that you want to be able to use - /// for injected properties or for data binding. - ///

- ///

- /// The standard .NET mechanism for specifying type converter for a particular type is - /// to decorate the type with a , passing the type - /// of the -derived class as a parameter. - ///

- ///

- /// This mechanism will still work and is a preferred way of defining type converters if - /// you control the source code for the type that you want to define a converter for. However, - /// this configuration section allows you to specify converters for the types that you don't - /// control and it also allows you to override some of the standard type converters, such as - /// the ones that are defined for some of the types in the .NET Base Class Library. - ///

- ///
- /// - ///

- /// The following example shows how to configure both this section handler and - /// how to define type converters within a Spring.NET config section: - ///

- /// - /// - /// - /// - ///
- /// - /// - /// - /// - /// - /// - /// ... - /// - /// ... - /// - /// - /// - /// - /// Aleksandar Seovic - /// $Id: TypeConvertersSectionHandler.cs,v 1.6 2007/07/31 18:15:50 bbaia Exp $ - /// - public class TypeConvertersSectionHandler : IConfigurationSectionHandler - { - private const string ConverterElementName = "converter"; - private const string ForAttributeName = "for"; - private const string TypeAttributeName = "type"; - - /// - /// Populates using values specified in - /// the typeConverters config section. - /// - /// - /// The configuration settings in a corresponding parent - /// configuration section. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is . - /// - /// - /// The for the section. - /// - /// - /// This method always returns , because the - /// is populated as a side-effect of - /// its execution and thus there is no need to return anything. - /// - public object Create(object parent, object configContext, XmlNode section) - { - if (section != null) - { - XmlNodeList converters = ((XmlElement) section).GetElementsByTagName(ConverterElementName); - foreach (XmlElement aliasElement in converters) - { - string forType = GetRequiredAttributeValue(aliasElement, ForAttributeName, section); - string converterType = GetRequiredAttributeValue(aliasElement, TypeAttributeName, section); - TypeConverterRegistry.RegisterConverter(forType, converterType); - } - } - return null; - } - - private static string GetRequiredAttributeValue( - XmlElement aliasElement, string requiredAttributeName, XmlNode section) - { - XmlAttribute attribute = aliasElement.GetAttributeNode(requiredAttributeName); - if (attribute == null) - { - string errorMessage = string.Format(CultureInfo.InvariantCulture, - "The '{0}' attribute is required for the element.", requiredAttributeName); - throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); - } - return attribute.Value; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.ComponentModel; +using System.Configuration; +using System.Globalization; +using System.Xml; + +using Spring.Core.TypeConversion; +using Spring.Util; + +#endregion + +namespace Spring.Context.Support +{ + /// + /// Configuration section handler for the Spring.NET typeConverters + /// config section. + /// + /// + ///

+ /// Type converters are used to convert objects from one type into another + /// when injecting property values, evaluating expressions, performing data + /// binding, etc. + ///

+ ///

+ /// They are a very powerful mechanism as they allow Spring.NET to automatically + /// convert string-based property values from the configuration file into the appropriate + /// type based on the target property's type or to convert string values submitted + /// via a web form into a type that is used by your data model when Spring.NET data + /// binding is used. Because they offer such tremendous help, you should always provide + /// a type converter implementation for your custom types that you want to be able to use + /// for injected properties or for data binding. + ///

+ ///

+ /// The standard .NET mechanism for specifying type converter for a particular type is + /// to decorate the type with a , passing the type + /// of the -derived class as a parameter. + ///

+ ///

+ /// This mechanism will still work and is a preferred way of defining type converters if + /// you control the source code for the type that you want to define a converter for. However, + /// this configuration section allows you to specify converters for the types that you don't + /// control and it also allows you to override some of the standard type converters, such as + /// the ones that are defined for some of the types in the .NET Base Class Library. + ///

+ ///
+ /// + ///

+ /// The following example shows how to configure both this section handler and + /// how to define type converters within a Spring.NET config section: + ///

+ /// + /// + /// + /// + ///
+ /// + /// + /// + /// + /// + /// + /// ... + /// + /// ... + /// + /// + /// + /// + /// Aleksandar Seovic + /// + public class TypeConvertersSectionHandler : IConfigurationSectionHandler + { + private const string ConverterElementName = "converter"; + private const string ForAttributeName = "for"; + private const string TypeAttributeName = "type"; + + /// + /// Populates using values specified in + /// the typeConverters config section. + /// + /// + /// The configuration settings in a corresponding parent + /// configuration section. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is . + /// + /// + /// The for the section. + /// + /// + /// This method always returns , because the + /// is populated as a side-effect of + /// its execution and thus there is no need to return anything. + /// + public object Create(object parent, object configContext, XmlNode section) + { + if (section != null) + { + XmlNodeList converters = ((XmlElement) section).GetElementsByTagName(ConverterElementName); + foreach (XmlElement aliasElement in converters) + { + string forType = GetRequiredAttributeValue(aliasElement, ForAttributeName, section); + string converterType = GetRequiredAttributeValue(aliasElement, TypeAttributeName, section); + TypeConverterRegistry.RegisterConverter(forType, converterType); + } + } + return null; + } + + private static string GetRequiredAttributeValue( + XmlElement aliasElement, string requiredAttributeName, XmlNode section) + { + XmlAttribute attribute = aliasElement.GetAttributeNode(requiredAttributeName); + if (attribute == null) + { + string errorMessage = string.Format(CultureInfo.InvariantCulture, + "The '{0}' attribute is required for the element.", requiredAttributeName); + throw ConfigurationUtils.CreateConfigurationException(errorMessage, section); + } + return attribute.Value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Context/Support/XmlApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/XmlApplicationContext.cs index 7dd00abc..91669a26 100644 --- a/src/Spring/Spring.Core/Context/Support/XmlApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/Support/XmlApplicationContext.cs @@ -1,235 +1,234 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Context.Support -{ - /// - /// An implementation that - /// reads context definitions from XML based resources. - /// - /// - ///

- /// Currently, the resources that are supported are the file, - /// http, ftp, config and assembly resource - /// types. - ///

- ///

- /// You can provide custom implementations of the - /// interface and and register them - /// with any that inherits - /// from the - /// - /// interface. - ///

- /// - /// In case of multiple config locations, later object definitions will - /// override ones defined in previously loaded resources. This can be - /// leveraged to deliberately override certain object definitions via an - /// extra XML file. - /// - ///
- /// - ///

- /// Find below some examples of instantiating an - /// using a - /// variety of different XML resources. - ///

- /// - /// // an XmlApplicationContext that reads its object definitions from an - /// // XML file that has been embedded in an assembly... - /// IApplicationContext context = new XmlApplicationContext - /// ( - /// "assembly://AssemblyName/NameSpace/ResourceName" - /// ); - /// - /// // an XmlApplicationContext that reads its object definitions from a - /// // number of disparate XML resources... - /// IApplicationContext context = new XmlApplicationContext - /// ( - /// // from an XML file that has been embedded in an assembly... - /// "assembly://AssemblyName/NameSpace/ResourceName", - /// // and from a (relative) filesystem-based resource... - /// "file://Objects/services.xml", - /// // and from an App.config / Web.config resource... - /// "config://spring/objects" - /// ); - /// - ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: XmlApplicationContext.cs,v 1.18 2007/08/08 17:46:37 bbaia Exp $ - /// - /// - /// - public class XmlApplicationContext : AbstractXmlApplicationContext - { - private string[] _configurationLocations; - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations. - /// - /// The created context will be case sensitive. - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext(params string[] configurationLocations) - : this(true, null, true, null, configurationLocations) - { } - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations. - /// - /// Flag specifying whether to make this context case sensitive or not. - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext(bool caseSensitive, - params string[] configurationLocations) - : this(true, null, caseSensitive, null, configurationLocations) - { } - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations. - /// - /// The application context name. - /// Flag specifying whether to make this context case sensitive or not. - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext(string name, bool caseSensitive, - params string[] configurationLocations) - : this(true, name, caseSensitive, null, configurationLocations) - { } - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations, - /// with the given . - /// - /// - /// The parent context (may be ). - /// - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext( - IApplicationContext parentContext, - params string[] configurationLocations) - : this(true, null, true, parentContext, configurationLocations) - { } - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations, - /// with the given . - /// - /// Flag specifying whether to make this context case sensitive or not. - /// - /// The parent context (may be ). - /// - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext( - bool caseSensitive, - IApplicationContext parentContext, - params string[] configurationLocations) - : this(true, null, caseSensitive, parentContext, configurationLocations) - { } - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations, - /// with the given . - /// - /// The application context name. - /// Flag specifying whether to make this context case sensitive or not. - /// - /// The parent context (may be ). - /// - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext( - string name, - bool caseSensitive, - IApplicationContext parentContext, - params string[] configurationLocations) - : this(true, name, caseSensitive, parentContext, configurationLocations) - {} - - /// - /// Creates a new instance of the - /// class, - /// loading the definitions from the supplied XML resource locations, - /// with the given . - /// - /// - /// This constructor is meant to be used by derived classes. By passing =false, it is - /// the responsibility of the deriving class to call to initialize the context instance. - /// - /// if true, is called automatically. - /// The application context name. - /// Flag specifying whether to make this context case sensitive or not. - /// - /// The parent context (may be ). - /// - /// - /// Any number of XML based object definition resource locations. - /// - public XmlApplicationContext( - bool refresh, - string name, - bool caseSensitive, - IApplicationContext parentContext, - params string[] configurationLocations) - : base(name, caseSensitive, parentContext ) - { - _configurationLocations = configurationLocations; - if (refresh) - { - Refresh(); - } - } - - /// - /// An array of resource locations, referring to the XML object - /// definition files that this context is to be built with. - /// - /// - /// An array of resource locations, or if none. - /// - /// - protected override string[] ConfigurationLocations - { - get { return _configurationLocations; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Context.Support +{ + /// + /// An implementation that + /// reads context definitions from XML based resources. + /// + /// + ///

+ /// Currently, the resources that are supported are the file, + /// http, ftp, config and assembly resource + /// types. + ///

+ ///

+ /// You can provide custom implementations of the + /// interface and and register them + /// with any that inherits + /// from the + /// + /// interface. + ///

+ /// + /// In case of multiple config locations, later object definitions will + /// override ones defined in previously loaded resources. This can be + /// leveraged to deliberately override certain object definitions via an + /// extra XML file. + /// + ///
+ /// + ///

+ /// Find below some examples of instantiating an + /// using a + /// variety of different XML resources. + ///

+ /// + /// // an XmlApplicationContext that reads its object definitions from an + /// // XML file that has been embedded in an assembly... + /// IApplicationContext context = new XmlApplicationContext + /// ( + /// "assembly://AssemblyName/NameSpace/ResourceName" + /// ); + /// + /// // an XmlApplicationContext that reads its object definitions from a + /// // number of disparate XML resources... + /// IApplicationContext context = new XmlApplicationContext + /// ( + /// // from an XML file that has been embedded in an assembly... + /// "assembly://AssemblyName/NameSpace/ResourceName", + /// // and from a (relative) filesystem-based resource... + /// "file://Objects/services.xml", + /// // and from an App.config / Web.config resource... + /// "config://spring/objects" + /// ); + /// + ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// + /// + /// + public class XmlApplicationContext : AbstractXmlApplicationContext + { + private string[] _configurationLocations; + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations. + /// + /// The created context will be case sensitive. + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext(params string[] configurationLocations) + : this(true, null, true, null, configurationLocations) + { } + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations. + /// + /// Flag specifying whether to make this context case sensitive or not. + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext(bool caseSensitive, + params string[] configurationLocations) + : this(true, null, caseSensitive, null, configurationLocations) + { } + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations. + /// + /// The application context name. + /// Flag specifying whether to make this context case sensitive or not. + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext(string name, bool caseSensitive, + params string[] configurationLocations) + : this(true, name, caseSensitive, null, configurationLocations) + { } + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations, + /// with the given . + /// + /// + /// The parent context (may be ). + /// + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext( + IApplicationContext parentContext, + params string[] configurationLocations) + : this(true, null, true, parentContext, configurationLocations) + { } + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations, + /// with the given . + /// + /// Flag specifying whether to make this context case sensitive or not. + /// + /// The parent context (may be ). + /// + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext( + bool caseSensitive, + IApplicationContext parentContext, + params string[] configurationLocations) + : this(true, null, caseSensitive, parentContext, configurationLocations) + { } + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations, + /// with the given . + /// + /// The application context name. + /// Flag specifying whether to make this context case sensitive or not. + /// + /// The parent context (may be ). + /// + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext( + string name, + bool caseSensitive, + IApplicationContext parentContext, + params string[] configurationLocations) + : this(true, name, caseSensitive, parentContext, configurationLocations) + {} + + /// + /// Creates a new instance of the + /// class, + /// loading the definitions from the supplied XML resource locations, + /// with the given . + /// + /// + /// This constructor is meant to be used by derived classes. By passing =false, it is + /// the responsibility of the deriving class to call to initialize the context instance. + /// + /// if true, is called automatically. + /// The application context name. + /// Flag specifying whether to make this context case sensitive or not. + /// + /// The parent context (may be ). + /// + /// + /// Any number of XML based object definition resource locations. + /// + public XmlApplicationContext( + bool refresh, + string name, + bool caseSensitive, + IApplicationContext parentContext, + params string[] configurationLocations) + : base(name, caseSensitive, parentContext ) + { + _configurationLocations = configurationLocations; + if (refresh) + { + Refresh(); + } + } + + /// + /// An array of resource locations, referring to the XML object + /// definition files that this context is to be built with. + /// + /// + /// An array of resource locations, or if none. + /// + /// + protected override string[] ConfigurationLocations + { + get { return _configurationLocations; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/CannotLoadObjectTypeException.cs b/src/Spring/Spring.Core/Core/CannotLoadObjectTypeException.cs index 99d9a92a..56412834 100644 --- a/src/Spring/Spring.Core/Core/CannotLoadObjectTypeException.cs +++ b/src/Spring/Spring.Core/Core/CannotLoadObjectTypeException.cs @@ -1,180 +1,179 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Exception thrown when the ObjectFactory cannot load the specified type of a given object. - /// - /// Mark Pollack - /// $Id: CannotLoadObjectTypeException.cs,v 1.4 2007/08/01 23:24:11 bbaia Exp $ - [Serializable] - public class CannotLoadObjectTypeException : FatalReflectionException - { - #region Constructor (s) / Destructor - - /// - /// Initializes a new instance of the class. - /// - public CannotLoadObjectTypeException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public CannotLoadObjectTypeException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public CannotLoadObjectTypeException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// The resource description that the object definition came from. - /// Name of the object requested - /// Name of the object type. - /// The root cause. - public CannotLoadObjectTypeException(string resourceDescription, string objectName, string objectTypeName, Exception rootCause ) - : base("Cannot resolve type [" + objectTypeName + "] for object with name '" + objectName + "' defined in " + resourceDescription, rootCause) - { - this.resourceDescription = resourceDescription; - this.objectName = objectName; - this.objectTypeName = objectTypeName; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected CannotLoadObjectTypeException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - - resourceDescription = info.GetString("ResourceDescription"); - objectName = info.GetString("ObjectName"); - objectTypeName = info.GetString("ObjectTypeName"); - } - - - #endregion - - #region Properties - - /// - /// Gets he name of the object we are trying to load. - /// - /// The name of the object. - public string ObjectName - { - get { return objectName; } - } - - /// - /// Gets the name of the object type we are trying to load. - /// - /// The name of the object type. - public string ObjectTypeName - { - get { return objectTypeName; } - } - - /// - /// Gets the resource description that the object definition came from - /// - /// The resource description. - public string ResourceDescription - { - get { return resourceDescription; } - } - - #endregion - - #region Methods - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("ResourceDescription", ResourceDescription); - info.AddValue("ObjectName", ObjectName); - info.AddValue("ObjectTypeName", ObjectTypeName); - } - - #endregion - - #region Fields - - private string resourceDescription; - private string objectName; - private string objectTypeName; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Exception thrown when the ObjectFactory cannot load the specified type of a given object. + /// + /// Mark Pollack + [Serializable] + public class CannotLoadObjectTypeException : FatalReflectionException + { + #region Constructor (s) / Destructor + + /// + /// Initializes a new instance of the class. + /// + public CannotLoadObjectTypeException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public CannotLoadObjectTypeException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public CannotLoadObjectTypeException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// The resource description that the object definition came from. + /// Name of the object requested + /// Name of the object type. + /// The root cause. + public CannotLoadObjectTypeException(string resourceDescription, string objectName, string objectTypeName, Exception rootCause ) + : base("Cannot resolve type [" + objectTypeName + "] for object with name '" + objectName + "' defined in " + resourceDescription, rootCause) + { + this.resourceDescription = resourceDescription; + this.objectName = objectName; + this.objectTypeName = objectTypeName; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected CannotLoadObjectTypeException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + + resourceDescription = info.GetString("ResourceDescription"); + objectName = info.GetString("ObjectName"); + objectTypeName = info.GetString("ObjectTypeName"); + } + + + #endregion + + #region Properties + + /// + /// Gets he name of the object we are trying to load. + /// + /// The name of the object. + public string ObjectName + { + get { return objectName; } + } + + /// + /// Gets the name of the object type we are trying to load. + /// + /// The name of the object type. + public string ObjectTypeName + { + get { return objectTypeName; } + } + + /// + /// Gets the resource description that the object definition came from + /// + /// The resource description. + public string ResourceDescription + { + get { return resourceDescription; } + } + + #endregion + + #region Methods + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("ResourceDescription", ResourceDescription); + info.AddValue("ObjectName", ObjectName); + info.AddValue("ObjectTypeName", ObjectTypeName); + } + + #endregion + + #region Fields + + private string resourceDescription; + private string objectName; + private string objectTypeName; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/ComposedCriteria.cs b/src/Spring/Spring.Core/Core/ComposedCriteria.cs index 30f1d6d1..8749898d 100644 --- a/src/Spring/Spring.Core/Core/ComposedCriteria.cs +++ b/src/Spring/Spring.Core/Core/ComposedCriteria.cs @@ -1,116 +1,116 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using Spring.Core; - -#endregion - -namespace Spring.Core -{ - /// - /// A implementation that represents - /// a composed collection of instances. - /// - public class ComposedCriteria : ICriteria - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public ComposedCriteria() : this(null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A user-defined (child) criteria that will be composed into this instance. - /// - public ComposedCriteria(ICriteria criteria) - { - _criteria = new ArrayList(); - Add(criteria); - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The data to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public virtual bool IsSatisfied(object datum) - { - foreach (ICriteria criteria in _criteria) - { - if (!criteria.IsSatisfied(datum)) - { - return false; - } - } - return true; - } - - /// - /// Adds the supplied into the criteria - /// composed within this instance. - /// - /// - /// The to be added. - /// - public void Add(ICriteria criteria) - { - if (criteria != null) - { - _criteria.Add(criteria); - } - } - - #endregion - - /// - /// The list of composing this - /// instance. - /// - protected IList Criteria - { - get { return _criteria; } - } - - #region Fields - - private IList _criteria; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using Spring.Core; + +#endregion + +namespace Spring.Core +{ + /// + /// A implementation that represents + /// a composed collection of instances. + /// + public class ComposedCriteria : ICriteria + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public ComposedCriteria() : this(null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A user-defined (child) criteria that will be composed into this instance. + /// + public ComposedCriteria(ICriteria criteria) + { + _criteria = new ArrayList(); + Add(criteria); + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The data to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public virtual bool IsSatisfied(object datum) + { + foreach (ICriteria criteria in _criteria) + { + if (!criteria.IsSatisfied(datum)) + { + return false; + } + } + return true; + } + + /// + /// Adds the supplied into the criteria + /// composed within this instance. + /// + /// + /// The to be added. + /// + public void Add(ICriteria criteria) + { + if (criteria != null) + { + _criteria.Add(criteria); + } + } + + #endregion + + /// + /// The list of composing this + /// instance. + /// + protected IList Criteria + { + get { return _criteria; } + } + + #region Fields + + private IList _criteria; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/ControlFlowFactory.cs b/src/Spring/Spring.Core/Core/ControlFlowFactory.cs index 34af262f..210c1bd1 100644 --- a/src/Spring/Spring.Core/Core/ControlFlowFactory.cs +++ b/src/Spring/Spring.Core/Core/ControlFlowFactory.cs @@ -1,151 +1,150 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Diagnostics; -using System.Reflection; - -#endregion - -namespace Spring.Core -{ - /// - /// Factory class to conceal any default implementation. - /// - /// Rod Johnson - /// Simon White (.NET) - /// $Id: ControlFlowFactory.cs,v 1.9 2007/07/31 01:35:07 markpollack Exp $ - public abstract class ControlFlowFactory - { - /// - /// Creates a new instance of the - /// implementation provided by this factory. - /// - /// - /// A new instance of the - /// implementation provided by this factory. - /// - public static IControlFlow CreateControlFlow() - { - return new DefaultControlFlow(); - } - - private class DefaultControlFlow : IControlFlow - { - private StackTrace _stackTrace; - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public DefaultControlFlow() - { - _stackTrace = new StackTrace(); - } - - #endregion - - #region IControlFlow Members - - /// - /// Detects whether the caller is under the supplied , - /// according to the current stacktrace. - /// - /// - bool IControlFlow.Under(Type type) - { - return IsMatch(new MethodsDeclaredTypeCriteria(type)); - } - - /// - /// Detects whether the caller is under the supplied - /// and , according to the current stacktrace. - /// - /// - ///

- /// Matches the whole method name. - ///

- ///
- /// - bool IControlFlow.Under(Type type, string methodName) - { - ComposedCriteria criteria = new ComposedCriteria(); - criteria.Add(new MethodsDeclaredTypeCriteria(type)); - criteria.Add(new RegularExpressionMethodNameCriteria(methodName)); - return IsMatch(criteria); - } - - /// - /// Does the current stack trace contain the supplied ? - /// - /// - ///

- /// This leaves it up to the caller to decide what matches, but is obviously less of - /// an abstraction because the caller must know the exact format of the underlying - /// stack trace. - ///

- ///
- /// - bool IControlFlow.UnderToken(string token) - { - return _stackTrace.ToString().IndexOf(token) != -1; - } - - private bool IsMatch(ICriteria criteria) - { - for (int i = 0; i < _stackTrace.FrameCount; i++) - { - MethodBase method = _stackTrace.GetFrame(i).GetMethod(); - if(criteria.IsSatisfied(method)) - { - return true; - } - } - return false; - } - - private sealed class MethodsDeclaredTypeCriteria : ICriteria - { - public MethodsDeclaredTypeCriteria(Type typeToMatch) - { - _typeToMatch = typeToMatch; - } - - public bool IsSatisfied(object datum) - { - MethodBase method = datum as MethodBase; - if(method != null && method.DeclaringType != null) - { - return method.DeclaringType.Equals(_typeToMatch); - } - return false; - } - - private Type _typeToMatch; - } - - #endregion - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Diagnostics; +using System.Reflection; + +#endregion + +namespace Spring.Core +{ + /// + /// Factory class to conceal any default implementation. + /// + /// Rod Johnson + /// Simon White (.NET) + public abstract class ControlFlowFactory + { + /// + /// Creates a new instance of the + /// implementation provided by this factory. + /// + /// + /// A new instance of the + /// implementation provided by this factory. + /// + public static IControlFlow CreateControlFlow() + { + return new DefaultControlFlow(); + } + + private class DefaultControlFlow : IControlFlow + { + private StackTrace _stackTrace; + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public DefaultControlFlow() + { + _stackTrace = new StackTrace(); + } + + #endregion + + #region IControlFlow Members + + /// + /// Detects whether the caller is under the supplied , + /// according to the current stacktrace. + /// + /// + bool IControlFlow.Under(Type type) + { + return IsMatch(new MethodsDeclaredTypeCriteria(type)); + } + + /// + /// Detects whether the caller is under the supplied + /// and , according to the current stacktrace. + /// + /// + ///

+ /// Matches the whole method name. + ///

+ ///
+ /// + bool IControlFlow.Under(Type type, string methodName) + { + ComposedCriteria criteria = new ComposedCriteria(); + criteria.Add(new MethodsDeclaredTypeCriteria(type)); + criteria.Add(new RegularExpressionMethodNameCriteria(methodName)); + return IsMatch(criteria); + } + + /// + /// Does the current stack trace contain the supplied ? + /// + /// + ///

+ /// This leaves it up to the caller to decide what matches, but is obviously less of + /// an abstraction because the caller must know the exact format of the underlying + /// stack trace. + ///

+ ///
+ /// + bool IControlFlow.UnderToken(string token) + { + return _stackTrace.ToString().IndexOf(token) != -1; + } + + private bool IsMatch(ICriteria criteria) + { + for (int i = 0; i < _stackTrace.FrameCount; i++) + { + MethodBase method = _stackTrace.GetFrame(i).GetMethod(); + if(criteria.IsSatisfied(method)) + { + return true; + } + } + return false; + } + + private sealed class MethodsDeclaredTypeCriteria : ICriteria + { + public MethodsDeclaredTypeCriteria(Type typeToMatch) + { + _typeToMatch = typeToMatch; + } + + public bool IsSatisfied(object datum) + { + MethodBase method = datum as MethodBase; + if(method != null && method.DeclaringType != null) + { + return method.DeclaringType.Equals(_typeToMatch); + } + return false; + } + + private Type _typeToMatch; + } + + #endregion + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/Conventions.cs b/src/Spring/Spring.Core/Core/Conventions.cs index a983fbd8..6cd952d3 100644 --- a/src/Spring/Spring.Core/Core/Conventions.cs +++ b/src/Spring/Spring.Core/Core/Conventions.cs @@ -1,71 +1,70 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Util; - -namespace Spring.Core -{ - /// - /// Provides methods to support various naming and other conventions used throughout the framework. - /// Mainly for internal use within the framework. - /// - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: Conventions.cs,v 1.1 2007/05/26 00:42:36 markpollack Exp $ - public sealed class Conventions - { - /// Convert Strings in attribute name format (lowercase, hyphens separating words) - /// into property name format (camel-cased). For example, transaction-manager is - /// converted into transactionManager. - /// - public static string AttributeNameToPropertyName(string attributeName) - { - AssertUtils.ArgumentNotNull(attributeName, "attributeName"); - if (attributeName.IndexOf("-") == -1) - { - return attributeName; - } - char[] chars = attributeName.ToCharArray(); - char[] result = new char[chars.Length - 1]; // not completely accurate but good guess - int currPos = 0; - bool upperCaseNext = false; - for (int i = 0; i < chars.Length; i++) - { - char c = chars[i]; - if (c == '-') - { - upperCaseNext = true; - } - else if (upperCaseNext) - { - result[currPos++] = Char.ToUpper(c); - upperCaseNext = false; - } - else - { - result[currPos++] = c; - } - } - return new String(result, 0, currPos); - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Util; + +namespace Spring.Core +{ + /// + /// Provides methods to support various naming and other conventions used throughout the framework. + /// Mainly for internal use within the framework. + /// + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public sealed class Conventions + { + /// Convert Strings in attribute name format (lowercase, hyphens separating words) + /// into property name format (camel-cased). For example, transaction-manager is + /// converted into transactionManager. + /// + public static string AttributeNameToPropertyName(string attributeName) + { + AssertUtils.ArgumentNotNull(attributeName, "attributeName"); + if (attributeName.IndexOf("-") == -1) + { + return attributeName; + } + char[] chars = attributeName.ToCharArray(); + char[] result = new char[chars.Length - 1]; // not completely accurate but good guess + int currPos = 0; + bool upperCaseNext = false; + for (int i = 0; i < chars.Length; i++) + { + char c = chars[i]; + if (c == '-') + { + upperCaseNext = true; + } + else if (upperCaseNext) + { + result[currPos++] = Char.ToUpper(c); + upperCaseNext = false; + } + else + { + result[currPos++] = c; + } + } + return new String(result, 0, currPos); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/CriteriaMemberFilter.cs b/src/Spring/Spring.Core/Core/CriteriaMemberFilter.cs index a7b57e4c..c1e8a0fc 100644 --- a/src/Spring/Spring.Core/Core/CriteriaMemberFilter.cs +++ b/src/Spring/Spring.Core/Core/CriteriaMemberFilter.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Reflection; - -#endregion - -namespace Spring.Core -{ - /// - /// Convenience class that exposes a signature that matches the - /// delegate. - /// - /// - ///

- /// Useful when filtering members via the - /// mechanism. - ///

- ///
- /// Rick Evans - /// $Id: CriteriaMemberFilter.cs,v 1.1 2007/07/31 21:43:52 markpollack Exp $ - public class CriteriaMemberFilter - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public CriteriaMemberFilter () - { - } - #endregion - - #region Methods - /// - /// Returns true if the supplied instance - /// satisfies the supplied (which must be an - /// implementation). - /// - /// - /// The instance that will be checked to see if - /// it matches the supplied . - /// - /// - /// The criteria against which to filter the supplied - /// instance. - /// - /// - /// True if the supplied instance - /// satisfies the supplied (which must be an - /// implementation); false if not or the - /// supplied is not an - /// implementation or is null. - /// - public virtual bool FilterMemberByCriteria (MemberInfo member, object filterCriteria) - { - ICriteria criteria = filterCriteria as ICriteria; - return criteria.IsSatisfied (member); - } - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Reflection; + +#endregion + +namespace Spring.Core +{ + /// + /// Convenience class that exposes a signature that matches the + /// delegate. + /// + /// + ///

+ /// Useful when filtering members via the + /// mechanism. + ///

+ ///
+ /// Rick Evans + public class CriteriaMemberFilter + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public CriteriaMemberFilter () + { + } + #endregion + + #region Methods + /// + /// Returns true if the supplied instance + /// satisfies the supplied (which must be an + /// implementation). + /// + /// + /// The instance that will be checked to see if + /// it matches the supplied . + /// + /// + /// The criteria against which to filter the supplied + /// instance. + /// + /// + /// True if the supplied instance + /// satisfies the supplied (which must be an + /// implementation); false if not or the + /// supplied is not an + /// implementation or is null. + /// + public virtual bool FilterMemberByCriteria (MemberInfo member, object filterCriteria) + { + ICriteria criteria = filterCriteria as ICriteria; + return criteria.IsSatisfied (member); + } + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IControlFlow.cs b/src/Spring/Spring.Core/Core/IControlFlow.cs index f1b464f2..e4c8ed23 100644 --- a/src/Spring/Spring.Core/Core/IControlFlow.cs +++ b/src/Spring/Spring.Core/Core/IControlFlow.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Core -{ - /// - /// Interface to be implemented by objects that can return information about - /// the current call stack. - /// - /// - ///

- /// Useful in AOP (as an expression of the AspectJ cflow concept) but not AOP-specific. - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.Net) - /// $Id: IControlFlow.cs,v 1.4 2006/04/09 07:18:38 markpollack Exp $ - public interface IControlFlow - { - /// - /// Detects whether the caller is under the supplied , - /// according to the current stacktrace. - /// - /// - /// The to look for. - /// - /// - /// if the caller is under the supplied . - /// - bool Under(Type type); - - /// - /// Detects whether the caller is under the supplied - /// and , according to the current stacktrace. - /// - /// - /// The to look for. - /// - /// The name of the method to look for. - /// - /// if the caller is under the supplied - /// and . - /// - bool Under(Type type, string methodName); - - /// - /// Does the current stack trace contain the supplied ? - /// - /// The token to match against. - /// - /// if the current stack trace contains the supplied - /// . - /// - bool UnderToken(string token); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Core +{ + /// + /// Interface to be implemented by objects that can return information about + /// the current call stack. + /// + /// + ///

+ /// Useful in AOP (as an expression of the AspectJ cflow concept) but not AOP-specific. + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.Net) + public interface IControlFlow + { + /// + /// Detects whether the caller is under the supplied , + /// according to the current stacktrace. + /// + /// + /// The to look for. + /// + /// + /// if the caller is under the supplied . + /// + bool Under(Type type); + + /// + /// Detects whether the caller is under the supplied + /// and , according to the current stacktrace. + /// + /// + /// The to look for. + /// + /// The name of the method to look for. + /// + /// if the caller is under the supplied + /// and . + /// + bool Under(Type type, string methodName); + + /// + /// Does the current stack trace contain the supplied ? + /// + /// The token to match against. + /// + /// if the current stack trace contains the supplied + /// . + /// + bool UnderToken(string token); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/ICriteria.cs b/src/Spring/Spring.Core/Core/ICriteria.cs index 81bdb297..21cf479d 100644 --- a/src/Spring/Spring.Core/Core/ICriteria.cs +++ b/src/Spring/Spring.Core/Core/ICriteria.cs @@ -1,51 +1,50 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Core -{ - /// - /// The criteria for an arbitrary filter. - /// - /// Rick Evans - /// $Id: ICriteria.cs,v 1.6 2006/04/09 07:18:38 markpollack Exp $ - public interface ICriteria - { - /// - /// Does the supplied satisfy the criteria - /// encapsulated by this instance? - /// - /// - /// The datum to be checked by this criteria instance. - /// - /// - /// if the supplied - /// satisfies the criteria encapsulated by this instance; - /// if not, or the supplied - /// is . - /// - bool IsSatisfied (object datum); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Core +{ + /// + /// The criteria for an arbitrary filter. + /// + /// Rick Evans + public interface ICriteria + { + /// + /// Does the supplied satisfy the criteria + /// encapsulated by this instance? + /// + /// + /// The datum to be checked by this criteria instance. + /// + /// + /// if the supplied + /// satisfies the criteria encapsulated by this instance; + /// if not, or the supplied + /// is . + /// + bool IsSatisfied (object datum); + } +} diff --git a/src/Spring/Spring.Core/Core/IErrorCoded.cs b/src/Spring/Spring.Core/Core/IErrorCoded.cs index 611c1dc0..9efa59e3 100644 --- a/src/Spring/Spring.Core/Core/IErrorCoded.cs +++ b/src/Spring/Spring.Core/Core/IErrorCoded.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Core -{ - /// - /// Interface that can be implemented by exceptions etc that are error coded. - /// - /// - ///

- /// The error code is a , rather than a number, so it can - /// be given user-readable values, such as "object.failureDescription". - ///

- ///
- /// Rod Johnson - /// Aleksandar Seovic (.Net) - /// $Id: IErrorCoded.cs,v 1.6 2006/04/09 07:18:38 markpollack Exp $ - public interface IErrorCoded - { - /// - /// Return the error code associated with this failure. - /// - /// - ///

- /// The GUI can render this anyway it pleases, allowing for I18n etc. - ///

- ///
- /// - /// The error code associated with this failure, - /// or the empty string instance if not error-coded. - /// - string ErrorCode - { - get; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Core +{ + /// + /// Interface that can be implemented by exceptions etc that are error coded. + /// + /// + ///

+ /// The error code is a , rather than a number, so it can + /// be given user-readable values, such as "object.failureDescription". + ///

+ ///
+ /// Rod Johnson + /// Aleksandar Seovic (.Net) + public interface IErrorCoded + { + /// + /// Return the error code associated with this failure. + /// + /// + ///

+ /// The GUI can render this anyway it pleases, allowing for I18n etc. + ///

+ ///
+ /// + /// The error code associated with this failure, + /// or the empty string instance if not error-coded. + /// + string ErrorCode + { + get; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/AbstractResource.cs b/src/Spring/Spring.Core/Core/IO/AbstractResource.cs index a5afc244..8ac9ee46 100644 --- a/src/Spring/Spring.Core/Core/IO/AbstractResource.cs +++ b/src/Spring/Spring.Core/Core/IO/AbstractResource.cs @@ -1,764 +1,763 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using System.Text; -using Spring.Util; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// Convenience base class for - /// implementations, pre-implementing typical behavior. - /// - /// - ///

- /// The method will - /// check whether a or - /// can be opened; - /// will always return - /// ; - /// and - /// throw an exception; - /// and will - /// return the value of the - /// property. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// Aleksandar Seovic (.NET) - /// $Id: AbstractResource.cs,v 1.25 2007/12/06 22:08:47 markpollack Exp $ - /// - public abstract class AbstractResource : IResource - { - /// - /// The default special character that denotes the base (home, or root) - /// path. - /// - /// - ///

- /// Will be resolved (by those - /// implementations that support it) to the home (or root) path for - /// the specific implementation. - ///

- ///

- /// For example, in the case of a web application this will (probably) - /// resolve to the virtual directory of said web application. - ///

- ///
- protected const string DefaultBasePathPlaceHolder = "~"; - - private string protocol; - private string basePathPlaceHolder = DefaultBasePathPlaceHolder; - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected AbstractResource() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- /// - /// A string representation of the resource. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s). - /// - protected AbstractResource(string resourceName) - { - AssertUtils.ArgumentHasText(resourceName, "resourceName"); - protocol = ConfigurableResourceLoader.GetProtocol(resourceName); - } - - #endregion - - #region Properties - - /// - /// The special character that denotes the base (home, or root) - /// path. - /// - /// - ///

- /// Will be resolved (by those - /// implementations that support it) to the home (or root) path for - /// the specific implementation. - ///

- ///

- /// For example, in the case of a web application this will (probably) - /// resolve to the virtual directory of said web application. - ///

- ///
- /// - public string BasePathPlaceHolder - { - get { return basePathPlaceHolder; } - set { basePathPlaceHolder = value; } - } - - /// - /// Return an for this resource. - /// - /// - /// An . - /// - /// - /// If the stream could not be opened. - /// - /// - public abstract Stream InputStream { get; } - - /// - /// Returns a description for this resource. - /// - /// - /// A description for this resource. - /// - /// - public abstract string Description { get; } - - /// - /// Returns the protocol associated with this resource (if any). - /// - /// - ///

- /// The value of this property may be if no - /// protocol is associated with the resource type (for example if the - /// resource is a memory stream). - ///

- ///
- /// - /// The protocol associated with this resource (if any). - /// - public string Protocol - { - get { return protocol; } - } - - /// - /// Does this resource represent a handle with an open stream? - /// - /// - ///

- /// This, the default implementation, always returns - /// . - ///

- ///
- /// - /// if this resource represents a handle with an - /// open stream. - /// - /// - public virtual bool IsOpen - { - get { return false; } - } - - /// - /// Returns the handle for this resource. - /// - /// - ///

- /// This, the default implementation, always throws a - /// , assuming that the - /// resource cannot be exposed as a . - ///

- ///
- /// - /// The handle for this resource. - /// - /// - /// This, the default implementation, always throws a - /// . - /// - /// - public virtual Uri Uri - { - get - { - throw new FileNotFoundException( - Description + " cannot be resolved to a Uri."); - } - } - - /// - /// Returns a handle for this resource. - /// - /// - ///

- /// This, the default implementation, always throws a - /// , assuming that the - /// resource cannot be resolved to an absolute file path. - ///

- ///
- /// - /// The handle for this resource. - /// - /// - /// This implementation always throws a - /// . - /// - /// - /// - public virtual FileInfo File - { - get - { - throw new FileNotFoundException( - Description + " cannot be resolved to an absolute file path."); - } - } - - /// - /// Does this resource actually exist in physical form? - /// - /// - ///

- /// This implementation checks whether a - /// can be opened, falling back to whether a - /// can be opened. - ///

- ///

- /// This will cover both directories and content resources. - ///

- ///

- /// This implementation will also return if - /// permission to the (file's) path is denied. - ///

- ///
- /// - /// if this resource actually exists in physical - /// form (for example on a filesystem). - /// - /// - /// - public virtual bool Exists - { - get - { - try - { - return File.Exists; - } - catch (IOException) - { - try - { - Stream inputStream = InputStream; - inputStream.Close(); - return true; - } catch (Exception) - { - return false; - } - } - } - } - - #endregion - - #region Methods - - /// - /// Strips any protocol name from the supplied - /// . - /// - /// - ///

- /// If the supplied does not - /// have any protocol associated with it, then the supplied - /// will be returned as-is. - ///

- ///
- /// - /// - /// GetResourceNameWithoutProtocol("http://www.mycompany.com/resource.txt"); - /// // returns www.mycompany.com/resource.txt - /// - /// - /// - /// The name of the resource. - /// - /// - /// The name of the resource without the protocol name. - /// - protected static string GetResourceNameWithoutProtocol(string resourceName) - { - int pos = resourceName.IndexOf( - ConfigurableResourceLoader.ProtocolSeparator); - if (pos == -1) - { - return resourceName; - } - else - { - return resourceName.Substring(pos + ConfigurableResourceLoader.ProtocolSeparator.Length); - } - } - - /// - /// Resolves the supplied to its value - /// sans any leading protocol. - /// - /// - /// The name of the resource. - /// - /// - /// The name of the resource without the protocol name. - /// - /// - protected virtual string ResolveResourceNameWithoutProtocol(string resourceName) - { - return ResolveBasePathPlaceHolder( - GetResourceNameWithoutProtocol(resourceName), BasePathPlaceHolder); - } - - /// - /// Resolves the presence of the - /// value - /// in the supplied into a path. - /// - /// - ///

- /// The default implementation simply returns the supplied - /// as is. - ///

- ///
- /// - /// The name of the resource. - /// - /// - /// The string that is a placeholder for a base path. - /// - /// - /// The name of the resource with any - /// value having been resolved into an actual path. - /// - protected virtual string ResolveBasePathPlaceHolder( - string resourceName, string basePathPlaceHolder) - { - return resourceName; - } - - /// - /// This implementation returns the - /// of this resource. - /// - /// - public override string ToString() - { - return Description; - } - - /// - /// Determines whether the specified is - /// equal to the current . - /// - /// - ///

- /// This implementation compares values. - ///

- ///
- /// - public override bool Equals(object obj) - { - return obj is IResource - && ((IResource)obj).Description.Equals(Description); - } - - /// - /// Serves as a hash function for a particular type, suitable for use - /// in hashing algorithms and data structures like a hash table. - /// - /// - ///

- /// This implementation returns the hashcode of the - /// property. - ///

- ///
- /// - public override int GetHashCode() - { - return Description.GetHashCode(); - } - - #endregion - - #region Relative Resource Support - - /// - /// Factory Method. Create a new instance of the current resource type using the given resourceName - /// - protected virtual IResource CreateResourceInstance( string resourceName ) - { - return null; - } - - /// - /// The ResourceLoader to be used for resolving relative resources - /// - protected virtual IResourceLoader GetResourceLoader() - { - return new ConfigurableResourceLoader(); - } - - /// - /// Does this support relative - /// resource retrieval? - /// - /// - ///

- /// This property is generally to be consulted prior to attempting - /// to attempting to access a resource that is relative to this - /// resource (via a call to - /// ). - ///

- ///

- /// This, the default implementation, always returns - /// . - ///

- ///
- /// - /// if this - /// supports relative resource - /// retrieval. - /// - protected virtual bool SupportsRelativeResources - { - get { return false; } - } - - /// - /// Gets the root location of the resource. - /// - /// - ///

- /// Where root resource can be taken to mean that part of the resource - /// descriptor that doesn't change when a relative resource is looked - /// up. Examples of such a root location would include a drive letter, - /// a web server name, an assembly name, etc. - ///

- ///
- /// - /// The root location of the resource. - /// - /// - /// This, the default implementation, always throws a - /// . - /// - protected virtual string RootLocation - { - get { throw new NotSupportedException(); } - } - - /// - /// Gets the current path of the resource. - /// - /// - ///

- /// An example value of this property would be the name of the - /// directory containing a filesystem based resource. - ///

- ///
- /// - /// The current path of the resource. - /// - /// - /// This, the default implementation, always throws a - /// . - /// - protected virtual string ResourcePath - { - get { throw new NotSupportedException(); } - } - - /// - /// Gets those characters that are valid path separators for the - /// resource type. - /// - /// - ///

- /// An example value of this property would be the - /// and - /// values for a - /// filesystem based resource. - ///

- ///

- /// Any derived classes that override this method are expected to - /// return a new array for each access of this property. - ///

- ///
- /// - /// Those characters that are valid path separators for the resource - /// type. - /// - /// - /// This, the default implementation, always throws a - /// . - /// - protected virtual char[] PathSeparatorChars - { - get { throw new NotSupportedException(); } - } - - /// - /// Does the supplied relative ? - /// - /// - /// The name of the resource to test. - /// - /// - /// if resource name is relative; - /// otherwise . - /// - protected virtual bool IsRelativeResource(string resourceName) - { - return false; - } - - /// - /// Creates a new resource that is relative to this resource based on the - /// supplied . - /// - /// - ///

- /// This method can accept either a fully qualified resource name or a - /// relative resource name as it's parameter. - ///

- ///

- /// A fully qualified resource is one that has a protocol prefix and - /// all elements of the resource name. All other resources are treated - /// as relative to this resource, and the following rules are used to - /// locate a relative resource: - ///

- /// - /// - /// If the starts with '..', - /// the current resource path is navigated backwards before the - /// is concatenated to the current - /// of - /// this resource. - /// - /// - /// If the starts with '/', the - /// current resource path is ignored and a new resource name is - /// appended to the - /// of - /// this resource. - /// - /// - /// If the starts with '.' or a - /// letter, a new path is appended to the current - /// of - /// this resource. - /// - /// - ///
- /// - /// The name of the resource to create. - /// - /// The relative resource. - /// - /// If the process of resolving the relative resource yielded an - /// invalid URI. - /// - /// - /// If this resource does not support the resolution of relative - /// resources (as determined by the value of the - /// - /// property). - /// - /// - public virtual IResource CreateRelative(string resourceName) - { - AssertUtils.ArgumentNotNull(resourceName, "relativePath"); - - // try to create fully qualified resource... - IResourceLoader loader = GetResourceLoader(); - - if (ConfigurableResourceLoader.HasProtocol(resourceName)) - { - IResource resource = loader.GetResource(resourceName); - if (resource != null) - { - return resource; - } - } - if (!SupportsRelativeResources) - { - throw new NotSupportedException(GetType().Name + - " does not support relative resources. Please use fully qualified resource name."); - } - - StringBuilder fullResourceName = new StringBuilder(256); - if (Protocol != null && Protocol != String.Empty) - { - fullResourceName.Append(Protocol).Append(ConfigurableResourceLoader.ProtocolSeparator); - } - - if (!IsRelativeResource(resourceName)) - { - fullResourceName.Append(resourceName); - } - else - { - string targetResource; - string resourcePath; - int n = resourceName.LastIndexOfAny(new char[] { '/', '\\' }); - if (n >= 0) - { - targetResource = resourceName.Substring(n + 1); - resourcePath = CalculateResourcePath(resourceName.Substring(0, n + 1)); - } - else // only resource name is specified, so current path should be used - { - targetResource = resourceName; - resourcePath = ResourcePath; - } - - fullResourceName.Append(RootLocation.TrimEnd('\\','/')); - if (resourcePath != null && resourcePath != String.Empty) - { - fullResourceName.Append('/').Append(resourcePath); - } - fullResourceName.Append('/').Append(targetResource); - } - - string resultResourceName = fullResourceName.ToString(); - - if (!ConfigurableResourceLoader.HasProtocol( resultResourceName )) - { - // give derived resource classes a chance to create an instance on their own - IResource resultResource = CreateResourceInstance( resultResourceName ); - if (resultResource != null) return resultResource; - } - - // create resource instance using default loader - return loader.GetResource(resultResourceName); - } - - /// - /// Calculates a new resource path based on the supplied - /// . - /// - /// - /// The relative path to evaluate. - /// - /// The newly calculated resource path. - private string CalculateResourcePath(string relativePath ) - { - StringBuilder path = new StringBuilder(256); - if (relativePath.StartsWith("..")) // back level navigation - { - string[] pathElements = ResourcePath.Split(PathSeparatorChars); - int upWalks = UpWalks(relativePath); - if (upWalks > pathElements.Length) - { - throw new UriFormatException("Too many back levels."); - } - char separator = PathSeparatorChars[0]; - for (int i = 0; i < pathElements.Length - upWalks; i++) - { - path.Append(pathElements[i]).Append(separator); - } - string[] relativeParts = relativePath.Split('/', '\\'); - for (int i = upWalks; i < relativeParts.Length - 1; i++) - { - path.Append(relativeParts[i]).Append(separator); - } - if (path.Length > 0) - { - path.Length -= 1; - } - return path.ToString(); - } - else if (relativePath.StartsWith("/")) // relative to root - { - if (relativePath.Length > 1) - { - return relativePath.Substring(1, relativePath.Length - 2); - } - else - { - return null; - } - } - else // relative to current namespace... - { - if (ResourcePath != null && ResourcePath != String.Empty) - { - path.Append(ResourcePath.TrimEnd(PathSeparatorChars)).Append(PathSeparatorChars[0]); - } - if (relativePath.StartsWith("./")) - { - if (relativePath.Length > 2) - { - path.Append(relativePath.Substring(2, relativePath.Length - 3)); - } - } - else - { - path.Append(relativePath.Substring(0, relativePath.Length - 1)); - } - - return path.ToString(); - } - } - - private int UpWalks(string path) - { - string[] parts = path.Split('/', '\\'); - int count = 0; - for (; count < parts.Length && parts[count].Equals(".."); count++) - { - ; - } - return count; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using System.Text; +using Spring.Util; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// Convenience base class for + /// implementations, pre-implementing typical behavior. + /// + /// + ///

+ /// The method will + /// check whether a or + /// can be opened; + /// will always return + /// ; + /// and + /// throw an exception; + /// and will + /// return the value of the + /// property. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// Aleksandar Seovic (.NET) + /// + public abstract class AbstractResource : IResource + { + /// + /// The default special character that denotes the base (home, or root) + /// path. + /// + /// + ///

+ /// Will be resolved (by those + /// implementations that support it) to the home (or root) path for + /// the specific implementation. + ///

+ ///

+ /// For example, in the case of a web application this will (probably) + /// resolve to the virtual directory of said web application. + ///

+ ///
+ protected const string DefaultBasePathPlaceHolder = "~"; + + private string protocol; + private string basePathPlaceHolder = DefaultBasePathPlaceHolder; + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected AbstractResource() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ /// + /// A string representation of the resource. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s). + /// + protected AbstractResource(string resourceName) + { + AssertUtils.ArgumentHasText(resourceName, "resourceName"); + protocol = ConfigurableResourceLoader.GetProtocol(resourceName); + } + + #endregion + + #region Properties + + /// + /// The special character that denotes the base (home, or root) + /// path. + /// + /// + ///

+ /// Will be resolved (by those + /// implementations that support it) to the home (or root) path for + /// the specific implementation. + ///

+ ///

+ /// For example, in the case of a web application this will (probably) + /// resolve to the virtual directory of said web application. + ///

+ ///
+ /// + public string BasePathPlaceHolder + { + get { return basePathPlaceHolder; } + set { basePathPlaceHolder = value; } + } + + /// + /// Return an for this resource. + /// + /// + /// An . + /// + /// + /// If the stream could not be opened. + /// + /// + public abstract Stream InputStream { get; } + + /// + /// Returns a description for this resource. + /// + /// + /// A description for this resource. + /// + /// + public abstract string Description { get; } + + /// + /// Returns the protocol associated with this resource (if any). + /// + /// + ///

+ /// The value of this property may be if no + /// protocol is associated with the resource type (for example if the + /// resource is a memory stream). + ///

+ ///
+ /// + /// The protocol associated with this resource (if any). + /// + public string Protocol + { + get { return protocol; } + } + + /// + /// Does this resource represent a handle with an open stream? + /// + /// + ///

+ /// This, the default implementation, always returns + /// . + ///

+ ///
+ /// + /// if this resource represents a handle with an + /// open stream. + /// + /// + public virtual bool IsOpen + { + get { return false; } + } + + /// + /// Returns the handle for this resource. + /// + /// + ///

+ /// This, the default implementation, always throws a + /// , assuming that the + /// resource cannot be exposed as a . + ///

+ ///
+ /// + /// The handle for this resource. + /// + /// + /// This, the default implementation, always throws a + /// . + /// + /// + public virtual Uri Uri + { + get + { + throw new FileNotFoundException( + Description + " cannot be resolved to a Uri."); + } + } + + /// + /// Returns a handle for this resource. + /// + /// + ///

+ /// This, the default implementation, always throws a + /// , assuming that the + /// resource cannot be resolved to an absolute file path. + ///

+ ///
+ /// + /// The handle for this resource. + /// + /// + /// This implementation always throws a + /// . + /// + /// + /// + public virtual FileInfo File + { + get + { + throw new FileNotFoundException( + Description + " cannot be resolved to an absolute file path."); + } + } + + /// + /// Does this resource actually exist in physical form? + /// + /// + ///

+ /// This implementation checks whether a + /// can be opened, falling back to whether a + /// can be opened. + ///

+ ///

+ /// This will cover both directories and content resources. + ///

+ ///

+ /// This implementation will also return if + /// permission to the (file's) path is denied. + ///

+ ///
+ /// + /// if this resource actually exists in physical + /// form (for example on a filesystem). + /// + /// + /// + public virtual bool Exists + { + get + { + try + { + return File.Exists; + } + catch (IOException) + { + try + { + Stream inputStream = InputStream; + inputStream.Close(); + return true; + } catch (Exception) + { + return false; + } + } + } + } + + #endregion + + #region Methods + + /// + /// Strips any protocol name from the supplied + /// . + /// + /// + ///

+ /// If the supplied does not + /// have any protocol associated with it, then the supplied + /// will be returned as-is. + ///

+ ///
+ /// + /// + /// GetResourceNameWithoutProtocol("http://www.mycompany.com/resource.txt"); + /// // returns www.mycompany.com/resource.txt + /// + /// + /// + /// The name of the resource. + /// + /// + /// The name of the resource without the protocol name. + /// + protected static string GetResourceNameWithoutProtocol(string resourceName) + { + int pos = resourceName.IndexOf( + ConfigurableResourceLoader.ProtocolSeparator); + if (pos == -1) + { + return resourceName; + } + else + { + return resourceName.Substring(pos + ConfigurableResourceLoader.ProtocolSeparator.Length); + } + } + + /// + /// Resolves the supplied to its value + /// sans any leading protocol. + /// + /// + /// The name of the resource. + /// + /// + /// The name of the resource without the protocol name. + /// + /// + protected virtual string ResolveResourceNameWithoutProtocol(string resourceName) + { + return ResolveBasePathPlaceHolder( + GetResourceNameWithoutProtocol(resourceName), BasePathPlaceHolder); + } + + /// + /// Resolves the presence of the + /// value + /// in the supplied into a path. + /// + /// + ///

+ /// The default implementation simply returns the supplied + /// as is. + ///

+ ///
+ /// + /// The name of the resource. + /// + /// + /// The string that is a placeholder for a base path. + /// + /// + /// The name of the resource with any + /// value having been resolved into an actual path. + /// + protected virtual string ResolveBasePathPlaceHolder( + string resourceName, string basePathPlaceHolder) + { + return resourceName; + } + + /// + /// This implementation returns the + /// of this resource. + /// + /// + public override string ToString() + { + return Description; + } + + /// + /// Determines whether the specified is + /// equal to the current . + /// + /// + ///

+ /// This implementation compares values. + ///

+ ///
+ /// + public override bool Equals(object obj) + { + return obj is IResource + && ((IResource)obj).Description.Equals(Description); + } + + /// + /// Serves as a hash function for a particular type, suitable for use + /// in hashing algorithms and data structures like a hash table. + /// + /// + ///

+ /// This implementation returns the hashcode of the + /// property. + ///

+ ///
+ /// + public override int GetHashCode() + { + return Description.GetHashCode(); + } + + #endregion + + #region Relative Resource Support + + /// + /// Factory Method. Create a new instance of the current resource type using the given resourceName + /// + protected virtual IResource CreateResourceInstance( string resourceName ) + { + return null; + } + + /// + /// The ResourceLoader to be used for resolving relative resources + /// + protected virtual IResourceLoader GetResourceLoader() + { + return new ConfigurableResourceLoader(); + } + + /// + /// Does this support relative + /// resource retrieval? + /// + /// + ///

+ /// This property is generally to be consulted prior to attempting + /// to attempting to access a resource that is relative to this + /// resource (via a call to + /// ). + ///

+ ///

+ /// This, the default implementation, always returns + /// . + ///

+ ///
+ /// + /// if this + /// supports relative resource + /// retrieval. + /// + protected virtual bool SupportsRelativeResources + { + get { return false; } + } + + /// + /// Gets the root location of the resource. + /// + /// + ///

+ /// Where root resource can be taken to mean that part of the resource + /// descriptor that doesn't change when a relative resource is looked + /// up. Examples of such a root location would include a drive letter, + /// a web server name, an assembly name, etc. + ///

+ ///
+ /// + /// The root location of the resource. + /// + /// + /// This, the default implementation, always throws a + /// . + /// + protected virtual string RootLocation + { + get { throw new NotSupportedException(); } + } + + /// + /// Gets the current path of the resource. + /// + /// + ///

+ /// An example value of this property would be the name of the + /// directory containing a filesystem based resource. + ///

+ ///
+ /// + /// The current path of the resource. + /// + /// + /// This, the default implementation, always throws a + /// . + /// + protected virtual string ResourcePath + { + get { throw new NotSupportedException(); } + } + + /// + /// Gets those characters that are valid path separators for the + /// resource type. + /// + /// + ///

+ /// An example value of this property would be the + /// and + /// values for a + /// filesystem based resource. + ///

+ ///

+ /// Any derived classes that override this method are expected to + /// return a new array for each access of this property. + ///

+ ///
+ /// + /// Those characters that are valid path separators for the resource + /// type. + /// + /// + /// This, the default implementation, always throws a + /// . + /// + protected virtual char[] PathSeparatorChars + { + get { throw new NotSupportedException(); } + } + + /// + /// Does the supplied relative ? + /// + /// + /// The name of the resource to test. + /// + /// + /// if resource name is relative; + /// otherwise . + /// + protected virtual bool IsRelativeResource(string resourceName) + { + return false; + } + + /// + /// Creates a new resource that is relative to this resource based on the + /// supplied . + /// + /// + ///

+ /// This method can accept either a fully qualified resource name or a + /// relative resource name as it's parameter. + ///

+ ///

+ /// A fully qualified resource is one that has a protocol prefix and + /// all elements of the resource name. All other resources are treated + /// as relative to this resource, and the following rules are used to + /// locate a relative resource: + ///

+ /// + /// + /// If the starts with '..', + /// the current resource path is navigated backwards before the + /// is concatenated to the current + /// of + /// this resource. + /// + /// + /// If the starts with '/', the + /// current resource path is ignored and a new resource name is + /// appended to the + /// of + /// this resource. + /// + /// + /// If the starts with '.' or a + /// letter, a new path is appended to the current + /// of + /// this resource. + /// + /// + ///
+ /// + /// The name of the resource to create. + /// + /// The relative resource. + /// + /// If the process of resolving the relative resource yielded an + /// invalid URI. + /// + /// + /// If this resource does not support the resolution of relative + /// resources (as determined by the value of the + /// + /// property). + /// + /// + public virtual IResource CreateRelative(string resourceName) + { + AssertUtils.ArgumentNotNull(resourceName, "relativePath"); + + // try to create fully qualified resource... + IResourceLoader loader = GetResourceLoader(); + + if (ConfigurableResourceLoader.HasProtocol(resourceName)) + { + IResource resource = loader.GetResource(resourceName); + if (resource != null) + { + return resource; + } + } + if (!SupportsRelativeResources) + { + throw new NotSupportedException(GetType().Name + + " does not support relative resources. Please use fully qualified resource name."); + } + + StringBuilder fullResourceName = new StringBuilder(256); + if (Protocol != null && Protocol != String.Empty) + { + fullResourceName.Append(Protocol).Append(ConfigurableResourceLoader.ProtocolSeparator); + } + + if (!IsRelativeResource(resourceName)) + { + fullResourceName.Append(resourceName); + } + else + { + string targetResource; + string resourcePath; + int n = resourceName.LastIndexOfAny(new char[] { '/', '\\' }); + if (n >= 0) + { + targetResource = resourceName.Substring(n + 1); + resourcePath = CalculateResourcePath(resourceName.Substring(0, n + 1)); + } + else // only resource name is specified, so current path should be used + { + targetResource = resourceName; + resourcePath = ResourcePath; + } + + fullResourceName.Append(RootLocation.TrimEnd('\\','/')); + if (resourcePath != null && resourcePath != String.Empty) + { + fullResourceName.Append('/').Append(resourcePath); + } + fullResourceName.Append('/').Append(targetResource); + } + + string resultResourceName = fullResourceName.ToString(); + + if (!ConfigurableResourceLoader.HasProtocol( resultResourceName )) + { + // give derived resource classes a chance to create an instance on their own + IResource resultResource = CreateResourceInstance( resultResourceName ); + if (resultResource != null) return resultResource; + } + + // create resource instance using default loader + return loader.GetResource(resultResourceName); + } + + /// + /// Calculates a new resource path based on the supplied + /// . + /// + /// + /// The relative path to evaluate. + /// + /// The newly calculated resource path. + private string CalculateResourcePath(string relativePath ) + { + StringBuilder path = new StringBuilder(256); + if (relativePath.StartsWith("..")) // back level navigation + { + string[] pathElements = ResourcePath.Split(PathSeparatorChars); + int upWalks = UpWalks(relativePath); + if (upWalks > pathElements.Length) + { + throw new UriFormatException("Too many back levels."); + } + char separator = PathSeparatorChars[0]; + for (int i = 0; i < pathElements.Length - upWalks; i++) + { + path.Append(pathElements[i]).Append(separator); + } + string[] relativeParts = relativePath.Split('/', '\\'); + for (int i = upWalks; i < relativeParts.Length - 1; i++) + { + path.Append(relativeParts[i]).Append(separator); + } + if (path.Length > 0) + { + path.Length -= 1; + } + return path.ToString(); + } + else if (relativePath.StartsWith("/")) // relative to root + { + if (relativePath.Length > 1) + { + return relativePath.Substring(1, relativePath.Length - 2); + } + else + { + return null; + } + } + else // relative to current namespace... + { + if (ResourcePath != null && ResourcePath != String.Empty) + { + path.Append(ResourcePath.TrimEnd(PathSeparatorChars)).Append(PathSeparatorChars[0]); + } + if (relativePath.StartsWith("./")) + { + if (relativePath.Length > 2) + { + path.Append(relativePath.Substring(2, relativePath.Length - 3)); + } + } + else + { + path.Append(relativePath.Substring(0, relativePath.Length - 1)); + } + + return path.ToString(); + } + } + + private int UpWalks(string path) + { + string[] parts = path.Split('/', '\\'); + int count = 0; + for (; count < parts.Length && parts[count].Equals(".."); count++) + { + ; + } + return count; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/AssemblyResource.cs b/src/Spring/Spring.Core/Core/IO/AssemblyResource.cs index d10283be..8f4d8dd5 100644 --- a/src/Spring/Spring.Core/Core/IO/AssemblyResource.cs +++ b/src/Spring/Spring.Core/Core/IO/AssemblyResource.cs @@ -1,272 +1,271 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.IO; -using System.Reflection; -using Common.Logging; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// An implementation for - /// resources stored within assemblies. - /// - /// - ///

- /// This implementation expects any resource name passed to the - /// constructor to adhere to the following format: - ///

- ///

- /// assembly://assemblyName/namespace/resourceName - ///

- ///
- /// Aleksandar Seovic (.NET) - /// Federico Spinazzi (.NET) - /// $Id: AssemblyResource.cs,v 1.16 2007/08/08 17:46:55 bbaia Exp $ - public class AssemblyResource : AbstractResource - { - #region Fields - - private Assembly _assembly; - private string[] _resources; - private string _resourceName; - private string _fullResourceName; - private string _resourceNamespace; - private string _resourceAssemblyName; - private static readonly ILog log = LogManager.GetLogger(typeof(AssemblyResource)); - - #endregion - - #region Constructors - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the assembly resource. - /// - /// - /// If the supplied did not conform - /// to the expected format. - /// - /// - /// If the assembly specified in the supplied - /// was loaded twice with two - /// different evidences. - /// - /// - /// If the assembly specified in the supplied - /// could not be found. - /// - /// - /// If the caller does not have the required permission to load - /// the assembly specified in the supplied - /// . - /// - /// - public AssemblyResource(string resourceName) : base(resourceName) - { - string[] info = GetResourceNameWithoutProtocol(resourceName).Split('/'); - if (info.Length != 3) - { - throw new UriFormatException( - "Invalid resource name. Name has to be in " + - "'assembly://' format."); - } -#if NET_2_0 - this._assembly = Assembly.Load(info[0]); -#else - this._assembly = Assembly.LoadWithPartialName(info[0]); -#endif - if (this._assembly == null) - { - throw new FileNotFoundException("Unable to load assembly [" + info[0] + "]"); - } - this._fullResourceName = resourceName; - this._resourceAssemblyName = info[0]; - this._resourceNamespace = info[1]; - this._resourceName = String.Format("{0}.{1}", info[1], info[2]); - } - - #endregion - - #region Properties - - /// - /// Return an for this resource. - /// - /// - /// An . - /// - /// - /// If the stream could not be opened. - /// - /// - /// If the caller does not have the required permission to load - /// the underlying assembly's manifest. - /// - /// - /// - public override Stream InputStream - { - get - { - Stream stream = _assembly.GetManifestResourceStream(_resourceName); - if (stream == null) - { - log.Error("Could not load resource with name = [" + _resourceName + - "] from assembly + " + _assembly); - log.Error("URI specified = [" + this._fullResourceName + "] Spring.NET URI syntax is 'assembly://assemblyName/namespace/resourceName'."); - log.Error("Resource name often has the default namespace prefixed, e.g. 'assembly://MyAssembly/MyNamespace/MyNamespace.MyResource.txt'."); - } - return stream; - } - } - - /// - /// Does the embedded resource specified in the value passed to the - /// constructor exist? - /// - /// - /// if this resource actually exists in physical - /// form (for example on a filesystem). - /// - /// - /// - /// - public override bool Exists - { - get - { - if (_resources == null) - { - _resources = _assembly.GetManifestResourceNames(); - Array.Sort(_resources); - } - return (Array.BinarySearch(_resources, _resourceName) >= 0); - } - } - - /// - /// Does this support relative - /// resource retrieval? - /// - /// - ///

- /// This implementation does support relative resource retrieval, and - /// so will always return . - ///

- ///
- /// - /// if this - /// supports relative resource - /// retrieval. - /// - /// - protected override bool SupportsRelativeResources - { - get { return true; } - } - - /// - /// Gets the root location of the resource (the assembly name in this - /// case). - /// - /// - /// The root location of the resource. - /// - /// - protected override string RootLocation - { - get { return _resourceAssemblyName; } - } - - /// - /// Gets the current path of the resource (the namespace in which the - /// target resource was embedded in this case). - /// - /// - /// The current path of the resource. - /// - /// - protected override string ResourcePath - { - get { return _resourceNamespace; } - } - - /// - /// Gets those characters that are valid path separators for the - /// resource type. - /// - /// - /// Those characters that are valid path separators for the resource - /// type. - /// - /// - protected override char[] PathSeparatorChars - { - get { return new char[] {'.'}; } - } - - /// - /// Returns a description for this resource. - /// - /// - /// A description for this resource. - /// - /// - public override string Description - { - get - { - return string.Format( - CultureInfo.InvariantCulture, - "assembly [{0}], resource [{1}]", _assembly.FullName, _resourceName); - } - } - - #endregion - - /// - /// Does the supplied relative ? - /// - /// - /// The name of the resource to test. - /// - /// - /// if resource name is relative; - /// otherwise . - /// - protected override bool IsRelativeResource(string resourceName) - { - return (resourceName.StartsWith("./") || - resourceName.StartsWith("/") || - resourceName.StartsWith("../") || - resourceName.Split('/').Length != 3); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using Common.Logging; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// An implementation for + /// resources stored within assemblies. + /// + /// + ///

+ /// This implementation expects any resource name passed to the + /// constructor to adhere to the following format: + ///

+ ///

+ /// assembly://assemblyName/namespace/resourceName + ///

+ ///
+ /// Aleksandar Seovic (.NET) + /// Federico Spinazzi (.NET) + public class AssemblyResource : AbstractResource + { + #region Fields + + private Assembly _assembly; + private string[] _resources; + private string _resourceName; + private string _fullResourceName; + private string _resourceNamespace; + private string _resourceAssemblyName; + private static readonly ILog log = LogManager.GetLogger(typeof(AssemblyResource)); + + #endregion + + #region Constructors + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the assembly resource. + /// + /// + /// If the supplied did not conform + /// to the expected format. + /// + /// + /// If the assembly specified in the supplied + /// was loaded twice with two + /// different evidences. + /// + /// + /// If the assembly specified in the supplied + /// could not be found. + /// + /// + /// If the caller does not have the required permission to load + /// the assembly specified in the supplied + /// . + /// + /// + public AssemblyResource(string resourceName) : base(resourceName) + { + string[] info = GetResourceNameWithoutProtocol(resourceName).Split('/'); + if (info.Length != 3) + { + throw new UriFormatException( + "Invalid resource name. Name has to be in " + + "'assembly://' format."); + } +#if NET_2_0 + this._assembly = Assembly.Load(info[0]); +#else + this._assembly = Assembly.LoadWithPartialName(info[0]); +#endif + if (this._assembly == null) + { + throw new FileNotFoundException("Unable to load assembly [" + info[0] + "]"); + } + this._fullResourceName = resourceName; + this._resourceAssemblyName = info[0]; + this._resourceNamespace = info[1]; + this._resourceName = String.Format("{0}.{1}", info[1], info[2]); + } + + #endregion + + #region Properties + + /// + /// Return an for this resource. + /// + /// + /// An . + /// + /// + /// If the stream could not be opened. + /// + /// + /// If the caller does not have the required permission to load + /// the underlying assembly's manifest. + /// + /// + /// + public override Stream InputStream + { + get + { + Stream stream = _assembly.GetManifestResourceStream(_resourceName); + if (stream == null) + { + log.Error("Could not load resource with name = [" + _resourceName + + "] from assembly + " + _assembly); + log.Error("URI specified = [" + this._fullResourceName + "] Spring.NET URI syntax is 'assembly://assemblyName/namespace/resourceName'."); + log.Error("Resource name often has the default namespace prefixed, e.g. 'assembly://MyAssembly/MyNamespace/MyNamespace.MyResource.txt'."); + } + return stream; + } + } + + /// + /// Does the embedded resource specified in the value passed to the + /// constructor exist? + /// + /// + /// if this resource actually exists in physical + /// form (for example on a filesystem). + /// + /// + /// + /// + public override bool Exists + { + get + { + if (_resources == null) + { + _resources = _assembly.GetManifestResourceNames(); + Array.Sort(_resources); + } + return (Array.BinarySearch(_resources, _resourceName) >= 0); + } + } + + /// + /// Does this support relative + /// resource retrieval? + /// + /// + ///

+ /// This implementation does support relative resource retrieval, and + /// so will always return . + ///

+ ///
+ /// + /// if this + /// supports relative resource + /// retrieval. + /// + /// + protected override bool SupportsRelativeResources + { + get { return true; } + } + + /// + /// Gets the root location of the resource (the assembly name in this + /// case). + /// + /// + /// The root location of the resource. + /// + /// + protected override string RootLocation + { + get { return _resourceAssemblyName; } + } + + /// + /// Gets the current path of the resource (the namespace in which the + /// target resource was embedded in this case). + /// + /// + /// The current path of the resource. + /// + /// + protected override string ResourcePath + { + get { return _resourceNamespace; } + } + + /// + /// Gets those characters that are valid path separators for the + /// resource type. + /// + /// + /// Those characters that are valid path separators for the resource + /// type. + /// + /// + protected override char[] PathSeparatorChars + { + get { return new char[] {'.'}; } + } + + /// + /// Returns a description for this resource. + /// + /// + /// A description for this resource. + /// + /// + public override string Description + { + get + { + return string.Format( + CultureInfo.InvariantCulture, + "assembly [{0}], resource [{1}]", _assembly.FullName, _resourceName); + } + } + + #endregion + + /// + /// Does the supplied relative ? + /// + /// + /// The name of the resource to test. + /// + /// + /// if resource name is relative; + /// otherwise . + /// + protected override bool IsRelativeResource(string resourceName) + { + return (resourceName.StartsWith("./") || + resourceName.StartsWith("/") || + resourceName.StartsWith("../") || + resourceName.Split('/').Length != 3); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/ConfigSectionResource.cs b/src/Spring/Spring.Core/Core/IO/ConfigSectionResource.cs index 4fd3bd7f..af5e99ca 100644 --- a/src/Spring/Spring.Core/Core/IO/ConfigSectionResource.cs +++ b/src/Spring/Spring.Core/Core/IO/ConfigSectionResource.cs @@ -1,204 +1,203 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using System.Text; -using System.Xml; - -using Spring.Util; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// Used when retrieving information from the standard .NET configuration - /// files (App.config / Web.config). - /// - /// - ///

- /// If created with the name of a configuration section, then all methods - /// aside from the description return , - /// , or throw an exception. If created with an - /// , then the - /// property - /// will return a corresponding to parse. - ///

- ///
- /// Mark Pollack - /// Rick Evans - /// $Id: ConfigSectionResource.cs,v 1.27 2007/12/05 00:57:31 bbaia Exp $ - public class ConfigSectionResource : AbstractResource - { - private XmlElement configElement; - private string sectionName; - - #region Constructor (s) / Destructor - - /// - /// Creates new instance of the - /// class. - /// - /// - /// The actual XML configuration section. - /// - /// - /// If the supplied is . - /// - public ConfigSectionResource(XmlElement configSection) - { - AssertUtils.ArgumentNotNull(configSection, "configSection"); - sectionName = configSection.Name; - configElement = configSection; - } - - /// - /// Creates new instance of the - /// class. - /// - /// - /// The name of the configuration section. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s). - /// - public ConfigSectionResource(string resourceName) : base(resourceName) - { - AssertUtils.ArgumentHasText(resourceName, "resourceName"); - sectionName = GetResourceNameWithoutProtocol(resourceName); - configElement = (XmlElement) ConfigurationUtils.GetSection(sectionName); - } - - #endregion - - #region IResource Members - - /// - /// Returns the handle for this resource. - /// - /// - ///

- /// This implementation always returns . - ///

- ///
- /// - /// . - /// - /// - public override Uri Uri - { - get { return null; } - } - - /// - /// Returns a handle for this resource. - /// - /// - ///

- /// This implementation always returns . - ///

- ///
- /// - /// . - /// - /// - public override FileInfo File - { - get { return null; } - } - - /// - /// Returns a description for this resource (the name of the - /// configuration section in this case). - /// - /// - /// A description for this resource. - /// - /// - public override string Description - { - get - { - return StringUtils.Surround("config [", sectionName, "]"); - } - } - - /// - /// Does this resource actually exist in physical form? - /// - /// - ///

- /// This implementation always returns . - ///

- ///
- /// - /// - /// - /// - /// - public override bool Exists - { - get { return false; } - } - - #endregion - - #region IInputStreamSource Members - - /// - /// Return an for this resource. - /// - /// - /// An . - /// - /// - /// If the stream could not be opened. - /// - /// - public override Stream InputStream - { - get { return new MemoryStream(Encoding.UTF8.GetBytes(configElement.OuterXml)); } - } - - #endregion - - #region Properties - - /// - /// Exposes the actual for the - /// configuration section. - /// - /// - ///

- /// Introduced to accomodate line info tracking during parsing. - ///

- ///
- internal XmlElement ConfigElement - { - get { return configElement; } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using System.Text; +using System.Xml; + +using Spring.Util; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// Used when retrieving information from the standard .NET configuration + /// files (App.config / Web.config). + /// + /// + ///

+ /// If created with the name of a configuration section, then all methods + /// aside from the description return , + /// , or throw an exception. If created with an + /// , then the + /// property + /// will return a corresponding to parse. + ///

+ ///
+ /// Mark Pollack + /// Rick Evans + public class ConfigSectionResource : AbstractResource + { + private XmlElement configElement; + private string sectionName; + + #region Constructor (s) / Destructor + + /// + /// Creates new instance of the + /// class. + /// + /// + /// The actual XML configuration section. + /// + /// + /// If the supplied is . + /// + public ConfigSectionResource(XmlElement configSection) + { + AssertUtils.ArgumentNotNull(configSection, "configSection"); + sectionName = configSection.Name; + configElement = configSection; + } + + /// + /// Creates new instance of the + /// class. + /// + /// + /// The name of the configuration section. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s). + /// + public ConfigSectionResource(string resourceName) : base(resourceName) + { + AssertUtils.ArgumentHasText(resourceName, "resourceName"); + sectionName = GetResourceNameWithoutProtocol(resourceName); + configElement = (XmlElement) ConfigurationUtils.GetSection(sectionName); + } + + #endregion + + #region IResource Members + + /// + /// Returns the handle for this resource. + /// + /// + ///

+ /// This implementation always returns . + ///

+ ///
+ /// + /// . + /// + /// + public override Uri Uri + { + get { return null; } + } + + /// + /// Returns a handle for this resource. + /// + /// + ///

+ /// This implementation always returns . + ///

+ ///
+ /// + /// . + /// + /// + public override FileInfo File + { + get { return null; } + } + + /// + /// Returns a description for this resource (the name of the + /// configuration section in this case). + /// + /// + /// A description for this resource. + /// + /// + public override string Description + { + get + { + return StringUtils.Surround("config [", sectionName, "]"); + } + } + + /// + /// Does this resource actually exist in physical form? + /// + /// + ///

+ /// This implementation always returns . + ///

+ ///
+ /// + /// + /// + /// + /// + public override bool Exists + { + get { return false; } + } + + #endregion + + #region IInputStreamSource Members + + /// + /// Return an for this resource. + /// + /// + /// An . + /// + /// + /// If the stream could not be opened. + /// + /// + public override Stream InputStream + { + get { return new MemoryStream(Encoding.UTF8.GetBytes(configElement.OuterXml)); } + } + + #endregion + + #region Properties + + /// + /// Exposes the actual for the + /// configuration section. + /// + /// + ///

+ /// Introduced to accomodate line info tracking during parsing. + ///

+ ///
+ internal XmlElement ConfigElement + { + get { return configElement; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/ConfigurableResourceLoader.cs b/src/Spring/Spring.Core/Core/IO/ConfigurableResourceLoader.cs index b577fe1e..f4e16c82 100644 --- a/src/Spring/Spring.Core/Core/IO/ConfigurableResourceLoader.cs +++ b/src/Spring/Spring.Core/Core/IO/ConfigurableResourceLoader.cs @@ -1,197 +1,196 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; -using Spring.Reflection.Dynamic; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// Configurable implementation of the - /// interface. - /// - /// - ///

- /// This implementation - /// supports the configuration of resource access protocols and the - /// corresponding .NET types that know how to handle those protocols. - ///

- ///

- /// Basic protocol-to-resource type mappings are also defined by this class, - /// while others can be added either internally, by application contexts - /// extending this class, or externally, by the end user configuring the - /// context. - ///

- ///

- /// Only one resource type can be defined for each protocol, but multiple - /// protocols can map to the same resource type (for example, the - /// "http" and "ftp" protocols both map to the - /// type. The protocols that are - /// mapped by default can be found in the following list. - ///

- ///

- /// - /// - /// assembly - /// - /// - /// config - /// - /// - /// file - /// - /// - /// http - /// - /// - /// https - /// - /// - ///

- ///
- /// Aleksandar Seovic - /// $Id: ConfigurableResourceLoader.cs,v 1.25 2007/08/08 17:46:55 bbaia Exp $ - /// - /// - /// - public class ConfigurableResourceLoader : IResourceLoader - { - /// - /// The separator between the protocol name and the resource name. - /// - public const string ProtocolSeparator = "://"; - - /// - /// Creates a new instance of the - /// class. - /// - public ConfigurableResourceLoader() - { } - - /// - /// Creates a new instance of the - /// class using the specified default protocol for unqualified resources. - /// - public ConfigurableResourceLoader(string defaultProtocol) - { - AssertUtils.ArgumentNotNull(defaultProtocol, "defaultProtocol"); - this.defaultProtocol = defaultProtocol; - } - - /// - /// The default protocol to use for unqualified resources. - /// - /// - ///

- /// The initial value is "file". - ///

- ///
- public string DefaultResourceProtocol - { - get { return defaultProtocol; } - set { defaultProtocol = value; } - } - - /// - /// Returns a that has been - /// mapped to the protocol of the supplied . - /// - /// The name of the resource. - /// - /// A new instance for the - /// supplied . - /// - /// - /// If a - /// mapping does not exist for the supplied . - /// - /// - /// In the case of any errors arising from the instantiation of the - /// returned instance. - /// - /// - public IResource GetResource(string resourceName) - { - string protocol = GetProtocol(resourceName); - if (protocol == null) - { - protocol = DefaultResourceProtocol; - resourceName = protocol + ProtocolSeparator + resourceName; - } - - IDynamicConstructor handler = ResourceHandlerRegistry.GetResourceHandler(protocol); - if (handler == null) - { - throw new UriFormatException("Resource handler for the '" + protocol + "' protocol is not defined."); - } - - return (IResource) handler.Invoke(new object[] { resourceName }); - } - - /// - /// Checks that the supplied starts - /// with one of the protocol names currently mapped by this - /// instance. - /// - /// The name of the resource. - /// - /// if the supplied - /// starts with one of the known - /// protocols; if not, or if the supplied - /// is itself . - /// - public static bool HasProtocol(string resourceName) - { - string protocol = GetProtocol(resourceName); - return protocol != null && ResourceHandlerRegistry.IsHandlerRegistered(protocol); - } - - /// - /// Extracts the protocol name from the supplied - /// . - /// - /// The name of the resource. - /// - /// The extracted protocol name or if the - /// supplied is unqualified (or - /// is itself ). - /// - internal static string GetProtocol(string resourceName) - { - if (resourceName == null) - { - return null; - } - int pos = resourceName.IndexOf(ProtocolSeparator); - return pos == -1 ? null : resourceName.Substring(0, pos); - } - - #region Fields - - private string defaultProtocol = "file"; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; +using Spring.Reflection.Dynamic; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// Configurable implementation of the + /// interface. + /// + /// + ///

+ /// This implementation + /// supports the configuration of resource access protocols and the + /// corresponding .NET types that know how to handle those protocols. + ///

+ ///

+ /// Basic protocol-to-resource type mappings are also defined by this class, + /// while others can be added either internally, by application contexts + /// extending this class, or externally, by the end user configuring the + /// context. + ///

+ ///

+ /// Only one resource type can be defined for each protocol, but multiple + /// protocols can map to the same resource type (for example, the + /// "http" and "ftp" protocols both map to the + /// type. The protocols that are + /// mapped by default can be found in the following list. + ///

+ ///

+ /// + /// + /// assembly + /// + /// + /// config + /// + /// + /// file + /// + /// + /// http + /// + /// + /// https + /// + /// + ///

+ ///
+ /// Aleksandar Seovic + /// + /// + /// + public class ConfigurableResourceLoader : IResourceLoader + { + /// + /// The separator between the protocol name and the resource name. + /// + public const string ProtocolSeparator = "://"; + + /// + /// Creates a new instance of the + /// class. + /// + public ConfigurableResourceLoader() + { } + + /// + /// Creates a new instance of the + /// class using the specified default protocol for unqualified resources. + /// + public ConfigurableResourceLoader(string defaultProtocol) + { + AssertUtils.ArgumentNotNull(defaultProtocol, "defaultProtocol"); + this.defaultProtocol = defaultProtocol; + } + + /// + /// The default protocol to use for unqualified resources. + /// + /// + ///

+ /// The initial value is "file". + ///

+ ///
+ public string DefaultResourceProtocol + { + get { return defaultProtocol; } + set { defaultProtocol = value; } + } + + /// + /// Returns a that has been + /// mapped to the protocol of the supplied . + /// + /// The name of the resource. + /// + /// A new instance for the + /// supplied . + /// + /// + /// If a + /// mapping does not exist for the supplied . + /// + /// + /// In the case of any errors arising from the instantiation of the + /// returned instance. + /// + /// + public IResource GetResource(string resourceName) + { + string protocol = GetProtocol(resourceName); + if (protocol == null) + { + protocol = DefaultResourceProtocol; + resourceName = protocol + ProtocolSeparator + resourceName; + } + + IDynamicConstructor handler = ResourceHandlerRegistry.GetResourceHandler(protocol); + if (handler == null) + { + throw new UriFormatException("Resource handler for the '" + protocol + "' protocol is not defined."); + } + + return (IResource) handler.Invoke(new object[] { resourceName }); + } + + /// + /// Checks that the supplied starts + /// with one of the protocol names currently mapped by this + /// instance. + /// + /// The name of the resource. + /// + /// if the supplied + /// starts with one of the known + /// protocols; if not, or if the supplied + /// is itself . + /// + public static bool HasProtocol(string resourceName) + { + string protocol = GetProtocol(resourceName); + return protocol != null && ResourceHandlerRegistry.IsHandlerRegistered(protocol); + } + + /// + /// Extracts the protocol name from the supplied + /// . + /// + /// The name of the resource. + /// + /// The extracted protocol name or if the + /// supplied is unqualified (or + /// is itself ). + /// + internal static string GetProtocol(string resourceName) + { + if (resourceName == null) + { + return null; + } + int pos = resourceName.IndexOf(ProtocolSeparator); + return pos == -1 ? null : resourceName.Substring(0, pos); + } + + #region Fields + + private string defaultProtocol = "file"; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/FileSystemResource.cs b/src/Spring/Spring.Core/Core/IO/FileSystemResource.cs index 4d96f082..5ed9e9c1 100644 --- a/src/Spring/Spring.Core/Core/IO/FileSystemResource.cs +++ b/src/Spring/Spring.Core/Core/IO/FileSystemResource.cs @@ -1,394 +1,393 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.IO; -using Spring.Util; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// A backed resource. - /// - /// - ///

- /// Supports resolution as both a and a - /// . - ///

- ///

- /// Also supports the use of the ~ character. If the ~ character - /// is the first character in a resource path (sans protocol), the ~ - /// character will be replaced with the value of the - /// System.AppDomain.CurrentDomain.BaseDirectory property (an example of - /// this can be seen in the examples below). - ///

- ///
- /// - ///

- /// Consider the example of an application that is running (has been launched - /// from) the C:\App\ directory. The following resource paths will map - /// to the following resources on the filesystem... - ///

- /// - /// strings.txt C:\App\strings.txt - /// ~/strings.txt C:\App\strings.txt - /// file://~/strings.txt C:\App\strings.txt - /// file://~/../strings.txt C:\strings.txt - /// ../strings.txt C:\strings.txt - /// ~/../strings.txt C:\strings.txt - /// - /// // note that only a leading ~ character is resolved to the executing directory... - /// stri~ngs.txt C:\App\stri~ngs.txt - /// - ///
- /// Juergen Hoeller - /// Leonardo Susatyo (.NET) - /// Aleksandar Seovic (.NET) - /// $Id: FileSystemResource.cs,v 1.23 2007/08/08 17:46:55 bbaia Exp $ - public class FileSystemResource : AbstractResource - { - private FileInfo fileHandle; - private string rootLocation; - private string resourcePath; - - #region Constructors - - /// - /// Creates a new instance of the - /// class. - /// - protected FileSystemResource() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the file system resource. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s). - /// - public FileSystemResource(string resourceName) - : this(resourceName, false) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the file system resource. - /// - /// - /// Supresses initialization of this instance. Used from derived classes. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s). - /// - protected FileSystemResource(string resourceName, bool suppressInitialize) - : base(resourceName) - { - if (!suppressInitialize) - { - Initialize( resourceName ); - } - } - - #endregion - - #region Properties - - /// - /// Returns the underlying handle for - /// this resource. - /// - /// - /// The handle for this resource. - /// - /// - public override FileInfo File - { - get { return fileHandle; } - } - - /// - /// Does this support relative - /// resource retrieval? - /// - /// - ///

- /// This implementation does support relative resource retrieval, and - /// so will always return . - ///

- ///
- /// - /// if this - /// supports relative resource - /// retrieval. - /// - /// - protected override bool SupportsRelativeResources - { - get { return true; } - } - - /// - /// Gets the root location of the resource (a drive or UNC file share - /// name in this case). - /// - /// - /// The root location of the resource. - /// - /// - protected override string RootLocation - { - get { return this.rootLocation; } - } - - /// - /// Gets the current path of the resource. - /// - /// - /// The current path of the resource. - /// - /// - protected override string ResourcePath - { - get { return this.resourcePath; } - } - - /// - /// Gets those characters that are valid path separators for the - /// resource type. - /// - /// - /// Those characters that are valid path separators for the resource - /// type. - /// - /// - /// - protected override char[] PathSeparatorChars - { - get { return new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; } - } - - /// - /// Return an for this resource. - /// - /// - /// An . - /// - /// - /// If the stream could not be opened. - /// - /// - /// If the underlying file could not be found. - /// - /// - public override Stream InputStream - { - get - { - if (Uri.IsFile) - { - try - { - return new FileStream(Uri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - } - catch(DirectoryNotFoundException) - { - // ignore difference between File & Directory exception in this case - } - } - throw new FileNotFoundException(Description - + " cannot be resolved to local file path" - + " - resource does not use 'file:' protocol."); - } - } - - /// - /// Returns a description for this resource. - /// - /// - /// A description for this resource. - /// - /// - public override string Description - { - get - { - return string.Format( - CultureInfo.InvariantCulture, - "file [{0}]", fileHandle.FullName); - } - } - - /// - /// Returns the handle for this resource. - /// - /// - /// The handle for this resource. - /// - /// - /// If the resource is not available or cannot be exposed as a - /// . - /// - /// - public override Uri Uri - { - get { return new UriBuilder("file", null, 0, fileHandle.FullName).Uri; } - } - - #endregion - - /// - /// Initializes this instance. - /// - /// - protected void Initialize( string resourceName ) - { - this.fileHandle = ResolveFileHandle(resourceName); - this.rootLocation = ResolveRootLocation(resourceName); - this.resourcePath = ResolveResourcePath(resourceName); - } - - /// - /// Resolves the handle - /// for the supplied . - /// - /// - /// The name of the file system resource. - /// - /// - /// The handle for this resource. - /// - protected virtual FileInfo ResolveFileHandle(string resourceName) - { - return new FileInfo(ResolveResourceNameWithoutProtocol(resourceName)); - } - - /// - /// Resolves the root location for the supplied . - /// - /// - /// The name of the file system resource. - /// - /// - /// The root location of the resource. - /// - protected virtual string ResolveRootLocation(string resourceName) - { - string root = this.fileHandle.Directory.Root.ToString(); - if (root.Length > 0 && - (root.EndsWith(Path.DirectorySeparatorChar.ToString()) || - root.EndsWith(Path.AltDirectorySeparatorChar.ToString()))) - { - root = root.Substring(0, root.Length - 1); - } - - return root; - } - - /// - /// Resolves the path for the supplied . - /// - /// - /// The name of the file system resource. - /// - /// - /// The current path of the resource. - /// - protected virtual string ResolveResourcePath(string resourceName) - { - string path = this.fileHandle.DirectoryName; - if (path.Equals(this.fileHandle.Directory.Root.ToString())) - { - path = null; - } - else - { - path = path.Substring(this.rootLocation.Length + 1); - } - - return path; - } - - /// - /// Resolves the presence of the - /// value - /// in the supplied into a path. - /// - /// - /// The name of the resource. - /// - /// - /// The string that is a placeholder for a base path. - /// - /// - /// The name of the resource with any - /// value having been resolved into an actual path. - /// - protected override string ResolveBasePathPlaceHolder( - string resourceName, string basePathPlaceHolder) - { - // Remove extra slashes used to indicate that resource is local (handle the case "/C:/path1/...") - if (resourceName[0] == '/' && resourceName[2] == ':') - { - resourceName = resourceName.Substring(1); - } - - if (StringUtils.HasText(resourceName) - && resourceName.TrimStart().StartsWith(basePathPlaceHolder)) - { - return resourceName.Replace(basePathPlaceHolder, AppDomain.CurrentDomain.BaseDirectory).TrimStart(); - } - return resourceName; - } - - /// - /// Does the supplied relative ? - /// - /// - /// The name of the resource to test. - /// - /// - /// if resource name is relative; - /// otherwise . - /// - protected override bool IsRelativeResource(string resourceName) - { - return (! - (resourceName.StartsWith(@"\\") || // UNC file share - resourceName.IndexOf(':') >= 0 || // drive - resourceName.StartsWith(BasePathPlaceHolder))); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.IO; +using Spring.Util; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// A backed resource. + /// + /// + ///

+ /// Supports resolution as both a and a + /// . + ///

+ ///

+ /// Also supports the use of the ~ character. If the ~ character + /// is the first character in a resource path (sans protocol), the ~ + /// character will be replaced with the value of the + /// System.AppDomain.CurrentDomain.BaseDirectory property (an example of + /// this can be seen in the examples below). + ///

+ ///
+ /// + ///

+ /// Consider the example of an application that is running (has been launched + /// from) the C:\App\ directory. The following resource paths will map + /// to the following resources on the filesystem... + ///

+ /// + /// strings.txt C:\App\strings.txt + /// ~/strings.txt C:\App\strings.txt + /// file://~/strings.txt C:\App\strings.txt + /// file://~/../strings.txt C:\strings.txt + /// ../strings.txt C:\strings.txt + /// ~/../strings.txt C:\strings.txt + /// + /// // note that only a leading ~ character is resolved to the executing directory... + /// stri~ngs.txt C:\App\stri~ngs.txt + /// + ///
+ /// Juergen Hoeller + /// Leonardo Susatyo (.NET) + /// Aleksandar Seovic (.NET) + public class FileSystemResource : AbstractResource + { + private FileInfo fileHandle; + private string rootLocation; + private string resourcePath; + + #region Constructors + + /// + /// Creates a new instance of the + /// class. + /// + protected FileSystemResource() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the file system resource. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s). + /// + public FileSystemResource(string resourceName) + : this(resourceName, false) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the file system resource. + /// + /// + /// Supresses initialization of this instance. Used from derived classes. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s). + /// + protected FileSystemResource(string resourceName, bool suppressInitialize) + : base(resourceName) + { + if (!suppressInitialize) + { + Initialize( resourceName ); + } + } + + #endregion + + #region Properties + + /// + /// Returns the underlying handle for + /// this resource. + /// + /// + /// The handle for this resource. + /// + /// + public override FileInfo File + { + get { return fileHandle; } + } + + /// + /// Does this support relative + /// resource retrieval? + /// + /// + ///

+ /// This implementation does support relative resource retrieval, and + /// so will always return . + ///

+ ///
+ /// + /// if this + /// supports relative resource + /// retrieval. + /// + /// + protected override bool SupportsRelativeResources + { + get { return true; } + } + + /// + /// Gets the root location of the resource (a drive or UNC file share + /// name in this case). + /// + /// + /// The root location of the resource. + /// + /// + protected override string RootLocation + { + get { return this.rootLocation; } + } + + /// + /// Gets the current path of the resource. + /// + /// + /// The current path of the resource. + /// + /// + protected override string ResourcePath + { + get { return this.resourcePath; } + } + + /// + /// Gets those characters that are valid path separators for the + /// resource type. + /// + /// + /// Those characters that are valid path separators for the resource + /// type. + /// + /// + /// + protected override char[] PathSeparatorChars + { + get { return new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; } + } + + /// + /// Return an for this resource. + /// + /// + /// An . + /// + /// + /// If the stream could not be opened. + /// + /// + /// If the underlying file could not be found. + /// + /// + public override Stream InputStream + { + get + { + if (Uri.IsFile) + { + try + { + return new FileStream(Uri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + } + catch(DirectoryNotFoundException) + { + // ignore difference between File & Directory exception in this case + } + } + throw new FileNotFoundException(Description + + " cannot be resolved to local file path" + + " - resource does not use 'file:' protocol."); + } + } + + /// + /// Returns a description for this resource. + /// + /// + /// A description for this resource. + /// + /// + public override string Description + { + get + { + return string.Format( + CultureInfo.InvariantCulture, + "file [{0}]", fileHandle.FullName); + } + } + + /// + /// Returns the handle for this resource. + /// + /// + /// The handle for this resource. + /// + /// + /// If the resource is not available or cannot be exposed as a + /// . + /// + /// + public override Uri Uri + { + get { return new UriBuilder("file", null, 0, fileHandle.FullName).Uri; } + } + + #endregion + + /// + /// Initializes this instance. + /// + /// + protected void Initialize( string resourceName ) + { + this.fileHandle = ResolveFileHandle(resourceName); + this.rootLocation = ResolveRootLocation(resourceName); + this.resourcePath = ResolveResourcePath(resourceName); + } + + /// + /// Resolves the handle + /// for the supplied . + /// + /// + /// The name of the file system resource. + /// + /// + /// The handle for this resource. + /// + protected virtual FileInfo ResolveFileHandle(string resourceName) + { + return new FileInfo(ResolveResourceNameWithoutProtocol(resourceName)); + } + + /// + /// Resolves the root location for the supplied . + /// + /// + /// The name of the file system resource. + /// + /// + /// The root location of the resource. + /// + protected virtual string ResolveRootLocation(string resourceName) + { + string root = this.fileHandle.Directory.Root.ToString(); + if (root.Length > 0 && + (root.EndsWith(Path.DirectorySeparatorChar.ToString()) || + root.EndsWith(Path.AltDirectorySeparatorChar.ToString()))) + { + root = root.Substring(0, root.Length - 1); + } + + return root; + } + + /// + /// Resolves the path for the supplied . + /// + /// + /// The name of the file system resource. + /// + /// + /// The current path of the resource. + /// + protected virtual string ResolveResourcePath(string resourceName) + { + string path = this.fileHandle.DirectoryName; + if (path.Equals(this.fileHandle.Directory.Root.ToString())) + { + path = null; + } + else + { + path = path.Substring(this.rootLocation.Length + 1); + } + + return path; + } + + /// + /// Resolves the presence of the + /// value + /// in the supplied into a path. + /// + /// + /// The name of the resource. + /// + /// + /// The string that is a placeholder for a base path. + /// + /// + /// The name of the resource with any + /// value having been resolved into an actual path. + /// + protected override string ResolveBasePathPlaceHolder( + string resourceName, string basePathPlaceHolder) + { + // Remove extra slashes used to indicate that resource is local (handle the case "/C:/path1/...") + if (resourceName[0] == '/' && resourceName[2] == ':') + { + resourceName = resourceName.Substring(1); + } + + if (StringUtils.HasText(resourceName) + && resourceName.TrimStart().StartsWith(basePathPlaceHolder)) + { + return resourceName.Replace(basePathPlaceHolder, AppDomain.CurrentDomain.BaseDirectory).TrimStart(); + } + return resourceName; + } + + /// + /// Does the supplied relative ? + /// + /// + /// The name of the resource to test. + /// + /// + /// if resource name is relative; + /// otherwise . + /// + protected override bool IsRelativeResource(string resourceName) + { + return (! + (resourceName.StartsWith(@"\\") || // UNC file share + resourceName.IndexOf(':') >= 0 || // drive + resourceName.StartsWith(BasePathPlaceHolder))); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/IInputStreamSource.cs b/src/Spring/Spring.Core/Core/IO/IInputStreamSource.cs index 64a9e5be..bb5e1f3a 100644 --- a/src/Spring/Spring.Core/Core/IO/IInputStreamSource.cs +++ b/src/Spring/Spring.Core/Core/IO/IInputStreamSource.cs @@ -1,68 +1,67 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// Simple interface for objects that are sources for - /// s. - /// - /// - ///

- /// This is the base interface for the abstraction encapsulated by - /// Spring.NET's interface. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IInputStreamSource.cs,v 1.10 2007/08/08 17:46:55 bbaia Exp $ - /// - public interface IInputStreamSource - { - /// - /// Return an for this resource. - /// - /// - /// - /// Clients of this interface must be aware that every access of this - /// property will create a fresh ; - /// it is the responsibility of the calling code to close any such - /// . - /// - /// - /// - /// An . - /// - /// - /// If the stream could not be opened. - /// - Stream InputStream - { - get; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// Simple interface for objects that are sources for + /// s. + /// + /// + ///

+ /// This is the base interface for the abstraction encapsulated by + /// Spring.NET's interface. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// + public interface IInputStreamSource + { + /// + /// Return an for this resource. + /// + /// + /// + /// Clients of this interface must be aware that every access of this + /// property will create a fresh ; + /// it is the responsibility of the calling code to close any such + /// . + /// + /// + /// + /// An . + /// + /// + /// If the stream could not be opened. + /// + Stream InputStream + { + get; + } + } +} diff --git a/src/Spring/Spring.Core/Core/IO/IResource.cs b/src/Spring/Spring.Core/Core/IO/IResource.cs index 6c459191..4aaab194 100644 --- a/src/Spring/Spring.Core/Core/IO/IResource.cs +++ b/src/Spring/Spring.Core/Core/IO/IResource.cs @@ -1,195 +1,194 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.IO; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// The central abstraction for Spring.NET's access to resources such as - /// s. - /// - /// - ///

- /// This interface encapsulates a resource descriptor that abstracts away - /// from the underlying type of resource; possible resource types include - /// files, memory streams, and databases (this list is not exhaustive). - ///

- ///

- /// A can definitely be opened and accessed - /// for every such resource; if the resource exists in a physical form (for - /// example, the resource is not an in-memory stream or one that has been - /// extracted from an assembly or ZIP file), a or - /// can also be accessed. The actual - /// behavior is implementation-specific. - ///

- ///

- /// This interface, when used in tandem with the - /// interface, forms the backbone of - /// Spring.NET's resource handling. Third party extensions or libraries - /// that want to integrate external resources with Spring.NET's IoC - /// container are encouraged expose such resources via this abstraction. - ///

- ///

- /// Interfaces cannot obviously mandate implementation, but derived classes - /// are strongly encouraged to expose a constructor that takes a - /// single as it's sole argument (see example). - /// Exposing such a constructor will make your custom - /// implementation integrate nicely - /// with the class. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IResource.cs,v 1.12 2007/08/08 17:46:55 bbaia Exp $ - /// - /// - [TypeConverter(typeof(ResourceConverter))] - public interface IResource : IInputStreamSource - { - /// - /// Does this resource represent a handle with an open stream? - /// - /// - ///

- /// If , the - /// cannot be read multiple times, and must be read and then closed to - /// avoid resource leaks. - ///

- ///

- /// Will be for all usual resource descriptors. - ///

- ///
- /// - /// if this resource represents a handle with an - /// open stream. - /// - /// - bool IsOpen { get; } - - /// - /// Returns the handle for this resource. - /// - /// - ///

- /// For safety, always check the value of the - /// property prior to - /// accessing this property; resources that cannot be exposed as - /// a will typically return - /// from a call to the - /// property. - ///

- ///
- /// - /// The handle for this resource. - /// - /// - /// If the resource is not available or cannot be exposed as a - /// . - /// - /// - /// - Uri Uri { get; } - - /// - /// Returns a handle for this resource. - /// - /// - ///

- /// For safety, always check the value of the - /// property prior to - /// accessing this property; resources that cannot be exposed as - /// a will typically return - /// from a call to the - /// property. - ///

- ///
- /// - /// The handle for this resource. - /// - /// - /// If the resource is not available on a filesystem, or cannot be - /// exposed as a handle. - /// - /// - /// - FileInfo File { get; } - - /// - /// Returns a description for this resource. - /// - /// - ///

- /// The description is typically used for diagnostics and other such - /// logging when working with the resource. - ///

- ///

- /// Implementations are also encouraged to return this value from their - /// method. - ///

- ///
- /// - /// A description for this resource. - /// - string Description { get; } - - /// - /// Does this resource actually exist in physical form? - /// - /// - ///

- /// An example of a resource that physically exists would be a - /// file on a local filesystem. An example of a resource that does not - /// physically exist would be an in-memory stream. - ///

- ///
- /// - /// if this resource actually exists in physical - /// form (for example on a filesystem). - /// - /// - /// - bool Exists { get; } - - /// - /// Creates a resource relative to this resource. - /// - /// - /// The path (always resolved as relative to this resource). - /// - /// - /// The relative resource. - /// - /// - /// If the relative resource could not be created from the supplied - /// path. - /// - /// - /// If the resource does not support the notion of a relative path. - /// - IResource CreateRelative(string relativePath); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.IO; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// The central abstraction for Spring.NET's access to resources such as + /// s. + /// + /// + ///

+ /// This interface encapsulates a resource descriptor that abstracts away + /// from the underlying type of resource; possible resource types include + /// files, memory streams, and databases (this list is not exhaustive). + ///

+ ///

+ /// A can definitely be opened and accessed + /// for every such resource; if the resource exists in a physical form (for + /// example, the resource is not an in-memory stream or one that has been + /// extracted from an assembly or ZIP file), a or + /// can also be accessed. The actual + /// behavior is implementation-specific. + ///

+ ///

+ /// This interface, when used in tandem with the + /// interface, forms the backbone of + /// Spring.NET's resource handling. Third party extensions or libraries + /// that want to integrate external resources with Spring.NET's IoC + /// container are encouraged expose such resources via this abstraction. + ///

+ ///

+ /// Interfaces cannot obviously mandate implementation, but derived classes + /// are strongly encouraged to expose a constructor that takes a + /// single as it's sole argument (see example). + /// Exposing such a constructor will make your custom + /// implementation integrate nicely + /// with the class. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// + /// + [TypeConverter(typeof(ResourceConverter))] + public interface IResource : IInputStreamSource + { + /// + /// Does this resource represent a handle with an open stream? + /// + /// + ///

+ /// If , the + /// cannot be read multiple times, and must be read and then closed to + /// avoid resource leaks. + ///

+ ///

+ /// Will be for all usual resource descriptors. + ///

+ ///
+ /// + /// if this resource represents a handle with an + /// open stream. + /// + /// + bool IsOpen { get; } + + /// + /// Returns the handle for this resource. + /// + /// + ///

+ /// For safety, always check the value of the + /// property prior to + /// accessing this property; resources that cannot be exposed as + /// a will typically return + /// from a call to the + /// property. + ///

+ ///
+ /// + /// The handle for this resource. + /// + /// + /// If the resource is not available or cannot be exposed as a + /// . + /// + /// + /// + Uri Uri { get; } + + /// + /// Returns a handle for this resource. + /// + /// + ///

+ /// For safety, always check the value of the + /// property prior to + /// accessing this property; resources that cannot be exposed as + /// a will typically return + /// from a call to the + /// property. + ///

+ ///
+ /// + /// The handle for this resource. + /// + /// + /// If the resource is not available on a filesystem, or cannot be + /// exposed as a handle. + /// + /// + /// + FileInfo File { get; } + + /// + /// Returns a description for this resource. + /// + /// + ///

+ /// The description is typically used for diagnostics and other such + /// logging when working with the resource. + ///

+ ///

+ /// Implementations are also encouraged to return this value from their + /// method. + ///

+ ///
+ /// + /// A description for this resource. + /// + string Description { get; } + + /// + /// Does this resource actually exist in physical form? + /// + /// + ///

+ /// An example of a resource that physically exists would be a + /// file on a local filesystem. An example of a resource that does not + /// physically exist would be an in-memory stream. + ///

+ ///
+ /// + /// if this resource actually exists in physical + /// form (for example on a filesystem). + /// + /// + /// + bool Exists { get; } + + /// + /// Creates a resource relative to this resource. + /// + /// + /// The path (always resolved as relative to this resource). + /// + /// + /// The relative resource. + /// + /// + /// If the relative resource could not be created from the supplied + /// path. + /// + /// + /// If the resource does not support the notion of a relative path. + /// + IResource CreateRelative(string relativePath); + } +} diff --git a/src/Spring/Spring.Core/Core/IO/IResourceLoader.cs b/src/Spring/Spring.Core/Core/IO/IResourceLoader.cs index 8c7c0140..9310b35c 100644 --- a/src/Spring/Spring.Core/Core/IO/IResourceLoader.cs +++ b/src/Spring/Spring.Core/Core/IO/IResourceLoader.cs @@ -1,94 +1,93 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Core.IO -{ - /// - /// Describes an object that can load - /// s. - /// - /// - ///

- /// An implementation is - /// generally required to support the functionality described by this - /// interface. - ///

- ///

- /// The class is a - /// standalone implementation that is usable outside an - /// ; the aforementioned - /// class is also used by the - /// class. - ///

- ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: IResourceLoader.cs,v 1.12 2007/08/08 17:46:55 bbaia Exp $ - /// - /// - /// - public interface IResourceLoader - { - /// - /// Return an handle for the - /// specified resource. - /// - /// - ///

- /// The handle should always be a reusable resource descriptor; this - /// allows one to make repeated calls to the underlying - /// . - ///

- ///

- ///

    - ///
  • - /// Must support fully qualified URLs, e.g. "file:C:/test.dat". - ///
  • - ///
  • - /// Should support relative file paths, e.g. "test.dat" (this will be - /// implementation-specific, typically provided by an - /// implementation). - ///
  • - ///
- ///

- /// - /// An handle does not imply an - /// existing resource; you need to check the value of an - /// 's - /// property to determine - /// conclusively whether or not the resource actually exists. - /// - ///
- /// The resource location. - /// - /// An appropriate handle. - /// - /// - /// - /// - IResource GetResource(string location); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Core.IO +{ + /// + /// Describes an object that can load + /// s. + /// + /// + ///

+ /// An implementation is + /// generally required to support the functionality described by this + /// interface. + ///

+ ///

+ /// The class is a + /// standalone implementation that is usable outside an + /// ; the aforementioned + /// class is also used by the + /// class. + ///

+ ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + /// + /// + /// + public interface IResourceLoader + { + /// + /// Return an handle for the + /// specified resource. + /// + /// + ///

+ /// The handle should always be a reusable resource descriptor; this + /// allows one to make repeated calls to the underlying + /// . + ///

+ ///

+ ///

    + ///
  • + /// Must support fully qualified URLs, e.g. "file:C:/test.dat". + ///
  • + ///
  • + /// Should support relative file paths, e.g. "test.dat" (this will be + /// implementation-specific, typically provided by an + /// implementation). + ///
  • + ///
+ ///

+ /// + /// An handle does not imply an + /// existing resource; you need to check the value of an + /// 's + /// property to determine + /// conclusively whether or not the resource actually exists. + /// + ///
+ /// The resource location. + /// + /// An appropriate handle. + /// + /// + /// + /// + IResource GetResource(string location); + } +} diff --git a/src/Spring/Spring.Core/Core/IO/InputStreamResource.cs b/src/Spring/Spring.Core/Core/IO/InputStreamResource.cs index fc051b95..9c0e0f7e 100644 --- a/src/Spring/Spring.Core/Core/IO/InputStreamResource.cs +++ b/src/Spring/Spring.Core/Core/IO/InputStreamResource.cs @@ -1,145 +1,144 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using Spring.Util; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// adapter implementation for a - /// . - /// - /// - ///

- /// Should only be used if no other - /// implementation is applicable. - ///

- ///

- /// In contrast to other - /// implementations, this is an adapter for an already opened - /// resource - the - /// therefore always returns . Do not use this class - /// if you need to keep the resource descriptor somewhere, or if you need - /// to read a stream multiple times. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: InputStreamResource.cs,v 1.10 2007/12/06 22:08:47 markpollack Exp $ - public class InputStreamResource : AbstractResource - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The input to use. - /// - /// - /// Where the input comes from. - /// - /// - /// If the supplied is - /// . - /// - public InputStreamResource(Stream inputStream, string description) - { - AssertUtils.ArgumentNotNull(inputStream, "inputStream"); - - _inputStream = inputStream; - _description = description == null ? string.Empty : description; - } - - #endregion - - #region Properties - - /// - /// The input to use. - /// - /// - /// If the underlying has already - /// been read. - /// - public override Stream InputStream - { - get - { - if (_inputStream == null) - { - throw new InvalidOperationException( - "InputStream has already been read - " + - "do not use InputStreamResource if a stream " + - "needs to be read multiple times"); - } - Stream result = _inputStream; - _inputStream = null; - return result; - } - } - - /// - /// Returns a description for this resource. - /// - /// - /// A description for this resource. - /// - /// - public override string Description - { - get { return _description; } - } - - /// - /// This implementation always returns true - /// - public override bool IsOpen - { - get { return true; } - } - - - - /// - /// This implemementation always returns true - /// - public override bool Exists - { - get { return true; } - } - - #endregion - - #region Fields - - private Stream _inputStream; - private string _description; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using Spring.Util; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// adapter implementation for a + /// . + /// + /// + ///

+ /// Should only be used if no other + /// implementation is applicable. + ///

+ ///

+ /// In contrast to other + /// implementations, this is an adapter for an already opened + /// resource - the + /// therefore always returns . Do not use this class + /// if you need to keep the resource descriptor somewhere, or if you need + /// to read a stream multiple times. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public class InputStreamResource : AbstractResource + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The input to use. + /// + /// + /// Where the input comes from. + /// + /// + /// If the supplied is + /// . + /// + public InputStreamResource(Stream inputStream, string description) + { + AssertUtils.ArgumentNotNull(inputStream, "inputStream"); + + _inputStream = inputStream; + _description = description == null ? string.Empty : description; + } + + #endregion + + #region Properties + + /// + /// The input to use. + /// + /// + /// If the underlying has already + /// been read. + /// + public override Stream InputStream + { + get + { + if (_inputStream == null) + { + throw new InvalidOperationException( + "InputStream has already been read - " + + "do not use InputStreamResource if a stream " + + "needs to be read multiple times"); + } + Stream result = _inputStream; + _inputStream = null; + return result; + } + } + + /// + /// Returns a description for this resource. + /// + /// + /// A description for this resource. + /// + /// + public override string Description + { + get { return _description; } + } + + /// + /// This implementation always returns true + /// + public override bool IsOpen + { + get { return true; } + } + + + + /// + /// This implemementation always returns true + /// + public override bool Exists + { + get { return true; } + } + + #endregion + + #region Fields + + private Stream _inputStream; + private string _description; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/ResourceConverter.cs b/src/Spring/Spring.Core/Core/IO/ResourceConverter.cs index 45a72155..6d7b5e98 100644 --- a/src/Spring/Spring.Core/Core/IO/ResourceConverter.cs +++ b/src/Spring/Spring.Core/Core/IO/ResourceConverter.cs @@ -1,215 +1,214 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.ComponentModel; -using System.Globalization; -using Common.Logging; -using Spring.Util; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// Custom type converter for instances. - /// - /// - ///

- /// A resource path may contain placeholder variables of the form ${...} - /// that will be expended to environment variables. - ///

- ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - ///

- /// On Win9x boxes, this resource path, ${userprofile}\objects.xml will - /// be expanded at runtime with the value of the 'userprofile' environment - /// variable substituted for the '${userprofile}' portion of the path. - ///

- /// - /// // assuming a user called Rick, running on a plain vanilla Windows XP setup... - /// // this resource path... - /// - /// ${userprofile}\objects.xml - /// - /// // will become (after expansion)... - /// - /// C:\Documents and Settings\Rick\objects.xml - /// - ///
- /// Mark Pollack - /// $Id: ResourceConverter.cs,v 1.14 2007/08/08 17:46:55 bbaia Exp $ - /// - /// - public class ResourceConverter : TypeConverter - { - private ILog _log = LogManager.GetLogger(typeof (ResourceConverter)); - private IResourceLoader _resourceLoader; - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public ResourceConverter() - { - _resourceLoader = new ConfigurableResourceLoader(); - } - - /// - /// Creates a new instance of the - /// class using the specified resourceLoader. - /// - /// the underlying IResourceLoader to be used to resolve resources - public ResourceConverter( IResourceLoader resourceLoader ) - { - AssertUtils.ArgumentNotNull( resourceLoader, "resourceLoader" ); - _resourceLoader = resourceLoader; - } - #endregion - - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// - /// if the conversion is possible. - /// - public override bool CanConvertFrom( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Convert from a string value to a - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// An if successful. - /// - /// - /// If the resource name objectained form the supplied - /// is malformed. - /// - /// - /// In the case of any errors arising from the instantiation of the - /// returned instance. - /// - public override object ConvertFrom( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - string resource = value as string; - if (resource != null) - { - return GetResourceLoader().GetResource(ResolvePath(resource)); - } - return base.ConvertFrom(context, culture, value); - } - - /// - /// Resolve the given path, replacing placeholder values with - /// corresponding property values if necessary. - /// - /// - ///

- /// This implementation resolves environment variables only. - ///

- ///
- /// The original resource path. - /// The resolved resource path. - protected virtual string ResolvePath(string path) - { - // quite inefficient, but cost is only ever paid once at startup... - IList expressions = StringUtils.GetAntExpressions(path); - foreach (string expression in expressions) - { - string environmentValue - = Environment.GetEnvironmentVariable(expression); - if (environmentValue != null) - { - path = StringUtils.SetAntExpression( - path, expression, environmentValue); - } - else - { - #region Instrumentation - - if (_log.IsWarnEnabled) - { - _log.Warn(string.Format( - CultureInfo.InvariantCulture, - "Could not resolve placeholder '{0}' in resource path " + - "'{1}' as an environment variable.", expression, path)); - } - - #endregion - } - } - return path; - } - - /// - /// Return the used to - /// resolve the string. - /// - /// - /// The used to resolve - /// the string. - /// - protected internal virtual IResourceLoader GetResourceLoader() - { - return _resourceLoader; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using Common.Logging; +using Spring.Util; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// Custom type converter for instances. + /// + /// + ///

+ /// A resource path may contain placeholder variables of the form ${...} + /// that will be expended to environment variables. + ///

+ ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + ///

+ /// On Win9x boxes, this resource path, ${userprofile}\objects.xml will + /// be expanded at runtime with the value of the 'userprofile' environment + /// variable substituted for the '${userprofile}' portion of the path. + ///

+ /// + /// // assuming a user called Rick, running on a plain vanilla Windows XP setup... + /// // this resource path... + /// + /// ${userprofile}\objects.xml + /// + /// // will become (after expansion)... + /// + /// C:\Documents and Settings\Rick\objects.xml + /// + ///
+ /// Mark Pollack + /// + /// + public class ResourceConverter : TypeConverter + { + private ILog _log = LogManager.GetLogger(typeof (ResourceConverter)); + private IResourceLoader _resourceLoader; + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public ResourceConverter() + { + _resourceLoader = new ConfigurableResourceLoader(); + } + + /// + /// Creates a new instance of the + /// class using the specified resourceLoader. + /// + /// the underlying IResourceLoader to be used to resolve resources + public ResourceConverter( IResourceLoader resourceLoader ) + { + AssertUtils.ArgumentNotNull( resourceLoader, "resourceLoader" ); + _resourceLoader = resourceLoader; + } + #endregion + + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// + /// if the conversion is possible. + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Convert from a string value to a + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// An if successful. + /// + /// + /// If the resource name objectained form the supplied + /// is malformed. + /// + /// + /// In the case of any errors arising from the instantiation of the + /// returned instance. + /// + public override object ConvertFrom( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + string resource = value as string; + if (resource != null) + { + return GetResourceLoader().GetResource(ResolvePath(resource)); + } + return base.ConvertFrom(context, culture, value); + } + + /// + /// Resolve the given path, replacing placeholder values with + /// corresponding property values if necessary. + /// + /// + ///

+ /// This implementation resolves environment variables only. + ///

+ ///
+ /// The original resource path. + /// The resolved resource path. + protected virtual string ResolvePath(string path) + { + // quite inefficient, but cost is only ever paid once at startup... + IList expressions = StringUtils.GetAntExpressions(path); + foreach (string expression in expressions) + { + string environmentValue + = Environment.GetEnvironmentVariable(expression); + if (environmentValue != null) + { + path = StringUtils.SetAntExpression( + path, expression, environmentValue); + } + else + { + #region Instrumentation + + if (_log.IsWarnEnabled) + { + _log.Warn(string.Format( + CultureInfo.InvariantCulture, + "Could not resolve placeholder '{0}' in resource path " + + "'{1}' as an environment variable.", expression, path)); + } + + #endregion + } + } + return path; + } + + /// + /// Return the used to + /// resolve the string. + /// + /// + /// The used to resolve + /// the string. + /// + protected internal virtual IResourceLoader GetResourceLoader() + { + return _resourceLoader; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs b/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs index 053d6154..bb3ab665 100644 --- a/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs +++ b/src/Spring/Spring.Core/Core/IO/ResourceHandlerRegistry.cs @@ -1,264 +1,263 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; - -using Spring.Context.Support; -using Spring.Core.TypeResolution; -using Spring.Util; -using Spring.Reflection.Dynamic; - -namespace Spring.Core.IO -{ - /// - /// Registry class that allows users to register and retrieve protocol handlers. - /// - /// - /// - /// Resource handler is an implementation of interface - /// that should be used to process resources with the specified protocol. - /// - /// - /// They are used throughout the framework to access resources from various - /// sources. For example, application context loads object definitions from the resources - /// that are processed using one of the registered resource handlers. - /// - /// Following resource handlers are registered by default: - /// - /// - /// Protocol - /// Handler Type - /// Description - /// - /// - /// config - /// - /// Resolves the resources by loading specified configuration section from the standard .NET config file. - /// - /// - /// file - /// - /// Resolves filesystem resources. - /// - /// - /// http - /// - /// Resolves remote web resources. - /// - /// - /// https - /// - /// Resolves remote web resources via HTTPS. - /// - /// - /// ftp - /// - /// Resolves ftp resources. - /// - /// - /// assembly - /// - /// Resolves resources that are embedded into an assembly. - /// - /// - /// web - /// Spring.Core.IO.WebResource, Spring.Web* - /// Resolves resources relative to the web application's virtual directory. - /// - /// - /// * only available in web applications. - /// - /// Users can create and register their own protocol handlers by implementing interface - /// and mapping custom protocol name to that implementation. See for details - /// on how to register custom protocol handler. - /// - /// - /// Aleksandar Seovic - /// $Id: ResourceHandlerRegistry.cs,v 1.7 2007/08/08 17:46:55 bbaia Exp $ - public class ResourceHandlerRegistry - { - /// - /// Name of the .Net config section that contains definitions - /// for custom resource handlers. - /// - private const string ResourcesSectionName = "spring/resourceHandlers"; - - private static IDictionary resourceHandlers = new Hashtable(); - - /// - /// Registers standard and user-configured resource handlers. - /// - static ResourceHandlerRegistry() - { - lock (resourceHandlers.SyncRoot) - { - resourceHandlers["config"] = GetResourceConstructor(typeof(ConfigSectionResource)); - resourceHandlers["file"] = GetResourceConstructor(typeof(FileSystemResource)); - resourceHandlers["http"] = GetResourceConstructor(typeof(UrlResource)); - resourceHandlers["https"] = GetResourceConstructor(typeof(UrlResource)); -#if NET_2_0 - resourceHandlers["ftp"] = GetResourceConstructor(typeof(UrlResource)); -#endif - resourceHandlers["assembly"] = GetResourceConstructor(typeof(AssemblyResource)); - - // register custom resource handlers - ConfigurationUtils.GetSection(ResourcesSectionName); - } - } - - /// - /// Returns resource handler for the specified protocol name. - /// - /// - /// - /// This method returns object that should be used - /// to create an instance of the -derived type by passing - /// resource location as a parameter. - /// - /// - /// Name of the protocol to get the handler for. - /// Resource handler constructor for the specified protocol name. - /// If is null. - public static IDynamicConstructor GetResourceHandler(string protocolName) - { - AssertUtils.ArgumentNotNull(protocolName, "protocolName"); - return (IDynamicConstructor) resourceHandlers[protocolName]; - } - - /// - /// Returns true if a handler is registered for the specified protocol, - /// false otherwise. - /// - /// Name of the protocol. - /// - /// true if a handler is registered for the specified protocol, false otherwise. - /// - /// If is null. - public static bool IsHandlerRegistered(string protocolName) - { - return resourceHandlers.Contains(protocolName); - } - - /// - /// Registers resource handler and maps it to the specified protocol name. - /// - /// - ///

- /// If the mapping already exists, the existing mapping will be - /// silently overwritten with the new mapping. - ///

- ///
- /// - /// The protocol to add (or override). - /// - /// - /// The type name of the concrete implementation of the - /// interface that will handle - /// the specified protocol. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s); or - /// if the supplied is - /// . - /// - /// - /// If the supplied is not a - /// that derives from the - /// interface; or (having passed - /// this first check), the supplied - /// does not expose a constructor that takes a single - /// parameter. - /// - public static void RegisterResourceHandler(string protocolName, string handlerTypeName) - { - AssertUtils.ArgumentHasText(protocolName, "protocolName"); - AssertUtils.ArgumentHasText(handlerTypeName, "handlerTypeName"); - - Type handlerType = TypeResolutionUtils.ResolveType(handlerTypeName); - RegisterResourceHandler(protocolName, handlerType); - } - - /// - /// Registers resource handler and maps it to the specified protocol name. - /// - /// - ///

- /// If the mapping already exists, the existing mapping will be - /// silently overwritten with the new mapping. - ///

- ///
- /// - /// The protocol to add (or override). - /// - /// - /// The concrete implementation of the - /// interface that will handle - /// the specified protocol. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s); or - /// if the supplied is - /// . - /// - /// - /// If the supplied is not a - /// that derives from the - /// interface; or (having passed - /// this first check), the supplied - /// does not expose a constructor that takes a single - /// parameter. - /// - public static void RegisterResourceHandler(string protocolName, Type handlerType) - { - #region Sanity Checks - - AssertUtils.ArgumentHasText(protocolName, "protocolName"); - AssertUtils.ArgumentNotNull(handlerType, "handlerType"); - if (!typeof(IResource).IsAssignableFrom(handlerType)) - { - throw new ArgumentException( - string.Format("[{0}] does not implement [{1}] interface (it must).", handlerType.FullName, typeof(IResource).FullName)); - } - - #endregion - - lock (resourceHandlers.SyncRoot) - { - IDynamicConstructor ctor = GetResourceConstructor(handlerType); - resourceHandlers[protocolName] = ctor; - } - } - - private static IDynamicConstructor GetResourceConstructor(Type handlerType) - { - ConstructorInfo ctor = handlerType.GetConstructor(new Type[] {typeof(string)}); - if (ctor == null) - { - throw new ArgumentException( - string.Format("[{0}] does not have a constructor that takes a single string as an argument (it must).", handlerType.FullName)); - } - return DynamicConstructor.Create(ctor); - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; + +using Spring.Context.Support; +using Spring.Core.TypeResolution; +using Spring.Util; +using Spring.Reflection.Dynamic; + +namespace Spring.Core.IO +{ + /// + /// Registry class that allows users to register and retrieve protocol handlers. + /// + /// + /// + /// Resource handler is an implementation of interface + /// that should be used to process resources with the specified protocol. + /// + /// + /// They are used throughout the framework to access resources from various + /// sources. For example, application context loads object definitions from the resources + /// that are processed using one of the registered resource handlers. + /// + /// Following resource handlers are registered by default: + /// + /// + /// Protocol + /// Handler Type + /// Description + /// + /// + /// config + /// + /// Resolves the resources by loading specified configuration section from the standard .NET config file. + /// + /// + /// file + /// + /// Resolves filesystem resources. + /// + /// + /// http + /// + /// Resolves remote web resources. + /// + /// + /// https + /// + /// Resolves remote web resources via HTTPS. + /// + /// + /// ftp + /// + /// Resolves ftp resources. + /// + /// + /// assembly + /// + /// Resolves resources that are embedded into an assembly. + /// + /// + /// web + /// Spring.Core.IO.WebResource, Spring.Web* + /// Resolves resources relative to the web application's virtual directory. + /// + /// + /// * only available in web applications. + /// + /// Users can create and register their own protocol handlers by implementing interface + /// and mapping custom protocol name to that implementation. See for details + /// on how to register custom protocol handler. + /// + /// + /// Aleksandar Seovic + public class ResourceHandlerRegistry + { + /// + /// Name of the .Net config section that contains definitions + /// for custom resource handlers. + /// + private const string ResourcesSectionName = "spring/resourceHandlers"; + + private static IDictionary resourceHandlers = new Hashtable(); + + /// + /// Registers standard and user-configured resource handlers. + /// + static ResourceHandlerRegistry() + { + lock (resourceHandlers.SyncRoot) + { + resourceHandlers["config"] = GetResourceConstructor(typeof(ConfigSectionResource)); + resourceHandlers["file"] = GetResourceConstructor(typeof(FileSystemResource)); + resourceHandlers["http"] = GetResourceConstructor(typeof(UrlResource)); + resourceHandlers["https"] = GetResourceConstructor(typeof(UrlResource)); +#if NET_2_0 + resourceHandlers["ftp"] = GetResourceConstructor(typeof(UrlResource)); +#endif + resourceHandlers["assembly"] = GetResourceConstructor(typeof(AssemblyResource)); + + // register custom resource handlers + ConfigurationUtils.GetSection(ResourcesSectionName); + } + } + + /// + /// Returns resource handler for the specified protocol name. + /// + /// + /// + /// This method returns object that should be used + /// to create an instance of the -derived type by passing + /// resource location as a parameter. + /// + /// + /// Name of the protocol to get the handler for. + /// Resource handler constructor for the specified protocol name. + /// If is null. + public static IDynamicConstructor GetResourceHandler(string protocolName) + { + AssertUtils.ArgumentNotNull(protocolName, "protocolName"); + return (IDynamicConstructor) resourceHandlers[protocolName]; + } + + /// + /// Returns true if a handler is registered for the specified protocol, + /// false otherwise. + /// + /// Name of the protocol. + /// + /// true if a handler is registered for the specified protocol, false otherwise. + /// + /// If is null. + public static bool IsHandlerRegistered(string protocolName) + { + return resourceHandlers.Contains(protocolName); + } + + /// + /// Registers resource handler and maps it to the specified protocol name. + /// + /// + ///

+ /// If the mapping already exists, the existing mapping will be + /// silently overwritten with the new mapping. + ///

+ ///
+ /// + /// The protocol to add (or override). + /// + /// + /// The type name of the concrete implementation of the + /// interface that will handle + /// the specified protocol. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s); or + /// if the supplied is + /// . + /// + /// + /// If the supplied is not a + /// that derives from the + /// interface; or (having passed + /// this first check), the supplied + /// does not expose a constructor that takes a single + /// parameter. + /// + public static void RegisterResourceHandler(string protocolName, string handlerTypeName) + { + AssertUtils.ArgumentHasText(protocolName, "protocolName"); + AssertUtils.ArgumentHasText(handlerTypeName, "handlerTypeName"); + + Type handlerType = TypeResolutionUtils.ResolveType(handlerTypeName); + RegisterResourceHandler(protocolName, handlerType); + } + + /// + /// Registers resource handler and maps it to the specified protocol name. + /// + /// + ///

+ /// If the mapping already exists, the existing mapping will be + /// silently overwritten with the new mapping. + ///

+ ///
+ /// + /// The protocol to add (or override). + /// + /// + /// The concrete implementation of the + /// interface that will handle + /// the specified protocol. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s); or + /// if the supplied is + /// . + /// + /// + /// If the supplied is not a + /// that derives from the + /// interface; or (having passed + /// this first check), the supplied + /// does not expose a constructor that takes a single + /// parameter. + /// + public static void RegisterResourceHandler(string protocolName, Type handlerType) + { + #region Sanity Checks + + AssertUtils.ArgumentHasText(protocolName, "protocolName"); + AssertUtils.ArgumentNotNull(handlerType, "handlerType"); + if (!typeof(IResource).IsAssignableFrom(handlerType)) + { + throw new ArgumentException( + string.Format("[{0}] does not implement [{1}] interface (it must).", handlerType.FullName, typeof(IResource).FullName)); + } + + #endregion + + lock (resourceHandlers.SyncRoot) + { + IDynamicConstructor ctor = GetResourceConstructor(handlerType); + resourceHandlers[protocolName] = ctor; + } + } + + private static IDynamicConstructor GetResourceConstructor(Type handlerType) + { + ConstructorInfo ctor = handlerType.GetConstructor(new Type[] {typeof(string)}); + if (ctor == null) + { + throw new ArgumentException( + string.Format("[{0}] does not have a constructor that takes a single string as an argument (it must).", handlerType.FullName)); + } + return DynamicConstructor.Create(ctor); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IO/UrlResource.cs b/src/Spring/Spring.Core/Core/IO/UrlResource.cs index fad9ae5d..92facea9 100644 --- a/src/Spring/Spring.Core/Core/IO/UrlResource.cs +++ b/src/Spring/Spring.Core/Core/IO/UrlResource.cs @@ -1,269 +1,268 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using System.Net; -using Spring.Util; - -#endregion - -namespace Spring.Core.IO -{ - /// - /// A backed resource - /// on top of - /// - /// - ///

- /// Obviously supports resolution as a , and also - /// as a in the case of the "file:" - /// protocol. - ///

- ///
- /// - ///

- /// Some examples of the strings that can be used to initialize a new - /// instance of the class - /// include... - /// - /// - /// file:///Config/objects.xml - /// - /// - /// http://www.mycompany.com/services.txt - /// - /// - ///

- ///
- /// Juergen Hoeller - /// Leonardo Susatyo (.NET) - /// Aleksandar Seovic (.NET) - /// $Id: UrlResource.cs,v 1.15 2007/08/08 17:46:55 bbaia Exp $ - /// - /// - /// - public class UrlResource : AbstractResource - { - private Uri _uri; - private WebRequest _webRequest; - private string _rootLocation; - private string _resourcePath; - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Some examples of the values that the - /// can typically be expected to hold include... - /// - /// - /// file:///Config/objects.xml - /// - /// - /// http://www.mycompany.com/services.txt - /// - /// - ///

- ///
- /// - /// A string representation of the resource. - /// - public UrlResource(string resourceName) : base(resourceName) - { - this._uri = new Uri(resourceName); - _rootLocation = _uri.Host; - if (!_uri.IsDefaultPort) - { - _rootLocation += ":" + _uri.Port; - } - _resourcePath = _uri.AbsolutePath; - int n = _resourcePath.LastIndexOf('/'); - if (n > 0) - { - _resourcePath = _resourcePath.Substring(1, n - 1); - } - else - { - _resourcePath = null; - } - _webRequest = WebRequest.Create(_uri); - } - - /// - /// Returns the instance - /// used for the resource resolution. - /// - /// - /// A instance. - /// - /// - /// - public WebRequest WebRequest - { - get { return _webRequest; } - } - - /// - /// Return an for this resource. - /// - /// - /// An . - /// - /// - /// If the stream could not be opened. - /// - /// - public override Stream InputStream - { - get { return _webRequest.GetResponse().GetResponseStream(); } - } - - /// - /// Returns the handle for this resource. - /// - /// - /// The handle for this resource. - /// - /// - /// If the resource is not available or cannot be exposed as a - /// . - /// - /// - public override Uri Uri - { - get { return _uri; } - } - - /// - /// Returns a handle for this resource. - /// - /// - /// The handle for this resource. - /// - /// - /// If the resource is not available on a filesystem. - /// - /// - public override FileInfo File - { - get - { - if (_uri.IsFile) - { - return new FileInfo(_uri.AbsolutePath); - } - throw new FileNotFoundException(Description + - " cannot be resolved to absolute file path - " + - "resource does not use 'file:' protocol." ); - } - } - - /// - /// Does this support relative - /// resource retrieval? - /// - /// - ///

- /// This implementation does support relative resource retrieval, and - /// so will always return . - ///

- ///
- /// - /// if this - /// supports relative resource - /// retrieval. - /// - /// - protected override bool SupportsRelativeResources - { - get { return true; } - } - - /// - /// Gets the root location of the resource. - /// - /// - /// The root location of the resource. - /// - /// - protected override string RootLocation - { - get { return _rootLocation; } - } - - /// - /// Gets the current path of the resource. - /// - /// - /// The current path of the resource. - /// - /// - protected override string ResourcePath - { - get { return _resourcePath; } - } - - /// - /// Gets those characters that are valid path separators for the - /// resource type. - /// - /// - /// Those characters that are valid path separators for the resource - /// type. - /// - /// - protected override char[] PathSeparatorChars - { - get { return new char[] {'/'}; } - } - - /// - /// Returns a description for this resource. - /// - /// - /// A description for this resource. - /// - /// - public override string Description - { - get { return StringUtils.Surround("URL [", Uri, "]"); } - } - - /// - /// Does the supplied relative ? - /// - /// - /// The name of the resource to test. - /// - /// - /// if resource name is relative; - /// otherwise . - /// - protected override bool IsRelativeResource(string resourceName) - { - return true; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using System.Net; +using Spring.Util; + +#endregion + +namespace Spring.Core.IO +{ + /// + /// A backed resource + /// on top of + /// + /// + ///

+ /// Obviously supports resolution as a , and also + /// as a in the case of the "file:" + /// protocol. + ///

+ ///
+ /// + ///

+ /// Some examples of the strings that can be used to initialize a new + /// instance of the class + /// include... + /// + /// + /// file:///Config/objects.xml + /// + /// + /// http://www.mycompany.com/services.txt + /// + /// + ///

+ ///
+ /// Juergen Hoeller + /// Leonardo Susatyo (.NET) + /// Aleksandar Seovic (.NET) + /// + /// + /// + public class UrlResource : AbstractResource + { + private Uri _uri; + private WebRequest _webRequest; + private string _rootLocation; + private string _resourcePath; + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Some examples of the values that the + /// can typically be expected to hold include... + /// + /// + /// file:///Config/objects.xml + /// + /// + /// http://www.mycompany.com/services.txt + /// + /// + ///

+ ///
+ /// + /// A string representation of the resource. + /// + public UrlResource(string resourceName) : base(resourceName) + { + this._uri = new Uri(resourceName); + _rootLocation = _uri.Host; + if (!_uri.IsDefaultPort) + { + _rootLocation += ":" + _uri.Port; + } + _resourcePath = _uri.AbsolutePath; + int n = _resourcePath.LastIndexOf('/'); + if (n > 0) + { + _resourcePath = _resourcePath.Substring(1, n - 1); + } + else + { + _resourcePath = null; + } + _webRequest = WebRequest.Create(_uri); + } + + /// + /// Returns the instance + /// used for the resource resolution. + /// + /// + /// A instance. + /// + /// + /// + public WebRequest WebRequest + { + get { return _webRequest; } + } + + /// + /// Return an for this resource. + /// + /// + /// An . + /// + /// + /// If the stream could not be opened. + /// + /// + public override Stream InputStream + { + get { return _webRequest.GetResponse().GetResponseStream(); } + } + + /// + /// Returns the handle for this resource. + /// + /// + /// The handle for this resource. + /// + /// + /// If the resource is not available or cannot be exposed as a + /// . + /// + /// + public override Uri Uri + { + get { return _uri; } + } + + /// + /// Returns a handle for this resource. + /// + /// + /// The handle for this resource. + /// + /// + /// If the resource is not available on a filesystem. + /// + /// + public override FileInfo File + { + get + { + if (_uri.IsFile) + { + return new FileInfo(_uri.AbsolutePath); + } + throw new FileNotFoundException(Description + + " cannot be resolved to absolute file path - " + + "resource does not use 'file:' protocol." ); + } + } + + /// + /// Does this support relative + /// resource retrieval? + /// + /// + ///

+ /// This implementation does support relative resource retrieval, and + /// so will always return . + ///

+ ///
+ /// + /// if this + /// supports relative resource + /// retrieval. + /// + /// + protected override bool SupportsRelativeResources + { + get { return true; } + } + + /// + /// Gets the root location of the resource. + /// + /// + /// The root location of the resource. + /// + /// + protected override string RootLocation + { + get { return _rootLocation; } + } + + /// + /// Gets the current path of the resource. + /// + /// + /// The current path of the resource. + /// + /// + protected override string ResourcePath + { + get { return _resourcePath; } + } + + /// + /// Gets those characters that are valid path separators for the + /// resource type. + /// + /// + /// Those characters that are valid path separators for the resource + /// type. + /// + /// + protected override char[] PathSeparatorChars + { + get { return new char[] {'/'}; } + } + + /// + /// Returns a description for this resource. + /// + /// + /// A description for this resource. + /// + /// + public override string Description + { + get { return StringUtils.Surround("URL [", Uri, "]"); } + } + + /// + /// Does the supplied relative ? + /// + /// + /// The name of the resource to test. + /// + /// + /// if resource name is relative; + /// otherwise . + /// + protected override bool IsRelativeResource(string resourceName) + { + return true; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/IOrdered.cs b/src/Spring/Spring.Core/Core/IOrdered.cs index b7dadb69..ade6ea8f 100644 --- a/src/Spring/Spring.Core/Core/IOrdered.cs +++ b/src/Spring/Spring.Core/Core/IOrdered.cs @@ -1,66 +1,65 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Core -{ - /// - /// Interface that can be implemented by objects that should be orderable, e.g. in an - /// . - /// - /// - ///

- /// The actual order can be interpreted as prioritization, the first object (with the - /// lowest order value) having the highest priority. - ///

- ///
- /// Juergen Hoeller - /// Aleksandar Seovic (.Net) - /// $Id: IOrdered.cs,v 1.6 2007/05/26 00:42:36 markpollack Exp $ - public interface IOrdered - { - - /// - /// Return the order value of this object, where a higher value means greater in - /// terms of sorting. - /// - /// - ///

- /// Normally starting with 0 or 1, with indicating - /// greatest. Same order values will result in arbitrary positions for the affected - /// objects. - ///

- ///

- /// Higher value can be interpreted as lower priority, consequently the first object - /// has highest priority. - ///

- ///
- /// The order value. - int Order - { - get; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Core +{ + /// + /// Interface that can be implemented by objects that should be orderable, e.g. in an + /// . + /// + /// + ///

+ /// The actual order can be interpreted as prioritization, the first object (with the + /// lowest order value) having the highest priority. + ///

+ ///
+ /// Juergen Hoeller + /// Aleksandar Seovic (.Net) + public interface IOrdered + { + + /// + /// Return the order value of this object, where a higher value means greater in + /// terms of sorting. + /// + /// + ///

+ /// Normally starting with 0 or 1, with indicating + /// greatest. Same order values will result in arbitrary positions for the affected + /// objects. + ///

+ ///

+ /// Higher value can be interpreted as lower priority, consequently the first object + /// has highest priority. + ///

+ ///
+ /// The order value. + int Order + { + get; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/InvalidPropertyException.cs b/src/Spring/Spring.Core/Core/InvalidPropertyException.cs index 17cae32f..46d5b415 100644 --- a/src/Spring/Spring.Core/Core/InvalidPropertyException.cs +++ b/src/Spring/Spring.Core/Core/InvalidPropertyException.cs @@ -1,214 +1,213 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Thrown in response to referring to an invalid property (most often via reflection). - /// - /// Rick Evans - /// $Id: InvalidPropertyException.cs,v 1.2 2007/07/31 03:47:22 markpollack Exp $ - [Serializable] - public class InvalidPropertyException : FatalReflectionException - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public InvalidPropertyException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public InvalidPropertyException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The that is (or rather was) the source of the - /// offending property. - /// - /// - /// The name of the offending property. - /// - public InvalidPropertyException(Type type, string propertyName) - : this(type, propertyName, string.Format( - CultureInfo.InvariantCulture, - "Invalid property '{0}' in class [{1}].", propertyName, type.FullName)) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The that is (or rather was) the source of the - /// offending property. - /// - /// - /// The name of the offending property. - /// - /// - /// A message about the exception. - /// - public InvalidPropertyException(Type type, string propertyName, string message) - : base(message) - { - offendingObjectType = type; - offendingPropertyName = propertyName; - } - - /// - /// Creates a new instance of the InvalidPropertyException class. - /// - /// - /// The that is (or rather was) the source of the - /// offending property. - /// - /// - /// The name of the offending property. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public InvalidPropertyException ( - Type offendingType, string offendingProperty, string message, Exception rootCause) - : base (message, rootCause) - { - offendingObjectType = offendingType; - offendingPropertyName = offendingProperty; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public InvalidPropertyException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected InvalidPropertyException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - offendingObjectType = info.GetValue("ObjectType", typeof (Type)) as Type; - offendingPropertyName = info.GetString("OffendingPropertyName"); - } - - #endregion - - #region Properties - - /// - /// The that is (or rather was) the source of the - /// offending property. - /// - public Type ObjectType - { - get { return offendingObjectType; } - } - - /// - /// The name of the offending property. - /// - public string OffendingPropertyName - { - get { return offendingPropertyName; } - } - - #endregion - - #region Methods - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("ObjectType", ObjectType, typeof (Type)); - info.AddValue("OffendingPropertyName", OffendingPropertyName); - } - - #endregion - - #region Fields - - private Type offendingObjectType; - private string offendingPropertyName; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Thrown in response to referring to an invalid property (most often via reflection). + /// + /// Rick Evans + [Serializable] + public class InvalidPropertyException : FatalReflectionException + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public InvalidPropertyException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public InvalidPropertyException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The that is (or rather was) the source of the + /// offending property. + /// + /// + /// The name of the offending property. + /// + public InvalidPropertyException(Type type, string propertyName) + : this(type, propertyName, string.Format( + CultureInfo.InvariantCulture, + "Invalid property '{0}' in class [{1}].", propertyName, type.FullName)) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The that is (or rather was) the source of the + /// offending property. + /// + /// + /// The name of the offending property. + /// + /// + /// A message about the exception. + /// + public InvalidPropertyException(Type type, string propertyName, string message) + : base(message) + { + offendingObjectType = type; + offendingPropertyName = propertyName; + } + + /// + /// Creates a new instance of the InvalidPropertyException class. + /// + /// + /// The that is (or rather was) the source of the + /// offending property. + /// + /// + /// The name of the offending property. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public InvalidPropertyException ( + Type offendingType, string offendingProperty, string message, Exception rootCause) + : base (message, rootCause) + { + offendingObjectType = offendingType; + offendingPropertyName = offendingProperty; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public InvalidPropertyException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected InvalidPropertyException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + offendingObjectType = info.GetValue("ObjectType", typeof (Type)) as Type; + offendingPropertyName = info.GetString("OffendingPropertyName"); + } + + #endregion + + #region Properties + + /// + /// The that is (or rather was) the source of the + /// offending property. + /// + public Type ObjectType + { + get { return offendingObjectType; } + } + + /// + /// The name of the offending property. + /// + public string OffendingPropertyName + { + get { return offendingPropertyName; } + } + + #endregion + + #region Methods + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("ObjectType", ObjectType, typeof (Type)); + info.AddValue("OffendingPropertyName", OffendingPropertyName); + } + + #endregion + + #region Fields + + private Type offendingObjectType; + private string offendingPropertyName; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/MethodGenericArgumentsCountCriteria.cs b/src/Spring/Spring.Core/Core/MethodGenericArgumentsCountCriteria.cs index fb8b4b2c..3cd57932 100644 --- a/src/Spring/Spring.Core/Core/MethodGenericArgumentsCountCriteria.cs +++ b/src/Spring/Spring.Core/Core/MethodGenericArgumentsCountCriteria.cs @@ -1,141 +1,140 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System; -using System.Reflection; - -using Spring.Core; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the number of generic arguments to a given - /// matches an arbitrary number. - /// - /// - ///

- /// This class supports checking the generic arguments count of both - /// generic methods and constructors. - ///

- ///
- /// Bruno Baia - /// $Id: MethodGenericArgumentsCountCriteria.cs,v 1.1 2007/08/04 01:04:33 bbaia Exp $ - public class MethodGenericArgumentsCountCriteria : ICriteria - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This constructor sets the - /// - /// property to zero (0). - ///

- ///
- public MethodGenericArgumentsCountCriteria() : this(0) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The number of generic arguments that a - /// must have to satisfy this criteria. - /// - /// - /// If the supplied is less - /// than zero. - /// - public MethodGenericArgumentsCountCriteria(int expectedGenericArgumentCount) - { - ExpectedGenericArgumentCount = expectedGenericArgumentCount; - } - - #endregion - - #region Properties - - /// - /// The number of generic arguments that a - /// must have to satisfy this criteria. - /// - /// - /// If the supplied value is less than zero. - /// - public int ExpectedGenericArgumentCount - { - get { return _count; } - set - { - if (value < 0) - { - throw new ArgumentOutOfRangeException( - "value", value, "Cannot specify a generic argument count of less than zero."); - } - _count = value; - } - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public bool IsSatisfied(object datum) - { - bool satisfied = false; - MethodBase method = datum as MethodBase; - if (method != null) - { - satisfied = method.GetGenericArguments().Length == ExpectedGenericArgumentCount; - } - return satisfied; - } - - #endregion - - #region Fields - - private int _count; - - #endregion - } -} - +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System; +using System.Reflection; + +using Spring.Core; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the number of generic arguments to a given + /// matches an arbitrary number. + /// + /// + ///

+ /// This class supports checking the generic arguments count of both + /// generic methods and constructors. + ///

+ ///
+ /// Bruno Baia + public class MethodGenericArgumentsCountCriteria : ICriteria + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This constructor sets the + /// + /// property to zero (0). + ///

+ ///
+ public MethodGenericArgumentsCountCriteria() : this(0) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The number of generic arguments that a + /// must have to satisfy this criteria. + /// + /// + /// If the supplied is less + /// than zero. + /// + public MethodGenericArgumentsCountCriteria(int expectedGenericArgumentCount) + { + ExpectedGenericArgumentCount = expectedGenericArgumentCount; + } + + #endregion + + #region Properties + + /// + /// The number of generic arguments that a + /// must have to satisfy this criteria. + /// + /// + /// If the supplied value is less than zero. + /// + public int ExpectedGenericArgumentCount + { + get { return _count; } + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException( + "value", value, "Cannot specify a generic argument count of less than zero."); + } + _count = value; + } + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public bool IsSatisfied(object datum) + { + bool satisfied = false; + MethodBase method = datum as MethodBase; + if (method != null) + { + satisfied = method.GetGenericArguments().Length == ExpectedGenericArgumentCount; + } + return satisfied; + } + + #endregion + + #region Fields + + private int _count; + + #endregion + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/MethodInvocationException.cs b/src/Spring/Spring.Core/Core/MethodInvocationException.cs index d9f4f5b3..11ad8b60 100644 --- a/src/Spring/Spring.Core/Core/MethodInvocationException.cs +++ b/src/Spring/Spring.Core/Core/MethodInvocationException.cs @@ -1,120 +1,118 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Core; - -#endregion - -namespace Spring.Core -{ - /// - /// Thrown when a method (typically a property getter or setter invoked via reflection) - /// throws an exception, analogous to a . - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: MethodInvocationException.cs,v 1.1 2007/07/31 00:08:42 markpollack Exp $ - /// - [Serializable] - public class MethodInvocationException : PropertyAccessException - { - /// - /// The error code string for this exception. - /// - override public string ErrorCode - { - get - { - return "methodInvocation"; - } - } - - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the MethodInvocationException class. - /// - public MethodInvocationException () - { - } - - /// - /// Creates a new instance of the MethodInvocationException class. - /// - /// - /// A message about the exception. - /// - public MethodInvocationException (string message) - : base (message) - { - } - - /// - /// Creates a new instance of the MethodInvocationException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public MethodInvocationException (string message, Exception rootCause) - : base (message, rootCause) - { - } - - /// - /// Constructor to use when an exception results from a - /// . - /// - /// - /// The raised by the invoked property. - /// - /// - /// The that - /// resulted in an exception. - /// - public MethodInvocationException (Exception ex, PropertyChangeEventArgs argument) : - base ("Property '" + argument.PropertyName + "' threw exception.", argument, ex) - { - } - - /// - /// Creates a new instance of the MethodInvocationException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected MethodInvocationException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Core; + +#endregion + +namespace Spring.Core +{ + /// + /// Thrown when a method (typically a property getter or setter invoked via reflection) + /// throws an exception, analogous to a . + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class MethodInvocationException : PropertyAccessException + { + /// + /// The error code string for this exception. + /// + override public string ErrorCode + { + get + { + return "methodInvocation"; + } + } + + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the MethodInvocationException class. + /// + public MethodInvocationException () + { + } + + /// + /// Creates a new instance of the MethodInvocationException class. + /// + /// + /// A message about the exception. + /// + public MethodInvocationException (string message) + : base (message) + { + } + + /// + /// Creates a new instance of the MethodInvocationException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public MethodInvocationException (string message, Exception rootCause) + : base (message, rootCause) + { + } + + /// + /// Constructor to use when an exception results from a + /// . + /// + /// + /// The raised by the invoked property. + /// + /// + /// The that + /// resulted in an exception. + /// + public MethodInvocationException (Exception ex, PropertyChangeEventArgs argument) : + base ("Property '" + argument.PropertyName + "' threw exception.", argument, ex) + { + } + + /// + /// Creates a new instance of the MethodInvocationException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected MethodInvocationException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/MethodNameMatchCriteria.cs b/src/Spring/Spring.Core/Core/MethodNameMatchCriteria.cs index 50f6c7d0..81d180cf 100644 --- a/src/Spring/Spring.Core/Core/MethodNameMatchCriteria.cs +++ b/src/Spring/Spring.Core/Core/MethodNameMatchCriteria.cs @@ -1,132 +1,131 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the method Name of an - /// instance matches a - /// supplied string pattern. - /// - /// - /// - /// Supports the following simple pattern styles: - /// "xxx*", "*xxx" and "*xxx*" matches, as well as direct equality. - /// - /// - /// Bruno Baia - /// $Id: MethodNameMatchCriteria.cs,v 1.1 2007/08/04 01:04:34 bbaia Exp $ - public class MethodNameMatchCriteria : ICriteria - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This constructor sets the - /// - /// property to * (any method name). - ///

- ///
- public MethodNameMatchCriteria() : this("*") - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The pattern that names - /// must match against in order to satisfy this criteria. - /// - /// If the supplied is null or resolve to an empty string. - /// - public MethodNameMatchCriteria(string pattern) - { - Pattern = pattern; - } - - #endregion - - #region Properties - - /// - /// The number of parameters that a - /// must have to satisfy this criteria. - /// - /// - /// If the supplied value is null or resolve to an empty string. - /// - public string Pattern - { - get { return pattern; } - set - { - AssertUtils.ArgumentHasText(value, "value"); - pattern = value; - } - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public bool IsSatisfied(object datum) - { - bool satisfied = false; - MethodBase method = datum as MethodBase; - if (method != null) - { - satisfied = PatternMatchUtils.SimpleMatch(pattern.ToLower(), method.Name.ToLower()); - } - return satisfied; - } - - #endregion - - #region Fields - - private string pattern; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the method Name of an + /// instance matches a + /// supplied string pattern. + /// + /// + /// + /// Supports the following simple pattern styles: + /// "xxx*", "*xxx" and "*xxx*" matches, as well as direct equality. + /// + /// + /// Bruno Baia + public class MethodNameMatchCriteria : ICriteria + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This constructor sets the + /// + /// property to * (any method name). + ///

+ ///
+ public MethodNameMatchCriteria() : this("*") + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The pattern that names + /// must match against in order to satisfy this criteria. + /// + /// If the supplied is null or resolve to an empty string. + /// + public MethodNameMatchCriteria(string pattern) + { + Pattern = pattern; + } + + #endregion + + #region Properties + + /// + /// The number of parameters that a + /// must have to satisfy this criteria. + /// + /// + /// If the supplied value is null or resolve to an empty string. + /// + public string Pattern + { + get { return pattern; } + set + { + AssertUtils.ArgumentHasText(value, "value"); + pattern = value; + } + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public bool IsSatisfied(object datum) + { + bool satisfied = false; + MethodBase method = datum as MethodBase; + if (method != null) + { + satisfied = PatternMatchUtils.SimpleMatch(pattern.ToLower(), method.Name.ToLower()); + } + return satisfied; + } + + #endregion + + #region Fields + + private string pattern; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/MethodParametersCountCriteria.cs b/src/Spring/Spring.Core/Core/MethodParametersCountCriteria.cs index 837f800a..34fa742d 100644 --- a/src/Spring/Spring.Core/Core/MethodParametersCountCriteria.cs +++ b/src/Spring/Spring.Core/Core/MethodParametersCountCriteria.cs @@ -1,148 +1,147 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Core; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the number of parameters to a given - /// matches an arbitrary number. - /// - /// - ///

- /// This class supports checking the parameter count of both methods and - /// constructors. - ///

- ///

- /// Default parameters, etc need to taken into account. - ///

- ///
- /// Rick Evans - /// $Id: MethodParametersCountCriteria.cs,v 1.2 2007/09/20 14:20:45 bbaia Exp $ - public class MethodParametersCountCriteria : ICriteria - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This constructor sets the - /// - /// property to zero (0). - ///

- ///
- public MethodParametersCountCriteria() : this(0) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The number of parameters that a - /// must have to satisfy this criteria. - /// - /// - /// If the supplied is less - /// than zero. - /// - public MethodParametersCountCriteria(int expectedParameterCount) - { - ExpectedParameterCount = expectedParameterCount; - } - - #endregion - - #region Properties - - /// - /// The number of parameters that a - /// must have to satisfy this criteria. - /// - /// - /// If the supplied value is less than zero. - /// - public int ExpectedParameterCount - { - get { return _count; } - set - { - if (value < 0) - { - throw new ArgumentOutOfRangeException( - "value", value, "Cannot specify a parameter count of less than zero."); - } - _count = value; - } - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public bool IsSatisfied(object datum) - { - bool satisfied = false; - MethodBase method = datum as MethodBase; - if (method != null) - { - ParameterInfo[] parameters = method.GetParameters(); - if (parameters.Length == ExpectedParameterCount) - { - satisfied = true; - } - else if ((parameters.Length > 0) && (ExpectedParameterCount >= parameters.Length-1)) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - satisfied = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; - } - } - return satisfied; - } - - #endregion - - #region Fields - - private int _count; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Core; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the number of parameters to a given + /// matches an arbitrary number. + /// + /// + ///

+ /// This class supports checking the parameter count of both methods and + /// constructors. + ///

+ ///

+ /// Default parameters, etc need to taken into account. + ///

+ ///
+ /// Rick Evans + public class MethodParametersCountCriteria : ICriteria + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This constructor sets the + /// + /// property to zero (0). + ///

+ ///
+ public MethodParametersCountCriteria() : this(0) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The number of parameters that a + /// must have to satisfy this criteria. + /// + /// + /// If the supplied is less + /// than zero. + /// + public MethodParametersCountCriteria(int expectedParameterCount) + { + ExpectedParameterCount = expectedParameterCount; + } + + #endregion + + #region Properties + + /// + /// The number of parameters that a + /// must have to satisfy this criteria. + /// + /// + /// If the supplied value is less than zero. + /// + public int ExpectedParameterCount + { + get { return _count; } + set + { + if (value < 0) + { + throw new ArgumentOutOfRangeException( + "value", value, "Cannot specify a parameter count of less than zero."); + } + _count = value; + } + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public bool IsSatisfied(object datum) + { + bool satisfied = false; + MethodBase method = datum as MethodBase; + if (method != null) + { + ParameterInfo[] parameters = method.GetParameters(); + if (parameters.Length == ExpectedParameterCount) + { + satisfied = true; + } + else if ((parameters.Length > 0) && (ExpectedParameterCount >= parameters.Length-1)) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + satisfied = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; + } + } + return satisfied; + } + + #endregion + + #region Fields + + private int _count; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/MethodParametersCriteria.cs b/src/Spring/Spring.Core/Core/MethodParametersCriteria.cs index 8712a08f..2cff1476 100644 --- a/src/Spring/Spring.Core/Core/MethodParametersCriteria.cs +++ b/src/Spring/Spring.Core/Core/MethodParametersCriteria.cs @@ -1,180 +1,179 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the of each of the - /// parameters of a given matches each - /// of the parameter s of a given - /// . - /// - /// - ///

- /// If no array is passed to the overloaded constructor, - /// any method that has no parameters will satisfy an instance of this - /// class. The same effect could be achieved by passing the - /// array to the overloaded constructor. - ///

- ///
- /// Rick Evans - /// $Id: MethodParametersCriteria.cs,v 1.2 2007/09/20 14:20:46 bbaia Exp $ - public class MethodParametersCriteria : ICriteria - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public MethodParametersCriteria() : this(Type.EmptyTypes) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// If the supplied array is null, then this - /// constructor uses the array. - ///

- ///
- /// - /// The array that this criteria will use to - /// check parameter s. - /// - public MethodParametersCriteria(Type[] parameters) - { - _parameters = parameters; - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// - ///

- /// This implementation respects the inheritance chain of any parameter - /// s... i.e. methods that have a base type (or - /// interface) that is assignable to the in the - /// same corresponding index of the parameter types will satisfy this - /// criteria instance. - ///

- ///
- /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public bool IsSatisfied(object datum) - { - bool satisfied = false; - MethodInfo method = datum as MethodInfo; - if (method != null) - { - bool isParamArray = false; - Type paramArrayType = null; - ParameterInfo[] parametersBeingChecked = method.GetParameters(); - if (parametersBeingChecked.Length > 0) - { - ParameterInfo lastParameter = parametersBeingChecked[parametersBeingChecked.Length - 1]; - isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; - if (isParamArray) - { - paramArrayType = lastParameter.ParameterType.GetElementType(); - } - } - if (parametersBeingChecked != null - && parametersBeingChecked.Length == _parameters.Length) - { - satisfied = true; - for (int i = 0; i < _parameters.Length; ++i) - { - Type sourceType = _parameters[i]; - Type typeBeingChecked = parametersBeingChecked[i].ParameterType; - if (!typeBeingChecked.IsAssignableFrom(sourceType)) - { - if (isParamArray && i == _parameters.Length - 1) - { - if (!paramArrayType.IsAssignableFrom(sourceType)) - { - satisfied = false; - break; - } - } - else - { - satisfied = false; - break; - } - } - } - } - else if (isParamArray && (_parameters.Length >= parametersBeingChecked.Length - 1)) - { - satisfied = true; - for (int i = 0; i < parametersBeingChecked.Length - 1; ++i) - { - Type sourceType = _parameters[i]; - Type typeBeingChecked = parametersBeingChecked[i].ParameterType; - if (!typeBeingChecked.IsAssignableFrom(sourceType)) - { - satisfied = false; - break; - } - } - for (int i = parametersBeingChecked.Length - 1; i < _parameters.Length; ++i) - { - Type sourceType = _parameters[i]; - if (!paramArrayType.IsAssignableFrom(sourceType)) - { - satisfied = false; - break; - } - } - } - } - return satisfied; - } - - #endregion - - #region Fields - - private readonly Type[] _parameters; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the of each of the + /// parameters of a given matches each + /// of the parameter s of a given + /// . + /// + /// + ///

+ /// If no array is passed to the overloaded constructor, + /// any method that has no parameters will satisfy an instance of this + /// class. The same effect could be achieved by passing the + /// array to the overloaded constructor. + ///

+ ///
+ /// Rick Evans + public class MethodParametersCriteria : ICriteria + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public MethodParametersCriteria() : this(Type.EmptyTypes) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// If the supplied array is null, then this + /// constructor uses the array. + ///

+ ///
+ /// + /// The array that this criteria will use to + /// check parameter s. + /// + public MethodParametersCriteria(Type[] parameters) + { + _parameters = parameters; + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// + ///

+ /// This implementation respects the inheritance chain of any parameter + /// s... i.e. methods that have a base type (or + /// interface) that is assignable to the in the + /// same corresponding index of the parameter types will satisfy this + /// criteria instance. + ///

+ ///
+ /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public bool IsSatisfied(object datum) + { + bool satisfied = false; + MethodInfo method = datum as MethodInfo; + if (method != null) + { + bool isParamArray = false; + Type paramArrayType = null; + ParameterInfo[] parametersBeingChecked = method.GetParameters(); + if (parametersBeingChecked.Length > 0) + { + ParameterInfo lastParameter = parametersBeingChecked[parametersBeingChecked.Length - 1]; + isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; + if (isParamArray) + { + paramArrayType = lastParameter.ParameterType.GetElementType(); + } + } + if (parametersBeingChecked != null + && parametersBeingChecked.Length == _parameters.Length) + { + satisfied = true; + for (int i = 0; i < _parameters.Length; ++i) + { + Type sourceType = _parameters[i]; + Type typeBeingChecked = parametersBeingChecked[i].ParameterType; + if (!typeBeingChecked.IsAssignableFrom(sourceType)) + { + if (isParamArray && i == _parameters.Length - 1) + { + if (!paramArrayType.IsAssignableFrom(sourceType)) + { + satisfied = false; + break; + } + } + else + { + satisfied = false; + break; + } + } + } + } + else if (isParamArray && (_parameters.Length >= parametersBeingChecked.Length - 1)) + { + satisfied = true; + for (int i = 0; i < parametersBeingChecked.Length - 1; ++i) + { + Type sourceType = _parameters[i]; + Type typeBeingChecked = parametersBeingChecked[i].ParameterType; + if (!typeBeingChecked.IsAssignableFrom(sourceType)) + { + satisfied = false; + break; + } + } + for (int i = parametersBeingChecked.Length - 1; i < _parameters.Length; ++i) + { + Type sourceType = _parameters[i]; + if (!paramArrayType.IsAssignableFrom(sourceType)) + { + satisfied = false; + break; + } + } + } + } + return satisfied; + } + + #endregion + + #region Fields + + private readonly Type[] _parameters; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/MethodReturnTypeCriteria.cs b/src/Spring/Spring.Core/Core/MethodReturnTypeCriteria.cs index 0fad4d09..f11cd630 100644 --- a/src/Spring/Spring.Core/Core/MethodReturnTypeCriteria.cs +++ b/src/Spring/Spring.Core/Core/MethodReturnTypeCriteria.cs @@ -1,121 +1,120 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Core; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the return of a given - /// matches a given . - /// - /// Rick Evans - /// $Id: MethodReturnTypeCriteria.cs,v 1.1 2007/07/31 02:03:36 markpollack Exp $ - public class MethodReturnTypeCriteria : ICriteria - { - #region Constants - - /// - /// The return to match against if no - /// is provided explictly. - /// - private static readonly Type DefaultType = typeof (void); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public MethodReturnTypeCriteria() - : this(DefaultType) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The that the return type of a given - /// must match in order to satisfy - /// this criteria. - /// - public MethodReturnTypeCriteria(Type type) - { - ReturnType = type; - } - - #endregion - - #region Properties - - /// - /// The that the return type of a given - /// must match in order to satisfy - /// this criteria. - /// - public Type ReturnType - { - get { return _type; } - set { _type = value == null ? DefaultType : value; } - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public bool IsSatisfied(object datum) - { - bool satisfied = false; - MethodInfo method = datum as MethodInfo; - if (method != null) - { - satisfied = method.ReturnType.Equals(ReturnType); - } - return satisfied; - } - - #endregion - - #region Fields - - private Type _type; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Core; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the return of a given + /// matches a given . + /// + /// Rick Evans + public class MethodReturnTypeCriteria : ICriteria + { + #region Constants + + /// + /// The return to match against if no + /// is provided explictly. + /// + private static readonly Type DefaultType = typeof (void); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public MethodReturnTypeCriteria() + : this(DefaultType) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The that the return type of a given + /// must match in order to satisfy + /// this criteria. + /// + public MethodReturnTypeCriteria(Type type) + { + ReturnType = type; + } + + #endregion + + #region Properties + + /// + /// The that the return type of a given + /// must match in order to satisfy + /// this criteria. + /// + public Type ReturnType + { + get { return _type; } + set { _type = value == null ? DefaultType : value; } + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public bool IsSatisfied(object datum) + { + bool satisfied = false; + MethodInfo method = datum as MethodInfo; + if (method != null) + { + satisfied = method.ReturnType.Equals(ReturnType); + } + return satisfied; + } + + #endregion + + #region Fields + + private Type _type; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/NotReadablePropertyException.cs b/src/Spring/Spring.Core/Core/NotReadablePropertyException.cs index 60cae8df..38c729f0 100644 --- a/src/Spring/Spring.Core/Core/NotReadablePropertyException.cs +++ b/src/Spring/Spring.Core/Core/NotReadablePropertyException.cs @@ -1,116 +1,115 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Core -{ - /// - /// Thrown in response to a failed attempt to read a property. - /// - /// - ///

- /// Typically thrown when attempting to read the value of a write-only - /// property via reflection. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: NotReadablePropertyException.cs,v 1.2 2007/07/31 00:26:30 markpollack Exp $ - [Serializable] - public class NotReadablePropertyException : InvalidPropertyException - { - /// - /// Creates a new instance of the - /// class. - /// - public NotReadablePropertyException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public NotReadablePropertyException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The that is (or rather was) the source of the - /// offending property. - /// - /// - /// The name of the offending property. - /// - public NotReadablePropertyException(Type type, string propertyName) - : base(type, propertyName, string.Format( - CultureInfo.InvariantCulture, - "Cannot read the value of the '{0}' property " + - "declared on the [{1}] class : property is read-only.", propertyName, type.FullName)) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NotReadablePropertyException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NotReadablePropertyException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Core +{ + /// + /// Thrown in response to a failed attempt to read a property. + /// + /// + ///

+ /// Typically thrown when attempting to read the value of a write-only + /// property via reflection. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class NotReadablePropertyException : InvalidPropertyException + { + /// + /// Creates a new instance of the + /// class. + /// + public NotReadablePropertyException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public NotReadablePropertyException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The that is (or rather was) the source of the + /// offending property. + /// + /// + /// The name of the offending property. + /// + public NotReadablePropertyException(Type type, string propertyName) + : base(type, propertyName, string.Format( + CultureInfo.InvariantCulture, + "Cannot read the value of the '{0}' property " + + "declared on the [{1}] class : property is read-only.", propertyName, type.FullName)) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NotReadablePropertyException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NotReadablePropertyException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/NotWritablePropertyException.cs b/src/Spring/Spring.Core/Core/NotWritablePropertyException.cs index 0f6b012a..2e9ef3e8 100644 --- a/src/Spring/Spring.Core/Core/NotWritablePropertyException.cs +++ b/src/Spring/Spring.Core/Core/NotWritablePropertyException.cs @@ -1,148 +1,147 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Core -{ - /// - /// Thrown in response to a failed attempt to write a property. - /// - /// Mark Pollack (.NET) - /// $Id: NotWritablePropertyException.cs,v 1.1 2007/07/31 00:08:42 markpollack Exp $ - [Serializable] - public class NotWritablePropertyException : InvalidPropertyException - { - /// - /// Creates a new instance of the NotWritablePropertyException class. - /// - public NotWritablePropertyException() - { - } - - /// - /// Creates a new instance of the NotWritablePropertyException class. - /// - /// - /// A message about the exception. - /// - public NotWritablePropertyException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the NotWritablePropertyException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NotWritablePropertyException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the NotWritablePropertyException class. - /// - /// - /// The that is (or rather was) the source of the - /// offending property. - /// - /// - /// The name of the offending property. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NotWritablePropertyException( - Type offendingType, string offendingProperty, string message, Exception rootCause) - : base(offendingType, offendingProperty, message, rootCause) - { - } - - /// - /// Creates a new instance of the NotWritablePropertyException class - /// summarizing what property was not writable. - /// - /// - /// The name of the property that is not writable. - /// - /// - /// The in which the property is not writable. - /// - public NotWritablePropertyException(string offendingProperty, Type offendingType) - : base(offendingType, offendingProperty, - string.Format(CultureInfo.InvariantCulture, - "Property '{0}' is not writable in class [{1}].", - offendingProperty, offendingType.FullName)) - { - } - - /// - /// Creates new NotWritablePropertyException with a root cause. - /// - /// - /// The name of the property that is not writable. - /// - /// - /// The in which the property is not writable. - /// - /// - /// The root cause indicating why the property was not writable. - /// - public NotWritablePropertyException(string offendingProperty, Type offendingType, Exception rootCause) - : base(offendingType, offendingProperty, - string.Format(CultureInfo.InvariantCulture, - "Property '{0}' is not writable in class [{1}].", - offendingProperty, - offendingType != null ? offendingType.FullName : "null"), - rootCause) - { - } - - /// - /// Creates a new instance of the NotWritablePropertyException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NotWritablePropertyException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Core +{ + /// + /// Thrown in response to a failed attempt to write a property. + /// + /// Mark Pollack (.NET) + [Serializable] + public class NotWritablePropertyException : InvalidPropertyException + { + /// + /// Creates a new instance of the NotWritablePropertyException class. + /// + public NotWritablePropertyException() + { + } + + /// + /// Creates a new instance of the NotWritablePropertyException class. + /// + /// + /// A message about the exception. + /// + public NotWritablePropertyException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the NotWritablePropertyException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NotWritablePropertyException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the NotWritablePropertyException class. + /// + /// + /// The that is (or rather was) the source of the + /// offending property. + /// + /// + /// The name of the offending property. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NotWritablePropertyException( + Type offendingType, string offendingProperty, string message, Exception rootCause) + : base(offendingType, offendingProperty, message, rootCause) + { + } + + /// + /// Creates a new instance of the NotWritablePropertyException class + /// summarizing what property was not writable. + /// + /// + /// The name of the property that is not writable. + /// + /// + /// The in which the property is not writable. + /// + public NotWritablePropertyException(string offendingProperty, Type offendingType) + : base(offendingType, offendingProperty, + string.Format(CultureInfo.InvariantCulture, + "Property '{0}' is not writable in class [{1}].", + offendingProperty, offendingType.FullName)) + { + } + + /// + /// Creates new NotWritablePropertyException with a root cause. + /// + /// + /// The name of the property that is not writable. + /// + /// + /// The in which the property is not writable. + /// + /// + /// The root cause indicating why the property was not writable. + /// + public NotWritablePropertyException(string offendingProperty, Type offendingType, Exception rootCause) + : base(offendingType, offendingProperty, + string.Format(CultureInfo.InvariantCulture, + "Property '{0}' is not writable in class [{1}].", + offendingProperty, + offendingType != null ? offendingType.FullName : "null"), + rootCause) + { + } + + /// + /// Creates a new instance of the NotWritablePropertyException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NotWritablePropertyException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/NullValueInNestedPathException.cs b/src/Spring/Spring.Core/Core/NullValueInNestedPathException.cs index 76ef1cc5..195ae23d 100644 --- a/src/Spring/Spring.Core/Core/NullValueInNestedPathException.cs +++ b/src/Spring/Spring.Core/Core/NullValueInNestedPathException.cs @@ -1,172 +1,171 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Thrown in response to encountering a value - /// when traversing a nested path expression. - /// - /// $Id: NullValueInNestedPathException.cs,v 1.2 2007/07/31 03:47:22 markpollack Exp $ - [Serializable] - public class NullValueInNestedPathException : FatalReflectionException - { - private string property; - private Type type; - - /// - /// The name of the offending property. - /// - public string PropertyName - { - get { return property; } - } - - /// - /// The of the class where the property was last looked for. - /// - public Type ObjectType - { - get { return type; } - } - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public NullValueInNestedPathException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public NullValueInNestedPathException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NullValueInNestedPathException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The of the object where the property was not found. - /// - /// The name of the property not found. - public NullValueInNestedPathException(Type type, string theProperty) - : this(type, theProperty, string.Format(CultureInfo.InvariantCulture, - "Value of nested property '{0}' is null in Type [{1}].", theProperty, type)) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The of the object where the property was not found. - /// - /// The name of the property not found. - /// A message about the exception. - public NullValueInNestedPathException(Type type, string theProperty, string message) - : base(message) - { - property = theProperty; - this.type = type; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NullValueInNestedPathException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - type = info.GetValue("ObjectType", typeof (Type)) as Type; - property = info.GetString("PropertyName"); - } - - #endregion - - #region Methods - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("ObjectType", ObjectType); - info.AddValue("PropertyName", PropertyName); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Thrown in response to encountering a value + /// when traversing a nested path expression. + /// + [Serializable] + public class NullValueInNestedPathException : FatalReflectionException + { + private string property; + private Type type; + + /// + /// The name of the offending property. + /// + public string PropertyName + { + get { return property; } + } + + /// + /// The of the class where the property was last looked for. + /// + public Type ObjectType + { + get { return type; } + } + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public NullValueInNestedPathException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public NullValueInNestedPathException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NullValueInNestedPathException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The of the object where the property was not found. + /// + /// The name of the property not found. + public NullValueInNestedPathException(Type type, string theProperty) + : this(type, theProperty, string.Format(CultureInfo.InvariantCulture, + "Value of nested property '{0}' is null in Type [{1}].", theProperty, type)) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The of the object where the property was not found. + /// + /// The name of the property not found. + /// A message about the exception. + public NullValueInNestedPathException(Type type, string theProperty, string message) + : base(message) + { + property = theProperty; + this.type = type; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NullValueInNestedPathException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + type = info.GetValue("ObjectType", typeof (Type)) as Type; + property = info.GetString("PropertyName"); + } + + #endregion + + #region Methods + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("ObjectType", ObjectType); + info.AddValue("PropertyName", PropertyName); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/OrderComparator.cs b/src/Spring/Spring.Core/Core/OrderComparator.cs index ccc061e2..4e4d8c76 100644 --- a/src/Spring/Spring.Core/Core/OrderComparator.cs +++ b/src/Spring/Spring.Core/Core/OrderComparator.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Core -{ - /// - /// Comparator implementation for objects, sorting by - /// order value ascending (resp. by priority descending). - /// - /// - ///

- /// Non- objects are treated as greatest order values, - /// thus ending up at the end of a list, in arbitrary order (just like same order values of - /// objects). - ///

- ///
- /// Juergen Hoeller - /// Aleksandar Seovic (.Net) - /// $Id: OrderComparator.cs,v 1.5 2006/04/09 07:18:38 markpollack Exp $ - public class OrderComparator : IComparer - { - /// - /// Compares two objects and returns a value indicating whether one is less than, - /// equal to or greater than the other. - /// - /// - ///

- /// Uses direct evaluation instead of - /// to avoid unnecessary boxing. - ///

- ///
- /// The first object to compare. - /// The second object to compare. - /// - /// -1 if first object is less then second, 1 if it is greater, or 0 if they are equal. - /// - public virtual int Compare(object o1, object o2) - { - IOrdered o1lhs = o1 as IOrdered; - IOrdered o2rhs = o2 as IOrdered; - int lhs = o1lhs != null ? o1lhs.Order : Int32.MaxValue; - int rhs = o2rhs != null ? o2rhs.Order : Int32.MaxValue; - if (lhs < rhs) - { - return - 1; - } - else if (lhs > rhs) - { - return 1; - } - else - { - return 0; - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Core +{ + /// + /// Comparator implementation for objects, sorting by + /// order value ascending (resp. by priority descending). + /// + /// + ///

+ /// Non- objects are treated as greatest order values, + /// thus ending up at the end of a list, in arbitrary order (just like same order values of + /// objects). + ///

+ ///
+ /// Juergen Hoeller + /// Aleksandar Seovic (.Net) + public class OrderComparator : IComparer + { + /// + /// Compares two objects and returns a value indicating whether one is less than, + /// equal to or greater than the other. + /// + /// + ///

+ /// Uses direct evaluation instead of + /// to avoid unnecessary boxing. + ///

+ ///
+ /// The first object to compare. + /// The second object to compare. + /// + /// -1 if first object is less then second, 1 if it is greater, or 0 if they are equal. + /// + public virtual int Compare(object o1, object o2) + { + IOrdered o1lhs = o1 as IOrdered; + IOrdered o2rhs = o2 as IOrdered; + int lhs = o1lhs != null ? o1lhs.Order : Int32.MaxValue; + int rhs = o2rhs != null ? o2rhs.Order : Int32.MaxValue; + if (lhs < rhs) + { + return - 1; + } + else if (lhs > rhs) + { + return 1; + } + else + { + return 0; + } + } + } +} diff --git a/src/Spring/Spring.Core/Core/PropertyAccessException.cs b/src/Spring/Spring.Core/Core/PropertyAccessException.cs index 275003a7..ffdeb897 100644 --- a/src/Spring/Spring.Core/Core/PropertyAccessException.cs +++ b/src/Spring/Spring.Core/Core/PropertyAccessException.cs @@ -1,159 +1,158 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Superclass for exceptions related to a property access, such as a - /// mismatch or a target invocation exception. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: PropertyAccessException.cs,v 1.2 2007/07/31 03:47:22 markpollack Exp $ - [Serializable] - public abstract class PropertyAccessException : ReflectionException, IErrorCoded - { - /// - /// Returns the PropertyChangeEventArgs that resulted in the problem. - /// - public PropertyChangeEventArgs PropertyChangeArgs - { - get { return _propertyChangeEventArgs; } - } - - /// - /// The string error code used to classify the error. - /// - public abstract string ErrorCode { get; } - - private PropertyChangeEventArgs _propertyChangeEventArgs; - - #region Methods - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("PropertyChangeArgs", PropertyChangeArgs); - } - - #endregion - - /// - /// Create a new instance of the PropertyAccessException class. - /// - /// - /// A message about the exception. - /// - /// Describes the change attempted on the property. - protected PropertyAccessException(string message, PropertyChangeEventArgs propertyChangeEvent) : base(message) - { - _propertyChangeEventArgs = propertyChangeEvent; - } - - /// - /// Create a new instance of the PropertyAccessException class. - /// - /// - /// A message about the exception. - /// - /// Describes the change attempted on the property. - /// - /// The root exception that is being wrapped. - /// - protected PropertyAccessException(string message, PropertyChangeEventArgs propertyChangeEvent, Exception rootCause) - : base(message, rootCause) - { - _propertyChangeEventArgs = propertyChangeEvent; - } - - /// - /// Creates a new instance of the PropertyAccessException class. - /// - protected PropertyAccessException() - { - } - - /// - /// Creates a new instance of the PropertyAccessException class. - /// - /// - /// A message about the exception. - /// - protected PropertyAccessException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the PropertyAccessExceptionsException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - protected PropertyAccessException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the PropertyAccessExceptionsException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected PropertyAccessException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - _propertyChangeEventArgs = info.GetValue("PropertyChangeArgs", typeof (object)) as PropertyChangeEventArgs; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Superclass for exceptions related to a property access, such as a + /// mismatch or a target invocation exception. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public abstract class PropertyAccessException : ReflectionException, IErrorCoded + { + /// + /// Returns the PropertyChangeEventArgs that resulted in the problem. + /// + public PropertyChangeEventArgs PropertyChangeArgs + { + get { return _propertyChangeEventArgs; } + } + + /// + /// The string error code used to classify the error. + /// + public abstract string ErrorCode { get; } + + private PropertyChangeEventArgs _propertyChangeEventArgs; + + #region Methods + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("PropertyChangeArgs", PropertyChangeArgs); + } + + #endregion + + /// + /// Create a new instance of the PropertyAccessException class. + /// + /// + /// A message about the exception. + /// + /// Describes the change attempted on the property. + protected PropertyAccessException(string message, PropertyChangeEventArgs propertyChangeEvent) : base(message) + { + _propertyChangeEventArgs = propertyChangeEvent; + } + + /// + /// Create a new instance of the PropertyAccessException class. + /// + /// + /// A message about the exception. + /// + /// Describes the change attempted on the property. + /// + /// The root exception that is being wrapped. + /// + protected PropertyAccessException(string message, PropertyChangeEventArgs propertyChangeEvent, Exception rootCause) + : base(message, rootCause) + { + _propertyChangeEventArgs = propertyChangeEvent; + } + + /// + /// Creates a new instance of the PropertyAccessException class. + /// + protected PropertyAccessException() + { + } + + /// + /// Creates a new instance of the PropertyAccessException class. + /// + /// + /// A message about the exception. + /// + protected PropertyAccessException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the PropertyAccessExceptionsException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + protected PropertyAccessException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the PropertyAccessExceptionsException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected PropertyAccessException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + _propertyChangeEventArgs = info.GetValue("PropertyChangeArgs", typeof (object)) as PropertyChangeEventArgs; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/PropertyChangeEventArgs.cs b/src/Spring/Spring.Core/Core/PropertyChangeEventArgs.cs index a861d711..1c74b628 100644 --- a/src/Spring/Spring.Core/Core/PropertyChangeEventArgs.cs +++ b/src/Spring/Spring.Core/Core/PropertyChangeEventArgs.cs @@ -1,83 +1,83 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; - -#endregion - -namespace Spring.Core -{ - /// - /// Provides additional data for the PropertyChanged event. - /// - /// - ///

- /// Provides some additional properties over and above the name of the - /// property that has changed (which is inherited from the - /// base class). - /// This allows calling code to determine whether or not a property has - /// actually changed (i.e. a PropertyChanged event may have been - /// raised, but the value itself may be equivalent). - ///

- ///
- /// - [Serializable] - public class PropertyChangeEventArgs : PropertyChangedEventArgs - { - private object oldValue; - private object newValue; - - /// - /// Create a new instance of the - /// class. - /// - /// - /// The name of the property that was changed. - /// The old value of the property. - /// the new value of the property. - public PropertyChangeEventArgs( - string propertyName, object oldValue, object newValue) : base(propertyName) - { - this.oldValue = oldValue; - this.newValue = newValue; - } - - /// - /// Get the old value for the property. - /// - /// - public object OldValue - { - get { return oldValue; } - } - - /// - /// Get the new value of the property. - /// - /// - public object NewValue - { - get { return newValue; } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; + +#endregion + +namespace Spring.Core +{ + /// + /// Provides additional data for the PropertyChanged event. + /// + /// + ///

+ /// Provides some additional properties over and above the name of the + /// property that has changed (which is inherited from the + /// base class). + /// This allows calling code to determine whether or not a property has + /// actually changed (i.e. a PropertyChanged event may have been + /// raised, but the value itself may be equivalent). + ///

+ ///
+ /// + [Serializable] + public class PropertyChangeEventArgs : PropertyChangedEventArgs + { + private object oldValue; + private object newValue; + + /// + /// Create a new instance of the + /// class. + /// + /// + /// The name of the property that was changed. + /// The old value of the property. + /// the new value of the property. + public PropertyChangeEventArgs( + string propertyName, object oldValue, object newValue) : base(propertyName) + { + this.oldValue = oldValue; + this.newValue = newValue; + } + + /// + /// Get the old value for the property. + /// + /// + public object OldValue + { + get { return oldValue; } + } + + /// + /// Get the new value of the property. + /// + /// + public object NewValue + { + get { return newValue; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/RegularExpressionCriteria.cs b/src/Spring/Spring.Core/Core/RegularExpressionCriteria.cs index 38160dad..3c7659ce 100644 --- a/src/Spring/Spring.Core/Core/RegularExpressionCriteria.cs +++ b/src/Spring/Spring.Core/Core/RegularExpressionCriteria.cs @@ -1,143 +1,142 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Text.RegularExpressions; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// A base class for all - /// implementations that are regular expression based. - /// - /// Rick Evans - /// $Id: RegularExpressionCriteria.cs,v 1.1 2007/07/31 01:35:07 markpollack Exp $ - public abstract class RegularExpressionCriteria : ICriteria - { - #region Constants - - /// - /// The default pattern... matches absolutely anything. - /// - protected const string MatchAnyThingPattern = ".*"; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - protected RegularExpressionCriteria() : this(RegularExpressionCriteria.MatchAnyThingPattern) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The regular expression pattern to be applied. - /// - protected RegularExpressionCriteria(string pattern) - { - Pattern = pattern; - } - - #endregion - - #region Properties - - /// - /// The regular expression pattern to be applied. - /// - public string Pattern - { - get { return _pattern; } - set - { - _pattern = StringUtils.HasText(value) ? - value : RegularExpressionCriteria.MatchAnyThingPattern; - Expression = new Regex(Pattern, Options); - } - } - - /// - /// The regular expression options to be applied. - /// - public RegexOptions Options - { - get { return _options; } - set { _options = value; } - } - - /// - /// The regular expression to be applied. - /// - public Regex Expression - { - get { return _expression; } - set { _expression = value; } - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public abstract bool IsSatisfied(object datum); - - /// - /// Convenience method that calls the - /// - /// on the supplied . - /// - /// The input to match against. - /// True if the matches. - protected bool IsMatch(string input) - { - return Expression.IsMatch(input); - } - - #endregion - - #region Fields - - private string _pattern; - private RegexOptions _options; - private Regex _expression; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Text.RegularExpressions; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// A base class for all + /// implementations that are regular expression based. + /// + /// Rick Evans + public abstract class RegularExpressionCriteria : ICriteria + { + #region Constants + + /// + /// The default pattern... matches absolutely anything. + /// + protected const string MatchAnyThingPattern = ".*"; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + protected RegularExpressionCriteria() : this(RegularExpressionCriteria.MatchAnyThingPattern) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The regular expression pattern to be applied. + /// + protected RegularExpressionCriteria(string pattern) + { + Pattern = pattern; + } + + #endregion + + #region Properties + + /// + /// The regular expression pattern to be applied. + /// + public string Pattern + { + get { return _pattern; } + set + { + _pattern = StringUtils.HasText(value) ? + value : RegularExpressionCriteria.MatchAnyThingPattern; + Expression = new Regex(Pattern, Options); + } + } + + /// + /// The regular expression options to be applied. + /// + public RegexOptions Options + { + get { return _options; } + set { _options = value; } + } + + /// + /// The regular expression to be applied. + /// + public Regex Expression + { + get { return _expression; } + set { _expression = value; } + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public abstract bool IsSatisfied(object datum); + + /// + /// Convenience method that calls the + /// + /// on the supplied . + /// + /// The input to match against. + /// True if the matches. + protected bool IsMatch(string input) + { + return Expression.IsMatch(input); + } + + #endregion + + #region Fields + + private string _pattern; + private RegexOptions _options; + private Regex _expression; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/RegularExpressionEventNameCriteria.cs b/src/Spring/Spring.Core/Core/RegularExpressionEventNameCriteria.cs index 8bb72195..a2ecd341 100644 --- a/src/Spring/Spring.Core/Core/RegularExpressionEventNameCriteria.cs +++ b/src/Spring/Spring.Core/Core/RegularExpressionEventNameCriteria.cs @@ -1,103 +1,102 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Reflection; -using System.Text.RegularExpressions; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the Name property of an - /// instance matches a - /// supplied regular expression pattern. - /// - /// Rick Evans - /// $Id: RegularExpressionEventNameCriteria.cs,v 1.1 2007/07/31 01:35:07 markpollack Exp $ - public class RegularExpressionEventNameCriteria : RegularExpressionCriteria - { - #region Constants - - /// - /// The default event name pattern... matches pretty much any event name. - /// - private const string MatchAnyEventNamePattern = ".+"; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public RegularExpressionEventNameCriteria() - : this(RegularExpressionEventNameCriteria.MatchAnyEventNamePattern) - { - Options = RegexOptions.IgnoreCase; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The pattern that names - /// must match against in order to satisfy this criteria. - /// - public RegularExpressionEventNameCriteria(string eventNamePattern) - { - Options = RegexOptions.IgnoreCase; - Pattern = StringUtils.HasText(eventNamePattern) ? - eventNamePattern : RegularExpressionEventNameCriteria.MatchAnyEventNamePattern; - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public override bool IsSatisfied(object datum) - { - bool satisfied = false; - EventInfo evt = datum as EventInfo; - if (evt != null) - { - satisfied = IsMatch(evt.Name); - } - return satisfied; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Reflection; +using System.Text.RegularExpressions; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the Name property of an + /// instance matches a + /// supplied regular expression pattern. + /// + /// Rick Evans + public class RegularExpressionEventNameCriteria : RegularExpressionCriteria + { + #region Constants + + /// + /// The default event name pattern... matches pretty much any event name. + /// + private const string MatchAnyEventNamePattern = ".+"; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public RegularExpressionEventNameCriteria() + : this(RegularExpressionEventNameCriteria.MatchAnyEventNamePattern) + { + Options = RegexOptions.IgnoreCase; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The pattern that names + /// must match against in order to satisfy this criteria. + /// + public RegularExpressionEventNameCriteria(string eventNamePattern) + { + Options = RegexOptions.IgnoreCase; + Pattern = StringUtils.HasText(eventNamePattern) ? + eventNamePattern : RegularExpressionEventNameCriteria.MatchAnyEventNamePattern; + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public override bool IsSatisfied(object datum) + { + bool satisfied = false; + EventInfo evt = datum as EventInfo; + if (evt != null) + { + satisfied = IsMatch(evt.Name); + } + return satisfied; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/RegularExpressionMethodNameCriteria.cs b/src/Spring/Spring.Core/Core/RegularExpressionMethodNameCriteria.cs index 0c619a71..315c67d7 100644 --- a/src/Spring/Spring.Core/Core/RegularExpressionMethodNameCriteria.cs +++ b/src/Spring/Spring.Core/Core/RegularExpressionMethodNameCriteria.cs @@ -1,103 +1,102 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Reflection; -using System.Text.RegularExpressions; -using Spring.Objects.Support; -using Spring.Util; - -#endregion - -namespace Spring.Core -{ - /// - /// Criteria that is satisfied if the Name property of an - /// instance matches a - /// supplied regular expression pattern. - /// - /// Rick Evans - /// $Id: RegularExpressionMethodNameCriteria.cs,v 1.1 2007/07/31 01:35:07 markpollack Exp $ - public class RegularExpressionMethodNameCriteria : RegularExpressionCriteria - { - #region Constants - - /// - /// The default method name pattern... matches pretty much any method name. - /// - private const string MatchAnyMethodNamePattern = ".+"; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public RegularExpressionMethodNameCriteria() - : this(RegularExpressionMethodNameCriteria.MatchAnyMethodNamePattern) - { - Options = RegexOptions.IgnoreCase; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The pattern that names - /// must match against in order to satisfy this criteria. - /// - public RegularExpressionMethodNameCriteria(string methodNamePattern) - { - Options = RegexOptions.IgnoreCase; - Pattern = StringUtils.HasText(methodNamePattern) ? - methodNamePattern : RegularExpressionMethodNameCriteria.MatchAnyMethodNamePattern; - } - - #endregion - - #region Methods - - /// - /// Does the supplied satisfy the criteria encapsulated by - /// this instance? - /// - /// The datum to be checked by this criteria instance. - /// - /// True if the supplied satisfies the criteria encapsulated - /// by this instance; false if not or the supplied is null. - /// - public override bool IsSatisfied(object datum) - { - bool satisfied = false; - MethodInfo method = datum as MethodInfo; - if (method != null) - { - satisfied = IsMatch(method.Name); - } - return satisfied; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Reflection; +using System.Text.RegularExpressions; +using Spring.Objects.Support; +using Spring.Util; + +#endregion + +namespace Spring.Core +{ + /// + /// Criteria that is satisfied if the Name property of an + /// instance matches a + /// supplied regular expression pattern. + /// + /// Rick Evans + public class RegularExpressionMethodNameCriteria : RegularExpressionCriteria + { + #region Constants + + /// + /// The default method name pattern... matches pretty much any method name. + /// + private const string MatchAnyMethodNamePattern = ".+"; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public RegularExpressionMethodNameCriteria() + : this(RegularExpressionMethodNameCriteria.MatchAnyMethodNamePattern) + { + Options = RegexOptions.IgnoreCase; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The pattern that names + /// must match against in order to satisfy this criteria. + /// + public RegularExpressionMethodNameCriteria(string methodNamePattern) + { + Options = RegexOptions.IgnoreCase; + Pattern = StringUtils.HasText(methodNamePattern) ? + methodNamePattern : RegularExpressionMethodNameCriteria.MatchAnyMethodNamePattern; + } + + #endregion + + #region Methods + + /// + /// Does the supplied satisfy the criteria encapsulated by + /// this instance? + /// + /// The datum to be checked by this criteria instance. + /// + /// True if the supplied satisfies the criteria encapsulated + /// by this instance; false if not or the supplied is null. + /// + public override bool IsSatisfied(object datum) + { + bool satisfied = false; + MethodInfo method = datum as MethodInfo; + if (method != null) + { + satisfied = IsMatch(method.Name); + } + return satisfied; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/CredentialConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/CredentialConverter.cs index b699da91..c7efc087 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/CredentialConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/CredentialConverter.cs @@ -1,125 +1,124 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Net; -using System.ComponentModel; -using System.Globalization; -using System.Text.RegularExpressions; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converts string representation of a credential for Web client authentication - /// into an instance of . - /// - /// - ///

- /// Find below some examples of the XML formatted strings that this - /// converter will sucessfully convert. - ///

- /// - /// - /// - /// - /// - /// - ///
- /// Bruno Baia - /// $Id: CredentialConverter.cs,v 1.2 2007/12/07 15:14:40 bbaia Exp $ - public class CredentialConverter : TypeConverter - { - private readonly static Regex credentialRegex = new Regex( - @"(((?[\w_.]+)\\)?)(?([\w_.]+))((:(?([\w_.]+)))?)", - RegexOptions.Compiled); - - /// - /// Can we convert from the sourcetype - /// to a instance ? - /// - /// - ///

- /// Currently only supports conversion from a instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Convert from a value to an - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A instance if successful. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value is string) - { - string credentials = (string)value; - Match m = credentialRegex.Match(credentials); - - if (!m.Success || m.Value != credentials) - { - throw new ArgumentException(String.Format("The credential '{0}' is not well-formed.", value)); - } - - // Get domain - string domain = m.Groups["domain"].Value; - - // Get user name - string userName = m.Groups["userName"].Value; - - // Get password - string password = m.Groups["password"].Value; - - return new NetworkCredential(userName, password, domain); - } - return base.ConvertFrom(context, culture, value); - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Net; +using System.ComponentModel; +using System.Globalization; +using System.Text.RegularExpressions; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converts string representation of a credential for Web client authentication + /// into an instance of . + /// + /// + ///

+ /// Find below some examples of the XML formatted strings that this + /// converter will sucessfully convert. + ///

+ /// + /// + /// + /// + /// + /// + ///
+ /// Bruno Baia + public class CredentialConverter : TypeConverter + { + private readonly static Regex credentialRegex = new Regex( + @"(((?[\w_.]+)\\)?)(?([\w_.]+))((:(?([\w_.]+)))?)", + RegexOptions.Compiled); + + /// + /// Can we convert from the sourcetype + /// to a instance ? + /// + /// + ///

+ /// Currently only supports conversion from a instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + return (sourceType == typeof(string)); + } + + /// + /// Convert from a value to an + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A instance if successful. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + string credentials = (string)value; + Match m = credentialRegex.Match(credentials); + + if (!m.Success || m.Value != credentials) + { + throw new ArgumentException(String.Format("The credential '{0}' is not well-formed.", value)); + } + + // Get domain + string domain = m.Groups["domain"].Value; + + // Get user name + string userName = m.Groups["userName"].Value; + + // Get password + string password = m.Groups["password"].Value; + + return new NetworkCredential(userName, password, domain); + } + return base.ConvertFrom(context, culture, value); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/CustomNumberConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/CustomNumberConverter.cs index f13c4b99..78224c52 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/CustomNumberConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/CustomNumberConverter.cs @@ -1,187 +1,186 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// A custom for any - /// primitive numeric type such as , - /// , , etc. - /// - /// - ///

- /// Can use a given for - /// (locale-specific) parsing and rendering. - ///

- ///

- /// This is not meant to be used as a system - /// but rather as a - /// locale-specific number converter within custom controller code, to - /// parse user-entered number strings into number properties of objects, - /// and render them in a UI form. - ///

- ///
- /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: CustomNumberConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class CustomNumberConverter : TypeConverter - { - private Type _type; - private NumberFormatInfo _nfi; - private bool _allowEmpty; - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The primitive numeric to convert to. - /// - /// - /// The to use for - /// (locale-specific) parsing and rendering - /// - /// - /// Is an empty string allowed to be converted? If - /// , an empty string value will be converted to - /// numeric 0. - /// - /// Id the supplied is not a primitive - /// . - /// - /// - public CustomNumberConverter( - Type type, NumberFormatInfo format, bool allowEmpty) - { - if (!type.IsPrimitive) - { - throw new ArgumentException( - "Property type must be a primitive type."); - } - this._type = type; - this._nfi = format; - this._allowEmpty = allowEmpty; - } - - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// - /// if the conversion is possible. - /// - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Converts the specified object (a string) to the required primitive - /// type. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// A primitive representation of the string value. - public override object ConvertFrom( - ITypeDescriptorContext context, CultureInfo culture, object val) - { - if (val is string) - { - string value = val as string; - if (!StringUtils.HasText(value) - && _allowEmpty) - { - value = "0"; - } - if (_type.Equals(typeof (Int16))) - { - return Convert.ToInt16(value, _nfi); - } - else if (_type.Equals(typeof (UInt16))) - { - return Convert.ToUInt16(value, _nfi); - } - else if (_type.Equals(typeof (Int32))) - { - return Convert.ToInt32(value, _nfi); - } - else if (_type.Equals(typeof (UInt32))) - { - return Convert.ToUInt32(value, _nfi); - } - else if (_type.Equals(typeof (Int64))) - { - return Convert.ToInt64(value, _nfi); - } - else if (_type.Equals(typeof (UInt64))) - { - return Convert.ToUInt64(value, _nfi); - } - else if (_type.Equals(typeof (Single))) - { - return Convert.ToSingle(value, _nfi); - } - else if (_type.Equals(typeof (Double))) - { - return Convert.ToDouble(value, _nfi); - } - } - return base.ConvertFrom(context, culture, val); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// A custom for any + /// primitive numeric type such as , + /// , , etc. + /// + /// + ///

+ /// Can use a given for + /// (locale-specific) parsing and rendering. + ///

+ ///

+ /// This is not meant to be used as a system + /// but rather as a + /// locale-specific number converter within custom controller code, to + /// parse user-entered number strings into number properties of objects, + /// and render them in a UI form. + ///

+ ///
+ /// Juergen Hoeller + /// Simon White (.NET) + public class CustomNumberConverter : TypeConverter + { + private Type _type; + private NumberFormatInfo _nfi; + private bool _allowEmpty; + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The primitive numeric to convert to. + /// + /// + /// The to use for + /// (locale-specific) parsing and rendering + /// + /// + /// Is an empty string allowed to be converted? If + /// , an empty string value will be converted to + /// numeric 0. + /// + /// Id the supplied is not a primitive + /// . + /// + /// + public CustomNumberConverter( + Type type, NumberFormatInfo format, bool allowEmpty) + { + if (!type.IsPrimitive) + { + throw new ArgumentException( + "Property type must be a primitive type."); + } + this._type = type; + this._nfi = format; + this._allowEmpty = allowEmpty; + } + + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// + /// if the conversion is possible. + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Converts the specified object (a string) to the required primitive + /// type. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// A primitive representation of the string value. + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object val) + { + if (val is string) + { + string value = val as string; + if (!StringUtils.HasText(value) + && _allowEmpty) + { + value = "0"; + } + if (_type.Equals(typeof (Int16))) + { + return Convert.ToInt16(value, _nfi); + } + else if (_type.Equals(typeof (UInt16))) + { + return Convert.ToUInt16(value, _nfi); + } + else if (_type.Equals(typeof (Int32))) + { + return Convert.ToInt32(value, _nfi); + } + else if (_type.Equals(typeof (UInt32))) + { + return Convert.ToUInt32(value, _nfi); + } + else if (_type.Equals(typeof (Int64))) + { + return Convert.ToInt64(value, _nfi); + } + else if (_type.Equals(typeof (UInt64))) + { + return Convert.ToUInt64(value, _nfi); + } + else if (_type.Equals(typeof (Single))) + { + return Convert.ToSingle(value, _nfi); + } + else if (_type.Equals(typeof (Double))) + { + return Convert.ToDouble(value, _nfi); + } + } + return base.ConvertFrom(context, culture, val); + } + } +} diff --git a/src/Spring/Spring.Core/Core/TypeConversion/FileInfoConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/FileInfoConverter.cs index 5533f958..93a08fec 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/FileInfoConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/FileInfoConverter.cs @@ -1,109 +1,109 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; -using System.IO; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converter for instances. - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - public class FileInfoConverter : TypeConverter - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public FileInfoConverter () {} - #endregion - - #region Methods - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// True if the conversion is possible. - public override bool CanConvertFrom ( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom (context, sourceType); - } - - /// - /// Convert from a string value to a instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A if successful. - /// - public override object ConvertFrom ( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - if (value is string) - { - return new FileInfo(value as string); - } - return base.ConvertFrom (context, culture, value); - } - #endregion - - } - +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; +using System.IO; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converter for instances. + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class FileInfoConverter : TypeConverter + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public FileInfoConverter () {} + #endregion + + #region Methods + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// True if the conversion is possible. + public override bool CanConvertFrom ( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom (context, sourceType); + } + + /// + /// Convert from a string value to a instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A if successful. + /// + public override object ConvertFrom ( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + if (value is string) + { + return new FileInfo(value as string); + } + return base.ConvertFrom (context, culture, value); + } + #endregion + + } + } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/NameValueConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/NameValueConverter.cs index b6556d00..03f86d3b 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/NameValueConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/NameValueConverter.cs @@ -1,159 +1,158 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Configuration; -using System.Globalization; -using System.Xml; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Custom implementation for - /// objects. - /// - /// - ///

- /// Handles conversion from an XML formatted string to a - /// object - /// (see below for an example of the expected XML format). - ///

- ///

- /// This converter must be registered before it will be available. Standard - /// converters in this namespace are automatically registered by the - /// class. - ///

- ///
- /// - ///

- /// Find below some examples of the XML formatted strings that this - /// converter will sucessfully convert. Note that the name of the top level - /// (document) element is quite arbitrary... it is only the content that - /// matters (and which must be in the format - /// <add key="..." value="..."/>. For your continued sanity - /// though, you may wish to standardize on the top level name of - /// 'dictionary' (although you are of course free to not do so). - ///

- /// - /// - /// - /// - /// - /// - ///

- /// The following example uses a different top level (document) element - /// name, but is equivalent to the first example. - ///

- /// - /// - /// - /// - /// - /// - ///
- /// Rod Johnson - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: NameValueConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class NameValueConverter : TypeConverter - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public NameValueConverter() - { - } - - #endregion - - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - /// - ///

- /// Currently only supports conversion from an - /// XML formatted instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// True if the conversion is possible. - public override bool CanConvertFrom( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Convert from a string value to a - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A - /// if successful. - /// - public override object ConvertFrom( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - string text = value as string; - if (text != null) - { - XmlDocument doc = new XmlDocument(); - doc.LoadXml(text); - return new NameValueSectionHandler() - .Create(null, null, doc.DocumentElement); - } - return base.ConvertFrom(context, culture, value); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Configuration; +using System.Globalization; +using System.Xml; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Custom implementation for + /// objects. + /// + /// + ///

+ /// Handles conversion from an XML formatted string to a + /// object + /// (see below for an example of the expected XML format). + ///

+ ///

+ /// This converter must be registered before it will be available. Standard + /// converters in this namespace are automatically registered by the + /// class. + ///

+ ///
+ /// + ///

+ /// Find below some examples of the XML formatted strings that this + /// converter will sucessfully convert. Note that the name of the top level + /// (document) element is quite arbitrary... it is only the content that + /// matters (and which must be in the format + /// <add key="..." value="..."/>. For your continued sanity + /// though, you may wish to standardize on the top level name of + /// 'dictionary' (although you are of course free to not do so). + ///

+ /// + /// + /// + /// + /// + /// + ///

+ /// The following example uses a different top level (document) element + /// name, but is equivalent to the first example. + ///

+ /// + /// + /// + /// + /// + /// + ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Simon White (.NET) + public class NameValueConverter : TypeConverter + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public NameValueConverter() + { + } + + #endregion + + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + /// + ///

+ /// Currently only supports conversion from an + /// XML formatted instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// True if the conversion is possible. + public override bool CanConvertFrom( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Convert from a string value to a + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A + /// if successful. + /// + public override object ConvertFrom( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + string text = value as string; + if (text != null) + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(text); + return new NameValueSectionHandler() + .Create(null, null, doc.DocumentElement); + } + return base.ConvertFrom(context, culture, value); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/RGBColorConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/RGBColorConverter.cs index 0356c04c..d8d2dee3 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/RGBColorConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/RGBColorConverter.cs @@ -1,170 +1,169 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Drawing; -using System.Globalization; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converter for from a comma separated - /// list of RBG values. - /// - /// - ///

- /// Please note that this class does not implement converting - /// to a comma separated list of RBG values from a - /// . - ///

- ///
- /// Federico Spinazzi - /// $Id: RGBColorConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public sealed class RGBColorConverter : TypeConverter - { - private const char ArgbSeparator = ','; - - private const string DefaultAlpha = "255"; - - /// - /// Returns whether this converter can convert an object of one - /// to a - /// . - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Converts the specified object (a string) a - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture: currently ignored. - /// - /// - /// The value that is to be converted, in "R,G,B", "A,R,G,B", or - /// symbolic color name (). - /// - /// - /// A representation of the string value. - /// - /// - /// If the input string is not in a supported format, or is not one of the - /// predefined system colors (). - /// - public override object ConvertFrom( - ITypeDescriptorContext context, CultureInfo culture, object value) - { - string input = value as string; - if (StringUtils.HasText(input)) - { - if (input.IndexOf(ArgbSeparator) > -1) - { - string[] colorSplit = input.Split(ArgbSeparator); - if (colorSplit.Length == 3) - { - return FromRgb(colorSplit); - } - else if (colorSplit.Length == 4) - { - return FromArgb(colorSplit); - } - else - { - throw new FormatException( - "Input string is not in the correct format : '" + input + "'."); - } - } - return FromName(input); - } - return base.ConvertFrom(context, culture, value); - } - - private static object FromRgb(string[] rgb) - { - return GetColorFrom(DefaultAlpha, rgb[0], rgb[1], rgb[2]); - } - - private static object FromArgb(string[] argb) - { - return GetColorFrom(argb[0], argb[1], argb[2], argb[3]); - } - - private static Color FromName(string name) - { - try - { - KnownColor color = (KnownColor) Enum.Parse(typeof (KnownColor), name); - return Color.FromKnownColor(color); - } - catch (Exception ex) - { - throw new FormatException( - "Input string is not a known system color : '" + name + "'.", ex); - } - } - - private static Color GetColorFrom(string alpha, string red, string green, string blue) - { - try - { - return Color.FromArgb(Int32.Parse(alpha), Int32.Parse(red), Int32.Parse(green), Int32.Parse(blue)); - } - catch (Exception ex) - { - throw new FormatException( - "Bad color format.", ex); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converter for from a comma separated + /// list of RBG values. + /// + /// + ///

+ /// Please note that this class does not implement converting + /// to a comma separated list of RBG values from a + /// . + ///

+ ///
+ /// Federico Spinazzi + public sealed class RGBColorConverter : TypeConverter + { + private const char ArgbSeparator = ','; + + private const string DefaultAlpha = "255"; + + /// + /// Returns whether this converter can convert an object of one + /// to a + /// . + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Converts the specified object (a string) a + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture: currently ignored. + /// + /// + /// The value that is to be converted, in "R,G,B", "A,R,G,B", or + /// symbolic color name (). + /// + /// + /// A representation of the string value. + /// + /// + /// If the input string is not in a supported format, or is not one of the + /// predefined system colors (). + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + string input = value as string; + if (StringUtils.HasText(input)) + { + if (input.IndexOf(ArgbSeparator) > -1) + { + string[] colorSplit = input.Split(ArgbSeparator); + if (colorSplit.Length == 3) + { + return FromRgb(colorSplit); + } + else if (colorSplit.Length == 4) + { + return FromArgb(colorSplit); + } + else + { + throw new FormatException( + "Input string is not in the correct format : '" + input + "'."); + } + } + return FromName(input); + } + return base.ConvertFrom(context, culture, value); + } + + private static object FromRgb(string[] rgb) + { + return GetColorFrom(DefaultAlpha, rgb[0], rgb[1], rgb[2]); + } + + private static object FromArgb(string[] argb) + { + return GetColorFrom(argb[0], argb[1], argb[2], argb[3]); + } + + private static Color FromName(string name) + { + try + { + KnownColor color = (KnownColor) Enum.Parse(typeof (KnownColor), name); + return Color.FromKnownColor(color); + } + catch (Exception ex) + { + throw new FormatException( + "Input string is not a known system color : '" + name + "'.", ex); + } + } + + private static Color GetColorFrom(string alpha, string red, string green, string blue) + { + try + { + return Color.FromArgb(Int32.Parse(alpha), Int32.Parse(red), Int32.Parse(green), Int32.Parse(blue)); + } + catch (Exception ex) + { + throw new FormatException( + "Bad color format.", ex); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/RegexConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/RegexConverter.cs index d85abc37..e33b6f37 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/RegexConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/RegexConverter.cs @@ -1,92 +1,91 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; -using System.Text.RegularExpressions; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converts string representation of a regular expression into an instance of . - /// - /// Aleksandar Seovic - /// $Id: RegexConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class RegexConverter : TypeConverter - { - /// - /// Can we convert from the sourcetype to a ? - /// - /// - ///

- /// Currently only supports conversion from a instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Convert from a value to an - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A if successful. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value is string) - { - return new Regex(value as string); - } - else - { - return base.ConvertFrom(context, culture, value); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; +using System.Text.RegularExpressions; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converts string representation of a regular expression into an instance of . + /// + /// Aleksandar Seovic + public class RegexConverter : TypeConverter + { + /// + /// Can we convert from the sourcetype to a ? + /// + /// + ///

+ /// Currently only supports conversion from a instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + return (sourceType == typeof(string)); + } + + /// + /// Convert from a value to an + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A if successful. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + return new Regex(value as string); + } + else + { + return base.ConvertFrom(context, culture, value); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/RegistryKeyConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/RegistryKeyConverter.cs index f9aabd11..fc58fdff 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/RegistryKeyConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/RegistryKeyConverter.cs @@ -1,164 +1,163 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; -using Microsoft.Win32; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converts string representation of the registry key - /// into instance. - /// - /// Aleksandar Seovic - /// $Id: RegistryKeyConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class RegistryKeyConverter : TypeConverter - { - /// - /// Can we convert from a the sourcetype to a ? - /// - /// - ///

- /// Currently only supports conversion from a instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Convert from a value to an - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A array if successful. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - - if (value is string) - { - string keyName = (string) value; - AssertUtils.ArgumentHasText(keyName, "value"); - - string[] keys = StringUtils.Split(keyName, "\\", false, true); - RegistryKey key = GetRootKey(keys[0]); - for (int i = 1; i < keys.Length; i++) - { - // open all sub-keys but the last one as read-only - key = key.OpenSubKey(keys[i], (i == keys.Length - 1)); - if (key == null) - { - throw new ArgumentException("Registry key [" + GetPartialKeyName(keys, i) + "] does not exist."); - } - } - - return key; - } - return base.ConvertFrom(context, culture, value); - } - - /// - /// Generates partial registry key name. - /// - /// - /// Key elements. - /// - /// - /// Index of the last element to use. - /// - /// - /// Friendly key name containing key element from - /// 0 to , inclusive. - /// - private static string GetPartialKeyName(string[] keys, int index) - { - string keyName = ""; - for (int i = 0; i <= index; i++) - { - keyName += (keys[i] + (i < index ? "\\" : "")); - } - return keyName; - } - - /// - /// Returns for the specified - /// root hive name. - /// - /// - /// Root hive name. - /// - /// - /// Registry key for the specified name. - /// - private static RegistryKey GetRootKey(string name) - { - switch (name) - { - case "HKEY_CURRENT_USER": - return Registry.CurrentUser; - case "HKEY_LOCAL_MACHINE": - return Registry.LocalMachine; - case "HKEY_CLASSES_ROOT": - return Registry.ClassesRoot; - case "HKEY_USERS": - return Registry.Users; - case "HKEY_PERFORMANCE_DATA": - return Registry.PerformanceData; - case "HKEY_CURRENT_CONFIG": - return Registry.CurrentConfig; - case "HKEY_DYN_DATA": - return Registry.DynData; - default: - throw new ArgumentException("Invalid root hive name [" + name + "]."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; +using Microsoft.Win32; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converts string representation of the registry key + /// into instance. + /// + /// Aleksandar Seovic + public class RegistryKeyConverter : TypeConverter + { + /// + /// Can we convert from a the sourcetype to a ? + /// + /// + ///

+ /// Currently only supports conversion from a instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return (sourceType == typeof(string)); + } + + /// + /// Convert from a value to an + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A array if successful. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + + if (value is string) + { + string keyName = (string) value; + AssertUtils.ArgumentHasText(keyName, "value"); + + string[] keys = StringUtils.Split(keyName, "\\", false, true); + RegistryKey key = GetRootKey(keys[0]); + for (int i = 1; i < keys.Length; i++) + { + // open all sub-keys but the last one as read-only + key = key.OpenSubKey(keys[i], (i == keys.Length - 1)); + if (key == null) + { + throw new ArgumentException("Registry key [" + GetPartialKeyName(keys, i) + "] does not exist."); + } + } + + return key; + } + return base.ConvertFrom(context, culture, value); + } + + /// + /// Generates partial registry key name. + /// + /// + /// Key elements. + /// + /// + /// Index of the last element to use. + /// + /// + /// Friendly key name containing key element from + /// 0 to , inclusive. + /// + private static string GetPartialKeyName(string[] keys, int index) + { + string keyName = ""; + for (int i = 0; i <= index; i++) + { + keyName += (keys[i] + (i < index ? "\\" : "")); + } + return keyName; + } + + /// + /// Returns for the specified + /// root hive name. + /// + /// + /// Root hive name. + /// + /// + /// Registry key for the specified name. + /// + private static RegistryKey GetRootKey(string name) + { + switch (name) + { + case "HKEY_CURRENT_USER": + return Registry.CurrentUser; + case "HKEY_LOCAL_MACHINE": + return Registry.LocalMachine; + case "HKEY_CLASSES_ROOT": + return Registry.ClassesRoot; + case "HKEY_USERS": + return Registry.Users; + case "HKEY_PERFORMANCE_DATA": + return Registry.PerformanceData; + case "HKEY_CURRENT_CONFIG": + return Registry.CurrentConfig; + case "HKEY_DYN_DATA": + return Registry.DynData; + default: + throw new ArgumentException("Invalid root hive name [" + name + "]."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/ResourceManagerConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/ResourceManagerConverter.cs index aaee91c2..bd51d985 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/ResourceManagerConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/ResourceManagerConverter.cs @@ -1,158 +1,158 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; -using System.Reflection; -using System.Resources; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converts a two part string, (resource name, assembly name) - /// to a ResourceManager instance. - /// - public class ResourceManagerConverter : TypeConverter - { - /// - /// This constant represents the name of the folder/assembly containing global resources. - /// - public static readonly string APP_GLOBALRESOURCES_ASSEMBLYNAME = "App_GlobalResources"; - - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public ResourceManagerConverter() - { - } - #endregion - - #region Methods - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// True if the conversion is possible. - public override bool CanConvertFrom ( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Convert from a string value to a - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A - /// if successful. - /// - /// If the specified does not denote a valid resource - public override object ConvertFrom ( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - if (value is string) - { - // convert incoming string into ResourceManager... - string[] resourceManagerDescription = StringUtils.DelimitedListToStringArray((string)value, ","); - if (resourceManagerDescription.Length != 2) - { - throw new ArgumentException ("The string to specify a ResourceManager must be a comma delimited list of length two. i.e. resourcename, assembly parial name."); - } - string resourceName = resourceManagerDescription[0].Trim(); - if (resourceName != null && resourceName.Length == 0) - { - throw new ArgumentException("Empty value set for the resource name in ResourceManager string."); - } - string assemblyName = resourceManagerDescription[1].Trim(); - if (assemblyName != null && assemblyName.Length == 0) - { - throw new ArgumentException("Empty value set for the assembly name in ResourceManager string."); - } -#if NET_2_0 - if (assemblyName == APP_GLOBALRESOURCES_ASSEMBLYNAME) - { - try - { - Type globalResourcesType = TypeResolutionUtils.ResolveType(resourceName); - // look both, NonPublic and Public properties (SPRNET-861) - PropertyInfo resourceManagerProperty = globalResourcesType.GetProperty("ResourceManager", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); - return (ResourceManager) resourceManagerProperty.GetValue(globalResourcesType, null); - } - catch (TypeLoadException ex) - { - throw new ArgumentException("Could not load resources '{0}'", resourceName, ex); - } - } - Assembly ass = Assembly.LoadWithPartialName(assemblyName); -#else - Assembly ass = Assembly.LoadWithPartialName(assemblyName); -#endif - if (ass == null) - { - throw new ArgumentException("Could not find assembly with name = '" + assemblyName + "'."); - } - return new ResourceManager(resourceName, ass); - } - return base.ConvertFrom (context, culture, value); - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; +using System.Reflection; +using System.Resources; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converts a two part string, (resource name, assembly name) + /// to a ResourceManager instance. + /// + public class ResourceManagerConverter : TypeConverter + { + /// + /// This constant represents the name of the folder/assembly containing global resources. + /// + public static readonly string APP_GLOBALRESOURCES_ASSEMBLYNAME = "App_GlobalResources"; + + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public ResourceManagerConverter() + { + } + #endregion + + #region Methods + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// True if the conversion is possible. + public override bool CanConvertFrom ( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Convert from a string value to a + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A + /// if successful. + /// + /// If the specified does not denote a valid resource + public override object ConvertFrom ( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + if (value is string) + { + // convert incoming string into ResourceManager... + string[] resourceManagerDescription = StringUtils.DelimitedListToStringArray((string)value, ","); + if (resourceManagerDescription.Length != 2) + { + throw new ArgumentException ("The string to specify a ResourceManager must be a comma delimited list of length two. i.e. resourcename, assembly parial name."); + } + string resourceName = resourceManagerDescription[0].Trim(); + if (resourceName != null && resourceName.Length == 0) + { + throw new ArgumentException("Empty value set for the resource name in ResourceManager string."); + } + string assemblyName = resourceManagerDescription[1].Trim(); + if (assemblyName != null && assemblyName.Length == 0) + { + throw new ArgumentException("Empty value set for the assembly name in ResourceManager string."); + } +#if NET_2_0 + if (assemblyName == APP_GLOBALRESOURCES_ASSEMBLYNAME) + { + try + { + Type globalResourcesType = TypeResolutionUtils.ResolveType(resourceName); + // look both, NonPublic and Public properties (SPRNET-861) + PropertyInfo resourceManagerProperty = globalResourcesType.GetProperty("ResourceManager", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); + return (ResourceManager) resourceManagerProperty.GetValue(globalResourcesType, null); + } + catch (TypeLoadException ex) + { + throw new ArgumentException("Could not load resources '{0}'", resourceName, ex); + } + } + Assembly ass = Assembly.LoadWithPartialName(assemblyName); +#else + Assembly ass = Assembly.LoadWithPartialName(assemblyName); +#endif + if (ass == null) + { + throw new ArgumentException("Could not find assembly with name = '" + assemblyName + "'."); + } + return new ResourceManager(resourceName, ass); + } + return base.ConvertFrom (context, culture, value); + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Core/TypeConversion/RuntimeTypeConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/RuntimeTypeConverter.cs index e609cbc2..60334aa7 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/RuntimeTypeConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/RuntimeTypeConverter.cs @@ -1,175 +1,174 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - - /// - /// A custom for - /// runtime type references. - /// - /// - ///

- /// Currently only supports conversion to and from a - /// . - ///

- ///
- /// Rick Evans (.NET) - /// $Id: RuntimeTypeConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class RuntimeTypeConverter : TypeConverter - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public RuntimeTypeConverter () {} - #endregion - - #region Methods - /// - /// Returns whether this converter can convert an object of one - /// to the - /// of this converter. - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// True if the conversion is possible. - public override bool CanConvertFrom ( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom (context, sourceType); - } - - /// - /// Returns whether this converter can convert the object to the specified - /// . - /// - /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert to. - /// - /// True if the conversion is possible. - public override bool CanConvertTo ( - ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof (Type)) - { - return true; - } - return base.CanConvertTo (context, destinationType); - } - - /// - /// Converts the given value to the type of this converter. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// An that represents the converted value. - /// - public override object ConvertFrom ( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - if (value is string) - { - return TypeResolutionUtils.ResolveType(value as string); - } - return base.ConvertFrom(context, culture, value); - } - - /// - /// Converts the given value object to the specified type, - /// using the specified context and culture information. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// The to convert the - /// parameter to. - /// - /// - /// An that represents the converted value. - /// - public override object ConvertTo ( - ITypeDescriptorContext context, - CultureInfo culture, object value, Type destinationType) - { - if (value is Type - && destinationType == typeof (string)) - { - return ((Type) value).AssemblyQualifiedName; - } - return base.ConvertTo (context, culture, value, destinationType); - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + + /// + /// A custom for + /// runtime type references. + /// + /// + ///

+ /// Currently only supports conversion to and from a + /// . + ///

+ ///
+ /// Rick Evans (.NET) + public class RuntimeTypeConverter : TypeConverter + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public RuntimeTypeConverter () {} + #endregion + + #region Methods + /// + /// Returns whether this converter can convert an object of one + /// to the + /// of this converter. + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// True if the conversion is possible. + public override bool CanConvertFrom ( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom (context, sourceType); + } + + /// + /// Returns whether this converter can convert the object to the specified + /// . + /// + /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert to. + /// + /// True if the conversion is possible. + public override bool CanConvertTo ( + ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == typeof (Type)) + { + return true; + } + return base.CanConvertTo (context, destinationType); + } + + /// + /// Converts the given value to the type of this converter. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// An that represents the converted value. + /// + public override object ConvertFrom ( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + if (value is string) + { + return TypeResolutionUtils.ResolveType(value as string); + } + return base.ConvertFrom(context, culture, value); + } + + /// + /// Converts the given value object to the specified type, + /// using the specified context and culture information. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// The to convert the + /// parameter to. + /// + /// + /// An that represents the converted value. + /// + public override object ConvertTo ( + ITypeDescriptorContext context, + CultureInfo culture, object value, Type destinationType) + { + if (value is Type + && destinationType == typeof (string)) + { + return ((Type) value).AssemblyQualifiedName; + } + return base.ConvertTo (context, culture, value, destinationType); + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Core/TypeConversion/StreamConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/StreamConverter.cs index de8f5b31..35e60dd8 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/StreamConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/StreamConverter.cs @@ -1,126 +1,126 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -using Spring.Core.IO; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converter for to directly set a - /// property. - /// - /// Jurgen Hoeller - /// Mark Pollack (.NET) - public class StreamConverter : TypeConverter - { - private ResourceConverter resourceConverter; - - #region Constructors - /// - /// Create a new StreamConverter using the default - /// . - /// - public StreamConverter() : this (new ResourceConverter()) - { - } - - /// - /// Create a new StreamConverter using the given - /// . - /// - /// - /// The to use. - public StreamConverter(ResourceConverter resourceConverter) - { - this.resourceConverter = resourceConverter == null - ? new ResourceConverter() : resourceConverter; - } - #endregion - - #region Methods - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// True if the conversion is possible. - public override bool CanConvertFrom ( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom (context, sourceType); - } - - /// - /// Convert from a string value to a instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A if successful. - /// - public override object ConvertFrom ( - ITypeDescriptorContext context, - CultureInfo culture, object val) - { - if (val is string) - { - IResource resource = (IResource) resourceConverter.ConvertFrom(context, culture, val); - return resource.InputStream; - } - return base.ConvertFrom (context, culture, val); - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +using Spring.Core.IO; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converter for to directly set a + /// property. + /// + /// Jurgen Hoeller + /// Mark Pollack (.NET) + public class StreamConverter : TypeConverter + { + private ResourceConverter resourceConverter; + + #region Constructors + /// + /// Create a new StreamConverter using the default + /// . + /// + public StreamConverter() : this (new ResourceConverter()) + { + } + + /// + /// Create a new StreamConverter using the given + /// . + /// + /// + /// The to use. + public StreamConverter(ResourceConverter resourceConverter) + { + this.resourceConverter = resourceConverter == null + ? new ResourceConverter() : resourceConverter; + } + #endregion + + #region Methods + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// True if the conversion is possible. + public override bool CanConvertFrom ( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom (context, sourceType); + } + + /// + /// Convert from a string value to a instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A if successful. + /// + public override object ConvertFrom ( + ITypeDescriptorContext context, + CultureInfo culture, object val) + { + if (val is string) + { + IResource resource = (IResource) resourceConverter.ConvertFrom(context, culture, val); + return resource.InputStream; + } + return base.ConvertFrom (context, culture, val); + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Core/TypeConversion/StringArrayConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/StringArrayConverter.cs index 51e284f6..ae0b34be 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/StringArrayConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/StringArrayConverter.cs @@ -1,183 +1,182 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converts a separated to a - /// array. - /// - /// - ///

- /// Defaults to using the , (comma) as the list separator. Note that the value - /// of the current is - /// not used. - ///

- ///

- /// If you want to provide your own list separator, you can set the value of the - /// - /// property to the value that you want. Please note that this value will be used - /// for all future conversions in preference to the default list separator. - ///

- ///

- /// Please note that the individual elements of a string will be passed - /// through as is (i.e. no conversion or trimming of surrounding - /// whitespace will be performed). - ///

- ///

- /// This should be - /// automatically registered with any - /// implementations. - ///

- ///
- /// - /// - /// public class StringArrayConverterExample - /// { - /// public static void Main() - /// { - /// StringArrayConverter converter = new StringArrayConverter(); - /// - /// string csvWords = "This,Is,It"; - /// string[] frankBoothWords = converter.ConvertFrom(csvWords); - /// - /// // the 'frankBoothWords' array will have 3 elements, namely - /// // "This", "Is", "It". - /// - /// // please note that extraneous whitespace is NOT trimmed off - /// // in the current implementation... - /// string csv = " Cogito ,ergo ,sum "; - /// string[] descartesWords = converter.ConvertFrom(csv); - /// - /// // the 'descartesWords' array will have 3 elements, namely - /// // " Cogito ", "ergo ", "sum ". - /// // notice how the whitespace has NOT been trimmed. - /// } - /// } - /// - /// - /// - /// $Id: StringArrayConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class StringArrayConverter : TypeConverter - { - private const string DefaultListSeparator = ","; - - private string listSeparator = DefaultListSeparator; - - /// - /// The value that will be used as the list separator when performing - /// conversions. - /// - /// - /// A 'single' string character that will be used as the list separator - /// when performing conversions. - /// - /// - /// If the supplied value is not and is an empty - /// string, or has more than one character. - /// - public string ListSeparator - { - get { return this.listSeparator; } - set - { - if (value != null) - { - if (value.Length != 1) - { - throw new ArgumentException( - "The 'ListSeparator' must be exactly one character in length."); - } - listSeparator = value; - } - else - { - listSeparator = DefaultListSeparator; - } - } - } - - /// - /// Can we convert from a the sourcetype to a array? - /// - /// - ///

- /// Currently only supports conversion from a instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Convert from a value to a - /// array. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A array if successful. - /// - public override object ConvertFrom( - ITypeDescriptorContext context, CultureInfo culture, object value) - { - string values = value as string; - if (values != null) - { - return StringUtils.DelimitedListToStringArray(values, this.ListSeparator); - } - return base.ConvertFrom(context, culture, value); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converts a separated to a + /// array. + /// + /// + ///

+ /// Defaults to using the , (comma) as the list separator. Note that the value + /// of the current is + /// not used. + ///

+ ///

+ /// If you want to provide your own list separator, you can set the value of the + /// + /// property to the value that you want. Please note that this value will be used + /// for all future conversions in preference to the default list separator. + ///

+ ///

+ /// Please note that the individual elements of a string will be passed + /// through as is (i.e. no conversion or trimming of surrounding + /// whitespace will be performed). + ///

+ ///

+ /// This should be + /// automatically registered with any + /// implementations. + ///

+ ///
+ /// + /// + /// public class StringArrayConverterExample + /// { + /// public static void Main() + /// { + /// StringArrayConverter converter = new StringArrayConverter(); + /// + /// string csvWords = "This,Is,It"; + /// string[] frankBoothWords = converter.ConvertFrom(csvWords); + /// + /// // the 'frankBoothWords' array will have 3 elements, namely + /// // "This", "Is", "It". + /// + /// // please note that extraneous whitespace is NOT trimmed off + /// // in the current implementation... + /// string csv = " Cogito ,ergo ,sum "; + /// string[] descartesWords = converter.ConvertFrom(csv); + /// + /// // the 'descartesWords' array will have 3 elements, namely + /// // " Cogito ", "ergo ", "sum ". + /// // notice how the whitespace has NOT been trimmed. + /// } + /// } + /// + /// + /// + public class StringArrayConverter : TypeConverter + { + private const string DefaultListSeparator = ","; + + private string listSeparator = DefaultListSeparator; + + /// + /// The value that will be used as the list separator when performing + /// conversions. + /// + /// + /// A 'single' string character that will be used as the list separator + /// when performing conversions. + /// + /// + /// If the supplied value is not and is an empty + /// string, or has more than one character. + /// + public string ListSeparator + { + get { return this.listSeparator; } + set + { + if (value != null) + { + if (value.Length != 1) + { + throw new ArgumentException( + "The 'ListSeparator' must be exactly one character in length."); + } + listSeparator = value; + } + else + { + listSeparator = DefaultListSeparator; + } + } + } + + /// + /// Can we convert from a the sourcetype to a array? + /// + /// + ///

+ /// Currently only supports conversion from a instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Convert from a value to a + /// array. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A array if successful. + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + string values = value as string; + if (values != null) + { + return StringUtils.DelimitedListToStringArray(values, this.ListSeparator); + } + return base.ConvertFrom(context, culture, value); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/TimeSpanConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/TimeSpanConverter.cs index 347e4bd9..b2c1a122 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/TimeSpanConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/TimeSpanConverter.cs @@ -1,110 +1,109 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converter for instances. - /// - /// Bruno Baia - /// $Id: TimeSpanConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class TimeSpanConverter : System.ComponentModel.TimeSpanConverter - { - #region Constants - - private const string DaySpecifier = "d"; - private const string HourSpecifier = "h"; - private const string MinuteSpecifier = "m"; - private const string SecondSpecifier = "s"; - private const string MillisecondSpecifier = "ms"; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public TimeSpanConverter() { } - - #endregion - - #region Methods - - /// - /// Convert from a string value to a instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A if successful. - /// - public override object ConvertFrom( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - if (value is string) - { - try - { - string timeSpan = ((string)value).ToLower(); - int specifierLengh = (timeSpan.EndsWith(MillisecondSpecifier)) ? 2 : 1; - int time = int.Parse(timeSpan.Substring(0, timeSpan.Length - specifierLengh)); - - switch (timeSpan.Substring(timeSpan.Length - specifierLengh, specifierLengh)) - { - case MillisecondSpecifier: - return TimeSpan.FromMilliseconds((double)time); - case SecondSpecifier: - return TimeSpan.FromSeconds((double)time); - case MinuteSpecifier: - return TimeSpan.FromMinutes((double)time); - case HourSpecifier: - return TimeSpan.FromHours((double)time); - case DaySpecifier: - return TimeSpan.FromDays((double)time); - } - } - catch { } - } - return base.ConvertFrom(context, culture, value); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converter for instances. + /// + /// Bruno Baia + public class TimeSpanConverter : System.ComponentModel.TimeSpanConverter + { + #region Constants + + private const string DaySpecifier = "d"; + private const string HourSpecifier = "h"; + private const string MinuteSpecifier = "m"; + private const string SecondSpecifier = "s"; + private const string MillisecondSpecifier = "ms"; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public TimeSpanConverter() { } + + #endregion + + #region Methods + + /// + /// Convert from a string value to a instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A if successful. + /// + public override object ConvertFrom( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + if (value is string) + { + try + { + string timeSpan = ((string)value).ToLower(); + int specifierLengh = (timeSpan.EndsWith(MillisecondSpecifier)) ? 2 : 1; + int time = int.Parse(timeSpan.Substring(0, timeSpan.Length - specifierLengh)); + + switch (timeSpan.Substring(timeSpan.Length - specifierLengh, specifierLengh)) + { + case MillisecondSpecifier: + return TimeSpan.FromMilliseconds((double)time); + case SecondSpecifier: + return TimeSpan.FromSeconds((double)time); + case MinuteSpecifier: + return TimeSpan.FromMinutes((double)time); + case HourSpecifier: + return TimeSpan.FromHours((double)time); + case DaySpecifier: + return TimeSpan.FromDays((double)time); + } + } + catch { } + } + return base.ConvertFrom(context, culture, value); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/TypeConversionUtils.cs b/src/Spring/Spring.Core/Core/TypeConversion/TypeConversionUtils.cs index 9fd69a6d..d3f20b3c 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/TypeConversionUtils.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/TypeConversionUtils.cs @@ -1,211 +1,210 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.ComponentModel; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Utility methods that are used to convert objects from one type into another. - /// - /// Aleksandar Seovic - /// $Id: TypeConversionUtils.cs,v 1.4 2008/03/20 23:58:16 oakinger Exp $ - public class TypeConversionUtils - { - /// - /// Convert the value to the required (if necessary from a string). - /// - /// The proposed change value. - /// - /// The we must convert to. - /// - /// Property name, used for error reporting purposes... - /// - /// If there is an internal error. - /// - /// The new value, possibly the result of type conversion. - public static object ConvertValueIfNecessary(Type requiredType, object newValue, string propertyName) - { - if (newValue != null) - { - // if it is assignable, return the value right away - if (IsAssignableFrom(newValue, requiredType)) - { - return newValue; - } - - // if required type is an array, convert all the elements - if (requiredType != null && requiredType.IsArray) - { - // convert individual elements to array elements - Type componentType = requiredType.GetElementType(); - if (newValue is IList) - { - IList elements = (IList) newValue; - return ToArrayWithTypeConversion(componentType, elements, propertyName); - } - else if (newValue is string) - { - if (requiredType.Equals(typeof(char[]))) - { - return ((string) newValue).ToCharArray(); - } - else - { - string[] elements = StringUtils.CommaDelimitedListToStringArray((string) newValue); - return ToArrayWithTypeConversion(componentType, elements, propertyName); - } - } - else if (!newValue.GetType().IsArray) - { - Array result = Array.CreateInstance(componentType, 1); - object val = ConvertValueIfNecessary(componentType, newValue, propertyName); - result.SetValue(val, 0); - return result; - } - } - - // try to convert using type converter - try - { - TypeConverter typeConverter = TypeConverterRegistry.GetConverter(requiredType); - if (typeConverter != null && typeConverter.CanConvertFrom(newValue.GetType())) - { - try - { - newValue = typeConverter.ConvertFrom(newValue); - } - catch - { - if (newValue is string) - { - newValue = typeConverter.ConvertFromInvariantString((string)newValue); - } - } - } - else - { - typeConverter = TypeConverterRegistry.GetConverter(newValue.GetType()); - if (typeConverter != null && typeConverter.CanConvertTo(requiredType)) - { - newValue = typeConverter.ConvertTo(newValue, requiredType); - } - else - { - // look if it's an enum - if (requiredType != null - && requiredType.IsEnum - && (!(newValue is float) - && (!(newValue is double)))) - { - // convert numeric value into enum's underlying type - Type numericType = Enum.GetUnderlyingType(requiredType); - newValue = Convert.ChangeType(newValue, numericType); - - if (Enum.IsDefined(requiredType, newValue)) - { - newValue = Enum.ToObject(requiredType, newValue); - } - else - { - throw new TypeMismatchException( - CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); - } - } - else if (newValue is IConvertible) - { - // last resort - try ChangeType - newValue = Convert.ChangeType(newValue, requiredType); - } - else - { - throw new TypeMismatchException( - CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); - } - } - } - } - catch (Exception ex) - { - throw new TypeMismatchException( - CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType, ex); - } - if (newValue == null) - { - throw new TypeMismatchException( - CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); - } - } - return newValue; - } - - private static object ToArrayWithTypeConversion(Type componentType, IList elements, string propertyName) - { - Array destination = Array.CreateInstance(componentType, elements.Count); - for (int i = 0; i < elements.Count; ++i) - { - object value = ConvertValueIfNecessary(componentType, elements[i], propertyName + "[" + i + "]"); - destination.SetValue(value, i); - } - return destination; - } - - private static bool IsAssignableFrom(object newValue, Type requiredType) - { - if (newValue is MarshalByRefObject) - { - //TODO see what type of type checking can be done. May need to - //preserve information when proxy was created by SaoServiceExporter. - return true; - } - if (requiredType == null) - { - return false; - } - return requiredType.IsAssignableFrom(newValue.GetType()); - } - - /// - /// Utility method to create a property change event. - /// - /// - /// The full name of the property that has changed. - /// - /// The property old value - /// The property new value - /// - /// A new . - /// - private static PropertyChangeEventArgs CreatePropertyChangeEventArgs(string fullPropertyName, object oldValue, - object newValue) - { - return new PropertyChangeEventArgs(fullPropertyName, oldValue, newValue); - } - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.ComponentModel; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Utility methods that are used to convert objects from one type into another. + /// + /// Aleksandar Seovic + public class TypeConversionUtils + { + /// + /// Convert the value to the required (if necessary from a string). + /// + /// The proposed change value. + /// + /// The we must convert to. + /// + /// Property name, used for error reporting purposes... + /// + /// If there is an internal error. + /// + /// The new value, possibly the result of type conversion. + public static object ConvertValueIfNecessary(Type requiredType, object newValue, string propertyName) + { + if (newValue != null) + { + // if it is assignable, return the value right away + if (IsAssignableFrom(newValue, requiredType)) + { + return newValue; + } + + // if required type is an array, convert all the elements + if (requiredType != null && requiredType.IsArray) + { + // convert individual elements to array elements + Type componentType = requiredType.GetElementType(); + if (newValue is IList) + { + IList elements = (IList) newValue; + return ToArrayWithTypeConversion(componentType, elements, propertyName); + } + else if (newValue is string) + { + if (requiredType.Equals(typeof(char[]))) + { + return ((string) newValue).ToCharArray(); + } + else + { + string[] elements = StringUtils.CommaDelimitedListToStringArray((string) newValue); + return ToArrayWithTypeConversion(componentType, elements, propertyName); + } + } + else if (!newValue.GetType().IsArray) + { + Array result = Array.CreateInstance(componentType, 1); + object val = ConvertValueIfNecessary(componentType, newValue, propertyName); + result.SetValue(val, 0); + return result; + } + } + + // try to convert using type converter + try + { + TypeConverter typeConverter = TypeConverterRegistry.GetConverter(requiredType); + if (typeConverter != null && typeConverter.CanConvertFrom(newValue.GetType())) + { + try + { + newValue = typeConverter.ConvertFrom(newValue); + } + catch + { + if (newValue is string) + { + newValue = typeConverter.ConvertFromInvariantString((string)newValue); + } + } + } + else + { + typeConverter = TypeConverterRegistry.GetConverter(newValue.GetType()); + if (typeConverter != null && typeConverter.CanConvertTo(requiredType)) + { + newValue = typeConverter.ConvertTo(newValue, requiredType); + } + else + { + // look if it's an enum + if (requiredType != null + && requiredType.IsEnum + && (!(newValue is float) + && (!(newValue is double)))) + { + // convert numeric value into enum's underlying type + Type numericType = Enum.GetUnderlyingType(requiredType); + newValue = Convert.ChangeType(newValue, numericType); + + if (Enum.IsDefined(requiredType, newValue)) + { + newValue = Enum.ToObject(requiredType, newValue); + } + else + { + throw new TypeMismatchException( + CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); + } + } + else if (newValue is IConvertible) + { + // last resort - try ChangeType + newValue = Convert.ChangeType(newValue, requiredType); + } + else + { + throw new TypeMismatchException( + CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); + } + } + } + } + catch (Exception ex) + { + throw new TypeMismatchException( + CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType, ex); + } + if (newValue == null) + { + throw new TypeMismatchException( + CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); + } + } + return newValue; + } + + private static object ToArrayWithTypeConversion(Type componentType, IList elements, string propertyName) + { + Array destination = Array.CreateInstance(componentType, elements.Count); + for (int i = 0; i < elements.Count; ++i) + { + object value = ConvertValueIfNecessary(componentType, elements[i], propertyName + "[" + i + "]"); + destination.SetValue(value, i); + } + return destination; + } + + private static bool IsAssignableFrom(object newValue, Type requiredType) + { + if (newValue is MarshalByRefObject) + { + //TODO see what type of type checking can be done. May need to + //preserve information when proxy was created by SaoServiceExporter. + return true; + } + if (requiredType == null) + { + return false; + } + return requiredType.IsAssignableFrom(newValue.GetType()); + } + + /// + /// Utility method to create a property change event. + /// + /// + /// The full name of the property that has changed. + /// + /// The property old value + /// The property new value + /// + /// A new . + /// + private static PropertyChangeEventArgs CreatePropertyChangeEventArgs(string fullPropertyName, object oldValue, + object newValue) + { + return new PropertyChangeEventArgs(fullPropertyName, oldValue, newValue); + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/TypeConverterRegistry.cs b/src/Spring/Spring.Core/Core/TypeConversion/TypeConverterRegistry.cs index caaf5cd0..a7b8e962 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/TypeConverterRegistry.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/TypeConverterRegistry.cs @@ -1,167 +1,166 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Drawing; -using System.IO; -using System.Net; -using System.Resources; -using System.Text.RegularExpressions; -using Microsoft.Win32; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Registry class that allows users to register and retrieve type converters. - /// - /// Aleksandar Seovic - /// $Id: TypeConverterRegistry.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class TypeConverterRegistry - { - /// - /// Name of the .Net config section that contains Spring.Net type aliases. - /// - private const string TypeConvertersSectionName = "spring/typeConverters"; - - private static IDictionary converters = new Hashtable(); - - /// - /// Registers standard and configured type converters. - /// - static TypeConverterRegistry() - { - lock (converters.SyncRoot) - { - converters[typeof(string[])] = new StringArrayConverter(); - converters[typeof(Type)] = new RuntimeTypeConverter(); - converters[typeof(Color)] = new RGBColorConverter(); - converters[typeof(Uri)] = new UriConverter(); - converters[typeof(FileInfo)] = new FileInfoConverter(); - converters[typeof(Stream)] = new StreamConverter(); - converters[typeof(NameValueCollection)] = new NameValueConverter(); - converters[typeof(ResourceManager)] = new ResourceManagerConverter(); - converters[typeof(Regex)] = new RegexConverter(); - converters[typeof(TimeSpan)] = new TimeSpanConverter(); - converters[typeof(ICredentials)] = new CredentialConverter(); - converters[typeof(NetworkCredential)] = new CredentialConverter(); - converters[typeof(RegistryKey)] = new RegistryKeyConverter(); - - // register user-defined type converters - ConfigurationUtils.GetSection(TypeConvertersSectionName); - } - } - - /// - /// Returns for the specified type. - /// - /// Type to get the converter for. - /// a type converter for the specified type. - /// If is null. - public static TypeConverter GetConverter(Type type) - { - AssertUtils.ArgumentNotNull(type, "type"); - - TypeConverter converter = (TypeConverter) converters[type]; - if (converter == null) - { - if (type.IsEnum) - { - converter = new EnumConverter(type); - } - else - { - converter = TypeDescriptor.GetConverter(type); - } - } - - return converter; - } - - /// - /// Registers for the specified type. - /// - /// Type to register the converter for. - /// Type converter to register. - /// If either of arguments is null. - public static void RegisterConverter(Type type, TypeConverter converter) - { - AssertUtils.ArgumentNotNull(type, "type"); - AssertUtils.ArgumentNotNull(converter, "converter"); - - lock (converters.SyncRoot) - { - converters[type] = converter; - } - } - - /// - /// Registers for the specified type. - /// - /// - /// This is a convinience method that accepts the names of both - /// type to register converter for and the converter itself, - /// resolves them using , creates an - /// instance of type converter and calls overloaded - /// method. - /// - /// Type name of the type to register the converter for (can be a type alias). - /// Type name of the type converter to register (can be a type alias). - /// If either of arguments is null or empty string. - /// - /// If either of arguments fails to resolve to a valid . - /// - /// - /// If type converter does not derive from or if it cannot be instantiated. - /// - public static void RegisterConverter(string typeName, string converterTypeName) - { - AssertUtils.ArgumentHasText(typeName, "typeName"); - AssertUtils.ArgumentHasText(converterTypeName, "converterTypeName"); - - try - { - Type type = TypeResolutionUtils.ResolveType(typeName); - Type converterType = TypeResolutionUtils.ResolveType(converterTypeName); - if (!typeof(TypeConverter).IsAssignableFrom(converterType)) - { - throw new ArgumentException( - "Type specified as a 'converterTypeName' does not inherit from System.ComponentModel.TypeConverter"); - } - RegisterConverter(type,(TypeConverter) ObjectUtils.InstantiateType(converterType)); - } - catch (FatalReflectionException e) - { - throw new ArgumentException("Failed to create an instance of the specified type converter.", e); - } - } - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Net; +using System.Resources; +using System.Text.RegularExpressions; +using Microsoft.Win32; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Registry class that allows users to register and retrieve type converters. + /// + /// Aleksandar Seovic + public class TypeConverterRegistry + { + /// + /// Name of the .Net config section that contains Spring.Net type aliases. + /// + private const string TypeConvertersSectionName = "spring/typeConverters"; + + private static IDictionary converters = new Hashtable(); + + /// + /// Registers standard and configured type converters. + /// + static TypeConverterRegistry() + { + lock (converters.SyncRoot) + { + converters[typeof(string[])] = new StringArrayConverter(); + converters[typeof(Type)] = new RuntimeTypeConverter(); + converters[typeof(Color)] = new RGBColorConverter(); + converters[typeof(Uri)] = new UriConverter(); + converters[typeof(FileInfo)] = new FileInfoConverter(); + converters[typeof(Stream)] = new StreamConverter(); + converters[typeof(NameValueCollection)] = new NameValueConverter(); + converters[typeof(ResourceManager)] = new ResourceManagerConverter(); + converters[typeof(Regex)] = new RegexConverter(); + converters[typeof(TimeSpan)] = new TimeSpanConverter(); + converters[typeof(ICredentials)] = new CredentialConverter(); + converters[typeof(NetworkCredential)] = new CredentialConverter(); + converters[typeof(RegistryKey)] = new RegistryKeyConverter(); + + // register user-defined type converters + ConfigurationUtils.GetSection(TypeConvertersSectionName); + } + } + + /// + /// Returns for the specified type. + /// + /// Type to get the converter for. + /// a type converter for the specified type. + /// If is null. + public static TypeConverter GetConverter(Type type) + { + AssertUtils.ArgumentNotNull(type, "type"); + + TypeConverter converter = (TypeConverter) converters[type]; + if (converter == null) + { + if (type.IsEnum) + { + converter = new EnumConverter(type); + } + else + { + converter = TypeDescriptor.GetConverter(type); + } + } + + return converter; + } + + /// + /// Registers for the specified type. + /// + /// Type to register the converter for. + /// Type converter to register. + /// If either of arguments is null. + public static void RegisterConverter(Type type, TypeConverter converter) + { + AssertUtils.ArgumentNotNull(type, "type"); + AssertUtils.ArgumentNotNull(converter, "converter"); + + lock (converters.SyncRoot) + { + converters[type] = converter; + } + } + + /// + /// Registers for the specified type. + /// + /// + /// This is a convinience method that accepts the names of both + /// type to register converter for and the converter itself, + /// resolves them using , creates an + /// instance of type converter and calls overloaded + /// method. + /// + /// Type name of the type to register the converter for (can be a type alias). + /// Type name of the type converter to register (can be a type alias). + /// If either of arguments is null or empty string. + /// + /// If either of arguments fails to resolve to a valid . + /// + /// + /// If type converter does not derive from or if it cannot be instantiated. + /// + public static void RegisterConverter(string typeName, string converterTypeName) + { + AssertUtils.ArgumentHasText(typeName, "typeName"); + AssertUtils.ArgumentHasText(converterTypeName, "converterTypeName"); + + try + { + Type type = TypeResolutionUtils.ResolveType(typeName); + Type converterType = TypeResolutionUtils.ResolveType(converterTypeName); + if (!typeof(TypeConverter).IsAssignableFrom(converterType)) + { + throw new ArgumentException( + "Type specified as a 'converterTypeName' does not inherit from System.ComponentModel.TypeConverter"); + } + RegisterConverter(type,(TypeConverter) ObjectUtils.InstantiateType(converterType)); + } + catch (FatalReflectionException e) + { + throw new ArgumentException("Failed to create an instance of the specified type converter.", e); + } + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/UniqueKeyConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/UniqueKeyConverter.cs index 5bcd16be..7cb7ffd0 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/UniqueKeyConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/UniqueKeyConverter.cs @@ -1,162 +1,161 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Importsusing System; - -using System; -using System.ComponentModel; -using System.Globalization; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converts between instances of and their string representations. - /// - /// Erich Eichinger - /// $Id: UniqueKeyConverter.cs,v 1.1 2007/08/22 20:17:35 oakinger Exp $ - public class UniqueKeyConverter : TypeConverter - { - /// - /// Can we convert from the sourcetype to a ? - /// - /// - ///

- /// Currently only supports conversion from a instance. - ///

- ///
- /// - /// A that provides a format context. - /// - /// - /// A that represents the you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - return (typeof(string)==sourceType || typeof(UniqueKey)==sourceType); - } - - /// - /// Convert from a value to an instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A if successful, otherwise. - /// - ///The conversion cannot be performed. - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value == null) return null; - - if (!CanConvertFrom(context, value.GetType())) - { - throw new NotSupportedException(string.Format("Conversion from value of type '{0}' is not supported", value.GetType().FullName)); - } - - if (value is string) - { - return new UniqueKey(value as string); - } - else if (value is UniqueKey) - { - return value; - } - - throw new NotSupportedException(string.Format("Cannot convert from value of type '{0}' to '{1}'", value.GetType().FullName, typeof(UniqueKey).FullName)); - } - - /// - ///Returns whether this converter can convert the object to the specified type, using the specified context. - /// - ///An that provides a format context. - ///A that represents the type you want to convert to. - /// - ///true if this converter can perform the conversion; otherwise, false. - /// - /// - /// At the moment only conversion to string is supported. - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return (typeof(string)==destinationType || typeof(UniqueKey)==destinationType); - } - - /// - ///Converts the given value object to the specified type, using the specified context and culture information. - /// - /// - /// - ///An that represents the converted value. - /// - /// - ///A . If null is passed, the current culture is assumed. - ///An that provides a format context. - ///The to convert the value parameter to. - ///The to convert. - ///The conversion cannot be performed. - ///The destinationType parameter is null. - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - // check destinationType - if (destinationType == null) - { - throw new ArgumentNullException("destinationType", "destinationType must not be null"); - } - if (!CanConvertTo(context, destinationType)) - { - throw new NotSupportedException(string.Format("conversion to destinationType '{0}' is not supported.", destinationType.FullName)); - } - - // value must either be null or a UniqueKey - if ( (value != null) && (typeof(UniqueKey) != value.GetType()) ) - { - throw new NotSupportedException(string.Format("value is not of type '{0}'", typeof(UniqueKey).FullName)); - } - - if (value == null) return null; - - if (typeof(string)==destinationType) - { - return (value).ToString(); - } - else if (typeof(UniqueKey)==destinationType) - { - return value; - } - - throw new NotSupportedException(string.Format("destinationType must be '{0}' but was '{1}'", typeof(string).FullName, destinationType)); - } - - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Importsusing System; + +using System; +using System.ComponentModel; +using System.Globalization; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converts between instances of and their string representations. + /// + /// Erich Eichinger + public class UniqueKeyConverter : TypeConverter + { + /// + /// Can we convert from the sourcetype to a ? + /// + /// + ///

+ /// Currently only supports conversion from a instance. + ///

+ ///
+ /// + /// A that provides a format context. + /// + /// + /// A that represents the you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + return (typeof(string)==sourceType || typeof(UniqueKey)==sourceType); + } + + /// + /// Convert from a value to an instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A if successful, otherwise. + /// + ///The conversion cannot be performed. + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value == null) return null; + + if (!CanConvertFrom(context, value.GetType())) + { + throw new NotSupportedException(string.Format("Conversion from value of type '{0}' is not supported", value.GetType().FullName)); + } + + if (value is string) + { + return new UniqueKey(value as string); + } + else if (value is UniqueKey) + { + return value; + } + + throw new NotSupportedException(string.Format("Cannot convert from value of type '{0}' to '{1}'", value.GetType().FullName, typeof(UniqueKey).FullName)); + } + + /// + ///Returns whether this converter can convert the object to the specified type, using the specified context. + /// + ///An that provides a format context. + ///A that represents the type you want to convert to. + /// + ///true if this converter can perform the conversion; otherwise, false. + /// + /// + /// At the moment only conversion to string is supported. + /// + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return (typeof(string)==destinationType || typeof(UniqueKey)==destinationType); + } + + /// + ///Converts the given value object to the specified type, using the specified context and culture information. + /// + /// + /// + ///An that represents the converted value. + /// + /// + ///A . If null is passed, the current culture is assumed. + ///An that provides a format context. + ///The to convert the value parameter to. + ///The to convert. + ///The conversion cannot be performed. + ///The destinationType parameter is null. + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + // check destinationType + if (destinationType == null) + { + throw new ArgumentNullException("destinationType", "destinationType must not be null"); + } + if (!CanConvertTo(context, destinationType)) + { + throw new NotSupportedException(string.Format("conversion to destinationType '{0}' is not supported.", destinationType.FullName)); + } + + // value must either be null or a UniqueKey + if ( (value != null) && (typeof(UniqueKey) != value.GetType()) ) + { + throw new NotSupportedException(string.Format("value is not of type '{0}'", typeof(UniqueKey).FullName)); + } + + if (value == null) return null; + + if (typeof(string)==destinationType) + { + return (value).ToString(); + } + else if (typeof(UniqueKey)==destinationType) + { + return value; + } + + throw new NotSupportedException(string.Format("destinationType must be '{0}' but was '{1}'", typeof(string).FullName, destinationType)); + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeConversion/UriConverter.cs b/src/Spring/Spring.Core/Core/TypeConversion/UriConverter.cs index 9c681263..891daece 100644 --- a/src/Spring/Spring.Core/Core/TypeConversion/UriConverter.cs +++ b/src/Spring/Spring.Core/Core/TypeConversion/UriConverter.cs @@ -1,114 +1,113 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -#endregion - -namespace Spring.Core.TypeConversion -{ - /// - /// Converter for instances. - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: UriConverter.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class UriConverter : TypeConverter - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public UriConverter () {} - #endregion - - #region Methods - /// - /// Returns whether this converter can convert an object of one - /// to a - /// - /// - ///

- /// Currently only supports conversion from a - /// instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// True if the conversion is possible. - public override bool CanConvertFrom ( - ITypeDescriptorContext context, - Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom (context, sourceType); - } - - /// - /// Convert from a string value to a instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A if successful. - /// - public override object ConvertFrom ( - ITypeDescriptorContext context, - CultureInfo culture, object value) - { - if (value is string) - { - try - { - return new Uri(value as string); - } - catch (UriFormatException ex) - { - throw new ArgumentException("Malformed URL: ", ex); - } - } - return base.ConvertFrom (context, culture, value); - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +#endregion + +namespace Spring.Core.TypeConversion +{ + /// + /// Converter for instances. + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class UriConverter : TypeConverter + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public UriConverter () {} + #endregion + + #region Methods + /// + /// Returns whether this converter can convert an object of one + /// to a + /// + /// + ///

+ /// Currently only supports conversion from a + /// instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// True if the conversion is possible. + public override bool CanConvertFrom ( + ITypeDescriptorContext context, + Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom (context, sourceType); + } + + /// + /// Convert from a string value to a instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A if successful. + /// + public override object ConvertFrom ( + ITypeDescriptorContext context, + CultureInfo culture, object value) + { + if (value is string) + { + try + { + return new Uri(value as string); + } + catch (UriFormatException ex) + { + throw new ArgumentException("Malformed URL: ", ex); + } + } + return base.ConvertFrom (context, culture, value); + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Core/TypeMismatchException.cs b/src/Spring/Spring.Core/Core/TypeMismatchException.cs index c5effa58..a254c35f 100644 --- a/src/Spring/Spring.Core/Core/TypeMismatchException.cs +++ b/src/Spring/Spring.Core/Core/TypeMismatchException.cs @@ -1,158 +1,157 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Text; -using Spring.Core; - -#endregion - -namespace Spring.Core -{ - /// - /// Exception thrown on a mismatch when trying to set a property - /// or resolve an argument to a method invocation. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: TypeMismatchException.cs,v 1.1 2007/07/31 00:08:42 markpollack Exp $ - [Serializable] - public class TypeMismatchException : PropertyAccessException - { - /// - /// The string error code used to classify the exception. - /// - public override string ErrorCode - { - get { return "typeMismatch"; } - } - - /// - /// Creates a new instance of the TypeMismatchException class. - /// - public TypeMismatchException() - { - } - - /// - /// Creates a new instance of the TypeMismatchException class. - /// - /// - /// A message about the exception. - /// - public TypeMismatchException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the TypeMismatchException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public TypeMismatchException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the TypeMismatchException class describing the - /// property and required type that could not used to set a property on the target object. - /// - /// - /// The description of the property that was to be changed. - /// - /// The target conversion type. - public TypeMismatchException( - PropertyChangeEventArgs propertyChangeEventArgs, Type requiredType) : - base(BuildMessage(propertyChangeEventArgs, requiredType), propertyChangeEventArgs) - { - } - - /// - /// Creates a new instance of the TypeMismatchException class describing the - /// property, required type, and underlying exception that could not be used - /// to set a property on the target object. - /// - /// - /// The description of the property that was to be changed. - /// - /// The target conversion type. - /// The underlying exception. - public TypeMismatchException( - PropertyChangeEventArgs propertyChangeEventArgs, Type requiredType, Exception rootCause) : - base(BuildMessage(propertyChangeEventArgs, requiredType), propertyChangeEventArgs, rootCause) - { - } - - /// - /// Creates a new instance of the TypeMismatchException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TypeMismatchException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - private static string BuildMessage(PropertyChangeEventArgs propertyChangeEventArgs, Type requiredType) - { - StringBuilder message = new StringBuilder(); - message.Append("Cannot convert property value of type ["); - if (propertyChangeEventArgs != null && propertyChangeEventArgs.NewValue != null) - { - message.Append(propertyChangeEventArgs.NewValue.GetType().FullName); - } - else - { - message.Append("null"); - } - message.Append("] to required type ["); - if (requiredType != null) - { - message.Append(requiredType.FullName); - } - else - { - message.Append("null"); - } - message.Append("] for property '"); - if (propertyChangeEventArgs != null && propertyChangeEventArgs.PropertyName != null) - { - message.Append(propertyChangeEventArgs.PropertyName); - } - message.Append("'."); - return message.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Text; +using Spring.Core; + +#endregion + +namespace Spring.Core +{ + /// + /// Exception thrown on a mismatch when trying to set a property + /// or resolve an argument to a method invocation. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + [Serializable] + public class TypeMismatchException : PropertyAccessException + { + /// + /// The string error code used to classify the exception. + /// + public override string ErrorCode + { + get { return "typeMismatch"; } + } + + /// + /// Creates a new instance of the TypeMismatchException class. + /// + public TypeMismatchException() + { + } + + /// + /// Creates a new instance of the TypeMismatchException class. + /// + /// + /// A message about the exception. + /// + public TypeMismatchException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the TypeMismatchException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public TypeMismatchException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the TypeMismatchException class describing the + /// property and required type that could not used to set a property on the target object. + /// + /// + /// The description of the property that was to be changed. + /// + /// The target conversion type. + public TypeMismatchException( + PropertyChangeEventArgs propertyChangeEventArgs, Type requiredType) : + base(BuildMessage(propertyChangeEventArgs, requiredType), propertyChangeEventArgs) + { + } + + /// + /// Creates a new instance of the TypeMismatchException class describing the + /// property, required type, and underlying exception that could not be used + /// to set a property on the target object. + /// + /// + /// The description of the property that was to be changed. + /// + /// The target conversion type. + /// The underlying exception. + public TypeMismatchException( + PropertyChangeEventArgs propertyChangeEventArgs, Type requiredType, Exception rootCause) : + base(BuildMessage(propertyChangeEventArgs, requiredType), propertyChangeEventArgs, rootCause) + { + } + + /// + /// Creates a new instance of the TypeMismatchException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TypeMismatchException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + private static string BuildMessage(PropertyChangeEventArgs propertyChangeEventArgs, Type requiredType) + { + StringBuilder message = new StringBuilder(); + message.Append("Cannot convert property value of type ["); + if (propertyChangeEventArgs != null && propertyChangeEventArgs.NewValue != null) + { + message.Append(propertyChangeEventArgs.NewValue.GetType().FullName); + } + else + { + message.Append("null"); + } + message.Append("] to required type ["); + if (requiredType != null) + { + message.Append(requiredType.FullName); + } + else + { + message.Append("null"); + } + message.Append("] for property '"); + if (propertyChangeEventArgs != null && propertyChangeEventArgs.PropertyName != null) + { + message.Append(propertyChangeEventArgs.PropertyName); + } + message.Append("'."); + return message.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeResolution/CachedTypeResolver.cs b/src/Spring/Spring.Core/Core/TypeResolution/CachedTypeResolver.cs index fb26323b..3172680c 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/CachedTypeResolver.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/CachedTypeResolver.cs @@ -1,125 +1,124 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Resolves (instantiates) a by it's (possibly - /// assembly qualified) name, and caches the - /// instance against the type name. - /// - /// Rick Evans - /// Bruno Baia - /// Erich Eichinger - /// $Id: CachedTypeResolver.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class CachedTypeResolver : ITypeResolver - { - /// - /// The cache, mapping type names ( instances) against - /// instances. - /// - private IDictionary typeCache = new HybridDictionary(); - - private ITypeResolver typeResolver; - - /// - /// Creates a new instance of the class. - /// - /// - /// The that this instance will delegate - /// actual resolution to if a - /// cannot be found in this instance's cache. - /// - /// - /// If the supplied is . - /// - public CachedTypeResolver(ITypeResolver typeResolver) - { - AssertUtils.ArgumentNotNull(typeResolver, "typeResolver"); - this.typeResolver = typeResolver; - } - - /// - /// Resolves the supplied to a - /// - /// instance. - /// - /// - /// The (possibly partially assembly qualified) name of a - /// . - /// - /// - /// A resolved instance. - /// - /// - /// If the supplied could not be resolved - /// to a . - /// - public Type Resolve(string typeName) - { - if (StringUtils.IsNullOrEmpty(typeName)) - { - throw BuildTypeLoadException(typeName); - } - Type type = null; - try - { - lock (this.typeCache.SyncRoot) - { - type = this.typeCache[typeName] as Type; - if (type == null) - { - type = this.typeResolver.Resolve(typeName); - this.typeCache[typeName] = type; - } - } - } - catch (Exception ex) - { - if (ex is TypeLoadException) - { - throw; - } - throw BuildTypeLoadException(typeName, ex); - } - return type; - } - - private static TypeLoadException BuildTypeLoadException(string typeName) - { - return new TypeLoadException("Could not load type from string value '" + typeName + "'."); - } - - private static TypeLoadException BuildTypeLoadException(string typeName, Exception ex) - { - return new TypeLoadException("Could not load type from string value '" + typeName + "'.", ex); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Resolves (instantiates) a by it's (possibly + /// assembly qualified) name, and caches the + /// instance against the type name. + /// + /// Rick Evans + /// Bruno Baia + /// Erich Eichinger + public class CachedTypeResolver : ITypeResolver + { + /// + /// The cache, mapping type names ( instances) against + /// instances. + /// + private IDictionary typeCache = new HybridDictionary(); + + private ITypeResolver typeResolver; + + /// + /// Creates a new instance of the class. + /// + /// + /// The that this instance will delegate + /// actual resolution to if a + /// cannot be found in this instance's cache. + /// + /// + /// If the supplied is . + /// + public CachedTypeResolver(ITypeResolver typeResolver) + { + AssertUtils.ArgumentNotNull(typeResolver, "typeResolver"); + this.typeResolver = typeResolver; + } + + /// + /// Resolves the supplied to a + /// + /// instance. + /// + /// + /// The (possibly partially assembly qualified) name of a + /// . + /// + /// + /// A resolved instance. + /// + /// + /// If the supplied could not be resolved + /// to a . + /// + public Type Resolve(string typeName) + { + if (StringUtils.IsNullOrEmpty(typeName)) + { + throw BuildTypeLoadException(typeName); + } + Type type = null; + try + { + lock (this.typeCache.SyncRoot) + { + type = this.typeCache[typeName] as Type; + if (type == null) + { + type = this.typeResolver.Resolve(typeName); + this.typeCache[typeName] = type; + } + } + } + catch (Exception ex) + { + if (ex is TypeLoadException) + { + throw; + } + throw BuildTypeLoadException(typeName, ex); + } + return type; + } + + private static TypeLoadException BuildTypeLoadException(string typeName) + { + return new TypeLoadException("Could not load type from string value '" + typeName + "'."); + } + + private static TypeLoadException BuildTypeLoadException(string typeName, Exception ex) + { + return new TypeLoadException("Could not load type from string value '" + typeName + "'.", ex); + } + } +} diff --git a/src/Spring/Spring.Core/Core/TypeResolution/GenericArgumentsHolder.cs b/src/Spring/Spring.Core/Core/TypeResolution/GenericArgumentsHolder.cs index f43e3809..c6dfedfd 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/GenericArgumentsHolder.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/GenericArgumentsHolder.cs @@ -1,223 +1,223 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System.Collections; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Holder for the generic arguments when using type parameters. - /// - /// - ///

- /// Type parameters can be applied to classes, interfaces, - /// structures, methods, delegates, etc... - ///

- ///
- public class GenericArgumentsHolder - { - #region Constants - - /// - /// The generic arguments prefix. - /// - public const char GenericArgumentsPrefix = '<'; - - /// - /// The generic arguments suffix. - /// - public const char GenericArgumentsSuffix = '>'; - - /// - /// The character that separates a list of generic arguments. - /// - public const char GenericArgumentsSeparator = ','; - - #endregion - - #region Fields - - private string unresolvedGenericTypeName; - private string unresolvedGenericMethodName; - private string[] unresolvedGenericArguments; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the GenericArgumentsHolder class. - /// - /// - /// The string value to parse looking for a generic definition - /// and retrieving its generic arguments. - /// - public GenericArgumentsHolder(string value) - { - ParseGenericArguments(value); - } - - #endregion - - #region Properties - - /// - /// The (unresolved) generic type name portion - /// of the original value when parsing a generic type. - /// - public string GenericTypeName - { - get { return unresolvedGenericTypeName; } - } - - /// - /// The (unresolved) generic method name portion - /// of the original value when parsing a generic method. - /// - public string GenericMethodName - { - get { return unresolvedGenericMethodName; } - } - - /// - /// Is the string value contains generic arguments ? - /// - /// - ///

- /// A generic argument can be a type parameter or a type argument. - ///

- ///
- public bool ContainsGenericArguments - { - get - { - return (unresolvedGenericArguments != null && - unresolvedGenericArguments.Length > 0); - } - } - - /// - /// Is generic arguments only contains type parameters ? - /// - public bool IsGenericDefinition - { - get - { - if (unresolvedGenericArguments == null) - return false; - - foreach (string arg in unresolvedGenericArguments) - { - if (arg.Length > 0) - return false; - } - return true; - } - } - - #endregion - - #region Methods - - /// - /// Returns an array of unresolved generic arguments types. - /// - /// - ///

- /// A empty string represents a type parameter that - /// did not have been substituted by a specific type. - ///

- ///
- /// - /// An array of strings that represents the unresolved generic - /// arguments types or an empty array if not generic. - /// - public string[] GetGenericArguments() - { - if (unresolvedGenericArguments == null) - return StringUtils.EmptyStrings; - - return unresolvedGenericArguments; - } - - private void ParseGenericArguments(string originalString) - { - int argsStartIndex - = originalString.IndexOf(GenericArgumentsPrefix); - if (argsStartIndex < 0) - { - unresolvedGenericTypeName = originalString; - unresolvedGenericMethodName = originalString; - } - else - { - int argsEndIndex = - originalString.LastIndexOf(GenericArgumentsSuffix); - if (argsEndIndex != -1) - { - unresolvedGenericMethodName = originalString.Remove( - argsStartIndex, argsEndIndex - argsStartIndex + 1); - - SplitGenericArguments(originalString.Substring( - argsStartIndex + 1, argsEndIndex - argsStartIndex - 1)); - - unresolvedGenericTypeName = originalString.Replace( - originalString.Substring(argsStartIndex, argsEndIndex - argsStartIndex + 1), - "`" + unresolvedGenericArguments.Length); - } - } - } - - private void SplitGenericArguments(string originalArgs) - { - IList args = new ArrayList(); - - int index = 0; - int cursor = originalArgs.IndexOf(GenericArgumentsSeparator, index); - while (cursor != -1) - { - string arg = originalArgs.Substring(index, cursor - index); - if (arg.Split(GenericArgumentsPrefix).Length == - arg.Split(GenericArgumentsSuffix).Length) - { - args.Add(arg.Trim()); - index = cursor + 1; - } - cursor = originalArgs.IndexOf(GenericArgumentsSeparator, cursor + 1); - } - args.Add(originalArgs.Substring(index, originalArgs.Length - index).Trim()); - - unresolvedGenericArguments = new string[args.Count]; - args.CopyTo(unresolvedGenericArguments, 0); - } - - #endregion - } -} - -#endif +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System.Collections; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Holder for the generic arguments when using type parameters. + /// + /// + ///

+ /// Type parameters can be applied to classes, interfaces, + /// structures, methods, delegates, etc... + ///

+ ///
+ public class GenericArgumentsHolder + { + #region Constants + + /// + /// The generic arguments prefix. + /// + public const char GenericArgumentsPrefix = '<'; + + /// + /// The generic arguments suffix. + /// + public const char GenericArgumentsSuffix = '>'; + + /// + /// The character that separates a list of generic arguments. + /// + public const char GenericArgumentsSeparator = ','; + + #endregion + + #region Fields + + private string unresolvedGenericTypeName; + private string unresolvedGenericMethodName; + private string[] unresolvedGenericArguments; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the GenericArgumentsHolder class. + /// + /// + /// The string value to parse looking for a generic definition + /// and retrieving its generic arguments. + /// + public GenericArgumentsHolder(string value) + { + ParseGenericArguments(value); + } + + #endregion + + #region Properties + + /// + /// The (unresolved) generic type name portion + /// of the original value when parsing a generic type. + /// + public string GenericTypeName + { + get { return unresolvedGenericTypeName; } + } + + /// + /// The (unresolved) generic method name portion + /// of the original value when parsing a generic method. + /// + public string GenericMethodName + { + get { return unresolvedGenericMethodName; } + } + + /// + /// Is the string value contains generic arguments ? + /// + /// + ///

+ /// A generic argument can be a type parameter or a type argument. + ///

+ ///
+ public bool ContainsGenericArguments + { + get + { + return (unresolvedGenericArguments != null && + unresolvedGenericArguments.Length > 0); + } + } + + /// + /// Is generic arguments only contains type parameters ? + /// + public bool IsGenericDefinition + { + get + { + if (unresolvedGenericArguments == null) + return false; + + foreach (string arg in unresolvedGenericArguments) + { + if (arg.Length > 0) + return false; + } + return true; + } + } + + #endregion + + #region Methods + + /// + /// Returns an array of unresolved generic arguments types. + /// + /// + ///

+ /// A empty string represents a type parameter that + /// did not have been substituted by a specific type. + ///

+ ///
+ /// + /// An array of strings that represents the unresolved generic + /// arguments types or an empty array if not generic. + /// + public string[] GetGenericArguments() + { + if (unresolvedGenericArguments == null) + return StringUtils.EmptyStrings; + + return unresolvedGenericArguments; + } + + private void ParseGenericArguments(string originalString) + { + int argsStartIndex + = originalString.IndexOf(GenericArgumentsPrefix); + if (argsStartIndex < 0) + { + unresolvedGenericTypeName = originalString; + unresolvedGenericMethodName = originalString; + } + else + { + int argsEndIndex = + originalString.LastIndexOf(GenericArgumentsSuffix); + if (argsEndIndex != -1) + { + unresolvedGenericMethodName = originalString.Remove( + argsStartIndex, argsEndIndex - argsStartIndex + 1); + + SplitGenericArguments(originalString.Substring( + argsStartIndex + 1, argsEndIndex - argsStartIndex - 1)); + + unresolvedGenericTypeName = originalString.Replace( + originalString.Substring(argsStartIndex, argsEndIndex - argsStartIndex + 1), + "`" + unresolvedGenericArguments.Length); + } + } + } + + private void SplitGenericArguments(string originalArgs) + { + IList args = new ArrayList(); + + int index = 0; + int cursor = originalArgs.IndexOf(GenericArgumentsSeparator, index); + while (cursor != -1) + { + string arg = originalArgs.Substring(index, cursor - index); + if (arg.Split(GenericArgumentsPrefix).Length == + arg.Split(GenericArgumentsSuffix).Length) + { + args.Add(arg.Trim()); + index = cursor + 1; + } + cursor = originalArgs.IndexOf(GenericArgumentsSeparator, cursor + 1); + } + args.Add(originalArgs.Substring(index, originalArgs.Length - index).Trim()); + + unresolvedGenericArguments = new string[args.Count]; + args.CopyTo(unresolvedGenericArguments, 0); + } + + #endregion + } +} + +#endif diff --git a/src/Spring/Spring.Core/Core/TypeResolution/GenericTypeResolver.cs b/src/Spring/Spring.Core/Core/TypeResolution/GenericTypeResolver.cs index b5fe9425..2dfe9a48 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/GenericTypeResolver.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/GenericTypeResolver.cs @@ -1,101 +1,100 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Resolves a generic by name. - /// - /// Bruno Baia - /// $Id: GenericTypeResolver.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public class GenericTypeResolver : TypeResolver - { - /// - /// Resolves the supplied generic to a - /// instance. - /// - /// - /// The unresolved (possibly generic) name of a . - /// - /// - /// A resolved instance. - /// - /// - /// If the supplied could not be resolved - /// to a . - /// - public override Type Resolve(string typeName) - { - if (StringUtils.IsNullOrEmpty(typeName)) - { - throw BuildTypeLoadException(typeName); - } - GenericArgumentsHolder genericInfo = new GenericArgumentsHolder(typeName); - Type type = null; - try - { - if (genericInfo.ContainsGenericArguments) - { - type = TypeResolutionUtils.ResolveType(genericInfo.GenericTypeName); - if (!genericInfo.IsGenericDefinition) - { - string[] unresolvedGenericArgs = genericInfo.GetGenericArguments(); - Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; - for (int i = 0; i < unresolvedGenericArgs.Length; i++) - { - genericArgs[i] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[i]); - } - type = type.MakeGenericType(genericArgs); - } - } - } - catch (Exception ex) - { - if (ex is TypeLoadException) - { - throw; - } - throw BuildTypeLoadException(typeName, ex); - } - - if (type == null) - { - type = base.Resolve(typeName); - } - - return type; - } - } -} - -#endif +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Resolves a generic by name. + /// + /// Bruno Baia + public class GenericTypeResolver : TypeResolver + { + /// + /// Resolves the supplied generic to a + /// instance. + /// + /// + /// The unresolved (possibly generic) name of a . + /// + /// + /// A resolved instance. + /// + /// + /// If the supplied could not be resolved + /// to a . + /// + public override Type Resolve(string typeName) + { + if (StringUtils.IsNullOrEmpty(typeName)) + { + throw BuildTypeLoadException(typeName); + } + GenericArgumentsHolder genericInfo = new GenericArgumentsHolder(typeName); + Type type = null; + try + { + if (genericInfo.ContainsGenericArguments) + { + type = TypeResolutionUtils.ResolveType(genericInfo.GenericTypeName); + if (!genericInfo.IsGenericDefinition) + { + string[] unresolvedGenericArgs = genericInfo.GetGenericArguments(); + Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; + for (int i = 0; i < unresolvedGenericArgs.Length; i++) + { + genericArgs[i] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[i]); + } + type = type.MakeGenericType(genericArgs); + } + } + } + catch (Exception ex) + { + if (ex is TypeLoadException) + { + throw; + } + throw BuildTypeLoadException(typeName, ex); + } + + if (type == null) + { + type = base.Resolve(typeName); + } + + return type; + } + } +} + +#endif diff --git a/src/Spring/Spring.Core/Core/TypeResolution/ITypeResolver.cs b/src/Spring/Spring.Core/Core/TypeResolution/ITypeResolver.cs index 28b3d639..8b245c16 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/ITypeResolver.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/ITypeResolver.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Resolves a by name. - /// - /// - ///

- /// The rationale behind the creation of this interface is to centralise - /// the resolution of type names to instances - /// beyond that offered by the plain vanilla - /// method call. - ///

- ///
- /// Rick Evans - /// $Id: ITypeResolver.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public interface ITypeResolver - { - /// - /// Resolves the supplied to a - /// - /// instance. - /// - /// - /// The (possibly partially assembly qualified) name of a - /// . - /// - /// - /// A resolved instance. - /// - /// - /// If the supplied could not be resolved - /// to a . - /// - Type Resolve(string typeName); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Resolves a by name. + /// + /// + ///

+ /// The rationale behind the creation of this interface is to centralise + /// the resolution of type names to instances + /// beyond that offered by the plain vanilla + /// method call. + ///

+ ///
+ /// Rick Evans + public interface ITypeResolver + { + /// + /// Resolves the supplied to a + /// + /// instance. + /// + /// + /// The (possibly partially assembly qualified) name of a + /// . + /// + /// + /// A resolved instance. + /// + /// + /// If the supplied could not be resolved + /// to a . + /// + Type Resolve(string typeName); + } +} diff --git a/src/Spring/Spring.Core/Core/TypeResolution/TypeAssemblyHolder.cs b/src/Spring/Spring.Core/Core/TypeResolution/TypeAssemblyHolder.cs index 38fa0f63..cdf98df4 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/TypeAssemblyHolder.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/TypeAssemblyHolder.cs @@ -1,117 +1,117 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Holds data about a and it's - /// attendant . - /// - public class TypeAssemblyHolder - { - #region Constants - - /// - /// The string that separates a name - /// from the name of it's attendant - /// in an assembly qualified type name. - /// - public const string TypeAssemblySeparator = ","; - - #endregion - - #region Fields - - private string unresolvedAssemblyName; - private string unresolvedTypeName; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the TypeAssemblyHolder class. - /// - /// - /// The unresolved name of a . - /// - public TypeAssemblyHolder(string unresolvedTypeName) - { - SplitTypeAndAssemblyNames(unresolvedTypeName); - } - - #endregion - - #region Properties - - /// - /// The (unresolved) type name portion of the original type name. - /// - public string TypeName - { - get { return unresolvedTypeName; } - } - - /// - /// The (unresolved, possibly partial) name of the attandant assembly. - /// - public string AssemblyName - { - get { return unresolvedAssemblyName; } - } - - /// - /// Is the type name being resolved assembly qualified? - /// - public bool IsAssemblyQualified - { - get { return StringUtils.HasText(AssemblyName); } - } - - #endregion - - #region Methods - - private void SplitTypeAndAssemblyNames(string originalTypeName) - { - int typeAssemblyIndex - = originalTypeName.IndexOf(TypeAssemblySeparator); - if (typeAssemblyIndex < 0) - { - unresolvedTypeName = originalTypeName; - } - else - { - unresolvedTypeName = originalTypeName.Substring( - 0, typeAssemblyIndex).Trim(); - unresolvedAssemblyName = originalTypeName.Substring( - typeAssemblyIndex + 1).Trim(); - } - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Holds data about a and it's + /// attendant . + /// + public class TypeAssemblyHolder + { + #region Constants + + /// + /// The string that separates a name + /// from the name of it's attendant + /// in an assembly qualified type name. + /// + public const string TypeAssemblySeparator = ","; + + #endregion + + #region Fields + + private string unresolvedAssemblyName; + private string unresolvedTypeName; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the TypeAssemblyHolder class. + /// + /// + /// The unresolved name of a . + /// + public TypeAssemblyHolder(string unresolvedTypeName) + { + SplitTypeAndAssemblyNames(unresolvedTypeName); + } + + #endregion + + #region Properties + + /// + /// The (unresolved) type name portion of the original type name. + /// + public string TypeName + { + get { return unresolvedTypeName; } + } + + /// + /// The (unresolved, possibly partial) name of the attandant assembly. + /// + public string AssemblyName + { + get { return unresolvedAssemblyName; } + } + + /// + /// Is the type name being resolved assembly qualified? + /// + public bool IsAssemblyQualified + { + get { return StringUtils.HasText(AssemblyName); } + } + + #endregion + + #region Methods + + private void SplitTypeAndAssemblyNames(string originalTypeName) + { + int typeAssemblyIndex + = originalTypeName.IndexOf(TypeAssemblySeparator); + if (typeAssemblyIndex < 0) + { + unresolvedTypeName = originalTypeName; + } + else + { + unresolvedTypeName = originalTypeName.Substring( + 0, typeAssemblyIndex).Trim(); + unresolvedAssemblyName = originalTypeName.Substring( + typeAssemblyIndex + 1).Trim(); + } + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Core/TypeResolution/TypeRegistry.cs b/src/Spring/Spring.Core/Core/TypeResolution/TypeRegistry.cs index 1fb1b35a..936b3436 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/TypeRegistry.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/TypeRegistry.cs @@ -1,685 +1,684 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Provides access to a central registry of aliased s. - /// - /// - ///

- /// Simplifies configuration by allowing aliases to be used instead of - /// fully qualified type names. - ///

- ///

- /// Comes 'pre-loaded' with a number of convenience alias' for the more - /// common types; an example would be the 'int' (or 'Integer' - /// for Visual Basic.NET developers) alias for the - /// type. - ///

- ///
- /// Aleksandar Seovic - /// - /// $Id: TypeRegistry.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public sealed class TypeRegistry - { - #region Constants - - /// - /// Name of the .Net config section that contains Spring.Net type aliases. - /// - private const string TypeAliasesSectionName = "spring/typeAliases"; - - /// - /// The alias around the 'int' type. - /// - public const string Int32Alias = "int"; - - /// - /// The alias around the 'Integer' type (Visual Basic.NET style). - /// - public const string Int32AliasVB = "Integer"; - - /// - /// The alias around the 'int[]' array type. - /// - public const string Int32ArrayAlias = "int[]"; - - /// - /// The alias around the 'Integer()' array type (Visual Basic.NET style). - /// - public const string Int32ArrayAliasVB = "Integer()"; - - /// - /// The alias around the 'decimal' type. - /// - public const string DecimalAlias = "decimal"; - - /// - /// The alias around the 'Decimal' type (Visual Basic.NET style). - /// - public const string DecimalAliasVB = "Decimal"; - - /// - /// The alias around the 'decimal[]' array type. - /// - public const string DecimalArrayAlias = "decimal[]"; - - /// - /// The alias around the 'Decimal()' array type (Visual Basic.NET style). - /// - public const string DecimalArrayAliasVB = "Decimal()"; - - /// - /// The alias around the 'char' type. - /// - public const string CharAlias = "char"; - - /// - /// The alias around the 'Char' type (Visual Basic.NET style). - /// - public const string CharAliasVB = "Char"; - - /// - /// The alias around the 'char[]' array type. - /// - public const string CharArrayAlias = "char[]"; - - /// - /// The alias around the 'Char()' array type (Visual Basic.NET style). - /// - public const string CharArrayAliasVB = "Char()"; - - /// - /// The alias around the 'long' type. - /// - public const string Int64Alias = "long"; - - /// - /// The alias around the 'Long' type (Visual Basic.NET style). - /// - public const string Int64AliasVB = "Long"; - - /// - /// The alias around the 'long[]' array type. - /// - public const string Int64ArrayAlias = "long[]"; - - /// - /// The alias around the 'Long()' array type (Visual Basic.NET style). - /// - public const string Int64ArrayAliasVB = "Long()"; - - /// - /// The alias around the 'short' type. - /// - public const string Int16Alias = "short"; - - /// - /// The alias around the 'Short' type (Visual Basic.NET style). - /// - public const string Int16AliasVB = "Short"; - - /// - /// The alias around the 'short[]' array type. - /// - public const string Int16ArrayAlias = "short[]"; - - /// - /// The alias around the 'Short()' array type (Visual Basic.NET style). - /// - public const string Int16ArrayAliasVB = "Short()"; - - /// - /// The alias around the 'unsigned int' type. - /// - public const string UInt32Alias = "uint"; - - /// - /// The alias around the 'unsigned long' type. - /// - public const string UInt64Alias = "ulong"; - - /// - /// The alias around the 'ulong[]' array type. - /// - public const string UInt64ArrayAlias = "ulong[]"; - - /// - /// The alias around the 'uint[]' array type. - /// - public const string UInt32ArrayAlias = "uint[]"; - - /// - /// The alias around the 'unsigned short' type. - /// - public const string UInt16Alias = "ushort"; - - /// - /// The alias around the 'ushort[]' array type. - /// - public const string UInt16ArrayAlias = "ushort[]"; - - /// - /// The alias around the 'double' type. - /// - public const string DoubleAlias = "double"; - - /// - /// The alias around the 'Double' type (Visual Basic.NET style). - /// - public const string DoubleAliasVB = "Double"; - - /// - /// The alias around the 'double[]' array type. - /// - public const string DoubleArrayAlias = "double[]"; - - /// - /// The alias around the 'Double()' array type (Visual Basic.NET style). - /// - public const string DoubleArrayAliasVB = "Double()"; - - /// - /// The alias around the 'float' type. - /// - public const string FloatAlias = "float"; - - /// - /// The alias around the 'Single' type (Visual Basic.NET style). - /// - public const string SingleAlias = "Single"; - - /// - /// The alias around the 'float[]' array type. - /// - public const string FloatArrayAlias = "float[]"; - - /// - /// The alias around the 'Single()' array type (Visual Basic.NET style). - /// - public const string SingleArrayAliasVB = "Single()"; - - /// - /// The alias around the 'DateTime' type. - /// - public const string DateTimeAlias = "DateTime"; - - /// - /// The alias around the 'DateTime' type (C# style). - /// - public const string DateAlias = "date"; - - /// - /// The alias around the 'DateTime' type (Visual Basic.NET style). - /// - public const string DateAliasVB = "Date"; - - /// - /// The alias around the 'DateTime[]' array type. - /// - public const string DateTimeArrayAlias = "DateTime[]"; - - /// - /// The alias around the 'DateTime[]' array type. - /// - public const string DateTimeArrayAliasCSharp = "date[]"; - - /// - /// The alias around the 'DateTime()' array type (Visual Basic.NET style). - /// - public const string DateTimeArrayAliasVB = "DateTime()"; - - /// - /// The alias around the 'bool' type. - /// - public const string BoolAlias = "bool"; - - /// - /// The alias around the 'Boolean' type (Visual Basic.NET style). - /// - public const string BoolAliasVB = "Boolean"; - - /// - /// The alias around the 'bool[]' array type. - /// - public const string BoolArrayAlias = "bool[]"; - - /// - /// The alias around the 'Boolean()' array type (Visual Basic.NET style). - /// - public const string BoolArrayAliasVB = "Boolean()"; - - /// - /// The alias around the 'string' type. - /// - public const string StringAlias = "string"; - - /// - /// The alias around the 'string' type (Visual Basic.NET style). - /// - public const string StringAliasVB = "String"; - - /// - /// The alias around the 'string[]' array type. - /// - public const string StringArrayAlias = "string[]"; - - /// - /// The alias around the 'string[]' array type (Visual Basic.NET style). - /// - public const string StringArrayAliasVB = "String()"; - - /// - /// The alias around the 'object' type. - /// - public const string ObjectAlias = "object"; - - /// - /// The alias around the 'object' type (Visual Basic.NET style). - /// - public const string ObjectAliasVB = "Object"; - - /// - /// The alias around the 'object[]' array type. - /// - public const string ObjectArrayAlias = "object[]"; - - /// - /// The alias around the 'object[]' array type (Visual Basic.NET style). - /// - public const string ObjectArrayAliasVB = "Object()"; - -#if NET_2_0 - /// - /// The alias around the 'int?' type. - /// - public const string NullableInt32Alias = "int?"; - - /// - /// The alias around the 'int?[]' array type. - /// - public const string NullableInt32ArrayAlias = "int?[]"; - - /// - /// The alias around the 'decimal?' type. - /// - public const string NullableDecimalAlias = "decimal?"; - - /// - /// The alias around the 'decimal?[]' array type. - /// - public const string NullableDecimalArrayAlias = "decimal?[]"; - - /// - /// The alias around the 'char?' type. - /// - public const string NullableCharAlias = "char?"; - - /// - /// The alias around the 'char?[]' array type. - /// - public const string NullableCharArrayAlias = "char?[]"; - - /// - /// The alias around the 'long?' type. - /// - public const string NullableInt64Alias = "long?"; - - /// - /// The alias around the 'long?[]' array type. - /// - public const string NullableInt64ArrayAlias = "long?[]"; - - /// - /// The alias around the 'short?' type. - /// - public const string NullableInt16Alias = "short?"; - - /// - /// The alias around the 'short?[]' array type. - /// - public const string NullableInt16ArrayAlias = "short?[]"; - - /// - /// The alias around the 'unsigned int?' type. - /// - public const string NullableUInt32Alias = "uint?"; - - /// - /// The alias around the 'unsigned long?' type. - /// - public const string NullableUInt64Alias = "ulong?"; - - /// - /// The alias around the 'ulong?[]' array type. - /// - public const string NullableUInt64ArrayAlias = "ulong?[]"; - - /// - /// The alias around the 'uint?[]' array type. - /// - public const string NullableUInt32ArrayAlias = "uint?[]"; - - /// - /// The alias around the 'unsigned short?' type. - /// - public const string NullableUInt16Alias = "ushort?"; - - /// - /// The alias around the 'ushort?[]' array type. - /// - public const string NullableUInt16ArrayAlias = "ushort?[]"; - - /// - /// The alias around the 'double?' type. - /// - public const string NullableDoubleAlias = "double?"; - - /// - /// The alias around the 'double?[]' array type. - /// - public const string NullableDoubleArrayAlias = "double?[]"; - - /// - /// The alias around the 'float?' type. - /// - public const string NullableFloatAlias = "float?"; - - /// - /// The alias around the 'float?[]' array type. - /// - public const string NullableFloatArrayAlias = "float?[]"; - - /// - /// The alias around the 'bool?' type. - /// - public const string NullableBoolAlias = "bool?"; - - /// - /// The alias around the 'bool?[]' array type. - /// - public const string NullableBoolArrayAlias = "bool?[]"; -#endif - - #endregion - - #region Fields - - private static IDictionary types = new Hashtable(); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Registers standard and user-configured type aliases. - /// - static TypeRegistry() - { - lock (types.SyncRoot) - { - types["Int32"] = typeof(Int32); - types[Int32Alias] = typeof(Int32); - types[Int32AliasVB] = typeof(Int32); - types[Int32ArrayAlias] = typeof(Int32[]); - types[Int32ArrayAliasVB] = typeof(Int32[]); - - types["UInt32"] = typeof(UInt32); - types[UInt32Alias] = typeof(UInt32); - types[UInt32ArrayAlias] = typeof(UInt32[]); - - types["Int16"] = typeof(Int16); - types[Int16Alias] = typeof(Int16); - types[Int16AliasVB] = typeof(Int16); - types[Int16ArrayAlias] = typeof(Int16[]); - types[Int16ArrayAliasVB] = typeof(Int16[]); - - types["UInt16"] = typeof(UInt16); - types[UInt16Alias] = typeof(UInt16); - types[UInt16ArrayAlias] = typeof(UInt16[]); - - types["Int64"] = typeof(Int64); - types[Int64Alias] = typeof(Int64); - types[Int64AliasVB] = typeof(Int64); - types[Int64ArrayAlias] = typeof(Int64[]); - types[Int64ArrayAliasVB] = typeof(Int64[]); - - types["UInt64"] = typeof(UInt64); - types[UInt64Alias] = typeof(UInt64); - types[UInt64ArrayAlias] = typeof(UInt64[]); - - types[DoubleAlias] = typeof(double); - types[DoubleAliasVB] = typeof(double); - types[DoubleArrayAlias] = typeof(double[]); - types[DoubleArrayAliasVB] = typeof(double[]); - - types[FloatAlias] = typeof(float); - types[SingleAlias] = typeof(float); - types[FloatArrayAlias] = typeof(float[]); - types[SingleArrayAliasVB] = typeof(float[]); - - types[DateTimeAlias] = typeof(DateTime); - types[DateAlias] = typeof(DateTime); - types[DateAliasVB] = typeof(DateTime); - types[DateTimeArrayAlias] = typeof(DateTime[]); - types[DateTimeArrayAliasCSharp] = typeof(DateTime[]); - types[DateTimeArrayAliasVB] = typeof(DateTime[]); - - types[BoolAlias] = typeof(bool); - types[BoolAliasVB] = typeof(bool); - types[BoolArrayAlias] = typeof(bool[]); - types[BoolArrayAliasVB] = typeof(bool[]); - - types[DecimalAlias] = typeof(decimal); - types[DecimalAliasVB] = typeof(decimal); - types[DecimalArrayAlias] = typeof(decimal[]); - types[DecimalArrayAliasVB] = typeof(decimal[]); - - types[CharAlias] = typeof(char); - types[CharAliasVB] = typeof(char); - types[CharArrayAlias] = typeof(char[]); - types[CharArrayAliasVB] = typeof(char[]); - - types[StringAlias] = typeof(string); - types[StringAliasVB] = typeof(string); - types[StringArrayAlias] = typeof(string[]); - types[StringArrayAliasVB] = typeof(string[]); - - types[ObjectAlias] = typeof(object); - types[ObjectAliasVB] = typeof(object); - types[ObjectArrayAlias] = typeof(object[]); - types[ObjectArrayAliasVB] = typeof(object[]); - -#if NET_2_0 - types[NullableInt32Alias] = typeof(int?); - types[NullableInt32ArrayAlias] = typeof(int?[]); - - types[NullableDecimalAlias] = typeof(decimal?); - types[NullableDecimalArrayAlias] = typeof(decimal?[]); - - types[NullableCharAlias] = typeof(char?); - types[NullableCharArrayAlias] = typeof(char?[]); - - types[NullableInt64Alias] = typeof(long?); - types[NullableInt64ArrayAlias] = typeof(long?[]); - - types[NullableInt16Alias] = typeof(short?); - types[NullableInt16ArrayAlias] = typeof(short?[]); - - types[NullableUInt32Alias] = typeof(uint?); - types[NullableUInt32ArrayAlias] = typeof(uint?[]); - - types[NullableUInt64Alias] = typeof(ulong?); - types[NullableUInt64ArrayAlias] = typeof(ulong?[]); - - types[NullableUInt16Alias] = typeof(ushort?); - types[NullableUInt16ArrayAlias] = typeof(ushort?[]); - - types[NullableDoubleAlias] = typeof(double?); - types[NullableDoubleArrayAlias] = typeof(double?[]); - - types[NullableFloatAlias] = typeof(float?); - types[NullableFloatArrayAlias] = typeof(float?[]); - - types[NullableBoolAlias] = typeof(bool?); - types[NullableBoolArrayAlias] = typeof(bool?[]); -#endif - - // register user-configured type aliases - ConfigurationUtils.GetSection(TypeAliasesSectionName); - } - } - - #endregion - - /// - /// Registers an alias for the specified . - /// - /// - ///

- /// This overload does eager resolution of the - /// referred to by the parameter. It will throw a - /// if the referred - /// to by the parameter cannot be resolved. - ///

- ///
- /// - /// A string that will be used as an alias for the specified - /// . - /// - /// - /// The (possibly partially assembly qualified) name of the - /// to register the alias for. - /// - /// - /// If either of the supplied parameters is or - /// contains only whitespace character(s). - /// - /// - /// If the referred to by the supplied - /// cannot be loaded. - /// - public static void RegisterType(string alias, string typeName) - { - AssertUtils.ArgumentHasText(alias, "alias"); - AssertUtils.ArgumentHasText(typeName, "typeName"); - - Type type = TypeResolutionUtils.ResolveType(typeName); -#if NET_2_0 - if (type.IsGenericTypeDefinition) - alias += ("`" + type.GetGenericArguments().Length); -#endif - RegisterType(alias, type); - } - - /// - /// Registers short type name as an alias for - /// the supplied . - /// - /// - /// The to register. - /// - /// - /// If the supplied is . - /// - public static void RegisterType(Type type) - { - AssertUtils.ArgumentNotNull(type, "type"); - - lock (types.SyncRoot) - { - types[type.Name] = type; - } - } - - /// - /// Registers an alias for the supplied . - /// - /// - /// The alias for the supplied . - /// - /// - /// The to register the supplied under. - /// - /// - /// If the supplied is ; or if - /// the supplied is or - /// contains only whitespace character(s). - /// - public static void RegisterType(string alias, Type type) - { - AssertUtils.ArgumentHasText(alias, "alias"); - AssertUtils.ArgumentNotNull(type, "type"); - - lock (types.SyncRoot) - { - types[alias] = type; - } - } - - /// - /// Resolves the supplied to a . - /// - /// - /// The alias to resolve. - /// - /// - /// The the supplied was - /// associated with, or if no - /// was previously registered for the supplied . - /// - /// - /// If the supplied is or - /// contains only whitespace character(s). - /// - public static Type ResolveType(string alias) - { - AssertUtils.ArgumentHasText(alias, "alias"); - return (Type) types[alias]; - } - - /// - /// Returns a flag specifying whether TypeRegistry contains - /// specified alias or not. - /// - /// - /// Alias to check. - /// - /// - /// true if the specified type alias is registered, - /// false otherwise. - /// - public static bool ContainsAlias(string alias) - { - return types.Contains(alias); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Provides access to a central registry of aliased s. + /// + /// + ///

+ /// Simplifies configuration by allowing aliases to be used instead of + /// fully qualified type names. + ///

+ ///

+ /// Comes 'pre-loaded' with a number of convenience alias' for the more + /// common types; an example would be the 'int' (or 'Integer' + /// for Visual Basic.NET developers) alias for the + /// type. + ///

+ ///
+ /// Aleksandar Seovic + /// + public sealed class TypeRegistry + { + #region Constants + + /// + /// Name of the .Net config section that contains Spring.Net type aliases. + /// + private const string TypeAliasesSectionName = "spring/typeAliases"; + + /// + /// The alias around the 'int' type. + /// + public const string Int32Alias = "int"; + + /// + /// The alias around the 'Integer' type (Visual Basic.NET style). + /// + public const string Int32AliasVB = "Integer"; + + /// + /// The alias around the 'int[]' array type. + /// + public const string Int32ArrayAlias = "int[]"; + + /// + /// The alias around the 'Integer()' array type (Visual Basic.NET style). + /// + public const string Int32ArrayAliasVB = "Integer()"; + + /// + /// The alias around the 'decimal' type. + /// + public const string DecimalAlias = "decimal"; + + /// + /// The alias around the 'Decimal' type (Visual Basic.NET style). + /// + public const string DecimalAliasVB = "Decimal"; + + /// + /// The alias around the 'decimal[]' array type. + /// + public const string DecimalArrayAlias = "decimal[]"; + + /// + /// The alias around the 'Decimal()' array type (Visual Basic.NET style). + /// + public const string DecimalArrayAliasVB = "Decimal()"; + + /// + /// The alias around the 'char' type. + /// + public const string CharAlias = "char"; + + /// + /// The alias around the 'Char' type (Visual Basic.NET style). + /// + public const string CharAliasVB = "Char"; + + /// + /// The alias around the 'char[]' array type. + /// + public const string CharArrayAlias = "char[]"; + + /// + /// The alias around the 'Char()' array type (Visual Basic.NET style). + /// + public const string CharArrayAliasVB = "Char()"; + + /// + /// The alias around the 'long' type. + /// + public const string Int64Alias = "long"; + + /// + /// The alias around the 'Long' type (Visual Basic.NET style). + /// + public const string Int64AliasVB = "Long"; + + /// + /// The alias around the 'long[]' array type. + /// + public const string Int64ArrayAlias = "long[]"; + + /// + /// The alias around the 'Long()' array type (Visual Basic.NET style). + /// + public const string Int64ArrayAliasVB = "Long()"; + + /// + /// The alias around the 'short' type. + /// + public const string Int16Alias = "short"; + + /// + /// The alias around the 'Short' type (Visual Basic.NET style). + /// + public const string Int16AliasVB = "Short"; + + /// + /// The alias around the 'short[]' array type. + /// + public const string Int16ArrayAlias = "short[]"; + + /// + /// The alias around the 'Short()' array type (Visual Basic.NET style). + /// + public const string Int16ArrayAliasVB = "Short()"; + + /// + /// The alias around the 'unsigned int' type. + /// + public const string UInt32Alias = "uint"; + + /// + /// The alias around the 'unsigned long' type. + /// + public const string UInt64Alias = "ulong"; + + /// + /// The alias around the 'ulong[]' array type. + /// + public const string UInt64ArrayAlias = "ulong[]"; + + /// + /// The alias around the 'uint[]' array type. + /// + public const string UInt32ArrayAlias = "uint[]"; + + /// + /// The alias around the 'unsigned short' type. + /// + public const string UInt16Alias = "ushort"; + + /// + /// The alias around the 'ushort[]' array type. + /// + public const string UInt16ArrayAlias = "ushort[]"; + + /// + /// The alias around the 'double' type. + /// + public const string DoubleAlias = "double"; + + /// + /// The alias around the 'Double' type (Visual Basic.NET style). + /// + public const string DoubleAliasVB = "Double"; + + /// + /// The alias around the 'double[]' array type. + /// + public const string DoubleArrayAlias = "double[]"; + + /// + /// The alias around the 'Double()' array type (Visual Basic.NET style). + /// + public const string DoubleArrayAliasVB = "Double()"; + + /// + /// The alias around the 'float' type. + /// + public const string FloatAlias = "float"; + + /// + /// The alias around the 'Single' type (Visual Basic.NET style). + /// + public const string SingleAlias = "Single"; + + /// + /// The alias around the 'float[]' array type. + /// + public const string FloatArrayAlias = "float[]"; + + /// + /// The alias around the 'Single()' array type (Visual Basic.NET style). + /// + public const string SingleArrayAliasVB = "Single()"; + + /// + /// The alias around the 'DateTime' type. + /// + public const string DateTimeAlias = "DateTime"; + + /// + /// The alias around the 'DateTime' type (C# style). + /// + public const string DateAlias = "date"; + + /// + /// The alias around the 'DateTime' type (Visual Basic.NET style). + /// + public const string DateAliasVB = "Date"; + + /// + /// The alias around the 'DateTime[]' array type. + /// + public const string DateTimeArrayAlias = "DateTime[]"; + + /// + /// The alias around the 'DateTime[]' array type. + /// + public const string DateTimeArrayAliasCSharp = "date[]"; + + /// + /// The alias around the 'DateTime()' array type (Visual Basic.NET style). + /// + public const string DateTimeArrayAliasVB = "DateTime()"; + + /// + /// The alias around the 'bool' type. + /// + public const string BoolAlias = "bool"; + + /// + /// The alias around the 'Boolean' type (Visual Basic.NET style). + /// + public const string BoolAliasVB = "Boolean"; + + /// + /// The alias around the 'bool[]' array type. + /// + public const string BoolArrayAlias = "bool[]"; + + /// + /// The alias around the 'Boolean()' array type (Visual Basic.NET style). + /// + public const string BoolArrayAliasVB = "Boolean()"; + + /// + /// The alias around the 'string' type. + /// + public const string StringAlias = "string"; + + /// + /// The alias around the 'string' type (Visual Basic.NET style). + /// + public const string StringAliasVB = "String"; + + /// + /// The alias around the 'string[]' array type. + /// + public const string StringArrayAlias = "string[]"; + + /// + /// The alias around the 'string[]' array type (Visual Basic.NET style). + /// + public const string StringArrayAliasVB = "String()"; + + /// + /// The alias around the 'object' type. + /// + public const string ObjectAlias = "object"; + + /// + /// The alias around the 'object' type (Visual Basic.NET style). + /// + public const string ObjectAliasVB = "Object"; + + /// + /// The alias around the 'object[]' array type. + /// + public const string ObjectArrayAlias = "object[]"; + + /// + /// The alias around the 'object[]' array type (Visual Basic.NET style). + /// + public const string ObjectArrayAliasVB = "Object()"; + +#if NET_2_0 + /// + /// The alias around the 'int?' type. + /// + public const string NullableInt32Alias = "int?"; + + /// + /// The alias around the 'int?[]' array type. + /// + public const string NullableInt32ArrayAlias = "int?[]"; + + /// + /// The alias around the 'decimal?' type. + /// + public const string NullableDecimalAlias = "decimal?"; + + /// + /// The alias around the 'decimal?[]' array type. + /// + public const string NullableDecimalArrayAlias = "decimal?[]"; + + /// + /// The alias around the 'char?' type. + /// + public const string NullableCharAlias = "char?"; + + /// + /// The alias around the 'char?[]' array type. + /// + public const string NullableCharArrayAlias = "char?[]"; + + /// + /// The alias around the 'long?' type. + /// + public const string NullableInt64Alias = "long?"; + + /// + /// The alias around the 'long?[]' array type. + /// + public const string NullableInt64ArrayAlias = "long?[]"; + + /// + /// The alias around the 'short?' type. + /// + public const string NullableInt16Alias = "short?"; + + /// + /// The alias around the 'short?[]' array type. + /// + public const string NullableInt16ArrayAlias = "short?[]"; + + /// + /// The alias around the 'unsigned int?' type. + /// + public const string NullableUInt32Alias = "uint?"; + + /// + /// The alias around the 'unsigned long?' type. + /// + public const string NullableUInt64Alias = "ulong?"; + + /// + /// The alias around the 'ulong?[]' array type. + /// + public const string NullableUInt64ArrayAlias = "ulong?[]"; + + /// + /// The alias around the 'uint?[]' array type. + /// + public const string NullableUInt32ArrayAlias = "uint?[]"; + + /// + /// The alias around the 'unsigned short?' type. + /// + public const string NullableUInt16Alias = "ushort?"; + + /// + /// The alias around the 'ushort?[]' array type. + /// + public const string NullableUInt16ArrayAlias = "ushort?[]"; + + /// + /// The alias around the 'double?' type. + /// + public const string NullableDoubleAlias = "double?"; + + /// + /// The alias around the 'double?[]' array type. + /// + public const string NullableDoubleArrayAlias = "double?[]"; + + /// + /// The alias around the 'float?' type. + /// + public const string NullableFloatAlias = "float?"; + + /// + /// The alias around the 'float?[]' array type. + /// + public const string NullableFloatArrayAlias = "float?[]"; + + /// + /// The alias around the 'bool?' type. + /// + public const string NullableBoolAlias = "bool?"; + + /// + /// The alias around the 'bool?[]' array type. + /// + public const string NullableBoolArrayAlias = "bool?[]"; +#endif + + #endregion + + #region Fields + + private static IDictionary types = new Hashtable(); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Registers standard and user-configured type aliases. + /// + static TypeRegistry() + { + lock (types.SyncRoot) + { + types["Int32"] = typeof(Int32); + types[Int32Alias] = typeof(Int32); + types[Int32AliasVB] = typeof(Int32); + types[Int32ArrayAlias] = typeof(Int32[]); + types[Int32ArrayAliasVB] = typeof(Int32[]); + + types["UInt32"] = typeof(UInt32); + types[UInt32Alias] = typeof(UInt32); + types[UInt32ArrayAlias] = typeof(UInt32[]); + + types["Int16"] = typeof(Int16); + types[Int16Alias] = typeof(Int16); + types[Int16AliasVB] = typeof(Int16); + types[Int16ArrayAlias] = typeof(Int16[]); + types[Int16ArrayAliasVB] = typeof(Int16[]); + + types["UInt16"] = typeof(UInt16); + types[UInt16Alias] = typeof(UInt16); + types[UInt16ArrayAlias] = typeof(UInt16[]); + + types["Int64"] = typeof(Int64); + types[Int64Alias] = typeof(Int64); + types[Int64AliasVB] = typeof(Int64); + types[Int64ArrayAlias] = typeof(Int64[]); + types[Int64ArrayAliasVB] = typeof(Int64[]); + + types["UInt64"] = typeof(UInt64); + types[UInt64Alias] = typeof(UInt64); + types[UInt64ArrayAlias] = typeof(UInt64[]); + + types[DoubleAlias] = typeof(double); + types[DoubleAliasVB] = typeof(double); + types[DoubleArrayAlias] = typeof(double[]); + types[DoubleArrayAliasVB] = typeof(double[]); + + types[FloatAlias] = typeof(float); + types[SingleAlias] = typeof(float); + types[FloatArrayAlias] = typeof(float[]); + types[SingleArrayAliasVB] = typeof(float[]); + + types[DateTimeAlias] = typeof(DateTime); + types[DateAlias] = typeof(DateTime); + types[DateAliasVB] = typeof(DateTime); + types[DateTimeArrayAlias] = typeof(DateTime[]); + types[DateTimeArrayAliasCSharp] = typeof(DateTime[]); + types[DateTimeArrayAliasVB] = typeof(DateTime[]); + + types[BoolAlias] = typeof(bool); + types[BoolAliasVB] = typeof(bool); + types[BoolArrayAlias] = typeof(bool[]); + types[BoolArrayAliasVB] = typeof(bool[]); + + types[DecimalAlias] = typeof(decimal); + types[DecimalAliasVB] = typeof(decimal); + types[DecimalArrayAlias] = typeof(decimal[]); + types[DecimalArrayAliasVB] = typeof(decimal[]); + + types[CharAlias] = typeof(char); + types[CharAliasVB] = typeof(char); + types[CharArrayAlias] = typeof(char[]); + types[CharArrayAliasVB] = typeof(char[]); + + types[StringAlias] = typeof(string); + types[StringAliasVB] = typeof(string); + types[StringArrayAlias] = typeof(string[]); + types[StringArrayAliasVB] = typeof(string[]); + + types[ObjectAlias] = typeof(object); + types[ObjectAliasVB] = typeof(object); + types[ObjectArrayAlias] = typeof(object[]); + types[ObjectArrayAliasVB] = typeof(object[]); + +#if NET_2_0 + types[NullableInt32Alias] = typeof(int?); + types[NullableInt32ArrayAlias] = typeof(int?[]); + + types[NullableDecimalAlias] = typeof(decimal?); + types[NullableDecimalArrayAlias] = typeof(decimal?[]); + + types[NullableCharAlias] = typeof(char?); + types[NullableCharArrayAlias] = typeof(char?[]); + + types[NullableInt64Alias] = typeof(long?); + types[NullableInt64ArrayAlias] = typeof(long?[]); + + types[NullableInt16Alias] = typeof(short?); + types[NullableInt16ArrayAlias] = typeof(short?[]); + + types[NullableUInt32Alias] = typeof(uint?); + types[NullableUInt32ArrayAlias] = typeof(uint?[]); + + types[NullableUInt64Alias] = typeof(ulong?); + types[NullableUInt64ArrayAlias] = typeof(ulong?[]); + + types[NullableUInt16Alias] = typeof(ushort?); + types[NullableUInt16ArrayAlias] = typeof(ushort?[]); + + types[NullableDoubleAlias] = typeof(double?); + types[NullableDoubleArrayAlias] = typeof(double?[]); + + types[NullableFloatAlias] = typeof(float?); + types[NullableFloatArrayAlias] = typeof(float?[]); + + types[NullableBoolAlias] = typeof(bool?); + types[NullableBoolArrayAlias] = typeof(bool?[]); +#endif + + // register user-configured type aliases + ConfigurationUtils.GetSection(TypeAliasesSectionName); + } + } + + #endregion + + /// + /// Registers an alias for the specified . + /// + /// + ///

+ /// This overload does eager resolution of the + /// referred to by the parameter. It will throw a + /// if the referred + /// to by the parameter cannot be resolved. + ///

+ ///
+ /// + /// A string that will be used as an alias for the specified + /// . + /// + /// + /// The (possibly partially assembly qualified) name of the + /// to register the alias for. + /// + /// + /// If either of the supplied parameters is or + /// contains only whitespace character(s). + /// + /// + /// If the referred to by the supplied + /// cannot be loaded. + /// + public static void RegisterType(string alias, string typeName) + { + AssertUtils.ArgumentHasText(alias, "alias"); + AssertUtils.ArgumentHasText(typeName, "typeName"); + + Type type = TypeResolutionUtils.ResolveType(typeName); +#if NET_2_0 + if (type.IsGenericTypeDefinition) + alias += ("`" + type.GetGenericArguments().Length); +#endif + RegisterType(alias, type); + } + + /// + /// Registers short type name as an alias for + /// the supplied . + /// + /// + /// The to register. + /// + /// + /// If the supplied is . + /// + public static void RegisterType(Type type) + { + AssertUtils.ArgumentNotNull(type, "type"); + + lock (types.SyncRoot) + { + types[type.Name] = type; + } + } + + /// + /// Registers an alias for the supplied . + /// + /// + /// The alias for the supplied . + /// + /// + /// The to register the supplied under. + /// + /// + /// If the supplied is ; or if + /// the supplied is or + /// contains only whitespace character(s). + /// + public static void RegisterType(string alias, Type type) + { + AssertUtils.ArgumentHasText(alias, "alias"); + AssertUtils.ArgumentNotNull(type, "type"); + + lock (types.SyncRoot) + { + types[alias] = type; + } + } + + /// + /// Resolves the supplied to a . + /// + /// + /// The alias to resolve. + /// + /// + /// The the supplied was + /// associated with, or if no + /// was previously registered for the supplied . + /// + /// + /// If the supplied is or + /// contains only whitespace character(s). + /// + public static Type ResolveType(string alias) + { + AssertUtils.ArgumentHasText(alias, "alias"); + return (Type) types[alias]; + } + + /// + /// Returns a flag specifying whether TypeRegistry contains + /// specified alias or not. + /// + /// + /// Alias to check. + /// + /// + /// true if the specified type alias is registered, + /// false otherwise. + /// + public static bool ContainsAlias(string alias) + { + return types.Contains(alias); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeResolution/TypeResolutionUtils.cs b/src/Spring/Spring.Core/Core/TypeResolution/TypeResolutionUtils.cs index 77c939ab..d42ade30 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/TypeResolutionUtils.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/TypeResolutionUtils.cs @@ -1,215 +1,214 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Text.RegularExpressions; -using System.Reflection; - -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Helper methods with regard to type resolution. - /// - /// - ///

- /// Not intended to be used directly by applications. - ///

- ///
- /// Bruno Baia - /// $Id: TypeResolutionUtils.cs,v 1.1 2007/07/31 18:16:08 bbaia Exp $ - public sealed class TypeResolutionUtils - { - #region Fields - -#if NET_2_0 - private static readonly ITypeResolver internalTypeResolver - = new CachedTypeResolver(new GenericTypeResolver()); -#else - private static readonly ITypeResolver internalTypeResolver - = new CachedTypeResolver(new TypeResolver()); -#endif - - #endregion - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private TypeResolutionUtils() - { - } - - // CLOVER:ON - - #endregion - - #region Methods - - /// - /// Resolves the supplied type name into a - /// instance. - /// - /// - ///

- /// If you require special resolution, do - /// not use this method, but rather instantiate - /// your own . - ///

- ///
- /// - /// The (possibly partially assembly qualified) name of a - /// . - /// - /// - /// A resolved instance. - /// - /// - /// If the type cannot be resolved. - /// - public static Type ResolveType(string typeName) - { - Type type = TypeRegistry.ResolveType(typeName); - if (type == null) - { - type = internalTypeResolver.Resolve(typeName); - } - return type; - } - - /// - /// Resolves a string array of interface names to - /// a array. - /// - /// - /// An array of valid interface names. Each name must include the full - /// interface and assembly name. - /// - /// An array of interface s. - /// - /// If any of the interfaces can't be loaded. - /// - /// - /// If any of the s specified is not an interface. - /// - /// - /// If (or any of its elements ) is - /// . - /// - public static Type[] ResolveInterfaceArray(string[] interfaceNames) - { - AssertUtils.ArgumentNotNull(interfaceNames, "interfaceNames"); - - ArrayList interfaces = new ArrayList(); - for (int i = 0; i < interfaceNames.Length; i++) - { - string interfaceName = interfaceNames[i]; - AssertUtils.ArgumentNotNull(interfaceName, - string.Format(CultureInfo.InvariantCulture, "interfaceNames[{0}]", i)); - Type resolvedInterface = ResolveType(interfaceName); - if (!resolvedInterface.IsInterface) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "[{0}] is a class.", - resolvedInterface.FullName)); - } - interfaces.Add(resolvedInterface); - interfaces.AddRange(resolvedInterface.GetInterfaces()); - } - return (Type[])interfaces.ToArray(typeof(Type)); - } - - #region MethodMatch - - // TODO : Use the future Pointcut expression language instead - - private readonly static Regex methodMatchRegex = new Regex( - @"(?([\w]+\.)*[\w\*]+)(?(\((?[\w\.]+(,[\w\.]+)*)*\))?)", - RegexOptions.Compiled | RegexOptions.ExplicitCapture); - - /// - /// Match a method against the given pattern. - /// - /// the pattern to match against. - /// the method to match. - /// - /// if the method matches the given pattern; otherwise . - /// - /// - /// If the supplied is invalid. - /// - public static bool MethodMatch(string pattern, MethodInfo method) - { - Match m = methodMatchRegex.Match(pattern); - - if (!m.Success) - throw new ArgumentException(String.Format("The pattern [{0}] is not well-formed.", pattern)); - - // Check method name - string methodNamePattern = m.Groups["methodName"].Value; - if (!PatternMatchUtils.SimpleMatch(methodNamePattern, method.Name)) - return false; - - if (m.Groups["parameters"].Value.Length > 0) - { - // Check parameter types - string parameters = m.Groups["parameterTypes"].Value; - string[] paramTypes = - (parameters.Length == 0) - ? new string[0] - : StringUtils.DelimitedListToStringArray(parameters, ","); - ParameterInfo[] paramInfos = method.GetParameters(); - - // Verify parameter count - if (paramTypes.Length != paramInfos.Length) - return false; - - // Match parameter types - for (int i = 0; i < paramInfos.Length; i++) - { - if (paramInfos[i].ParameterType != TypeResolutionUtils.ResolveType(paramTypes[i])) - return false; - } - } - - return true; - } - - #endregion - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Text.RegularExpressions; +using System.Reflection; + +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Helper methods with regard to type resolution. + /// + /// + ///

+ /// Not intended to be used directly by applications. + ///

+ ///
+ /// Bruno Baia + public sealed class TypeResolutionUtils + { + #region Fields + +#if NET_2_0 + private static readonly ITypeResolver internalTypeResolver + = new CachedTypeResolver(new GenericTypeResolver()); +#else + private static readonly ITypeResolver internalTypeResolver + = new CachedTypeResolver(new TypeResolver()); +#endif + + #endregion + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private TypeResolutionUtils() + { + } + + // CLOVER:ON + + #endregion + + #region Methods + + /// + /// Resolves the supplied type name into a + /// instance. + /// + /// + ///

+ /// If you require special resolution, do + /// not use this method, but rather instantiate + /// your own . + ///

+ ///
+ /// + /// The (possibly partially assembly qualified) name of a + /// . + /// + /// + /// A resolved instance. + /// + /// + /// If the type cannot be resolved. + /// + public static Type ResolveType(string typeName) + { + Type type = TypeRegistry.ResolveType(typeName); + if (type == null) + { + type = internalTypeResolver.Resolve(typeName); + } + return type; + } + + /// + /// Resolves a string array of interface names to + /// a array. + /// + /// + /// An array of valid interface names. Each name must include the full + /// interface and assembly name. + /// + /// An array of interface s. + /// + /// If any of the interfaces can't be loaded. + /// + /// + /// If any of the s specified is not an interface. + /// + /// + /// If (or any of its elements ) is + /// . + /// + public static Type[] ResolveInterfaceArray(string[] interfaceNames) + { + AssertUtils.ArgumentNotNull(interfaceNames, "interfaceNames"); + + ArrayList interfaces = new ArrayList(); + for (int i = 0; i < interfaceNames.Length; i++) + { + string interfaceName = interfaceNames[i]; + AssertUtils.ArgumentNotNull(interfaceName, + string.Format(CultureInfo.InvariantCulture, "interfaceNames[{0}]", i)); + Type resolvedInterface = ResolveType(interfaceName); + if (!resolvedInterface.IsInterface) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "[{0}] is a class.", + resolvedInterface.FullName)); + } + interfaces.Add(resolvedInterface); + interfaces.AddRange(resolvedInterface.GetInterfaces()); + } + return (Type[])interfaces.ToArray(typeof(Type)); + } + + #region MethodMatch + + // TODO : Use the future Pointcut expression language instead + + private readonly static Regex methodMatchRegex = new Regex( + @"(?([\w]+\.)*[\w\*]+)(?(\((?[\w\.]+(,[\w\.]+)*)*\))?)", + RegexOptions.Compiled | RegexOptions.ExplicitCapture); + + /// + /// Match a method against the given pattern. + /// + /// the pattern to match against. + /// the method to match. + /// + /// if the method matches the given pattern; otherwise . + /// + /// + /// If the supplied is invalid. + /// + public static bool MethodMatch(string pattern, MethodInfo method) + { + Match m = methodMatchRegex.Match(pattern); + + if (!m.Success) + throw new ArgumentException(String.Format("The pattern [{0}] is not well-formed.", pattern)); + + // Check method name + string methodNamePattern = m.Groups["methodName"].Value; + if (!PatternMatchUtils.SimpleMatch(methodNamePattern, method.Name)) + return false; + + if (m.Groups["parameters"].Value.Length > 0) + { + // Check parameter types + string parameters = m.Groups["parameterTypes"].Value; + string[] paramTypes = + (parameters.Length == 0) + ? new string[0] + : StringUtils.DelimitedListToStringArray(parameters, ","); + ParameterInfo[] paramInfos = method.GetParameters(); + + // Verify parameter count + if (paramTypes.Length != paramInfos.Length) + return false; + + // Match parameter types + for (int i = 0; i < paramInfos.Length; i++) + { + if (paramInfos[i].ParameterType != TypeResolutionUtils.ResolveType(paramTypes[i])) + return false; + } + } + + return true; + } + + #endregion + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Core/TypeResolution/TypeResolver.cs b/src/Spring/Spring.Core/Core/TypeResolution/TypeResolver.cs index e73f4827..c468bcee 100644 --- a/src/Spring/Spring.Core/Core/TypeResolution/TypeResolver.cs +++ b/src/Spring/Spring.Core/Core/TypeResolution/TypeResolver.cs @@ -1,169 +1,168 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Core.TypeResolution -{ - /// - /// Resolves a by name. - /// - /// Rick Evans - /// Aleksandar Seovic - /// Bruno Baia - /// $Id: TypeResolver.cs,v 1.3 2007/08/27 15:18:24 oakinger Exp $ - public class TypeResolver : ITypeResolver - { - /// - /// Resolves the supplied to a - /// instance. - /// - /// - /// The unresolved (possibly partially assembly qualified) name - /// of a . - /// - /// - /// A resolved instance. - /// - /// - /// If the supplied could not be resolved - /// to a . - /// - public virtual Type Resolve(string typeName) - { - if (StringUtils.IsNullOrEmpty(typeName)) - { - throw BuildTypeLoadException(typeName); - } - TypeAssemblyHolder typeInfo = new TypeAssemblyHolder(typeName); - Type type = null; - try - { - type = (typeInfo.IsAssemblyQualified) ? - LoadTypeDirectlyFromAssembly(typeInfo) : - LoadTypeByIteratingOverAllLoadedAssemblies(typeInfo); - } - catch (Exception ex) - { - if (ex is TypeLoadException) - { - throw; - } - throw BuildTypeLoadException(typeName, ex); - } - if (type == null) - { - throw BuildTypeLoadException(typeName); - } - return type; - } - - /// - /// Uses - /// to load an and then the attendant - /// referred to by the - /// parameter. - /// - /// - ///

- /// is - /// deprecated in .NET 2.0, but is still used here (even when this class is - /// compiled for .NET 2.0); - /// will - /// still resolve (non-.NET Framework) local assemblies when given only the - /// display name of an assembly (the behaviour for .NET Framework assemblies - /// and strongly named assemblies is documented in the docs for the - /// method). - ///

- ///
- /// - /// The assembly and type to be loaded. - /// - /// - /// A , or . - /// - /// - /// - /// - private static Type LoadTypeDirectlyFromAssembly(TypeAssemblyHolder typeInfo) - { - Type type = null; - Assembly assembly = Assembly.LoadWithPartialName(typeInfo.AssemblyName); - if (assembly != null) - { - type = assembly.GetType(typeInfo.TypeName, true, true); - } - return type; - } - - /// - /// Uses - /// to load the attendant referred to by - /// the parameter. - /// - /// - /// The type to be loaded. - /// - /// - /// A , or . - /// - private static Type LoadTypeByIteratingOverAllLoadedAssemblies(TypeAssemblyHolder typeInfo) - { - Type type = null; - Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly assembly in assemblies) - { - type = assembly.GetType(typeInfo.TypeName, false, false); - if (type != null) - { - break; - } - } - return type; - } - - /// - /// Creates a new instance - /// from the given - /// - protected static TypeLoadException BuildTypeLoadException(string typeName) - { - return new TypeLoadException("Could not load type from string value '" + typeName + "'."); - } - - /// - /// Creates a new instance - /// from the given with the given inner - /// - protected static TypeLoadException BuildTypeLoadException(string typeName, Exception ex) - { - return new TypeLoadException("Could not load type from string value '" + typeName + "'.", ex); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Core.TypeResolution +{ + /// + /// Resolves a by name. + /// + /// Rick Evans + /// Aleksandar Seovic + /// Bruno Baia + public class TypeResolver : ITypeResolver + { + /// + /// Resolves the supplied to a + /// instance. + /// + /// + /// The unresolved (possibly partially assembly qualified) name + /// of a . + /// + /// + /// A resolved instance. + /// + /// + /// If the supplied could not be resolved + /// to a . + /// + public virtual Type Resolve(string typeName) + { + if (StringUtils.IsNullOrEmpty(typeName)) + { + throw BuildTypeLoadException(typeName); + } + TypeAssemblyHolder typeInfo = new TypeAssemblyHolder(typeName); + Type type = null; + try + { + type = (typeInfo.IsAssemblyQualified) ? + LoadTypeDirectlyFromAssembly(typeInfo) : + LoadTypeByIteratingOverAllLoadedAssemblies(typeInfo); + } + catch (Exception ex) + { + if (ex is TypeLoadException) + { + throw; + } + throw BuildTypeLoadException(typeName, ex); + } + if (type == null) + { + throw BuildTypeLoadException(typeName); + } + return type; + } + + /// + /// Uses + /// to load an and then the attendant + /// referred to by the + /// parameter. + /// + /// + ///

+ /// is + /// deprecated in .NET 2.0, but is still used here (even when this class is + /// compiled for .NET 2.0); + /// will + /// still resolve (non-.NET Framework) local assemblies when given only the + /// display name of an assembly (the behaviour for .NET Framework assemblies + /// and strongly named assemblies is documented in the docs for the + /// method). + ///

+ ///
+ /// + /// The assembly and type to be loaded. + /// + /// + /// A , or . + /// + /// + /// + /// + private static Type LoadTypeDirectlyFromAssembly(TypeAssemblyHolder typeInfo) + { + Type type = null; + Assembly assembly = Assembly.LoadWithPartialName(typeInfo.AssemblyName); + if (assembly != null) + { + type = assembly.GetType(typeInfo.TypeName, true, true); + } + return type; + } + + /// + /// Uses + /// to load the attendant referred to by + /// the parameter. + /// + /// + /// The type to be loaded. + /// + /// + /// A , or . + /// + private static Type LoadTypeByIteratingOverAllLoadedAssemblies(TypeAssemblyHolder typeInfo) + { + Type type = null; + Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (Assembly assembly in assemblies) + { + type = assembly.GetType(typeInfo.TypeName, false, false); + if (type != null) + { + break; + } + } + return type; + } + + /// + /// Creates a new instance + /// from the given + /// + protected static TypeLoadException BuildTypeLoadException(string typeName) + { + return new TypeLoadException("Could not load type from string value '" + typeName + "'."); + } + + /// + /// Creates a new instance + /// from the given with the given inner + /// + protected static TypeLoadException BuildTypeLoadException(string typeName, Exception ex) + { + return new TypeLoadException("Could not load type from string value '" + typeName + "'.", ex); + } + } +} diff --git a/src/Spring/Spring.Core/DataBinding/AbstractBinding.cs b/src/Spring/Spring.Core/DataBinding/AbstractBinding.cs index 0b17df5a..c36e3316 100644 --- a/src/Spring/Spring.Core/DataBinding/AbstractBinding.cs +++ b/src/Spring/Spring.Core/DataBinding/AbstractBinding.cs @@ -1,181 +1,180 @@ -using System; -using System.Collections; -using Spring.Threading; -using Spring.Util; -using Spring.Validation; - -namespace Spring.DataBinding -{ - /// - /// Abstract base class for implementations. - /// - /// Aleksandar Seovic - /// $Id: AbstractBinding.cs,v 1.2 2008/02/05 20:40:25 aseovic Exp $ - public abstract class AbstractBinding : IBinding - { - #region Fields - - // each Binding instance needs its own ID - private readonly string BINDING_ID = Guid.NewGuid().ToString("N"); - - private BindingDirection direction = BindingDirection.Bidirectional; - private ErrorMessage errorMessage; - private string[] errorProviders; - - #endregion - - #region Properties - - /// - /// Gets or sets a flag specifying whether this binding is valid. - /// - /// - /// true if this binding evaluated without errors; - /// false otherwise. - /// - public bool IsValid - { - get - { - object val = LogicalThreadContext.GetData(GetIsValidKey()); - return val == null || (bool)val; - } - set - { - LogicalThreadContext.SetData(GetIsValidKey(), value); - } - } - - /// - /// Gets or sets the . - /// - /// The binding direction. - public BindingDirection Direction - { - get { return direction; } - set { direction = value; } - } - - /// - /// Gets the error message. - /// - /// The error message. - public ErrorMessage ErrorMessage - { - get { return errorMessage; } - } - - /// - /// Gets the error providers. - /// - public string[] ErrorProviders - { - get { return errorProviders; } - } - - #endregion - - #region IBinding Implementation - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - public void BindSourceToTarget(object source, object target, IValidationErrors validationErrors) - { - BindSourceToTarget(source, target, validationErrors, null); - } - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - public void BindTargetToSource(object source, object target, IValidationErrors validationErrors) - { - BindTargetToSource(source, target, validationErrors, null); - } - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public abstract void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, IDictionary variables); - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public abstract void BindTargetToSource(object source, object target, IValidationErrors validationErrors, IDictionary variables); - - /// - /// Sets error message that should be displayed in the case - /// of a non-fatal binding error. - /// - /// - /// Resource ID of the error message. - /// - /// - /// List of error providers message should be added to. - /// - public void SetErrorMessage(string messageId, params string[] errorProviders) - { - AssertUtils.ArgumentHasText(messageId, "messageId"); - if (errorProviders == null || errorProviders.Length == 0) - { - throw new ArgumentException("At least one error provider has to be specified.", "providers"); - } - - this.errorMessage = new ErrorMessage(messageId, null); - this.errorProviders = errorProviders; - } - - #endregion - - #region Private Methods - - private string GetIsValidKey() - { - return "Binding." + BINDING_ID + ".IsValid"; - } - - #endregion - } +using System; +using System.Collections; +using Spring.Threading; +using Spring.Util; +using Spring.Validation; + +namespace Spring.DataBinding +{ + /// + /// Abstract base class for implementations. + /// + /// Aleksandar Seovic + public abstract class AbstractBinding : IBinding + { + #region Fields + + // each Binding instance needs its own ID + private readonly string BINDING_ID = Guid.NewGuid().ToString("N"); + + private BindingDirection direction = BindingDirection.Bidirectional; + private ErrorMessage errorMessage; + private string[] errorProviders; + + #endregion + + #region Properties + + /// + /// Gets or sets a flag specifying whether this binding is valid. + /// + /// + /// true if this binding evaluated without errors; + /// false otherwise. + /// + public bool IsValid + { + get + { + object val = LogicalThreadContext.GetData(GetIsValidKey()); + return val == null || (bool)val; + } + set + { + LogicalThreadContext.SetData(GetIsValidKey(), value); + } + } + + /// + /// Gets or sets the . + /// + /// The binding direction. + public BindingDirection Direction + { + get { return direction; } + set { direction = value; } + } + + /// + /// Gets the error message. + /// + /// The error message. + public ErrorMessage ErrorMessage + { + get { return errorMessage; } + } + + /// + /// Gets the error providers. + /// + public string[] ErrorProviders + { + get { return errorProviders; } + } + + #endregion + + #region IBinding Implementation + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + public void BindSourceToTarget(object source, object target, IValidationErrors validationErrors) + { + BindSourceToTarget(source, target, validationErrors, null); + } + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + public void BindTargetToSource(object source, object target, IValidationErrors validationErrors) + { + BindTargetToSource(source, target, validationErrors, null); + } + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public abstract void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, IDictionary variables); + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public abstract void BindTargetToSource(object source, object target, IValidationErrors validationErrors, IDictionary variables); + + /// + /// Sets error message that should be displayed in the case + /// of a non-fatal binding error. + /// + /// + /// Resource ID of the error message. + /// + /// + /// List of error providers message should be added to. + /// + public void SetErrorMessage(string messageId, params string[] errorProviders) + { + AssertUtils.ArgumentHasText(messageId, "messageId"); + if (errorProviders == null || errorProviders.Length == 0) + { + throw new ArgumentException("At least one error provider has to be specified.", "providers"); + } + + this.errorMessage = new ErrorMessage(messageId, null); + this.errorProviders = errorProviders; + } + + #endregion + + #region Private Methods + + private string GetIsValidKey() + { + return "Binding." + BINDING_ID + ".IsValid"; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs b/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs index b9335d1f..f6a215a4 100644 --- a/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs +++ b/src/Spring/Spring.Core/DataBinding/AbstractSimpleBinding.cs @@ -1,253 +1,252 @@ -using System; -using System.Collections; -using Spring.Globalization; -using Spring.Validation; - -namespace Spring.DataBinding -{ - /// - /// Abstract base class for simple, one-to-one implementations. - /// - /// Aleksandar Seovic - /// $Id: AbstractSimpleBinding.cs,v 1.4 2008/02/05 20:40:25 aseovic Exp $ - public abstract class AbstractSimpleBinding : AbstractBinding - { - #region Fields - - private IFormatter formatter; - - #endregion - - #region Constructor(s) - - /// - /// Initialize a new instance of without any - /// - protected AbstractSimpleBinding() - { - } - - /// - /// Initialize a new instance of with the - /// specified . - /// - protected AbstractSimpleBinding(IFormatter formatter) - { - this.formatter = formatter; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the to use. - /// - /// The formatter to use. - public IFormatter Formatter - { - get { return formatter; } - set { formatter = value; } - } - - #endregion - - #region IBinding Implementation - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public override void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, - IDictionary variables) - { - if (this.IsValid - && - (this.Direction == BindingDirection.Bidirectional || this.Direction == BindingDirection.SourceToTarget)) - { - try - { - DoBindSourceToTarget(source, target, variables); - this.IsValid = true; - } - catch (Exception) - { - this.IsValid = false; - if (this.ErrorMessage != null && validationErrors != null) - { - foreach (string provider in this.ErrorProviders) - { - validationErrors.AddError(provider, this.ErrorMessage); - } - } - else - { - throw; - } - } - } - } - - /// - /// Concrete implementation if source to target binding. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Variables that should be used during expression evaluation. - /// - protected virtual void DoBindSourceToTarget(object source, object target, IDictionary variables) - { - object value = this.GetSourceValue(source, variables); - if (this.Formatter != null && value is string) - { - value = this.Formatter.Parse((string) value); - } - this.SetTargetValue(target, value, variables); - } - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public override void BindTargetToSource(object source, object target, IValidationErrors validationErrors, - IDictionary variables) - { - if (this.IsValid - && - (this.Direction == BindingDirection.Bidirectional || this.Direction == BindingDirection.TargetToSource)) - { - try - { - DoBindTargetToSource(source, target, variables); - this.IsValid = true; - } - catch (Exception) - { - this.IsValid = false; - if (this.ErrorMessage != null && validationErrors != null) - { - foreach (string provider in this.ErrorProviders) - { - validationErrors.AddError(provider, this.ErrorMessage); - } - } - else - { - throw; - } - } - } - } - - /// - /// Concrete implementation of target to source binding. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Variables that should be used during expression evaluation. - /// - protected virtual void DoBindTargetToSource(object source, object target, IDictionary variables) - { - object value = this.GetTargetValue(target, variables); - if (this.Formatter != null) - { - value = this.Formatter.Format(value); - } - this.SetSourceValue(source, value, variables); - } - - #endregion - - #region Abstract Methods - - /// - /// Gets the source value for the binding. - /// - /// - /// Source object to extract value from. - /// - /// - /// Variables for expression evaluation. - /// - /// - /// The source value for the binding. - /// - protected abstract object GetSourceValue(object source, IDictionary variables); - - /// - /// Sets the source value for the binding. - /// - /// - /// The source object to set the value on. - /// - /// - /// The value to set. - /// - /// - /// Variables for expression evaluation. - /// - protected abstract void SetSourceValue(object source, object value, IDictionary variables); - - /// - /// Gets the target value for the binding. - /// - /// - /// Source object to extract value from. - /// - /// - /// Variables for expression evaluation. - /// - /// - /// The target value for the binding. - /// - protected abstract object GetTargetValue(object target, IDictionary variables); - - /// - /// Sets the target value for the binding. - /// - /// - /// The target object to set the value on. - /// - /// - /// The value to set. - /// - /// - /// Variables for expression evaluation. - /// - protected abstract void SetTargetValue(object target, object value, IDictionary variables); - - #endregion - } +using System; +using System.Collections; +using Spring.Globalization; +using Spring.Validation; + +namespace Spring.DataBinding +{ + /// + /// Abstract base class for simple, one-to-one implementations. + /// + /// Aleksandar Seovic + public abstract class AbstractSimpleBinding : AbstractBinding + { + #region Fields + + private IFormatter formatter; + + #endregion + + #region Constructor(s) + + /// + /// Initialize a new instance of without any + /// + protected AbstractSimpleBinding() + { + } + + /// + /// Initialize a new instance of with the + /// specified . + /// + protected AbstractSimpleBinding(IFormatter formatter) + { + this.formatter = formatter; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the to use. + /// + /// The formatter to use. + public IFormatter Formatter + { + get { return formatter; } + set { formatter = value; } + } + + #endregion + + #region IBinding Implementation + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public override void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, + IDictionary variables) + { + if (this.IsValid + && + (this.Direction == BindingDirection.Bidirectional || this.Direction == BindingDirection.SourceToTarget)) + { + try + { + DoBindSourceToTarget(source, target, variables); + this.IsValid = true; + } + catch (Exception) + { + this.IsValid = false; + if (this.ErrorMessage != null && validationErrors != null) + { + foreach (string provider in this.ErrorProviders) + { + validationErrors.AddError(provider, this.ErrorMessage); + } + } + else + { + throw; + } + } + } + } + + /// + /// Concrete implementation if source to target binding. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Variables that should be used during expression evaluation. + /// + protected virtual void DoBindSourceToTarget(object source, object target, IDictionary variables) + { + object value = this.GetSourceValue(source, variables); + if (this.Formatter != null && value is string) + { + value = this.Formatter.Parse((string) value); + } + this.SetTargetValue(target, value, variables); + } + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public override void BindTargetToSource(object source, object target, IValidationErrors validationErrors, + IDictionary variables) + { + if (this.IsValid + && + (this.Direction == BindingDirection.Bidirectional || this.Direction == BindingDirection.TargetToSource)) + { + try + { + DoBindTargetToSource(source, target, variables); + this.IsValid = true; + } + catch (Exception) + { + this.IsValid = false; + if (this.ErrorMessage != null && validationErrors != null) + { + foreach (string provider in this.ErrorProviders) + { + validationErrors.AddError(provider, this.ErrorMessage); + } + } + else + { + throw; + } + } + } + } + + /// + /// Concrete implementation of target to source binding. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Variables that should be used during expression evaluation. + /// + protected virtual void DoBindTargetToSource(object source, object target, IDictionary variables) + { + object value = this.GetTargetValue(target, variables); + if (this.Formatter != null) + { + value = this.Formatter.Format(value); + } + this.SetSourceValue(source, value, variables); + } + + #endregion + + #region Abstract Methods + + /// + /// Gets the source value for the binding. + /// + /// + /// Source object to extract value from. + /// + /// + /// Variables for expression evaluation. + /// + /// + /// The source value for the binding. + /// + protected abstract object GetSourceValue(object source, IDictionary variables); + + /// + /// Sets the source value for the binding. + /// + /// + /// The source object to set the value on. + /// + /// + /// The value to set. + /// + /// + /// Variables for expression evaluation. + /// + protected abstract void SetSourceValue(object source, object value, IDictionary variables); + + /// + /// Gets the target value for the binding. + /// + /// + /// Source object to extract value from. + /// + /// + /// Variables for expression evaluation. + /// + /// + /// The target value for the binding. + /// + protected abstract object GetTargetValue(object target, IDictionary variables); + + /// + /// Sets the target value for the binding. + /// + /// + /// The target object to set the value on. + /// + /// + /// The value to set. + /// + /// + /// Variables for expression evaluation. + /// + protected abstract void SetTargetValue(object target, object value, IDictionary variables); + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/BaseBindingContainer.cs b/src/Spring/Spring.Core/DataBinding/BaseBindingContainer.cs index eaebbbd1..1a4f20ca 100644 --- a/src/Spring/Spring.Core/DataBinding/BaseBindingContainer.cs +++ b/src/Spring/Spring.Core/DataBinding/BaseBindingContainer.cs @@ -1,262 +1,261 @@ -using System.Collections; -using Spring.Globalization; -using Spring.Validation; - -namespace Spring.DataBinding -{ - /// - /// Base implementation of the . - /// - /// Aleksandar Seovic - /// $Id: BaseBindingContainer.cs,v 1.2 2008/02/05 20:40:25 aseovic Exp $ - public class BaseBindingContainer : IBindingContainer - { - #region Fields - - private IList bindings = new ArrayList(); - - #endregion - - #region Constructor(s) - - /// - /// Creates a new instance of . - /// - public BaseBindingContainer() - {} - - #endregion - - #region Properties - - /// - /// Gets a list of bindings for this container. - /// - /// - /// A list of bindings for this container. - /// - protected IList Bindings - { - get { return bindings; } - } - - #endregion - - #region IBindingContainer Implementation - - /// - /// Gets a value indicating whether this instance has bindings. - /// - /// - /// true if this instance has bindings; otherwise, false. - /// - public bool HasBindings - { - get { return bindings.Count > 0; } - } - - /// - /// Adds the binding. - /// - /// - /// Binding definition to add. - /// - /// - /// Added instance. - /// - public IBinding AddBinding(IBinding binding) - { - bindings.Add(binding); - return binding; - } - - /// - /// Adds the binding with a default - /// binding direction of . - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// Added instance. - /// - public IBinding AddBinding(string sourceExpression, string targetExpression) - { - return AddBinding(sourceExpression, targetExpression, BindingDirection.Bidirectional, null); - } - - /// - /// Adds the binding. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// Binding direction. - /// - /// - /// Added instance. - /// - public IBinding AddBinding(string sourceExpression, string targetExpression, BindingDirection direction) - { - return AddBinding(sourceExpression, targetExpression, direction, null); - } - - /// - /// Adds the binding with a default - /// binding direction of . - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// to use for value formatting and parsing. - /// - /// - /// Added instance. - /// - public IBinding AddBinding(string sourceExpression, string targetExpression, IFormatter formatter) - { - return AddBinding(sourceExpression, targetExpression, BindingDirection.Bidirectional, formatter); - } - - /// - /// Adds the binding. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// Binding direction. - /// - /// - /// to use for value formatting and parsing. - /// - /// - /// Added instance. - /// - public virtual IBinding AddBinding(string sourceExpression, string targetExpression, - BindingDirection direction, IFormatter formatter) - { - SimpleExpressionBinding binding = new SimpleExpressionBinding(sourceExpression, targetExpression); - binding.Direction = direction; - binding.Formatter = formatter; - bindings.Add(binding); - - return binding; - } - - #endregion - - #region IBinding Implementation - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - public void BindSourceToTarget(object source, object target, IValidationErrors validationErrors) - { - BindSourceToTarget(source, target, validationErrors, null); - } - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public virtual void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, - IDictionary variables) - { - foreach (IBinding binding in bindings) - { - binding.BindSourceToTarget(source, target, validationErrors); - } - } - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - public void BindTargetToSource(object source, object target, IValidationErrors validationErrors) - { - BindTargetToSource(source, target, validationErrors, null); - } - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public virtual void BindTargetToSource(object source, object target, IValidationErrors validationErrors, - IDictionary variables) - { - foreach (IBinding binding in bindings) - { - binding.BindTargetToSource(source, target, validationErrors); - } - } - - /// - /// Sets error message that should be displayed in the case - /// of a non-fatal binding error. - /// - /// - /// Resource ID of the error message. - /// - /// - /// List of error providers message should be added to. - /// - public virtual void SetErrorMessage(string messageId, params string[] errorProviders) - {} - - #endregion - } +using System.Collections; +using Spring.Globalization; +using Spring.Validation; + +namespace Spring.DataBinding +{ + /// + /// Base implementation of the . + /// + /// Aleksandar Seovic + public class BaseBindingContainer : IBindingContainer + { + #region Fields + + private IList bindings = new ArrayList(); + + #endregion + + #region Constructor(s) + + /// + /// Creates a new instance of . + /// + public BaseBindingContainer() + {} + + #endregion + + #region Properties + + /// + /// Gets a list of bindings for this container. + /// + /// + /// A list of bindings for this container. + /// + protected IList Bindings + { + get { return bindings; } + } + + #endregion + + #region IBindingContainer Implementation + + /// + /// Gets a value indicating whether this instance has bindings. + /// + /// + /// true if this instance has bindings; otherwise, false. + /// + public bool HasBindings + { + get { return bindings.Count > 0; } + } + + /// + /// Adds the binding. + /// + /// + /// Binding definition to add. + /// + /// + /// Added instance. + /// + public IBinding AddBinding(IBinding binding) + { + bindings.Add(binding); + return binding; + } + + /// + /// Adds the binding with a default + /// binding direction of . + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// Added instance. + /// + public IBinding AddBinding(string sourceExpression, string targetExpression) + { + return AddBinding(sourceExpression, targetExpression, BindingDirection.Bidirectional, null); + } + + /// + /// Adds the binding. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// Binding direction. + /// + /// + /// Added instance. + /// + public IBinding AddBinding(string sourceExpression, string targetExpression, BindingDirection direction) + { + return AddBinding(sourceExpression, targetExpression, direction, null); + } + + /// + /// Adds the binding with a default + /// binding direction of . + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// to use for value formatting and parsing. + /// + /// + /// Added instance. + /// + public IBinding AddBinding(string sourceExpression, string targetExpression, IFormatter formatter) + { + return AddBinding(sourceExpression, targetExpression, BindingDirection.Bidirectional, formatter); + } + + /// + /// Adds the binding. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// Binding direction. + /// + /// + /// to use for value formatting and parsing. + /// + /// + /// Added instance. + /// + public virtual IBinding AddBinding(string sourceExpression, string targetExpression, + BindingDirection direction, IFormatter formatter) + { + SimpleExpressionBinding binding = new SimpleExpressionBinding(sourceExpression, targetExpression); + binding.Direction = direction; + binding.Formatter = formatter; + bindings.Add(binding); + + return binding; + } + + #endregion + + #region IBinding Implementation + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + public void BindSourceToTarget(object source, object target, IValidationErrors validationErrors) + { + BindSourceToTarget(source, target, validationErrors, null); + } + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public virtual void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, + IDictionary variables) + { + foreach (IBinding binding in bindings) + { + binding.BindSourceToTarget(source, target, validationErrors); + } + } + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + public void BindTargetToSource(object source, object target, IValidationErrors validationErrors) + { + BindTargetToSource(source, target, validationErrors, null); + } + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public virtual void BindTargetToSource(object source, object target, IValidationErrors validationErrors, + IDictionary variables) + { + foreach (IBinding binding in bindings) + { + binding.BindTargetToSource(source, target, validationErrors); + } + } + + /// + /// Sets error message that should be displayed in the case + /// of a non-fatal binding error. + /// + /// + /// Resource ID of the error message. + /// + /// + /// List of error providers message should be added to. + /// + public virtual void SetErrorMessage(string messageId, params string[] errorProviders) + {} + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/BaseBindingManager.cs b/src/Spring/Spring.Core/DataBinding/BaseBindingManager.cs index b0d6391a..36f8eb41 100644 --- a/src/Spring/Spring.Core/DataBinding/BaseBindingManager.cs +++ b/src/Spring/Spring.Core/DataBinding/BaseBindingManager.cs @@ -1,46 +1,45 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -using Spring.Globalization; -using Spring.Validation; - -namespace Spring.DataBinding -{ - /// - /// BaseBindingManager keeps track of all registered bindings and - /// represents an entry point for the binding and unbinding process. - /// - /// Aleksandar Seovic - /// $Id: BaseBindingManager.cs,v 1.1 2006/11/21 05:46:57 aseovic Exp $ - public class BaseBindingManager : BaseBindingContainer - { - #region Constructor(s) - - /// - /// Initializes a new instance of the class. - /// - public BaseBindingManager() - {} - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +using Spring.Globalization; +using Spring.Validation; + +namespace Spring.DataBinding +{ + /// + /// BaseBindingManager keeps track of all registered bindings and + /// represents an entry point for the binding and unbinding process. + /// + /// Aleksandar Seovic + public class BaseBindingManager : BaseBindingContainer + { + #region Constructor(s) + + /// + /// Initializes a new instance of the class. + /// + public BaseBindingManager() + {} + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/BindingDirection.cs b/src/Spring/Spring.Core/DataBinding/BindingDirection.cs index 2be758c6..6a2d2ffb 100644 --- a/src/Spring/Spring.Core/DataBinding/BindingDirection.cs +++ b/src/Spring/Spring.Core/DataBinding/BindingDirection.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.DataBinding -{ - /// - /// Enumeration that defines possible values for data binding direction. - /// - /// Aleksandar Seovic - /// $Id: BindingDirection.cs,v 1.2 2006/04/09 07:18:39 markpollack Exp $ - [Flags] - public enum BindingDirection - { - /// - /// Specifies that value from the control property should be bound to a data model. - /// - SourceToTarget = 0x0001, - - /// - /// Specifies that value from the data model should be bound to control property. - /// - TargetToSource = 0x0002, - - /// - /// Specifies that binding is bidirectional. - /// - Bidirectional = SourceToTarget | TargetToSource - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.DataBinding +{ + /// + /// Enumeration that defines possible values for data binding direction. + /// + /// Aleksandar Seovic + [Flags] + public enum BindingDirection + { + /// + /// Specifies that value from the control property should be bound to a data model. + /// + SourceToTarget = 0x0001, + + /// + /// Specifies that value from the data model should be bound to control property. + /// + TargetToSource = 0x0002, + + /// + /// Specifies that binding is bidirectional. + /// + Bidirectional = SourceToTarget | TargetToSource + } +} diff --git a/src/Spring/Spring.Core/DataBinding/IBinding.cs b/src/Spring/Spring.Core/DataBinding/IBinding.cs index fa0c20e3..2bf89bed 100644 --- a/src/Spring/Spring.Core/DataBinding/IBinding.cs +++ b/src/Spring/Spring.Core/DataBinding/IBinding.cs @@ -1,88 +1,87 @@ -using System.Collections; -using Spring.Validation; - -namespace Spring.DataBinding -{ - /// - /// An interface that defines the methods that have to be implemented by all data bindings. - /// - /// Aleksandar Seovic - /// $Id: IBinding.cs,v 1.3 2008/02/05 20:40:25 aseovic Exp $ - public interface IBinding - { - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - void BindSourceToTarget(object source, object target, IValidationErrors validationErrors); - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, IDictionary variables); - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - void BindTargetToSource(object source, object target, IValidationErrors validationErrors); - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - void BindTargetToSource(object source, object target, IValidationErrors validationErrors, IDictionary variables); - - /// - /// Sets error message that should be displayed in the case - /// of a non-fatal binding error. - /// - /// - /// Resource ID of the error message. - /// - /// - /// List of error providers message should be added to. - /// - void SetErrorMessage(string messageId, params string[] errorProviders); - - } +using System.Collections; +using Spring.Validation; + +namespace Spring.DataBinding +{ + /// + /// An interface that defines the methods that have to be implemented by all data bindings. + /// + /// Aleksandar Seovic + public interface IBinding + { + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + void BindSourceToTarget(object source, object target, IValidationErrors validationErrors); + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, IDictionary variables); + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + void BindTargetToSource(object source, object target, IValidationErrors validationErrors); + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + void BindTargetToSource(object source, object target, IValidationErrors validationErrors, IDictionary variables); + + /// + /// Sets error message that should be displayed in the case + /// of a non-fatal binding error. + /// + /// + /// Resource ID of the error message. + /// + /// + /// List of error providers message should be added to. + /// + void SetErrorMessage(string messageId, params string[] errorProviders); + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/IBindingContainer.cs b/src/Spring/Spring.Core/DataBinding/IBindingContainer.cs index f63dc54e..a2baaa5d 100644 --- a/src/Spring/Spring.Core/DataBinding/IBindingContainer.cs +++ b/src/Spring/Spring.Core/DataBinding/IBindingContainer.cs @@ -1,120 +1,119 @@ -using Spring.Globalization; - -namespace Spring.DataBinding -{ - /// - /// An interface that has to be implemented by all data binding containers. - /// - /// Aleksandar Seovic - /// $Id: IBindingContainer.cs,v 1.1 2006/11/21 05:46:57 aseovic Exp $ - public interface IBindingContainer : IBinding - { - /// - /// Gets a value indicating whether this data binding container - /// has bindings. - /// - /// - /// true if this data binding container has bindings; - /// false otherwise. - /// - bool HasBindings { get; } - - /// - /// Adds the binding. - /// - /// - /// Binding definition to add. - /// - /// - /// Added instance. - /// - IBinding AddBinding(IBinding binding); - - /// - /// Adds the binding with a default - /// binding direction of . - /// - /// - /// This is a convinience method for adding SimpleExpressionBinding, - /// one of the most often used binding types, to the bindings list. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// Added instance. - /// - IBinding AddBinding(string sourceExpression, string targetExpression); - - /// - /// Adds the binding. - /// - /// - /// This is a convinience method for adding SimpleExpressionBinding, - /// one of the most often used binding types, to the bindings list. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// Binding direction. - /// - /// - /// Added instance. - /// - IBinding AddBinding(string sourceExpression, string targetExpression, BindingDirection direction); - - /// - /// Adds the binding with a default - /// binding direction of . - /// - /// - /// This is a convinience method for adding SimpleExpressionBinding, - /// one of the most often used binding types, to the bindings list. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// to use for value formatting and parsing. - /// - /// - /// Added instance. - /// - IBinding AddBinding(string sourceExpression, string targetExpression, IFormatter formatter); - - /// - /// Adds the binding. - /// - /// - /// This is a convinience method for adding SimpleExpressionBinding, - /// one of the most often used binding types, to the bindings list. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// Binding direction. - /// - /// - /// to use for value formatting and parsing. - /// - /// - /// Added instance. - /// - IBinding AddBinding(string sourceExpression, string targetExpression, BindingDirection direction, - IFormatter formatter); - } +using Spring.Globalization; + +namespace Spring.DataBinding +{ + /// + /// An interface that has to be implemented by all data binding containers. + /// + /// Aleksandar Seovic + public interface IBindingContainer : IBinding + { + /// + /// Gets a value indicating whether this data binding container + /// has bindings. + /// + /// + /// true if this data binding container has bindings; + /// false otherwise. + /// + bool HasBindings { get; } + + /// + /// Adds the binding. + /// + /// + /// Binding definition to add. + /// + /// + /// Added instance. + /// + IBinding AddBinding(IBinding binding); + + /// + /// Adds the binding with a default + /// binding direction of . + /// + /// + /// This is a convinience method for adding SimpleExpressionBinding, + /// one of the most often used binding types, to the bindings list. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// Added instance. + /// + IBinding AddBinding(string sourceExpression, string targetExpression); + + /// + /// Adds the binding. + /// + /// + /// This is a convinience method for adding SimpleExpressionBinding, + /// one of the most often used binding types, to the bindings list. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// Binding direction. + /// + /// + /// Added instance. + /// + IBinding AddBinding(string sourceExpression, string targetExpression, BindingDirection direction); + + /// + /// Adds the binding with a default + /// binding direction of . + /// + /// + /// This is a convinience method for adding SimpleExpressionBinding, + /// one of the most often used binding types, to the bindings list. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// to use for value formatting and parsing. + /// + /// + /// Added instance. + /// + IBinding AddBinding(string sourceExpression, string targetExpression, IFormatter formatter); + + /// + /// Adds the binding. + /// + /// + /// This is a convinience method for adding SimpleExpressionBinding, + /// one of the most often used binding types, to the bindings list. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// Binding direction. + /// + /// + /// to use for value formatting and parsing. + /// + /// + /// Added instance. + /// + IBinding AddBinding(string sourceExpression, string targetExpression, BindingDirection direction, + IFormatter formatter); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/IDataBound.cs b/src/Spring/Spring.Core/DataBinding/IDataBound.cs index cdf68c63..96ab9926 100644 --- a/src/Spring/Spring.Core/DataBinding/IDataBound.cs +++ b/src/Spring/Spring.Core/DataBinding/IDataBound.cs @@ -1,37 +1,36 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.DataBinding -{ - /// - /// Interface that should be implemented by data bound objects, such as - /// web pages, user controls, windows forms, etc. - /// - /// Aleksandar Seovic - /// $Id: IDataBound.cs,v 1.3 2006/11/21 05:46:57 aseovic Exp $ - public interface IDataBound - { - /// - /// Gets the binding manager. - /// - /// The binding manager. - IBindingContainer BindingManager { get; } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.DataBinding +{ + /// + /// Interface that should be implemented by data bound objects, such as + /// web pages, user controls, windows forms, etc. + /// + /// Aleksandar Seovic + public interface IDataBound + { + /// + /// Gets the binding manager. + /// + /// The binding manager. + IBindingContainer BindingManager { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/ListBinding.cs b/src/Spring/Spring.Core/DataBinding/ListBinding.cs index 30aea12a..b22a3373 100644 --- a/src/Spring/Spring.Core/DataBinding/ListBinding.cs +++ b/src/Spring/Spring.Core/DataBinding/ListBinding.cs @@ -1,75 +1,74 @@ -using System.Collections; -using Spring.Expressions; -using Spring.Validation; - -namespace Spring.DataBinding -{ - /// - /// implementation that allows - /// data binding between collections that implement - /// interface. - /// - /// Aleksandar Seovic - /// $Id: ListBinding.cs,v 1.2 2008/02/05 20:40:25 aseovic Exp $ - public class ListBinding : AbstractBinding - { - private IExpression sourceExpression = Expression.Parse("#source = #target"); - private IExpression targetExpression = Expression.Parse("#target = #source"); - - /// - /// Binds source object to target object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public override void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, - IDictionary variables) - { - if (variables == null) - { - variables = new Hashtable(); - } - variables["source"] = source; - variables["target"] = target; - - targetExpression.GetValue(null, variables); - } - - /// - /// Binds target object to source object. - /// - /// - /// The source object. - /// - /// - /// The target object. - /// - /// - /// Validation errors collection that type conversion errors should be added to. - /// - /// - /// Variables that should be used during expression evaluation. - /// - public override void BindTargetToSource(object source, object target, IValidationErrors validationErrors, - IDictionary variables) - { - if (variables == null) - { - variables = new Hashtable(); - } - variables["source"] = source; - variables["target"] = target; - - sourceExpression.GetValue(null, variables); - } - } +using System.Collections; +using Spring.Expressions; +using Spring.Validation; + +namespace Spring.DataBinding +{ + /// + /// implementation that allows + /// data binding between collections that implement + /// interface. + /// + /// Aleksandar Seovic + public class ListBinding : AbstractBinding + { + private IExpression sourceExpression = Expression.Parse("#source = #target"); + private IExpression targetExpression = Expression.Parse("#target = #source"); + + /// + /// Binds source object to target object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public override void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, + IDictionary variables) + { + if (variables == null) + { + variables = new Hashtable(); + } + variables["source"] = source; + variables["target"] = target; + + targetExpression.GetValue(null, variables); + } + + /// + /// Binds target object to source object. + /// + /// + /// The source object. + /// + /// + /// The target object. + /// + /// + /// Validation errors collection that type conversion errors should be added to. + /// + /// + /// Variables that should be used during expression evaluation. + /// + public override void BindTargetToSource(object source, object target, IValidationErrors validationErrors, + IDictionary variables) + { + if (variables == null) + { + variables = new Hashtable(); + } + variables["source"] = source; + variables["target"] = target; + + sourceExpression.GetValue(null, variables); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/DataBinding/SimpleExpressionBinding.cs b/src/Spring/Spring.Core/DataBinding/SimpleExpressionBinding.cs index bc7b41eb..ada74baf 100644 --- a/src/Spring/Spring.Core/DataBinding/SimpleExpressionBinding.cs +++ b/src/Spring/Spring.Core/DataBinding/SimpleExpressionBinding.cs @@ -1,175 +1,174 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using Spring.Expressions; -using Spring.Globalization; - -namespace Spring.DataBinding -{ - /// - /// Simple, expression-based implementation of that - /// binds source to target one-to-one. - /// - /// Aleksandar Seovic - /// $Id: SimpleExpressionBinding.cs,v 1.3 2007/03/19 16:05:52 oakinger Exp $ - public class SimpleExpressionBinding : AbstractSimpleBinding - { - #region Fields - - private IExpression sourceExpression; - private IExpression targetExpression; - - #endregion - - #region Constructor(s) - - /// - /// Initializes a new instance of the class. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - public SimpleExpressionBinding(string sourceExpression, string targetExpression) - { - this.sourceExpression = Expression.Parse(sourceExpression); - this.targetExpression = Expression.Parse(targetExpression); - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The source expression. - /// - /// - /// The target expression. - /// - /// - /// The formatter to use. - /// - public SimpleExpressionBinding(string sourceExpression, string targetExpression, IFormatter formatter) - :base(formatter) - { - this.sourceExpression = Expression.Parse(sourceExpression); - this.targetExpression = Expression.Parse(targetExpression); - } - - #endregion - - #region Properties - - /// - /// Gets the source expression. - /// - /// The source expression. - public IExpression SourceExpression - { - get { return sourceExpression; } - } - - /// - /// Gets the target expression. - /// - /// The target expression. - public IExpression TargetExpression - { - get { return targetExpression; } - } - - #endregion - - #region Abstract Methods Implementation - - /// - /// Gets the source value for the binding. - /// - /// - /// Source object to extract value from. - /// - /// - /// Variables for expression evaluation. - /// - /// - /// The source value for the binding. - /// - protected override object GetSourceValue(object source, IDictionary variables) - { - return this.SourceExpression.GetValue(source, variables); - } - - /// - /// Sets the source value for the binding. - /// - /// - /// The source object to set the value on. - /// - /// - /// The value to set. - /// - /// - /// Variables for expression evaluation. - /// - protected override void SetSourceValue(object source, object value, IDictionary variables) - { - this.SourceExpression.SetValue(source, variables, value); - } - - /// - /// Gets the target value for the binding. - /// - /// - /// Source object to extract value from. - /// - /// - /// Variables for expression evaluation. - /// - /// - /// The target value for the binding. - /// - protected override object GetTargetValue(object target, IDictionary variables) - { - return this.TargetExpression.GetValue(target, variables); - } - - /// - /// Sets the target value for the binding. - /// - /// - /// The target object to set the value on. - /// - /// - /// The value to set. - /// - /// - /// Variables for expression evaluation. - /// - protected override void SetTargetValue(object target, object value, IDictionary variables) - { - this.TargetExpression.SetValue(target, variables, value); - } - - #endregion - - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using Spring.Expressions; +using Spring.Globalization; + +namespace Spring.DataBinding +{ + /// + /// Simple, expression-based implementation of that + /// binds source to target one-to-one. + /// + /// Aleksandar Seovic + public class SimpleExpressionBinding : AbstractSimpleBinding + { + #region Fields + + private IExpression sourceExpression; + private IExpression targetExpression; + + #endregion + + #region Constructor(s) + + /// + /// Initializes a new instance of the class. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + public SimpleExpressionBinding(string sourceExpression, string targetExpression) + { + this.sourceExpression = Expression.Parse(sourceExpression); + this.targetExpression = Expression.Parse(targetExpression); + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The source expression. + /// + /// + /// The target expression. + /// + /// + /// The formatter to use. + /// + public SimpleExpressionBinding(string sourceExpression, string targetExpression, IFormatter formatter) + :base(formatter) + { + this.sourceExpression = Expression.Parse(sourceExpression); + this.targetExpression = Expression.Parse(targetExpression); + } + + #endregion + + #region Properties + + /// + /// Gets the source expression. + /// + /// The source expression. + public IExpression SourceExpression + { + get { return sourceExpression; } + } + + /// + /// Gets the target expression. + /// + /// The target expression. + public IExpression TargetExpression + { + get { return targetExpression; } + } + + #endregion + + #region Abstract Methods Implementation + + /// + /// Gets the source value for the binding. + /// + /// + /// Source object to extract value from. + /// + /// + /// Variables for expression evaluation. + /// + /// + /// The source value for the binding. + /// + protected override object GetSourceValue(object source, IDictionary variables) + { + return this.SourceExpression.GetValue(source, variables); + } + + /// + /// Sets the source value for the binding. + /// + /// + /// The source object to set the value on. + /// + /// + /// The value to set. + /// + /// + /// Variables for expression evaluation. + /// + protected override void SetSourceValue(object source, object value, IDictionary variables) + { + this.SourceExpression.SetValue(source, variables, value); + } + + /// + /// Gets the target value for the binding. + /// + /// + /// Source object to extract value from. + /// + /// + /// Variables for expression evaluation. + /// + /// + /// The target value for the binding. + /// + protected override object GetTargetValue(object target, IDictionary variables) + { + return this.TargetExpression.GetValue(target, variables); + } + + /// + /// Sets the target value for the binding. + /// + /// + /// The target object to set the value on. + /// + /// + /// The value to set. + /// + /// + /// Variables for expression evaluation. + /// + protected override void SetTargetValue(object target, object value, IDictionary variables) + { + this.TargetExpression.SetValue(target, variables, value); + } + + #endregion + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ArrayConstructorNode.cs b/src/Spring/Spring.Core/Expressions/ArrayConstructorNode.cs index 2dd3cc45..278b45af 100644 --- a/src/Spring/Spring.Core/Expressions/ArrayConstructorNode.cs +++ b/src/Spring/Spring.Core/Expressions/ArrayConstructorNode.cs @@ -1,101 +1,100 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -using antlr.collections; -using Spring.Core.TypeResolution; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents parsed method node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: ArrayConstructorNode.cs,v 1.11 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public class ArrayConstructorNode : NodeWithArguments - { - private Type arrayType; - - /// - /// Create a new instance - /// - public ArrayConstructorNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected ArrayConstructorNode(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - /// - /// Creates new instance of the type defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (arrayType == null) - { - lock (this) - { - if (arrayType == null) - { - arrayType = TypeResolutionUtils.ResolveType(getText()); - } - } - } - - AST rankRoot = getFirstChild(); - int dimensions = rankRoot.getNumberOfChildren(); - int[] ranks = new int[dimensions]; - if (dimensions > 0) - { - int i = 0; - AST rankNode = rankRoot.getFirstChild(); - while (rankNode != null) - { - ranks[i++] = (int)((BaseNode)rankNode).GetValueInternal(context, evalContext); - rankNode = rankNode.getNextSibling(); - } - return Array.CreateInstance(arrayType, ranks); - } - else - { - AST valuesRoot = getFirstChild().getNextSibling(); - if (valuesRoot != null) - { - ArrayList values = (ArrayList)((BaseNode)valuesRoot).GetValueInternal(context, evalContext); - return values.ToArray(arrayType); - } - } - - throw new ArgumentException("You have to specify either rank or initializer for an array."); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +using antlr.collections; +using Spring.Core.TypeResolution; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents parsed method node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class ArrayConstructorNode : NodeWithArguments + { + private Type arrayType; + + /// + /// Create a new instance + /// + public ArrayConstructorNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected ArrayConstructorNode(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + /// + /// Creates new instance of the type defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (arrayType == null) + { + lock (this) + { + if (arrayType == null) + { + arrayType = TypeResolutionUtils.ResolveType(getText()); + } + } + } + + AST rankRoot = getFirstChild(); + int dimensions = rankRoot.getNumberOfChildren(); + int[] ranks = new int[dimensions]; + if (dimensions > 0) + { + int i = 0; + AST rankNode = rankRoot.getFirstChild(); + while (rankNode != null) + { + ranks[i++] = (int)((BaseNode)rankNode).GetValueInternal(context, evalContext); + rankNode = rankNode.getNextSibling(); + } + return Array.CreateInstance(arrayType, ranks); + } + else + { + AST valuesRoot = getFirstChild().getNextSibling(); + if (valuesRoot != null) + { + ArrayList values = (ArrayList)((BaseNode)valuesRoot).GetValueInternal(context, evalContext); + return values.ToArray(arrayType); + } + } + + throw new ArgumentException("You have to specify either rank or initializer for an array."); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/AssignNode.cs b/src/Spring/Spring.Core/Expressions/AssignNode.cs index e16922fc..859f5bee 100644 --- a/src/Spring/Spring.Core/Expressions/AssignNode.cs +++ b/src/Spring/Spring.Core/Expressions/AssignNode.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents parsed assignment node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: AssignNode.cs,v 1.9 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public class AssignNode : BaseNode - { - /// - /// Create a new instance - /// - public AssignNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected AssignNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Assigns value of the right operand to the left one. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - AST left = getFirstChild(); - AST right = left.getNextSibling(); - - object result; - - if (right.getFirstChild() is LambdaExpressionNode) - { - if (!(left.getFirstChild() is VariableNode)) - { - throw new ArgumentException("Lambda expression can only be assigned to a global variable."); - } - result = right.getFirstChild(); - } - else - { - result = ((BaseNode)right).GetValueInternal(context, evalContext); - } - - ((BaseNode)left).SetValueInternal( context, evalContext, result ); - - return result; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents parsed assignment node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class AssignNode : BaseNode + { + /// + /// Create a new instance + /// + public AssignNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected AssignNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Assigns value of the right operand to the left one. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + AST left = getFirstChild(); + AST right = left.getNextSibling(); + + object result; + + if (right.getFirstChild() is LambdaExpressionNode) + { + if (!(left.getFirstChild() is VariableNode)) + { + throw new ArgumentException("Lambda expression can only be assigned to a global variable."); + } + result = right.getFirstChild(); + } + else + { + result = ((BaseNode)right).GetValueInternal(context, evalContext); + } + + ((BaseNode)left).SetValueInternal( context, evalContext, result ); + + return result; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/AttributeNode.cs b/src/Spring/Spring.Core/Expressions/AttributeNode.cs index e241cc3c..1e41557f 100644 --- a/src/Spring/Spring.Core/Expressions/AttributeNode.cs +++ b/src/Spring/Spring.Core/Expressions/AttributeNode.cs @@ -1,85 +1,84 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -using Spring.Core.TypeResolution; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents parsed attribute node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: AttributeNode.cs,v 1.9 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public class AttributeNode : ConstructorNode - { - /// - /// Create a new instance - /// - public AttributeNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected AttributeNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Tries to determine attribute type based on the specified - /// attribute type name. - /// - /// - /// Attribute type name to resolve. - /// - /// - /// Resolved attribute type. - /// - /// - /// If type cannot be resolved. - /// - protected override Type GetObjectType(string typeName) - { - Type type; - - try - { - type = base.GetObjectType(typeName); - } - catch (TypeLoadException) - { - if (typeName.EndsWith("Attribute")) - { - throw; - } - type = TypeResolutionUtils.ResolveType(typeName + "Attribute"); - } - - return type; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +using Spring.Core.TypeResolution; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents parsed attribute node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class AttributeNode : ConstructorNode + { + /// + /// Create a new instance + /// + public AttributeNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected AttributeNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Tries to determine attribute type based on the specified + /// attribute type name. + /// + /// + /// Attribute type name to resolve. + /// + /// + /// Resolved attribute type. + /// + /// + /// If type cannot be resolved. + /// + protected override Type GetObjectType(string typeName) + { + Type type; + + try + { + type = base.GetObjectType(typeName); + } + catch (TypeLoadException) + { + if (typeName.EndsWith("Attribute")) + { + throw; + } + type = TypeResolutionUtils.ResolveType(typeName + "Attribute"); + } + + return type; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/BaseNode.cs b/src/Spring/Spring.Core/Expressions/BaseNode.cs index 88d87ac2..f718529b 100644 --- a/src/Spring/Spring.Core/Expressions/BaseNode.cs +++ b/src/Spring/Spring.Core/Expressions/BaseNode.cs @@ -1,267 +1,266 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Base type for all expression nodes. - /// - /// Aleksandar Seovic - /// $Id: BaseNode.cs,v 1.24 2007/09/07 03:01:21 markpollack Exp $ - //[Serializable] - public abstract class BaseNode : SpringAST, IExpression - { - #region EvaluationContext class - - /// - /// Holds the state during evaluating an expression. - /// - public class EvaluationContext - { - #region Holder classes - - private class ThisContextHolder : IDisposable - { - private readonly EvaluationContext owner; - private readonly object savedThisContext; - - public ThisContextHolder(EvaluationContext owner) - { - this.owner = owner; - this.savedThisContext = owner.ThisContext; - } - - public void Dispose() - { - owner.ThisContext = savedThisContext; - } - } - - private class LocalVariablesHolder : IDisposable - { - private readonly EvaluationContext owner; - private readonly IDictionary savedLocalVariables; - - public LocalVariablesHolder(EvaluationContext owner, IDictionary newLocalVariables) - { - this.owner = owner; - this.savedLocalVariables = owner.LocalVariables; - owner.LocalVariables = newLocalVariables; - } - - public void Dispose() - { - owner.LocalVariables = savedLocalVariables; - } - } - - #endregion - - /// - /// Gets/Sets the root context of the current evaluation - /// - public object RootContext; - /// - /// Gets the type of the - /// - public Type RootContextType { get { return (RootContext == null) ? null : RootContext.GetType(); } } - /// - /// Gets/Sets the current context of the current evaluation - /// - public object ThisContext; - /// - /// Gets/Sets global variables of the current evaluation - /// - public IDictionary Variables; - /// - /// Gets/Sets local variables of the current evaluation - /// - public IDictionary LocalVariables; - - /// - /// Initializes a new EvaluationContext instance. - /// - /// The root context for this evaluation - /// dictionary of global variables used during this evaluation - public EvaluationContext(object rootContext, IDictionary globalVariables) - { - this.RootContext = rootContext; - this.ThisContext = rootContext; - this.Variables = globalVariables; - } - - /// - /// Switches current ThisContext. - /// - public IDisposable SwitchThisContext() - { - return new ThisContextHolder(this); - } - - /// - /// Switches current LocalVariables. - /// - public IDisposable SwitchLocalVariables(IDictionary newLocalVariables) - { - return new LocalVariablesHolder(this, newLocalVariables); - } - } - - #endregion - - /// - /// Create a new instance - /// - public BaseNode() - {} - - /// - /// Create a new instance from SerializationInfo - /// - protected BaseNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value. - /// - /// Node's value. - object IExpression.GetValue() - { - return GetValue(null, null); - } - - /// - /// Returns node's value for the given context. - /// - /// Object to evaluate node against. - /// Node's value. - object IExpression.GetValue(object context) - { - return GetValue(context, null); - } - - /// - /// Returns node's value for the given context. - /// - /// Object to evaluate node against. - /// Expression variables map. - /// Node's value. - object IExpression.GetValue(object context, IDictionary variables) - { - return GetValue(context, variables); - } - - /// - /// This is the entrypoint into evaluating this expression. - /// - private object GetValue(object context, IDictionary variables) - { - EvaluationContext evalContext = new EvaluationContext( context,variables ); - return Get( context, evalContext ); - } - - /// - /// Called internally during expression evaluation - /// - /// Object to evaluate node against. - /// Current expression evaluation context. - /// - protected internal object GetValueInternal(object context, EvaluationContext evalContext) - { - return Get(context, evalContext); - } - - /// - /// Returns node's value for the given context. - /// - /// Node's value. - protected abstract object Get(object context, EvaluationContext evalContext); - - /// - /// Sets node's value for the given context. - /// - /// Object to evaluate node against. - /// New value for this node. - void IExpression.SetValue(object context, object newValue) - { - SetValue(context, null, newValue); - } - - /// - /// Sets node's value for the given context. - /// - /// Object to evaluate node against. - /// Expression variables map. - /// New value for this node. - void IExpression.SetValue(object context, IDictionary variables, object newValue) - { - SetValue( context,variables,newValue ); - } - - /// - /// This is the entrypoint into evaluating this expression. - /// - private void SetValue(object context,IDictionary variables,object newValue) - { - EvaluationContext evalContext = new EvaluationContext( context,variables ); - Set( context, evalContext,newValue ); - } - - /// - /// Called internally during expression evaluation. - /// - protected internal void SetValueInternal(object context, EvaluationContext evalContext, object newValue) - { - Set(context, evalContext, newValue); - } - - /// - /// Sets node's value for the given context. - /// - /// - ///

- /// This is a default implementation of Set method, which - /// simply throws . - ///

- ///

- /// This was done in order to avoid redundant Set method implementations, - /// because most of the node types do not support value setting. - ///

- ///
- protected virtual void Set(object context, EvaluationContext evalContext, object newValue) - { - throw new NotSupportedException("You cannot set the value for the node of this type: [" + this.GetType().Name + "]."); - } - - /// - /// Returns a string representation of this node instance. - /// - public override string ToString() - { - return string.Format("{0}[{1}]", this.GetType().Name, base.GetHashCode()); - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Base type for all expression nodes. + /// + /// Aleksandar Seovic + //[Serializable] + public abstract class BaseNode : SpringAST, IExpression + { + #region EvaluationContext class + + /// + /// Holds the state during evaluating an expression. + /// + public class EvaluationContext + { + #region Holder classes + + private class ThisContextHolder : IDisposable + { + private readonly EvaluationContext owner; + private readonly object savedThisContext; + + public ThisContextHolder(EvaluationContext owner) + { + this.owner = owner; + this.savedThisContext = owner.ThisContext; + } + + public void Dispose() + { + owner.ThisContext = savedThisContext; + } + } + + private class LocalVariablesHolder : IDisposable + { + private readonly EvaluationContext owner; + private readonly IDictionary savedLocalVariables; + + public LocalVariablesHolder(EvaluationContext owner, IDictionary newLocalVariables) + { + this.owner = owner; + this.savedLocalVariables = owner.LocalVariables; + owner.LocalVariables = newLocalVariables; + } + + public void Dispose() + { + owner.LocalVariables = savedLocalVariables; + } + } + + #endregion + + /// + /// Gets/Sets the root context of the current evaluation + /// + public object RootContext; + /// + /// Gets the type of the + /// + public Type RootContextType { get { return (RootContext == null) ? null : RootContext.GetType(); } } + /// + /// Gets/Sets the current context of the current evaluation + /// + public object ThisContext; + /// + /// Gets/Sets global variables of the current evaluation + /// + public IDictionary Variables; + /// + /// Gets/Sets local variables of the current evaluation + /// + public IDictionary LocalVariables; + + /// + /// Initializes a new EvaluationContext instance. + /// + /// The root context for this evaluation + /// dictionary of global variables used during this evaluation + public EvaluationContext(object rootContext, IDictionary globalVariables) + { + this.RootContext = rootContext; + this.ThisContext = rootContext; + this.Variables = globalVariables; + } + + /// + /// Switches current ThisContext. + /// + public IDisposable SwitchThisContext() + { + return new ThisContextHolder(this); + } + + /// + /// Switches current LocalVariables. + /// + public IDisposable SwitchLocalVariables(IDictionary newLocalVariables) + { + return new LocalVariablesHolder(this, newLocalVariables); + } + } + + #endregion + + /// + /// Create a new instance + /// + public BaseNode() + {} + + /// + /// Create a new instance from SerializationInfo + /// + protected BaseNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns node's value. + /// + /// Node's value. + object IExpression.GetValue() + { + return GetValue(null, null); + } + + /// + /// Returns node's value for the given context. + /// + /// Object to evaluate node against. + /// Node's value. + object IExpression.GetValue(object context) + { + return GetValue(context, null); + } + + /// + /// Returns node's value for the given context. + /// + /// Object to evaluate node against. + /// Expression variables map. + /// Node's value. + object IExpression.GetValue(object context, IDictionary variables) + { + return GetValue(context, variables); + } + + /// + /// This is the entrypoint into evaluating this expression. + /// + private object GetValue(object context, IDictionary variables) + { + EvaluationContext evalContext = new EvaluationContext( context,variables ); + return Get( context, evalContext ); + } + + /// + /// Called internally during expression evaluation + /// + /// Object to evaluate node against. + /// Current expression evaluation context. + /// + protected internal object GetValueInternal(object context, EvaluationContext evalContext) + { + return Get(context, evalContext); + } + + /// + /// Returns node's value for the given context. + /// + /// Node's value. + protected abstract object Get(object context, EvaluationContext evalContext); + + /// + /// Sets node's value for the given context. + /// + /// Object to evaluate node against. + /// New value for this node. + void IExpression.SetValue(object context, object newValue) + { + SetValue(context, null, newValue); + } + + /// + /// Sets node's value for the given context. + /// + /// Object to evaluate node against. + /// Expression variables map. + /// New value for this node. + void IExpression.SetValue(object context, IDictionary variables, object newValue) + { + SetValue( context,variables,newValue ); + } + + /// + /// This is the entrypoint into evaluating this expression. + /// + private void SetValue(object context,IDictionary variables,object newValue) + { + EvaluationContext evalContext = new EvaluationContext( context,variables ); + Set( context, evalContext,newValue ); + } + + /// + /// Called internally during expression evaluation. + /// + protected internal void SetValueInternal(object context, EvaluationContext evalContext, object newValue) + { + Set(context, evalContext, newValue); + } + + /// + /// Sets node's value for the given context. + /// + /// + ///

+ /// This is a default implementation of Set method, which + /// simply throws . + ///

+ ///

+ /// This was done in order to avoid redundant Set method implementations, + /// because most of the node types do not support value setting. + ///

+ ///
+ protected virtual void Set(object context, EvaluationContext evalContext, object newValue) + { + throw new NotSupportedException("You cannot set the value for the node of this type: [" + this.GetType().Name + "]."); + } + + /// + /// Returns a string representation of this node instance. + /// + public override string ToString() + { + return string.Format("{0}[{1}]", this.GetType().Name, base.GetHashCode()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/BinaryOperator.cs b/src/Spring/Spring.Core/Expressions/BinaryOperator.cs index 0136a374..541b158f 100644 --- a/src/Spring/Spring.Core/Expressions/BinaryOperator.cs +++ b/src/Spring/Spring.Core/Expressions/BinaryOperator.cs @@ -1,65 +1,64 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Base class for unary operators. - /// - /// Aleksandar Seovic - /// $Id: BinaryOperator.cs,v 1.8 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public abstract class BinaryOperator : BaseNode - { - /// - /// Create a new instance - /// - public BinaryOperator() - {} - - /// - /// Create a new instance from SerializationInfo - /// - protected BinaryOperator(SerializationInfo info, StreamingContext context) - : base(info, context) - {} - - /// - /// Gets the left operand. - /// - /// The left operand. - public BaseNode Left - { - get { return (BaseNode) this.getFirstChild(); } - } - - /// - /// Gets the right operand. - /// - /// The right operand. - public BaseNode Right - { - get { return (BaseNode) this.getFirstChild().getNextSibling(); } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Base class for unary operators. + /// + /// Aleksandar Seovic + [Serializable] + public abstract class BinaryOperator : BaseNode + { + /// + /// Create a new instance + /// + public BinaryOperator() + {} + + /// + /// Create a new instance from SerializationInfo + /// + protected BinaryOperator(SerializationInfo info, StreamingContext context) + : base(info, context) + {} + + /// + /// Gets the left operand. + /// + /// The left operand. + public BaseNode Left + { + get { return (BaseNode) this.getFirstChild(); } + } + + /// + /// Gets the right operand. + /// + /// The right operand. + public BaseNode Right + { + get { return (BaseNode) this.getFirstChild().getNextSibling(); } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/BooleanLiteralNode.cs b/src/Spring/Spring.Core/Expressions/BooleanLiteralNode.cs index 77660747..cc01f0aa 100644 --- a/src/Spring/Spring.Core/Expressions/BooleanLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/BooleanLiteralNode.cs @@ -1,74 +1,73 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed boolean literal node. - /// - /// Aleksandar Seovic - /// $Id: BooleanLiteralNode.cs,v 1.9 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public class BooleanLiteralNode : BaseNode - { - private object nodeValue; - - /// - /// Create a new instance - /// - public BooleanLiteralNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected BooleanLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the boolean literal node. - /// - /// - /// This is the entrypoint into evaluating this expression. - /// - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (nodeValue == null) - { - lock(this) - { - if (nodeValue == null) - { - nodeValue = Boolean.Parse(this.getText()); - } - } - } - - return nodeValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed boolean literal node. + /// + /// Aleksandar Seovic + [Serializable] + public class BooleanLiteralNode : BaseNode + { + private object nodeValue; + + /// + /// Create a new instance + /// + public BooleanLiteralNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected BooleanLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the boolean literal node. + /// + /// + /// This is the entrypoint into evaluating this expression. + /// + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (nodeValue == null) + { + lock(this) + { + if (nodeValue == null) + { + nodeValue = Boolean.Parse(this.getText()); + } + } + } + + return nodeValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ConstructorNode.cs b/src/Spring/Spring.Core/Expressions/ConstructorNode.cs index d43b39a4..7f57e604 100644 --- a/src/Spring/Spring.Core/Expressions/ConstructorNode.cs +++ b/src/Spring/Spring.Core/Expressions/ConstructorNode.cs @@ -1,208 +1,207 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.Serialization; - -using Spring.Core.TypeResolution; -using Spring.Util; -using Spring.Reflection.Dynamic; - -namespace Spring.Expressions -{ - /// - /// Represents parsed method node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: ConstructorNode.cs,v 1.16 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public class ConstructorNode : NodeWithArguments - { - private SafeConstructor constructor; - private IDictionary namedArgs; - private bool isParamArray = false; - private Type paramArrayType; - private int argumentCount; - - /// - /// Create a new instance - /// - public ConstructorNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected ConstructorNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Creates new instance of the type defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object[] argValues = ResolveArguments(evalContext); - IDictionary namedArgValues = ResolveNamedArguments(evalContext); - - if (constructor == null) - { - lock(this) - { - if (constructor == null) - { - constructor = InitializeNode(argValues, namedArgValues); - } - } - } - - object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues); - object instance = constructor.Invoke(paramValues); - if (namedArgValues != null) - { - SetNamedArguments(instance, namedArgValues); - } - - return instance; - } - - /// - /// Determines the type of object that should be instantiated. - /// - /// - /// The type name to resolve. - /// - /// - /// The type of object that should be instantiated. - /// - /// - /// If the type cannot be resolved. - /// - protected virtual Type GetObjectType(string typeName) - { - return TypeResolutionUtils.ResolveType(typeName); - } - - /// - /// Initializes this node by caching necessary constructor and property info. - /// - /// - /// - private SafeConstructor InitializeNode(object[] argValues, IDictionary namedArgValues) - { - SafeConstructor ctor = null; - Type objectType = GetObjectType(this.getText().Trim()); - - // cache constructor info - ConstructorInfo ci = GetBestConstructor(objectType, argValues); - if (ci == null) - { - throw new ArgumentException( - String.Format("Constructor for the type [{0}] with a specified " + - "number and types of arguments does not exist.", - objectType.FullName)); - } - else - { - ParameterInfo[] parameters = ci.GetParameters(); - if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; - if (isParamArray) - { - paramArrayType = lastParameter.ParameterType.GetElementType(); - argumentCount = parameters.Length; - } - } - ctor = new SafeConstructor(ci); - } - - // cache named args info - if (namedArgValues != null) - { - namedArgs = new Hashtable(namedArgValues.Count); - foreach (string name in namedArgValues.Keys) - { - this.namedArgs[name] = Expression.ParseProperty(name); - } - } - - return ctor; - } - - /// - /// Sets the named arguments (properties). - /// - /// Instance to set property values on. - /// Argument (property) name to value mappings. - private void SetNamedArguments(object instance, IDictionary namedArgValues) - { - foreach (string name in namedArgValues.Keys) - { - IExpression property = (IExpression) namedArgs[name]; - property.SetValue(instance, namedArgValues[name]); - } - } - - private static ConstructorInfo GetBestConstructor(Type type, object[] argValues) - { - ConstructorInfo[] candidates = GetCandidateConstructors(type, argValues.Length); - if (candidates.Length > 0) - { - return ReflectionUtils.GetConstructorByArgumentValues(candidates, argValues); - } - return null; - } - - private static ConstructorInfo[] GetCandidateConstructors(Type type, int argCount) - { - ConstructorInfo[] ctors = type.GetConstructors(); - ArrayList matches = new ArrayList(); - - foreach (ConstructorInfo ctor in ctors) - { - ParameterInfo[] parameters = ctor.GetParameters(); - if (parameters.Length == argCount) - { - matches.Add(ctor); - } - else if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) - { - matches.Add(ctor); - } - } - } - - return (ConstructorInfo[]) matches.ToArray(typeof(ConstructorInfo)); - } - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.Serialization; + +using Spring.Core.TypeResolution; +using Spring.Util; +using Spring.Reflection.Dynamic; + +namespace Spring.Expressions +{ + /// + /// Represents parsed method node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class ConstructorNode : NodeWithArguments + { + private SafeConstructor constructor; + private IDictionary namedArgs; + private bool isParamArray = false; + private Type paramArrayType; + private int argumentCount; + + /// + /// Create a new instance + /// + public ConstructorNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected ConstructorNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Creates new instance of the type defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object[] argValues = ResolveArguments(evalContext); + IDictionary namedArgValues = ResolveNamedArguments(evalContext); + + if (constructor == null) + { + lock(this) + { + if (constructor == null) + { + constructor = InitializeNode(argValues, namedArgValues); + } + } + } + + object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues); + object instance = constructor.Invoke(paramValues); + if (namedArgValues != null) + { + SetNamedArguments(instance, namedArgValues); + } + + return instance; + } + + /// + /// Determines the type of object that should be instantiated. + /// + /// + /// The type name to resolve. + /// + /// + /// The type of object that should be instantiated. + /// + /// + /// If the type cannot be resolved. + /// + protected virtual Type GetObjectType(string typeName) + { + return TypeResolutionUtils.ResolveType(typeName); + } + + /// + /// Initializes this node by caching necessary constructor and property info. + /// + /// + /// + private SafeConstructor InitializeNode(object[] argValues, IDictionary namedArgValues) + { + SafeConstructor ctor = null; + Type objectType = GetObjectType(this.getText().Trim()); + + // cache constructor info + ConstructorInfo ci = GetBestConstructor(objectType, argValues); + if (ci == null) + { + throw new ArgumentException( + String.Format("Constructor for the type [{0}] with a specified " + + "number and types of arguments does not exist.", + objectType.FullName)); + } + else + { + ParameterInfo[] parameters = ci.GetParameters(); + if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; + if (isParamArray) + { + paramArrayType = lastParameter.ParameterType.GetElementType(); + argumentCount = parameters.Length; + } + } + ctor = new SafeConstructor(ci); + } + + // cache named args info + if (namedArgValues != null) + { + namedArgs = new Hashtable(namedArgValues.Count); + foreach (string name in namedArgValues.Keys) + { + this.namedArgs[name] = Expression.ParseProperty(name); + } + } + + return ctor; + } + + /// + /// Sets the named arguments (properties). + /// + /// Instance to set property values on. + /// Argument (property) name to value mappings. + private void SetNamedArguments(object instance, IDictionary namedArgValues) + { + foreach (string name in namedArgValues.Keys) + { + IExpression property = (IExpression) namedArgs[name]; + property.SetValue(instance, namedArgValues[name]); + } + } + + private static ConstructorInfo GetBestConstructor(Type type, object[] argValues) + { + ConstructorInfo[] candidates = GetCandidateConstructors(type, argValues.Length); + if (candidates.Length > 0) + { + return ReflectionUtils.GetConstructorByArgumentValues(candidates, argValues); + } + return null; + } + + private static ConstructorInfo[] GetCandidateConstructors(Type type, int argCount) + { + ConstructorInfo[] ctors = type.GetConstructors(); + ArrayList matches = new ArrayList(); + + foreach (ConstructorInfo ctor in ctors) + { + ParameterInfo[] parameters = ctor.GetParameters(); + if (parameters.Length == argCount) + { + matches.Add(ctor); + } + else if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) + { + matches.Add(ctor); + } + } + } + + return (ConstructorInfo[]) matches.ToArray(typeof(ConstructorInfo)); + } + + } +} diff --git a/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs b/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs index 90115ecb..84820472 100644 --- a/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs @@ -1,85 +1,84 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents parsed node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: DateLiteralNode.cs,v 1.7 2007/09/07 03:01:21 markpollack Exp $ - [Serializable] - public class DateLiteralNode : BaseNode - { - private object nodeValue; - - /// - /// Create a new instance - /// - public DateLiteralNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected DateLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (nodeValue == null) - { - lock (this) - { - if (nodeValue == null) - { - AST dateString = this.getFirstChild(); - if (getNumberOfChildren() == 2) - { - AST dateFormat = dateString.getNextSibling(); - nodeValue = - DateTime.ParseExact(dateString.getText(), dateFormat.getText(), - CultureInfo.InvariantCulture); - } - else - { - nodeValue = DateTime.Parse(dateString.getText()); - } - } - } - } - return nodeValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents parsed node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class DateLiteralNode : BaseNode + { + private object nodeValue; + + /// + /// Create a new instance + /// + public DateLiteralNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected DateLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (nodeValue == null) + { + lock (this) + { + if (nodeValue == null) + { + AST dateString = this.getFirstChild(); + if (getNumberOfChildren() == 2) + { + AST dateFormat = dateString.getNextSibling(); + nodeValue = + DateTime.ParseExact(dateString.getText(), dateFormat.getText(), + CultureInfo.InvariantCulture); + } + else + { + nodeValue = DateTime.Parse(dateString.getText()); + } + } + } + } + return nodeValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/DefaultNode.cs b/src/Spring/Spring.Core/Expressions/DefaultNode.cs index cfda1b04..38b81233 100644 --- a/src/Spring/Spring.Core/Expressions/DefaultNode.cs +++ b/src/Spring/Spring.Core/Expressions/DefaultNode.cs @@ -1,63 +1,62 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed default node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: DefaultNode.cs,v 1.3 2007/09/07 03:01:24 markpollack Exp $ - [Serializable] - public class DefaultNode : BinaryOperator - { - /// - /// Create a new instance - /// - public DefaultNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected DefaultNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns left operand if it is not null, or the right operand if it is. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal(context, evalContext); - object right = Right.GetValueInternal(context, evalContext); - - return (left != null ? left : right); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed default node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class DefaultNode : BinaryOperator + { + /// + /// Create a new instance + /// + public DefaultNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected DefaultNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns left operand if it is not null, or the right operand if it is. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal(context, evalContext); + object right = Right.GetValueInternal(context, evalContext); + + return (left != null ? left : right); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Expression.cs b/src/Spring/Spring.Core/Expressions/Expression.cs index a646ae62..3bd00647 100644 --- a/src/Spring/Spring.Core/Expressions/Expression.cs +++ b/src/Spring/Spring.Core/Expressions/Expression.cs @@ -1,285 +1,284 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization; -using antlr; -using antlr.collections; -using Spring.Core; -using Spring.Util; -using StringUtils=Spring.Util.StringUtils; - -namespace Spring.Expressions -{ - /// - /// Container object for the parsed expression. - /// - /// - ///

- /// Preparing this object once and reusing it many times for expression - /// evaluation can result in significant performance improvements, as - /// expression parsing and reflection lookups are only performed once. - ///

- ///
- /// Aleksandar Seovic - /// $Id: Expression.cs,v 1.19 2008/03/20 10:35:54 oakinger Exp $ - [Serializable] - public class Expression : BaseNode - { - /// - /// Contains a list of reserved variable names. - /// You must not use any variable names with the reserved prefix! - /// - public class ReservedVariableNames - { - /// - /// Variable Names using this prefix are reserved for internal framework use - /// - public static readonly string RESERVEDPREFIX = "____spring_"; - - /// - /// variable name of the currently processed object factory, if any - /// - internal static readonly string CurrentObjectFactory = RESERVEDPREFIX + "CurrentObjectFactory"; - } - - private class SpringASTFactory : ASTFactory - { - public SpringASTFactory(Type t) : base(t.FullName) - { - base.defaultASTNodeTypeObject_ = t; - base.typename2creator_ = new Hashtable(32, 0.3f); - base.typename2creator_[t.FullName] = SpringAST.Creator; - } - } - - private class SpringExpressionParser : ExpressionParser - { - public SpringExpressionParser(TokenStream lexer) - : base(lexer) - { - base.astFactory = new SpringASTFactory(typeof(SpringAST)); - base.initialize(); - } - } - - static Expression() - { - // Ensure antlr is loaded (fixes GAC issues)! - Assembly antlrAss = typeof(antlr.LLkParser).Assembly; - } - - /// - /// Initializes a new instance of the class - /// by parsing specified expression string. - /// - /// Expression to parse. - public static IExpression Parse(string expression) - { - if (StringUtils.HasText(expression)) - { - ExpressionLexer lexer = new ExpressionLexer(new StringReader(expression)); - ExpressionParser parser = new SpringExpressionParser(lexer); - - parser.expr(); - - return (IExpression) parser.getAST(); - } - else - { - return new Expression(); - } - } - - /// - /// Registers lambda expression under the specified . - /// - /// Function name to register expression as. - /// Lambda expression to register. - /// Variables dictionary that the function will be registered in. - public static void RegisterFunction(string functionName, string lambdaExpression, IDictionary variables) - { - AssertUtils.ArgumentHasText(functionName, "functionName"); - AssertUtils.ArgumentHasText(lambdaExpression, "lambdaExpression"); - - ExpressionLexer lexer = new ExpressionLexer(new StringReader(lambdaExpression)); - ExpressionParser parser = new SpringExpressionParser(lexer); - - parser.lambda(); - variables[functionName] = parser.getAST(); - } - - /// - /// Initializes a new instance of the class - /// by parsing specified primary expression string. - /// - /// Primary expression to parse. - internal static IExpression ParsePrimary(string expression) - { - if (StringUtils.HasText(expression)) - { - ExpressionLexer lexer = new ExpressionLexer(new StringReader(expression)); - ExpressionParser parser = new SpringExpressionParser(lexer); - - parser.primaryExpression(); - return (IExpression) parser.getAST(); - } - else - { - return new Expression(); - } - } - - /// - /// Initializes a new instance of the class - /// by parsing specified property expression string. - /// - /// Property expression to parse. - internal static IExpression ParseProperty(string expression) - { - if (StringUtils.HasText(expression)) - { - ExpressionLexer lexer = new ExpressionLexer(new StringReader(expression)); - ExpressionParser parser = new SpringExpressionParser(lexer); - - parser.property(); - return (IExpression) parser.getAST(); - } - else - { - return new Expression(); - } - } - - /// - /// Initializes a new instance of the class. - /// - public Expression() - {} - - /// - /// Create a new instance from SerializationInfo - /// - protected Expression(SerializationInfo info, StreamingContext context) - : base(info, context) - {} - - /// - /// Evaluates this expression for the specified root object and returns - /// value of the last node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Value of the last node. - protected override object Get(object context, EvaluationContext evalContext) - { - object result = context; - - if (this.getNumberOfChildren() > 0) - { - AST node = this.getFirstChild(); - while (node != null) - { - result = ((BaseNode)node).GetValueInternal( result, evalContext ); - - node = node.getNextSibling(); - } - } - - return result; - } - - /// - /// Evaluates this expression for the specified root object and sets - /// value of the last node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Value to set last node to. - /// If navigation expression is empty. - protected override void Set(object context, EvaluationContext evalContext, object newValue) - { - object target = context; - - if (this.getNumberOfChildren() > 0) - { - AST node = this.getFirstChild(); - - for (int i = 0; i < this.getNumberOfChildren() - 1; i++) - { - try - { - target = ((BaseNode) node).GetValueInternal(target, evalContext); - node = node.getNextSibling(); - } - catch (NotReadablePropertyException e) - { - throw new NotWritablePropertyException("Cannot read the value of '" + node.getText() + "' property in the expression.", e); - } - } - ((BaseNode) node).SetValueInternal(target, evalContext, newValue); - } - else - { - throw new NotSupportedException("You cannot set the value for an empty expression."); - } - } - - /// - /// Evaluates this expression for the specified root object and returns - /// of the last node, if possible. - /// - /// Context to evaluate expression against. - /// Expression variables map. - /// Value of the last node. - internal PropertyInfo GetPropertyInfo(object context, IDictionary variables) - { - if (this.getNumberOfChildren() > 0) - { - object target = context; - AST node = this.getFirstChild(); - - for (int i = 0; i < this.getNumberOfChildren() - 1; i++) - { - target = ((IExpression) node).GetValue(target, variables); - node = node.getNextSibling(); - } - - if (node is PropertyOrFieldNode) - { - return (PropertyInfo) ((PropertyOrFieldNode) node).GetMemberInfo(target); - } - else if (node is IndexerNode) - { - return ((IndexerNode)node).GetPropertyInfo(target, variables); - } - else - { - throw new FatalReflectionException("Cannot obtain PropertyInfo from an expression that does not resolve to a property or an indexer."); - } - } - - throw new FatalReflectionException("Cannot obtain PropertyInfo for empty property name."); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.IO; +using System.Reflection; +using System.Runtime.Serialization; +using antlr; +using antlr.collections; +using Spring.Core; +using Spring.Util; +using StringUtils=Spring.Util.StringUtils; + +namespace Spring.Expressions +{ + /// + /// Container object for the parsed expression. + /// + /// + ///

+ /// Preparing this object once and reusing it many times for expression + /// evaluation can result in significant performance improvements, as + /// expression parsing and reflection lookups are only performed once. + ///

+ ///
+ /// Aleksandar Seovic + [Serializable] + public class Expression : BaseNode + { + /// + /// Contains a list of reserved variable names. + /// You must not use any variable names with the reserved prefix! + /// + public class ReservedVariableNames + { + /// + /// Variable Names using this prefix are reserved for internal framework use + /// + public static readonly string RESERVEDPREFIX = "____spring_"; + + /// + /// variable name of the currently processed object factory, if any + /// + internal static readonly string CurrentObjectFactory = RESERVEDPREFIX + "CurrentObjectFactory"; + } + + private class SpringASTFactory : ASTFactory + { + public SpringASTFactory(Type t) : base(t.FullName) + { + base.defaultASTNodeTypeObject_ = t; + base.typename2creator_ = new Hashtable(32, 0.3f); + base.typename2creator_[t.FullName] = SpringAST.Creator; + } + } + + private class SpringExpressionParser : ExpressionParser + { + public SpringExpressionParser(TokenStream lexer) + : base(lexer) + { + base.astFactory = new SpringASTFactory(typeof(SpringAST)); + base.initialize(); + } + } + + static Expression() + { + // Ensure antlr is loaded (fixes GAC issues)! + Assembly antlrAss = typeof(antlr.LLkParser).Assembly; + } + + /// + /// Initializes a new instance of the class + /// by parsing specified expression string. + /// + /// Expression to parse. + public static IExpression Parse(string expression) + { + if (StringUtils.HasText(expression)) + { + ExpressionLexer lexer = new ExpressionLexer(new StringReader(expression)); + ExpressionParser parser = new SpringExpressionParser(lexer); + + parser.expr(); + + return (IExpression) parser.getAST(); + } + else + { + return new Expression(); + } + } + + /// + /// Registers lambda expression under the specified . + /// + /// Function name to register expression as. + /// Lambda expression to register. + /// Variables dictionary that the function will be registered in. + public static void RegisterFunction(string functionName, string lambdaExpression, IDictionary variables) + { + AssertUtils.ArgumentHasText(functionName, "functionName"); + AssertUtils.ArgumentHasText(lambdaExpression, "lambdaExpression"); + + ExpressionLexer lexer = new ExpressionLexer(new StringReader(lambdaExpression)); + ExpressionParser parser = new SpringExpressionParser(lexer); + + parser.lambda(); + variables[functionName] = parser.getAST(); + } + + /// + /// Initializes a new instance of the class + /// by parsing specified primary expression string. + /// + /// Primary expression to parse. + internal static IExpression ParsePrimary(string expression) + { + if (StringUtils.HasText(expression)) + { + ExpressionLexer lexer = new ExpressionLexer(new StringReader(expression)); + ExpressionParser parser = new SpringExpressionParser(lexer); + + parser.primaryExpression(); + return (IExpression) parser.getAST(); + } + else + { + return new Expression(); + } + } + + /// + /// Initializes a new instance of the class + /// by parsing specified property expression string. + /// + /// Property expression to parse. + internal static IExpression ParseProperty(string expression) + { + if (StringUtils.HasText(expression)) + { + ExpressionLexer lexer = new ExpressionLexer(new StringReader(expression)); + ExpressionParser parser = new SpringExpressionParser(lexer); + + parser.property(); + return (IExpression) parser.getAST(); + } + else + { + return new Expression(); + } + } + + /// + /// Initializes a new instance of the class. + /// + public Expression() + {} + + /// + /// Create a new instance from SerializationInfo + /// + protected Expression(SerializationInfo info, StreamingContext context) + : base(info, context) + {} + + /// + /// Evaluates this expression for the specified root object and returns + /// value of the last node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Value of the last node. + protected override object Get(object context, EvaluationContext evalContext) + { + object result = context; + + if (this.getNumberOfChildren() > 0) + { + AST node = this.getFirstChild(); + while (node != null) + { + result = ((BaseNode)node).GetValueInternal( result, evalContext ); + + node = node.getNextSibling(); + } + } + + return result; + } + + /// + /// Evaluates this expression for the specified root object and sets + /// value of the last node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Value to set last node to. + /// If navigation expression is empty. + protected override void Set(object context, EvaluationContext evalContext, object newValue) + { + object target = context; + + if (this.getNumberOfChildren() > 0) + { + AST node = this.getFirstChild(); + + for (int i = 0; i < this.getNumberOfChildren() - 1; i++) + { + try + { + target = ((BaseNode) node).GetValueInternal(target, evalContext); + node = node.getNextSibling(); + } + catch (NotReadablePropertyException e) + { + throw new NotWritablePropertyException("Cannot read the value of '" + node.getText() + "' property in the expression.", e); + } + } + ((BaseNode) node).SetValueInternal(target, evalContext, newValue); + } + else + { + throw new NotSupportedException("You cannot set the value for an empty expression."); + } + } + + /// + /// Evaluates this expression for the specified root object and returns + /// of the last node, if possible. + /// + /// Context to evaluate expression against. + /// Expression variables map. + /// Value of the last node. + internal PropertyInfo GetPropertyInfo(object context, IDictionary variables) + { + if (this.getNumberOfChildren() > 0) + { + object target = context; + AST node = this.getFirstChild(); + + for (int i = 0; i < this.getNumberOfChildren() - 1; i++) + { + target = ((IExpression) node).GetValue(target, variables); + node = node.getNextSibling(); + } + + if (node is PropertyOrFieldNode) + { + return (PropertyInfo) ((PropertyOrFieldNode) node).GetMemberInfo(target); + } + else if (node is IndexerNode) + { + return ((IndexerNode)node).GetPropertyInfo(target, variables); + } + else + { + throw new FatalReflectionException("Cannot obtain PropertyInfo from an expression that does not resolve to a property or an indexer."); + } + } + + throw new FatalReflectionException("Cannot obtain PropertyInfo for empty property name."); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ExpressionConverter.cs b/src/Spring/Spring.Core/Expressions/ExpressionConverter.cs index 3550bbcf..75eab3b0 100644 --- a/src/Spring/Spring.Core/Expressions/ExpressionConverter.cs +++ b/src/Spring/Spring.Core/Expressions/ExpressionConverter.cs @@ -1,87 +1,86 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using System.Globalization; - -using Spring.Expressions; - -#endregion - -namespace Spring.Expressions -{ - /// - /// Converts string representation of expression into an instance of . - /// - /// Aleksandar Seovic - /// $Id: ExpressionConverter.cs,v 1.1 2007/07/31 02:13:52 markpollack Exp $ - public class ExpressionConverter : TypeConverter - { - /// - /// Can we convert from a the sourcetype to a ? - /// - /// - ///

- /// Currently only supports conversion from a instance. - ///

- ///
- /// - /// A - /// that provides a format context. - /// - /// - /// A that represents the - /// you want to convert from. - /// - /// if the conversion is possible. - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - return (sourceType == typeof(string)); - } - - /// - /// Convert from a value to an - /// instance. - /// - /// - /// A - /// that provides a format context. - /// - /// - /// The to use - /// as the current culture. - /// - /// - /// The value that is to be converted. - /// - /// - /// A array if successful. - /// - public override object ConvertFrom( - ITypeDescriptorContext context, CultureInfo culture, object value) - { - return Expression.Parse(value as string); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using System.Globalization; + +using Spring.Expressions; + +#endregion + +namespace Spring.Expressions +{ + /// + /// Converts string representation of expression into an instance of . + /// + /// Aleksandar Seovic + public class ExpressionConverter : TypeConverter + { + /// + /// Can we convert from a the sourcetype to a ? + /// + /// + ///

+ /// Currently only supports conversion from a instance. + ///

+ ///
+ /// + /// A + /// that provides a format context. + /// + /// + /// A that represents the + /// you want to convert from. + /// + /// if the conversion is possible. + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + return (sourceType == typeof(string)); + } + + /// + /// Convert from a value to an + /// instance. + /// + /// + /// A + /// that provides a format context. + /// + /// + /// The to use + /// as the current culture. + /// + /// + /// The value that is to be converted. + /// + /// + /// A array if successful. + /// + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object value) + { + return Expression.Parse(value as string); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ExpressionEvaluator.cs b/src/Spring/Spring.Core/Expressions/ExpressionEvaluator.cs index e768a04a..11fd3f42 100644 --- a/src/Spring/Spring.Core/Expressions/ExpressionEvaluator.cs +++ b/src/Spring/Spring.Core/Expressions/ExpressionEvaluator.cs @@ -1,98 +1,97 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Expressions -{ - /// - /// Utility class that enables easy expression evaluation. - /// - /// - ///

- /// This class allows users to get or set properties, execute methods, and evaluate - /// logical and arithmetic expressions. - ///

- ///

- /// Methods in this class parse expression on every invocation. - /// If you plan to reuse the same expression many times, you should prepare - /// the expression once using the static method, - /// and then call to evaluate it. - ///

- ///

- /// This can result in significant performance improvements as it avoids expression - /// parsing and node resolution every time it is called. - ///

- ///

- ///

- ///
- /// Aleksandar Seovic - /// $Id: ExpressionEvaluator.cs,v 1.2 2006/04/09 07:18:39 markpollack Exp $ - public class ExpressionEvaluator - { - /// - /// Parses and evaluates specified expression. - /// - /// Root object. - /// Expression to evaluate. - /// Value of the last node in the expression. - public static object GetValue(object root, string expression) - { - return Expression.Parse(expression).GetValue(root, null); - } - - /// - /// Parses and evaluates specified expression. - /// - /// Root object. - /// Expression to evaluate. - /// Expression variables map. - /// Value of the last node in the expression. - public static object GetValue(object root, string expression, IDictionary variables) - { - return Expression.Parse(expression).GetValue(root, variables); - } - - /// - /// Parses and specified expression and sets the value of the - /// last node to the value of the newValue parameter. - /// - /// Root object. - /// Expression to evaluate. - /// Value to set last node to. - public static void SetValue(object root, string expression, object newValue) - { - Expression.Parse(expression).SetValue(root, null, newValue); - } - - /// - /// Parses and specified expression and sets the value of the - /// last node to the value of the newValue parameter. - /// - /// Root object. - /// Expression to evaluate. - /// Expression variables map. - /// Value to set last node to. - public static void SetValue(object root, string expression, IDictionary variables, object newValue) - { - Expression.Parse(expression).SetValue(root, variables, newValue); - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Expressions +{ + /// + /// Utility class that enables easy expression evaluation. + /// + /// + ///

+ /// This class allows users to get or set properties, execute methods, and evaluate + /// logical and arithmetic expressions. + ///

+ ///

+ /// Methods in this class parse expression on every invocation. + /// If you plan to reuse the same expression many times, you should prepare + /// the expression once using the static method, + /// and then call to evaluate it. + ///

+ ///

+ /// This can result in significant performance improvements as it avoids expression + /// parsing and node resolution every time it is called. + ///

+ ///

+ ///

+ ///
+ /// Aleksandar Seovic + public class ExpressionEvaluator + { + /// + /// Parses and evaluates specified expression. + /// + /// Root object. + /// Expression to evaluate. + /// Value of the last node in the expression. + public static object GetValue(object root, string expression) + { + return Expression.Parse(expression).GetValue(root, null); + } + + /// + /// Parses and evaluates specified expression. + /// + /// Root object. + /// Expression to evaluate. + /// Expression variables map. + /// Value of the last node in the expression. + public static object GetValue(object root, string expression, IDictionary variables) + { + return Expression.Parse(expression).GetValue(root, variables); + } + + /// + /// Parses and specified expression and sets the value of the + /// last node to the value of the newValue parameter. + /// + /// Root object. + /// Expression to evaluate. + /// Value to set last node to. + public static void SetValue(object root, string expression, object newValue) + { + Expression.Parse(expression).SetValue(root, null, newValue); + } + + /// + /// Parses and specified expression and sets the value of the + /// last node to the value of the newValue parameter. + /// + /// Root object. + /// Expression to evaluate. + /// Expression variables map. + /// Value to set last node to. + public static void SetValue(object root, string expression, IDictionary variables, object newValue) + { + Expression.Parse(expression).SetValue(root, variables, newValue); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ExpressionListNode.cs b/src/Spring/Spring.Core/Expressions/ExpressionListNode.cs index a59771b3..f7c4177f 100644 --- a/src/Spring/Spring.Core/Expressions/ExpressionListNode.cs +++ b/src/Spring/Spring.Core/Expressions/ExpressionListNode.cs @@ -1,69 +1,68 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents parsed expression list node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: ExpressionListNode.cs,v 1.6 2007/09/07 03:01:24 markpollack Exp $ - [Serializable] - public class ExpressionListNode : BaseNode - { - /// - /// Create a new instance - /// - public ExpressionListNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected ExpressionListNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a result of the last expression in a list. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Result of the last expression in a list - protected override object Get(object context, EvaluationContext evalContext) - { - object result = context; - - AST node = this.getFirstChild(); - while (node != null) - { - result = ((BaseNode) node).GetValueInternal(context, evalContext); - node = node.getNextSibling(); - } - return result; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents parsed expression list node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class ExpressionListNode : BaseNode + { + /// + /// Create a new instance + /// + public ExpressionListNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected ExpressionListNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a result of the last expression in a list. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Result of the last expression in a list + protected override object Get(object context, EvaluationContext evalContext) + { + object result = context; + + AST node = this.getFirstChild(); + while (node != null) + { + result = ((BaseNode) node).GetValueInternal(context, evalContext); + node = node.getNextSibling(); + } + return result; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/FunctionNode.cs b/src/Spring/Spring.Core/Expressions/FunctionNode.cs index b7b4f369..5846f5aa 100644 --- a/src/Spring/Spring.Core/Expressions/FunctionNode.cs +++ b/src/Spring/Spring.Core/Expressions/FunctionNode.cs @@ -1,93 +1,92 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed function node. - /// - /// Aleksandar Seovic - /// $Id: FunctionNode.cs,v 1.7 2008/03/20 23:58:16 oakinger Exp $ - [Serializable] - public class FunctionNode : NodeWithArguments - { - /// - /// Create a new instance - /// - public FunctionNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected FunctionNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Evaluates function represented by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Result of the function evaluation. - protected override object Get(object context, EvaluationContext evalContext) - { - string name = this.getText(); - LambdaExpressionNode lambda = evalContext.Variables[name] as LambdaExpressionNode; - Delegate function = evalContext.Variables[name] as Delegate; - - if (lambda == null && function == null) - { - throw new InvalidOperationException("Function '" + name + "' is not defined."); - } - - object[] argValues = ResolveArguments(evalContext); - - // delegate? - if (function != null) - { - return function.DynamicInvoke(argValues); - } - - // lambda! - string[] argNames = lambda.ArgumentNames; - - if (argValues.Length != argNames.Length) - { - throw new InvalidOperationException( - "Function '" + name + "' requires " + argNames.Length + " arguments."); - } - - IDictionary arguments = new Hashtable(); - for (int i = 0; i < argValues.Length; i++) - { - arguments[argNames[i]] = argValues[i]; - } - - return lambda.GetValueInternal(context, evalContext, arguments); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed function node. + /// + /// Aleksandar Seovic + [Serializable] + public class FunctionNode : NodeWithArguments + { + /// + /// Create a new instance + /// + public FunctionNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected FunctionNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Evaluates function represented by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Result of the function evaluation. + protected override object Get(object context, EvaluationContext evalContext) + { + string name = this.getText(); + LambdaExpressionNode lambda = evalContext.Variables[name] as LambdaExpressionNode; + Delegate function = evalContext.Variables[name] as Delegate; + + if (lambda == null && function == null) + { + throw new InvalidOperationException("Function '" + name + "' is not defined."); + } + + object[] argValues = ResolveArguments(evalContext); + + // delegate? + if (function != null) + { + return function.DynamicInvoke(argValues); + } + + // lambda! + string[] argNames = lambda.ArgumentNames; + + if (argValues.Length != argNames.Length) + { + throw new InvalidOperationException( + "Function '" + name + "' requires " + argNames.Length + " arguments."); + } + + IDictionary arguments = new Hashtable(); + for (int i = 0; i < argValues.Length; i++) + { + arguments[argNames[i]] = argValues[i]; + } + + return lambda.GetValueInternal(context, evalContext, arguments); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/HexLiteralNode.cs b/src/Spring/Spring.Core/Expressions/HexLiteralNode.cs index 6e863d88..f9de2fc7 100644 --- a/src/Spring/Spring.Core/Expressions/HexLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/HexLiteralNode.cs @@ -1,82 +1,81 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed hexadecimal integer literal node. - /// - /// Aleksandar Seovic - /// $Id: HexLiteralNode.cs,v 1.9 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class HexLiteralNode : BaseNode - { - private object nodeValue; - - /// - /// Create a new instance - /// - public HexLiteralNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected HexLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the hexadecimal integer literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (nodeValue == null) - { - lock (this) - { - if (nodeValue == null) - { - string n = this.getText(); - try - { - nodeValue = Int32.Parse(n.Substring(2), NumberStyles.HexNumber); - } - catch (OverflowException) - { - nodeValue = Int64.Parse(n.Substring(2), NumberStyles.HexNumber); - } - } - } - } - - return nodeValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed hexadecimal integer literal node. + /// + /// Aleksandar Seovic + [Serializable] + public class HexLiteralNode : BaseNode + { + private object nodeValue; + + /// + /// Create a new instance + /// + public HexLiteralNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected HexLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the hexadecimal integer literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (nodeValue == null) + { + lock (this) + { + if (nodeValue == null) + { + string n = this.getText(); + try + { + nodeValue = Int32.Parse(n.Substring(2), NumberStyles.HexNumber); + } + catch (OverflowException) + { + nodeValue = Int64.Parse(n.Substring(2), NumberStyles.HexNumber); + } + } + } + } + + return nodeValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/IExpression.cs b/src/Spring/Spring.Core/Expressions/IExpression.cs index e5d76d5b..55e87e29 100644 --- a/src/Spring/Spring.Core/Expressions/IExpression.cs +++ b/src/Spring/Spring.Core/Expressions/IExpression.cs @@ -1,70 +1,69 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using System.ComponentModel; - -namespace Spring.Expressions -{ - /// - /// Interface that all navigation expression nodes have to implement. - /// - /// Aleksandar Seovic - /// $Id: IExpression.cs,v 1.5 2007/07/31 08:18:20 markpollack Exp $ - [TypeConverter(typeof(ExpressionConverter))] - public interface IExpression - { - /// - /// Returns expression value. - /// - /// Value of the expression. - object GetValue(); - - /// - /// Returns expression value. - /// - /// Object to evaluate expression against. - /// Value of the expression. - object GetValue(object context); - - /// - /// Returns expression value. - /// - /// Object to evaluate expression against. - /// Expression variables map. - /// Value of the expression. - object GetValue(object context, IDictionary variables); - - /// - /// Sets expression value. - /// - /// Object to evaluate expression against. - /// New value for the last node of the expression. - void SetValue(object context, object newValue); - - /// - /// Sets expression value. - /// - /// Object to evaluate expression against. - /// Expression variables map. - /// New value for the last node of the expression. - void SetValue(object context, IDictionary variables, object newValue); - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using System.ComponentModel; + +namespace Spring.Expressions +{ + /// + /// Interface that all navigation expression nodes have to implement. + /// + /// Aleksandar Seovic + [TypeConverter(typeof(ExpressionConverter))] + public interface IExpression + { + /// + /// Returns expression value. + /// + /// Value of the expression. + object GetValue(); + + /// + /// Returns expression value. + /// + /// Object to evaluate expression against. + /// Value of the expression. + object GetValue(object context); + + /// + /// Returns expression value. + /// + /// Object to evaluate expression against. + /// Expression variables map. + /// Value of the expression. + object GetValue(object context, IDictionary variables); + + /// + /// Sets expression value. + /// + /// Object to evaluate expression against. + /// New value for the last node of the expression. + void SetValue(object context, object newValue); + + /// + /// Sets expression value. + /// + /// Object to evaluate expression against. + /// Expression variables map. + /// New value for the last node of the expression. + void SetValue(object context, IDictionary variables, object newValue); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/IndexerNode.cs b/src/Spring/Spring.Core/Expressions/IndexerNode.cs index d0b32143..730de743 100644 --- a/src/Spring/Spring.Core/Expressions/IndexerNode.cs +++ b/src/Spring/Spring.Core/Expressions/IndexerNode.cs @@ -1,294 +1,293 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.Serialization; -using Spring.Core; -using Spring.Util; -using Spring.Reflection.Dynamic; - -namespace Spring.Expressions -{ - /// - /// Represents parsed indexer node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: IndexerNode.cs,v 1.16 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class IndexerNode : NodeWithArguments - { - private const BindingFlags BINDING_FLAGS - = BindingFlags.Public | BindingFlags.NonPublic - | BindingFlags.Instance | BindingFlags.Static - | BindingFlags.IgnoreCase; - - private SafeIndexer indexer; - - /// - /// Create a new instance - /// - public IndexerNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected IndexerNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (context == null) - { - throw new NullValueInNestedPathException("Cannot retrieve the value of the indexer because the context for its resolution is null."); - } - - try - { - if (context is Array) - { - return GetArrayValue( (Array) context, evalContext ); - } - else if (context is IList) - { - return GetListValue( (IList) context, evalContext ); - } - else if (context is IDictionary) - { - return GetDictionaryValue( (IDictionary) context, evalContext ); - } - else if (context is string) - { - return GetCharacter( (string) context, evalContext ); - } - else - { - return GetGenericIndexer( context, evalContext ); - } - } - catch (TargetInvocationException e) - { - throw new InvalidPropertyException(evalContext.RootContextType, this.ToString(), "Getter for indexer threw an exception.", e); - } - catch (UnauthorizedAccessException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Illegal attempt to get value for the indexer.",e ); - } - catch (IndexOutOfRangeException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Index out of range.",e ); - } - catch (ArgumentOutOfRangeException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Argument out of range.",e ); - } - catch (InvalidCastException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid index type.",e ); - } - catch (ArgumentException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid argument.",e ); - } - } - - /// - /// Sets node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// New value for this node. - protected override void Set(object context, EvaluationContext evalContext, object newValue) - { - if (context == null) - { - throw new NullValueInNestedPathException("Cannot set the value of the indexer because the context for its resolution is null."); - } - - try - { - if (context is Array) - { - SetArrayValue( (Array) context, evalContext,newValue ); - } - else if (context is IList) - { - SetListValue( (IList) context, evalContext,newValue ); - } - else if (context is IDictionary) - { - SetDictionaryValue( (IDictionary) context, evalContext,newValue ); - } - else - { - SetGenericIndexer( context, evalContext,newValue ); - } - } - catch (TargetInvocationException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Setter for indexer threw an exception.",e ); - } - catch (UnauthorizedAccessException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Illegal attempt to set value for the indexer.",e ); - } - catch (IndexOutOfRangeException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Index out of range.",e ); - } - catch (ArgumentOutOfRangeException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Argument out of range.",e ); - } - catch (InvalidCastException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid index type.",e ); - } - catch (ArgumentException e) - { - throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid argument.",e ); - } - - } - - /// - /// Utility method that is needed by ObjectWrapper and AbstractAutowireCapableObjectFactory. - /// - /// Context to resolve property against. - /// Expression variables map. - /// PropertyInfo for this node. - internal PropertyInfo GetPropertyInfo(object context, IDictionary variables) - { - lock (this) - { - EvaluationContext evalContext = new EvaluationContext(context, variables); - InitializeIndexerProperty(context, evalContext); - - return indexer.IndexerProperty; - } - } - - private object GetArrayValue(Array array, EvaluationContext evalContext) - { - int argCount = array.Rank; - AssertArgumentCount(argCount); - - Int32[] indices = new Int32[argCount]; - for (int i = 0; i < argCount; i++) - { - indices[i] = (Int32) ResolveArgument(i, evalContext); - } - return array.GetValue(indices); - } - - private object GetListValue(IList list, EvaluationContext evalContext) - { - AssertArgumentCount(1); - return list[(int) ResolveArgument(0, evalContext)]; - } - - private object GetDictionaryValue(IDictionary dictionary, EvaluationContext evalContext) - { - AssertArgumentCount(1); - return dictionary[ResolveArgument( 0,evalContext )]; - } - - private object GetCharacter(string character, EvaluationContext evalContext) - { - AssertArgumentCount(1); - return character[(int)ResolveArgument( 0,evalContext )]; - } - - private object GetGenericIndexer(object context, EvaluationContext evalContext) - { - object[] indices = InitializeIndexerProperty( context, evalContext ); - return indexer.GetValue(context, indices); - } - - private void SetArrayValue(Array array, EvaluationContext evalContext,object newValue) - { - int argCount = array.Rank; - AssertArgumentCount(argCount); - - Int32[] indices = new Int32[argCount]; - for (int i = 0; i < argCount; i++) - { - indices[i] = (Int32) ResolveArgument(i, evalContext); - } - array.SetValue(newValue, indices); - } - - private void SetListValue(IList list, EvaluationContext evalContext,object newValue) - { - AssertArgumentCount(1); - list[(int) ResolveArgument(0, evalContext)] = newValue; - } - - private void SetDictionaryValue(IDictionary dictionary, EvaluationContext evalContext,object newValue) - { - AssertArgumentCount(1); - dictionary[ResolveArgument( 0,evalContext )] = newValue; - } - - private void SetGenericIndexer(object context, EvaluationContext evalContext,object newValue) - { - object[] indices = InitializeIndexerProperty( context, evalContext ); - indexer.SetValue( context,indices,newValue ); - } - - private object[] InitializeIndexerProperty(object context, EvaluationContext evalContext) - { - object[] indices = ResolveArguments( evalContext ); - - if (indexer == null) - { - lock (this) - { - if (indexer == null) - { - Type[] argTypes = ReflectionUtils.GetTypes(indices); - PropertyInfo indexerProperty = context.GetType().GetProperty("Item", BINDING_FLAGS, null, null, argTypes, null); - if (indexerProperty == null) - { - throw new ArgumentException("Indexer property with specified number and types of arguments does not exist."); - } - else - { - indexer = new SafeIndexer(indexerProperty); - } - } - } - } - - return indices; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.Serialization; +using Spring.Core; +using Spring.Util; +using Spring.Reflection.Dynamic; + +namespace Spring.Expressions +{ + /// + /// Represents parsed indexer node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class IndexerNode : NodeWithArguments + { + private const BindingFlags BINDING_FLAGS + = BindingFlags.Public | BindingFlags.NonPublic + | BindingFlags.Instance | BindingFlags.Static + | BindingFlags.IgnoreCase; + + private SafeIndexer indexer; + + /// + /// Create a new instance + /// + public IndexerNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected IndexerNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (context == null) + { + throw new NullValueInNestedPathException("Cannot retrieve the value of the indexer because the context for its resolution is null."); + } + + try + { + if (context is Array) + { + return GetArrayValue( (Array) context, evalContext ); + } + else if (context is IList) + { + return GetListValue( (IList) context, evalContext ); + } + else if (context is IDictionary) + { + return GetDictionaryValue( (IDictionary) context, evalContext ); + } + else if (context is string) + { + return GetCharacter( (string) context, evalContext ); + } + else + { + return GetGenericIndexer( context, evalContext ); + } + } + catch (TargetInvocationException e) + { + throw new InvalidPropertyException(evalContext.RootContextType, this.ToString(), "Getter for indexer threw an exception.", e); + } + catch (UnauthorizedAccessException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Illegal attempt to get value for the indexer.",e ); + } + catch (IndexOutOfRangeException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Index out of range.",e ); + } + catch (ArgumentOutOfRangeException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Argument out of range.",e ); + } + catch (InvalidCastException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid index type.",e ); + } + catch (ArgumentException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid argument.",e ); + } + } + + /// + /// Sets node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// New value for this node. + protected override void Set(object context, EvaluationContext evalContext, object newValue) + { + if (context == null) + { + throw new NullValueInNestedPathException("Cannot set the value of the indexer because the context for its resolution is null."); + } + + try + { + if (context is Array) + { + SetArrayValue( (Array) context, evalContext,newValue ); + } + else if (context is IList) + { + SetListValue( (IList) context, evalContext,newValue ); + } + else if (context is IDictionary) + { + SetDictionaryValue( (IDictionary) context, evalContext,newValue ); + } + else + { + SetGenericIndexer( context, evalContext,newValue ); + } + } + catch (TargetInvocationException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Setter for indexer threw an exception.",e ); + } + catch (UnauthorizedAccessException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Illegal attempt to set value for the indexer.",e ); + } + catch (IndexOutOfRangeException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Index out of range.",e ); + } + catch (ArgumentOutOfRangeException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Argument out of range.",e ); + } + catch (InvalidCastException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid index type.",e ); + } + catch (ArgumentException e) + { + throw new InvalidPropertyException( evalContext.RootContextType,this.ToString(),"Invalid argument.",e ); + } + + } + + /// + /// Utility method that is needed by ObjectWrapper and AbstractAutowireCapableObjectFactory. + /// + /// Context to resolve property against. + /// Expression variables map. + /// PropertyInfo for this node. + internal PropertyInfo GetPropertyInfo(object context, IDictionary variables) + { + lock (this) + { + EvaluationContext evalContext = new EvaluationContext(context, variables); + InitializeIndexerProperty(context, evalContext); + + return indexer.IndexerProperty; + } + } + + private object GetArrayValue(Array array, EvaluationContext evalContext) + { + int argCount = array.Rank; + AssertArgumentCount(argCount); + + Int32[] indices = new Int32[argCount]; + for (int i = 0; i < argCount; i++) + { + indices[i] = (Int32) ResolveArgument(i, evalContext); + } + return array.GetValue(indices); + } + + private object GetListValue(IList list, EvaluationContext evalContext) + { + AssertArgumentCount(1); + return list[(int) ResolveArgument(0, evalContext)]; + } + + private object GetDictionaryValue(IDictionary dictionary, EvaluationContext evalContext) + { + AssertArgumentCount(1); + return dictionary[ResolveArgument( 0,evalContext )]; + } + + private object GetCharacter(string character, EvaluationContext evalContext) + { + AssertArgumentCount(1); + return character[(int)ResolveArgument( 0,evalContext )]; + } + + private object GetGenericIndexer(object context, EvaluationContext evalContext) + { + object[] indices = InitializeIndexerProperty( context, evalContext ); + return indexer.GetValue(context, indices); + } + + private void SetArrayValue(Array array, EvaluationContext evalContext,object newValue) + { + int argCount = array.Rank; + AssertArgumentCount(argCount); + + Int32[] indices = new Int32[argCount]; + for (int i = 0; i < argCount; i++) + { + indices[i] = (Int32) ResolveArgument(i, evalContext); + } + array.SetValue(newValue, indices); + } + + private void SetListValue(IList list, EvaluationContext evalContext,object newValue) + { + AssertArgumentCount(1); + list[(int) ResolveArgument(0, evalContext)] = newValue; + } + + private void SetDictionaryValue(IDictionary dictionary, EvaluationContext evalContext,object newValue) + { + AssertArgumentCount(1); + dictionary[ResolveArgument( 0,evalContext )] = newValue; + } + + private void SetGenericIndexer(object context, EvaluationContext evalContext,object newValue) + { + object[] indices = InitializeIndexerProperty( context, evalContext ); + indexer.SetValue( context,indices,newValue ); + } + + private object[] InitializeIndexerProperty(object context, EvaluationContext evalContext) + { + object[] indices = ResolveArguments( evalContext ); + + if (indexer == null) + { + lock (this) + { + if (indexer == null) + { + Type[] argTypes = ReflectionUtils.GetTypes(indices); + PropertyInfo indexerProperty = context.GetType().GetProperty("Item", BINDING_FLAGS, null, null, argTypes, null); + if (indexerProperty == null) + { + throw new ArgumentException("Indexer property with specified number and types of arguments does not exist."); + } + else + { + indexer = new SafeIndexer(indexerProperty); + } + } + } + } + + return indices; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/IntLiteralNode.cs b/src/Spring/Spring.Core/Expressions/IntLiteralNode.cs index 856ca77e..3034e41c 100644 --- a/src/Spring/Spring.Core/Expressions/IntLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/IntLiteralNode.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed integer literal node. - /// - /// Aleksandar Seovic - /// $Id: IntLiteralNode.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class IntLiteralNode : BaseNode - { - private object nodeValue; - - /// - /// Create a new instance - /// - public IntLiteralNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected IntLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the integer literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (nodeValue == null) - { - lock (this) - { - if (nodeValue == null) - { - string n = this.getText(); - try - { - nodeValue = Int32.Parse(n); - } - catch (OverflowException) - { - nodeValue = Int64.Parse(n); - } - } - } - } - - return nodeValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed integer literal node. + /// + /// Aleksandar Seovic + [Serializable] + public class IntLiteralNode : BaseNode + { + private object nodeValue; + + /// + /// Create a new instance + /// + public IntLiteralNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected IntLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the integer literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (nodeValue == null) + { + lock (this) + { + if (nodeValue == null) + { + string n = this.getText(); + try + { + nodeValue = Int32.Parse(n); + } + catch (OverflowException) + { + nodeValue = Int64.Parse(n); + } + } + } + } + + return nodeValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/LambdaExpressionNode.cs b/src/Spring/Spring.Core/Expressions/LambdaExpressionNode.cs index a2983f62..220efb8b 100644 --- a/src/Spring/Spring.Core/Expressions/LambdaExpressionNode.cs +++ b/src/Spring/Spring.Core/Expressions/LambdaExpressionNode.cs @@ -1,138 +1,137 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents lambda expression. - /// - /// Aleksandar Seovic - /// $Id: LambdaExpressionNode.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class LambdaExpressionNode : BaseNode - { - /// - /// caches argumentNames of this instance - /// - private string[] argumentNames; - - /// - /// caches body expression of this lambda function - /// - private BaseNode bodyExpression; - - /// - /// Create a new instance - /// - public LambdaExpressionNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected LambdaExpressionNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Gets argument names for this lambda expression. - /// - public string[] ArgumentNames - { - get - { - if(bodyExpression == null) - { - InitializeLambda(); - } - return argumentNames; - } - } - - /// - /// Assigns value of the right operand to the left one. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if(bodyExpression == null) - { - InitializeLambda(); - } - - object result = bodyExpression.GetValueInternal(context, evalContext); - return result; - } - - /// - /// Returns Lambda Expression's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// A dictionary containing argument map for this lambda expression. - /// Node's value. - public object GetValueInternal(object context, EvaluationContext evalContext, IDictionary arguments) - { - using (evalContext.SwitchLocalVariables(arguments)) - { - object result = base.GetValueInternal(context, evalContext); - return result; - } - } - - private void InitializeLambda() - { - lock (this) - { - if (bodyExpression == null) - { - if (this.getNumberOfChildren() == 1) - { - argumentNames = new string[0]; - bodyExpression = (BaseNode)this.getFirstChild(); - } - else - { - AST argsNode = this.getFirstChild(); - argumentNames = new string[argsNode.getNumberOfChildren()]; - AST argNode = argsNode.getFirstChild(); - int i = 0; - while (argNode != null) - { - argumentNames[i++] = argNode.getText(); - argNode = argNode.getNextSibling(); - } - - bodyExpression = (BaseNode)argsNode.getNextSibling(); - } - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents lambda expression. + /// + /// Aleksandar Seovic + [Serializable] + public class LambdaExpressionNode : BaseNode + { + /// + /// caches argumentNames of this instance + /// + private string[] argumentNames; + + /// + /// caches body expression of this lambda function + /// + private BaseNode bodyExpression; + + /// + /// Create a new instance + /// + public LambdaExpressionNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected LambdaExpressionNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Gets argument names for this lambda expression. + /// + public string[] ArgumentNames + { + get + { + if(bodyExpression == null) + { + InitializeLambda(); + } + return argumentNames; + } + } + + /// + /// Assigns value of the right operand to the left one. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if(bodyExpression == null) + { + InitializeLambda(); + } + + object result = bodyExpression.GetValueInternal(context, evalContext); + return result; + } + + /// + /// Returns Lambda Expression's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// A dictionary containing argument map for this lambda expression. + /// Node's value. + public object GetValueInternal(object context, EvaluationContext evalContext, IDictionary arguments) + { + using (evalContext.SwitchLocalVariables(arguments)) + { + object result = base.GetValueInternal(context, evalContext); + return result; + } + } + + private void InitializeLambda() + { + lock (this) + { + if (bodyExpression == null) + { + if (this.getNumberOfChildren() == 1) + { + argumentNames = new string[0]; + bodyExpression = (BaseNode)this.getFirstChild(); + } + else + { + AST argsNode = this.getFirstChild(); + argumentNames = new string[argsNode.getNumberOfChildren()]; + AST argNode = argsNode.getFirstChild(); + int i = 0; + while (argNode != null) + { + argumentNames[i++] = argNode.getText(); + argNode = argNode.getNextSibling(); + } + + bodyExpression = (BaseNode)argsNode.getNextSibling(); + } + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ListInitializerNode.cs b/src/Spring/Spring.Core/Expressions/ListInitializerNode.cs index a2dc371a..7c279d0d 100644 --- a/src/Spring/Spring.Core/Expressions/ListInitializerNode.cs +++ b/src/Spring/Spring.Core/Expressions/ListInitializerNode.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed list initializer node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: ListInitializerNode.cs,v 1.4 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class ListInitializerNode : NodeWithArguments - { - /// - /// Create a new instance - /// - public ListInitializerNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected ListInitializerNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Creates new instance of the list defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object[] values = ResolveArguments(evalContext); - return new ArrayList(values); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed list initializer node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class ListInitializerNode : NodeWithArguments + { + /// + /// Create a new instance + /// + public ListInitializerNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected ListInitializerNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Creates new instance of the list defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object[] values = ResolveArguments(evalContext); + return new ArrayList(values); + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/LocalFunctionNode.cs b/src/Spring/Spring.Core/Expressions/LocalFunctionNode.cs index deba2fd5..9253bf61 100644 --- a/src/Spring/Spring.Core/Expressions/LocalFunctionNode.cs +++ b/src/Spring/Spring.Core/Expressions/LocalFunctionNode.cs @@ -1,85 +1,84 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents local function node. - /// - /// Aleksandar Seovic - /// $Id: LocalFunctionNode.cs,v 1.7 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class LocalFunctionNode : NodeWithArguments - { - /// - /// Create a new instance - /// - public LocalFunctionNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected LocalFunctionNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Evaluates function represented by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Result of the function evaluation. - protected override object Get(object context, EvaluationContext evalContext) - { - string name = this.getText(); - IDictionary locals = evalContext.LocalVariables; - LambdaExpressionNode lambda = locals[name] as LambdaExpressionNode; - - if (lambda == null) - { - throw new InvalidOperationException("Function '" + name + "' is not defined."); - } - - object[] argValues = ResolveArguments(evalContext); - string[] argNames = lambda.ArgumentNames; - - if (argValues.Length != argNames.Length) - { - throw new InvalidOperationException( - "Function '" + name + "' requires " + argNames.Length + " arguments."); - } - - IDictionary arguments = new Hashtable(); - for (int i = 0; i < argValues.Length; i++) - { - arguments[argNames[i]] = argValues[i]; - } - - return lambda.GetValueInternal(context, evalContext, arguments); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents local function node. + /// + /// Aleksandar Seovic + [Serializable] + public class LocalFunctionNode : NodeWithArguments + { + /// + /// Create a new instance + /// + public LocalFunctionNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected LocalFunctionNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Evaluates function represented by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Result of the function evaluation. + protected override object Get(object context, EvaluationContext evalContext) + { + string name = this.getText(); + IDictionary locals = evalContext.LocalVariables; + LambdaExpressionNode lambda = locals[name] as LambdaExpressionNode; + + if (lambda == null) + { + throw new InvalidOperationException("Function '" + name + "' is not defined."); + } + + object[] argValues = ResolveArguments(evalContext); + string[] argNames = lambda.ArgumentNames; + + if (argValues.Length != argNames.Length) + { + throw new InvalidOperationException( + "Function '" + name + "' requires " + argNames.Length + " arguments."); + } + + IDictionary arguments = new Hashtable(); + for (int i = 0; i < argValues.Length; i++) + { + arguments[argNames[i]] = argValues[i]; + } + + return lambda.GetValueInternal(context, evalContext, arguments); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/LocalVariableNode.cs b/src/Spring/Spring.Core/Expressions/LocalVariableNode.cs index e4268ec5..cef8462d 100644 --- a/src/Spring/Spring.Core/Expressions/LocalVariableNode.cs +++ b/src/Spring/Spring.Core/Expressions/LocalVariableNode.cs @@ -1,87 +1,86 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed variable node. - /// - /// Aleksandar Seovic - /// $Id: LocalVariableNode.cs,v 1.4 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class LocalVariableNode : BaseNode - { - //internal const string LOCAL_VARIABLES = "__locals"; - - /// - /// Create a new instance - /// - public LocalVariableNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected LocalVariableNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns value of the local variable represented by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - string varName = this.getText(); - IDictionary locals = evalContext.LocalVariables; - if (locals != null) - { - return locals[varName]; - } - return null; - } - - /// - /// Sets value of the local variable represented by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// New value for this node. - protected override void Set(object context, EvaluationContext evalContext, object newValue) - { - string varName = this.getText(); - IDictionary locals = evalContext.LocalVariables; - if (locals == null) - { - locals = new Hashtable(); - evalContext.LocalVariables = locals; - } - locals[varName] = newValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed variable node. + /// + /// Aleksandar Seovic + [Serializable] + public class LocalVariableNode : BaseNode + { + //internal const string LOCAL_VARIABLES = "__locals"; + + /// + /// Create a new instance + /// + public LocalVariableNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected LocalVariableNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns value of the local variable represented by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + string varName = this.getText(); + IDictionary locals = evalContext.LocalVariables; + if (locals != null) + { + return locals[varName]; + } + return null; + } + + /// + /// Sets value of the local variable represented by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// New value for this node. + protected override void Set(object context, EvaluationContext evalContext, object newValue) + { + string varName = this.getText(); + IDictionary locals = evalContext.LocalVariables; + if (locals == null) + { + locals = new Hashtable(); + evalContext.LocalVariables = locals; + } + locals[varName] = newValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/MapEntryNode.cs b/src/Spring/Spring.Core/Expressions/MapEntryNode.cs index ea3bd763..e6c8c1ab 100644 --- a/src/Spring/Spring.Core/Expressions/MapEntryNode.cs +++ b/src/Spring/Spring.Core/Expressions/MapEntryNode.cs @@ -1,63 +1,62 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed map entry node. - /// - /// Aleksandar Seovic - /// $Id: MapEntryNode.cs,v 1.4 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class MapEntryNode : BaseNode - { - /// - /// Creates a new instance of . - /// - public MapEntryNode() - {} - - /// - /// Create a new instance from SerializationInfo - /// - protected MapEntryNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Creates new instance of the map entry defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object key = ((BaseNode)this.getFirstChild()).GetValueInternal(context, evalContext); - object value = ((BaseNode)this.getFirstChild().getNextSibling()).GetValueInternal(context, evalContext); - - return new DictionaryEntry(key, value); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed map entry node. + /// + /// Aleksandar Seovic + [Serializable] + public class MapEntryNode : BaseNode + { + /// + /// Creates a new instance of . + /// + public MapEntryNode() + {} + + /// + /// Create a new instance from SerializationInfo + /// + protected MapEntryNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Creates new instance of the map entry defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object key = ((BaseNode)this.getFirstChild()).GetValueInternal(context, evalContext); + object value = ((BaseNode)this.getFirstChild().getNextSibling()).GetValueInternal(context, evalContext); + + return new DictionaryEntry(key, value); + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/MapInitializerNode.cs b/src/Spring/Spring.Core/Expressions/MapInitializerNode.cs index 53a322b2..88690777 100644 --- a/src/Spring/Spring.Core/Expressions/MapInitializerNode.cs +++ b/src/Spring/Spring.Core/Expressions/MapInitializerNode.cs @@ -1,71 +1,70 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents parsed map initializer node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: MapInitializerNode.cs,v 1.4 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class MapInitializerNode : BaseNode - { - /// - /// Creates a new instance of . - /// - public MapInitializerNode() - {} - - /// - /// Create a new instance from SerializationInfo - /// - protected MapInitializerNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Creates new instance of the map defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - IDictionary entries = new Hashtable(); - AST entryNode = this.getFirstChild(); - while (entryNode != null) - { - DictionaryEntry entry = (DictionaryEntry) - ((MapEntryNode)entryNode).GetValueInternal( evalContext.RootContext, evalContext ); - entries[entry.Key] = entry.Value; - entryNode = entryNode.getNextSibling(); - } - - return entries; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents parsed map initializer node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class MapInitializerNode : BaseNode + { + /// + /// Creates a new instance of . + /// + public MapInitializerNode() + {} + + /// + /// Create a new instance from SerializationInfo + /// + protected MapInitializerNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Creates new instance of the map defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + IDictionary entries = new Hashtable(); + AST entryNode = this.getFirstChild(); + while (entryNode != null) + { + DictionaryEntry entry = (DictionaryEntry) + ((MapEntryNode)entryNode).GetValueInternal( evalContext.RootContext, evalContext ); + entries[entry.Key] = entry.Value; + entryNode = entryNode.getNextSibling(); + } + + return entries; + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/MethodNode.cs b/src/Spring/Spring.Core/Expressions/MethodNode.cs index 4e446eab..98078214 100644 --- a/src/Spring/Spring.Core/Expressions/MethodNode.cs +++ b/src/Spring/Spring.Core/Expressions/MethodNode.cs @@ -1,287 +1,286 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.Serialization; -using Spring.Expressions.Processors; -using Spring.Util; -using Spring.Reflection.Dynamic; - -namespace Spring.Expressions -{ - /// - /// Represents parsed method node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: MethodNode.cs,v 1.21 2008/03/20 23:58:16 oakinger Exp $ - [Serializable] - public class MethodNode : NodeWithArguments - { - private const BindingFlags BINDING_FLAGS - = BindingFlags.Public | BindingFlags.NonPublic - | BindingFlags.Instance | BindingFlags.Static - | BindingFlags.IgnoreCase; - - private static readonly IDictionary collectionProcessorMap = new Hashtable(); - - private bool initialized = false; - private bool isParamArray = false; - private Type paramArrayType; - private int argumentCount; - private SafeMethod method; - private int methodHash; - private bool isCollectionProcessor = false; - private ICollectionProcessor collectionProcessor; - - /// - /// Static constructor. Initializes a map of special collection processor methods. - /// - static MethodNode() - { - collectionProcessorMap.Add("count", new CountAggregator()); - collectionProcessorMap.Add("sum", new SumAggregator()); - collectionProcessorMap.Add("max", new MaxAggregator()); - collectionProcessorMap.Add("min", new MinAggregator()); - collectionProcessorMap.Add("average", new AverageAggregator()); - collectionProcessorMap.Add("sort", new SortProcessor()); - collectionProcessorMap.Add("orderBy", new OrderByProcessor()); - collectionProcessorMap.Add("distinct", new DistinctProcessor()); - collectionProcessorMap.Add("nonNull", new NonNullProcessor()); - collectionProcessorMap.Add("convert", new ConversionProcessor()); - collectionProcessorMap.Add("reverse", new ReverseProcessor()); - } - - /// - /// Create a new instance - /// - public MethodNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected MethodNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object[] argValues = ResolveArguments(evalContext); - - ICollectionProcessor localCollectionProcessor = null; - SafeMethod localMethod = null; - - // resolve method, if necessary - lock (this) - { - if (!isCollectionProcessor) - { - if ((context == null || context is ICollection)) - { - string methodName = this.getText(); - - // predefined collection processor? - collectionProcessor = (ICollectionProcessor)collectionProcessorMap[methodName]; - isCollectionProcessor = (collectionProcessor != null); - localCollectionProcessor = collectionProcessor; - - if (!isCollectionProcessor && evalContext.Variables != null) - { - localCollectionProcessor = evalContext.Variables[methodName] as ICollectionProcessor; - } - } - } - else - { - localCollectionProcessor = collectionProcessor; - } - - if (localCollectionProcessor == null) - { - if (context == null) - { - throw new ArgumentNullException("Context for method invocation cannot be null."); - } - - // calculate checksum, if the cached method matches the current context - if (initialized) - { - int calculatedHash = CalculateMethodHash(context.GetType(), argValues); - initialized = (calculatedHash == methodHash); - } - - if (!initialized) - { - string methodName = this.getText(); - Initialize(methodName, argValues, context); - initialized = true; - } - - localMethod = method; - } - } - - // invoke method - if (localCollectionProcessor != null) - { - return localCollectionProcessor.Process((ICollection)context, argValues); - } - else - { - object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues); - return localMethod.Invoke(context, paramValues); - } - } - - private int CalculateMethodHash(Type contextType, object[] argValues) - { - int hash = contextType.GetHashCode(); - for (int i = 0; i < argValues.Length; i++) - { - object arg = argValues[i]; - if (arg != null) hash += s_primes[i] * arg.GetType().GetHashCode(); - } - return hash; - } - - private void Initialize(string methodName, object[] argValues, object context) - { - Type contextType = (context is Type ? context as Type : context.GetType()); - - // check the context type first - MethodInfo mi = GetBestMethod(contextType, methodName, BINDING_FLAGS, argValues); - - // if not found, probe the Type's type - if (mi == null) - { - mi = GetBestMethod(typeof(Type), methodName, BINDING_FLAGS, argValues); - } - - if (mi == null) - { - throw new ArgumentException( - string.Format("Method '{0}' with the specified number and types of arguments does not exist.", - methodName)); - } - else - { - ParameterInfo[] parameters = mi.GetParameters(); - if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; - if (isParamArray) - { - paramArrayType = lastParameter.ParameterType.GetElementType(); - argumentCount = parameters.Length; - } - } - - method = new SafeMethod(mi); - methodHash = CalculateMethodHash(contextType, argValues); - } - } - - /// - /// Gets the best method given the name, argument values, for a given type. - /// - /// The type on which to search for the method. - /// Name of the method. - /// The binding flags. - /// The arg values. - /// Best matching method or null if none found. - public static MethodInfo GetBestMethod(Type type, string methodName, BindingFlags bindingFlags, object[] argValues) - { - MethodInfo mi = null; - try - { - mi = type.GetMethod(methodName, bindingFlags | BindingFlags.FlattenHierarchy); - } - catch (AmbiguousMatchException) - { - - MethodInfo[] overloads = GetCandidateMethods(type, methodName, bindingFlags, argValues.Length); - if (overloads.Length > 0) - { - mi = ReflectionUtils.GetMethodByArgumentValues(overloads, argValues); - } - } - return mi; - } - - - - private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount) - { - MethodInfo[] methods = type.GetMethods(bindingFlags | BindingFlags.FlattenHierarchy); - ArrayList matches = new ArrayList(); - - foreach (MethodInfo method in methods) - { - if (method.Name == methodName) - { - ParameterInfo[] parameters = method.GetParameters(); - if (parameters.Length == argCount) - { - matches.Add(method); - } - else if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) - { - matches.Add(method); - } - } - } - } - - return (MethodInfo[])matches.ToArray(typeof(MethodInfo)); - } - - // used to calculate signature hash while caring for arg positions - private static readonly int[] s_primes = - { - 17, 19, 23, 29 - , 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 - , 73, 79, 83, 89, 97, 101, 103, 107, 109, 113 - , 127, 131, 137, 139, 149, 151, 157, 163, 167, 173 - , 179, 181, 191, 193, 197, 199, 211, 223, 227, 229 - , 233, 239, 241, 251, 257, 263, 269, 271, 277, 281 - , 283, 293, 307, 311, 313, 317, 331, 337, 347, 349 - , 353, 359, 367, 373, 379, 383, 389, 397, 401, 409 - , 419, 421, 431, 433, 439, 443, 449, 457, 461, 463 - , 467, 479, 487, 491, 499, 503, 509, 521, 523, 541 - , 547, 557, 563, 569, 571, 577, 587, 593, 599, 601 - , 607, 613, 617, 619, 631, 641, 643, 647, 653, 659 - , 661, 673, 677, 683, 691, 701, 709, 719, 727, 733 - }; - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.Serialization; +using Spring.Expressions.Processors; +using Spring.Util; +using Spring.Reflection.Dynamic; + +namespace Spring.Expressions +{ + /// + /// Represents parsed method node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class MethodNode : NodeWithArguments + { + private const BindingFlags BINDING_FLAGS + = BindingFlags.Public | BindingFlags.NonPublic + | BindingFlags.Instance | BindingFlags.Static + | BindingFlags.IgnoreCase; + + private static readonly IDictionary collectionProcessorMap = new Hashtable(); + + private bool initialized = false; + private bool isParamArray = false; + private Type paramArrayType; + private int argumentCount; + private SafeMethod method; + private int methodHash; + private bool isCollectionProcessor = false; + private ICollectionProcessor collectionProcessor; + + /// + /// Static constructor. Initializes a map of special collection processor methods. + /// + static MethodNode() + { + collectionProcessorMap.Add("count", new CountAggregator()); + collectionProcessorMap.Add("sum", new SumAggregator()); + collectionProcessorMap.Add("max", new MaxAggregator()); + collectionProcessorMap.Add("min", new MinAggregator()); + collectionProcessorMap.Add("average", new AverageAggregator()); + collectionProcessorMap.Add("sort", new SortProcessor()); + collectionProcessorMap.Add("orderBy", new OrderByProcessor()); + collectionProcessorMap.Add("distinct", new DistinctProcessor()); + collectionProcessorMap.Add("nonNull", new NonNullProcessor()); + collectionProcessorMap.Add("convert", new ConversionProcessor()); + collectionProcessorMap.Add("reverse", new ReverseProcessor()); + } + + /// + /// Create a new instance + /// + public MethodNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected MethodNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object[] argValues = ResolveArguments(evalContext); + + ICollectionProcessor localCollectionProcessor = null; + SafeMethod localMethod = null; + + // resolve method, if necessary + lock (this) + { + if (!isCollectionProcessor) + { + if ((context == null || context is ICollection)) + { + string methodName = this.getText(); + + // predefined collection processor? + collectionProcessor = (ICollectionProcessor)collectionProcessorMap[methodName]; + isCollectionProcessor = (collectionProcessor != null); + localCollectionProcessor = collectionProcessor; + + if (!isCollectionProcessor && evalContext.Variables != null) + { + localCollectionProcessor = evalContext.Variables[methodName] as ICollectionProcessor; + } + } + } + else + { + localCollectionProcessor = collectionProcessor; + } + + if (localCollectionProcessor == null) + { + if (context == null) + { + throw new ArgumentNullException("Context for method invocation cannot be null."); + } + + // calculate checksum, if the cached method matches the current context + if (initialized) + { + int calculatedHash = CalculateMethodHash(context.GetType(), argValues); + initialized = (calculatedHash == methodHash); + } + + if (!initialized) + { + string methodName = this.getText(); + Initialize(methodName, argValues, context); + initialized = true; + } + + localMethod = method; + } + } + + // invoke method + if (localCollectionProcessor != null) + { + return localCollectionProcessor.Process((ICollection)context, argValues); + } + else + { + object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues); + return localMethod.Invoke(context, paramValues); + } + } + + private int CalculateMethodHash(Type contextType, object[] argValues) + { + int hash = contextType.GetHashCode(); + for (int i = 0; i < argValues.Length; i++) + { + object arg = argValues[i]; + if (arg != null) hash += s_primes[i] * arg.GetType().GetHashCode(); + } + return hash; + } + + private void Initialize(string methodName, object[] argValues, object context) + { + Type contextType = (context is Type ? context as Type : context.GetType()); + + // check the context type first + MethodInfo mi = GetBestMethod(contextType, methodName, BINDING_FLAGS, argValues); + + // if not found, probe the Type's type + if (mi == null) + { + mi = GetBestMethod(typeof(Type), methodName, BINDING_FLAGS, argValues); + } + + if (mi == null) + { + throw new ArgumentException( + string.Format("Method '{0}' with the specified number and types of arguments does not exist.", + methodName)); + } + else + { + ParameterInfo[] parameters = mi.GetParameters(); + if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; + if (isParamArray) + { + paramArrayType = lastParameter.ParameterType.GetElementType(); + argumentCount = parameters.Length; + } + } + + method = new SafeMethod(mi); + methodHash = CalculateMethodHash(contextType, argValues); + } + } + + /// + /// Gets the best method given the name, argument values, for a given type. + /// + /// The type on which to search for the method. + /// Name of the method. + /// The binding flags. + /// The arg values. + /// Best matching method or null if none found. + public static MethodInfo GetBestMethod(Type type, string methodName, BindingFlags bindingFlags, object[] argValues) + { + MethodInfo mi = null; + try + { + mi = type.GetMethod(methodName, bindingFlags | BindingFlags.FlattenHierarchy); + } + catch (AmbiguousMatchException) + { + + MethodInfo[] overloads = GetCandidateMethods(type, methodName, bindingFlags, argValues.Length); + if (overloads.Length > 0) + { + mi = ReflectionUtils.GetMethodByArgumentValues(overloads, argValues); + } + } + return mi; + } + + + + private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount) + { + MethodInfo[] methods = type.GetMethods(bindingFlags | BindingFlags.FlattenHierarchy); + ArrayList matches = new ArrayList(); + + foreach (MethodInfo method in methods) + { + if (method.Name == methodName) + { + ParameterInfo[] parameters = method.GetParameters(); + if (parameters.Length == argCount) + { + matches.Add(method); + } + else if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) + { + matches.Add(method); + } + } + } + } + + return (MethodInfo[])matches.ToArray(typeof(MethodInfo)); + } + + // used to calculate signature hash while caring for arg positions + private static readonly int[] s_primes = + { + 17, 19, 23, 29 + , 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 + , 73, 79, 83, 89, 97, 101, 103, 107, 109, 113 + , 127, 131, 137, 139, 149, 151, 157, 163, 167, 173 + , 179, 181, 191, 193, 197, 199, 211, 223, 227, 229 + , 233, 239, 241, 251, 257, 263, 269, 271, 277, 281 + , 283, 293, 307, 311, 313, 317, 331, 337, 347, 349 + , 353, 359, 367, 373, 379, 383, 389, 397, 401, 409 + , 419, 421, 431, 433, 439, 443, 449, 457, 461, 463 + , 467, 479, 487, 491, 499, 503, 509, 521, 523, 541 + , 547, 557, 563, 569, 571, 577, 587, 593, 599, 601 + , 607, 613, 617, 619, 631, 641, 643, 647, 653, 659 + , 661, 673, 677, 683, 691, 701, 709, 719, 727, 733 + }; + } +} diff --git a/src/Spring/Spring.Core/Expressions/NamedArgumentNode.cs b/src/Spring/Spring.Core/Expressions/NamedArgumentNode.cs index 7919a669..ae1e95f0 100644 --- a/src/Spring/Spring.Core/Expressions/NamedArgumentNode.cs +++ b/src/Spring/Spring.Core/Expressions/NamedArgumentNode.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed named argument node in the expression. - /// - /// Aleksandar Seovic - /// $Id: NamedArgumentNode.cs,v 1.4 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class NamedArgumentNode : BaseNode - { - /// - /// Create a new instance - /// - public NamedArgumentNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected NamedArgumentNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns the value of the named argument defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - return ((BaseNode) this.getFirstChild()).GetValueInternal(evalContext.RootContext, evalContext); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed named argument node in the expression. + /// + /// Aleksandar Seovic + [Serializable] + public class NamedArgumentNode : BaseNode + { + /// + /// Create a new instance + /// + public NamedArgumentNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected NamedArgumentNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns the value of the named argument defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + return ((BaseNode) this.getFirstChild()).GetValueInternal(evalContext.RootContext, evalContext); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/NodeWithArguments.cs b/src/Spring/Spring.Core/Expressions/NodeWithArguments.cs index 6734ac1c..0f1953c6 100644 --- a/src/Spring/Spring.Core/Expressions/NodeWithArguments.cs +++ b/src/Spring/Spring.Core/Expressions/NodeWithArguments.cs @@ -1,176 +1,175 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Base type for nodes that accept arguments. - /// - /// Aleksandar Seovic - /// $Id: NodeWithArguments.cs,v 1.15 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public abstract class NodeWithArguments : BaseNode - { - private BaseNode[] args; - private IDictionary namedArgs; - - /// - /// Create a new instance - /// - public NodeWithArguments() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected NodeWithArguments(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Initializes the node. - /// - private void InitializeNode() - { - if (args == null) - { - lock (this) - { - if (args == null) - { - ArrayList argList = new ArrayList(); - namedArgs = new Hashtable(); - - AST node = this.getFirstChild(); - - while (node != null) - { - if (node.getFirstChild() is LambdaExpressionNode) - { - argList.Add(node.getFirstChild()); - } - else if (node is NamedArgumentNode) - { - namedArgs.Add(node.getText(), node); - } - else - { - argList.Add(node); - } - node = node.getNextSibling(); - } - - args = (BaseNode[])argList.ToArray(typeof(BaseNode)); - } - } - } - } - - /// - /// Asserts the argument count. - /// - /// The required count. - protected void AssertArgumentCount(int requiredCount) - { - InitializeNode(); - if (requiredCount != args.Length) - { - throw new ArgumentException("This expression node requires exactly " + - requiredCount + " argument(s) and " + - args.Length + " were specified."); - } - } - - /// - /// Resolves the arguments. - /// - /// Current expression evaluation context. - /// An array of argument values - protected object[] ResolveArguments(EvaluationContext evalContext) - { - InitializeNode(); - object[] values = new object[args.Length]; - for (int i = 0; i < args.Length; i++) - { - values[i] = ResolveArgument(i, evalContext); - } - return values; - } - - /// - /// Resolves the named arguments. - /// - /// Current expression evaluation context. - /// A dictionary of argument name to value mappings. - protected IDictionary ResolveNamedArguments(EvaluationContext evalContext) - { - InitializeNode(); - if (namedArgs.Count == 0) - { - return null; - } - - IDictionary namesAndValues = new Hashtable(namedArgs.Count); - foreach (string name in namedArgs.Keys) - { - namesAndValues[name] = ResolveNamedArgument(name, evalContext); - } - return namesAndValues; - } - - /// - /// Resolves the argument. - /// - /// Argument position. - /// Current expression evaluation context. - /// Resolved argument value. - protected object ResolveArgument(int position, EvaluationContext evalContext) - { - InitializeNode(); - if (args[position] is LambdaExpressionNode) - { - return args[position]; - } - else - { - return ((BaseNode)args[position]).GetValueInternal(evalContext.ThisContext, evalContext); - } - } - - /// - /// Resolves the named argument. - /// - /// Argument name. - /// Current expression evaluation context. - /// Resolved named argument value. - private object ResolveNamedArgument(string name, EvaluationContext evalContext) - { - return ((BaseNode)namedArgs[name]).GetValueInternal(evalContext.ThisContext, evalContext); - } - - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Base type for nodes that accept arguments. + /// + /// Aleksandar Seovic + [Serializable] + public abstract class NodeWithArguments : BaseNode + { + private BaseNode[] args; + private IDictionary namedArgs; + + /// + /// Create a new instance + /// + public NodeWithArguments() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected NodeWithArguments(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Initializes the node. + /// + private void InitializeNode() + { + if (args == null) + { + lock (this) + { + if (args == null) + { + ArrayList argList = new ArrayList(); + namedArgs = new Hashtable(); + + AST node = this.getFirstChild(); + + while (node != null) + { + if (node.getFirstChild() is LambdaExpressionNode) + { + argList.Add(node.getFirstChild()); + } + else if (node is NamedArgumentNode) + { + namedArgs.Add(node.getText(), node); + } + else + { + argList.Add(node); + } + node = node.getNextSibling(); + } + + args = (BaseNode[])argList.ToArray(typeof(BaseNode)); + } + } + } + } + + /// + /// Asserts the argument count. + /// + /// The required count. + protected void AssertArgumentCount(int requiredCount) + { + InitializeNode(); + if (requiredCount != args.Length) + { + throw new ArgumentException("This expression node requires exactly " + + requiredCount + " argument(s) and " + + args.Length + " were specified."); + } + } + + /// + /// Resolves the arguments. + /// + /// Current expression evaluation context. + /// An array of argument values + protected object[] ResolveArguments(EvaluationContext evalContext) + { + InitializeNode(); + object[] values = new object[args.Length]; + for (int i = 0; i < args.Length; i++) + { + values[i] = ResolveArgument(i, evalContext); + } + return values; + } + + /// + /// Resolves the named arguments. + /// + /// Current expression evaluation context. + /// A dictionary of argument name to value mappings. + protected IDictionary ResolveNamedArguments(EvaluationContext evalContext) + { + InitializeNode(); + if (namedArgs.Count == 0) + { + return null; + } + + IDictionary namesAndValues = new Hashtable(namedArgs.Count); + foreach (string name in namedArgs.Keys) + { + namesAndValues[name] = ResolveNamedArgument(name, evalContext); + } + return namesAndValues; + } + + /// + /// Resolves the argument. + /// + /// Argument position. + /// Current expression evaluation context. + /// Resolved argument value. + protected object ResolveArgument(int position, EvaluationContext evalContext) + { + InitializeNode(); + if (args[position] is LambdaExpressionNode) + { + return args[position]; + } + else + { + return ((BaseNode)args[position]).GetValueInternal(evalContext.ThisContext, evalContext); + } + } + + /// + /// Resolves the named argument. + /// + /// Argument name. + /// Current expression evaluation context. + /// Resolved named argument value. + private object ResolveNamedArgument(string name, EvaluationContext evalContext) + { + return ((BaseNode)namedArgs[name]).GetValueInternal(evalContext.ThisContext, evalContext); + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/NullLiteralNode.cs b/src/Spring/Spring.Core/Expressions/NullLiteralNode.cs index ad53f007..b6616a1e 100644 --- a/src/Spring/Spring.Core/Expressions/NullLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/NullLiteralNode.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed null literal node. - /// - /// Aleksandar Seovic - /// $Id: NullLiteralNode.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class NullLiteralNode : BaseNode - { - /// - /// Create a new instance - /// - public NullLiteralNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected NullLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the null literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - return null; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed null literal node. + /// + /// Aleksandar Seovic + [Serializable] + public class NullLiteralNode : BaseNode + { + /// + /// Create a new instance + /// + public NullLiteralNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected NullLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the null literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpADD.cs b/src/Spring/Spring.Core/Expressions/OpADD.cs index 928d8d7f..2ff159cd 100644 --- a/src/Spring/Spring.Core/Expressions/OpADD.cs +++ b/src/Spring/Spring.Core/Expressions/OpADD.cs @@ -1,120 +1,119 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using Spring.Collections; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents arithmetic addition operator. - /// - /// Aleksandar Seovic - /// $Id: OpADD.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpADD : BinaryOperator - { - /// - /// Create a new instance - /// - public OpADD() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpADD(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the arithmetic addition operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal(context, evalContext); - object right = Right.GetValueInternal(context, evalContext); - - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - return NumberUtils.Add(left, right); - } - else if (left is DateTime && (right is TimeSpan || right is string || NumberUtils.IsNumber(right))) - { - if (NumberUtils.IsNumber(right)) - { - right = TimeSpan.FromDays(Convert.ToDouble(right)); - } - else if (right is string) - { - right = TimeSpan.Parse((string) right); - } - - return (DateTime) left + (TimeSpan) right; - } - else if (left is String || right is String) - { - return left.ToString() + right.ToString(); - } - else if ((left is IList || left is ISet) && (right is IList || right is ISet)) - { - ISet leftset = new HybridSet(left as ICollection); - ISet rightset = new HybridSet(right as ICollection); - return leftset.Union(rightset); - } - else if (left is IDictionary && right is IDictionary) - { - ISet leftset = new HybridSet(((IDictionary) left).Keys); - ISet rightset = new HybridSet(((IDictionary) right).Keys); - ISet unionset = leftset.Union(rightset); - - IDictionary result = new Hashtable(unionset.Count); - foreach(object key in unionset) - { - if(leftset.Contains(key)) - { - result.Add(key, ((IDictionary)left)[key]); - } - else - { - result.Add(key, ((IDictionary)right)[key]); - } - } - return result; - } - else - { - throw new ArgumentException("Cannot add instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using Spring.Collections; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents arithmetic addition operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpADD : BinaryOperator + { + /// + /// Create a new instance + /// + public OpADD() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpADD(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the arithmetic addition operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal(context, evalContext); + object right = Right.GetValueInternal(context, evalContext); + + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + return NumberUtils.Add(left, right); + } + else if (left is DateTime && (right is TimeSpan || right is string || NumberUtils.IsNumber(right))) + { + if (NumberUtils.IsNumber(right)) + { + right = TimeSpan.FromDays(Convert.ToDouble(right)); + } + else if (right is string) + { + right = TimeSpan.Parse((string) right); + } + + return (DateTime) left + (TimeSpan) right; + } + else if (left is String || right is String) + { + return left.ToString() + right.ToString(); + } + else if ((left is IList || left is ISet) && (right is IList || right is ISet)) + { + ISet leftset = new HybridSet(left as ICollection); + ISet rightset = new HybridSet(right as ICollection); + return leftset.Union(rightset); + } + else if (left is IDictionary && right is IDictionary) + { + ISet leftset = new HybridSet(((IDictionary) left).Keys); + ISet rightset = new HybridSet(((IDictionary) right).Keys); + ISet unionset = leftset.Union(rightset); + + IDictionary result = new Hashtable(unionset.Count); + foreach(object key in unionset) + { + if(leftset.Contains(key)) + { + result.Add(key, ((IDictionary)left)[key]); + } + else + { + result.Add(key, ((IDictionary)right)[key]); + } + } + return result; + } + else + { + throw new ArgumentException("Cannot add instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpAND.cs b/src/Spring/Spring.Core/Expressions/OpAND.cs index cb3ea50b..633fc26f 100644 --- a/src/Spring/Spring.Core/Expressions/OpAND.cs +++ b/src/Spring/Spring.Core/Expressions/OpAND.cs @@ -1,61 +1,60 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents logical AND operator. - /// - /// Aleksandar Seovic - /// $Id: OpAND.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpAND : BinaryOperator - { - /// - /// Create a new instance - /// - public OpAND() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpAND(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical AND operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - return Convert.ToBoolean(Left.GetValueInternal(context, evalContext)) - && Convert.ToBoolean(Right.GetValueInternal(context, evalContext)); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents logical AND operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpAND : BinaryOperator + { + /// + /// Create a new instance + /// + public OpAND() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpAND(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical AND operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + return Convert.ToBoolean(Left.GetValueInternal(context, evalContext)) + && Convert.ToBoolean(Right.GetValueInternal(context, evalContext)); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpBetween.cs b/src/Spring/Spring.Core/Expressions/OpBetween.cs index 298d6409..897e5559 100644 --- a/src/Spring/Spring.Core/Expressions/OpBetween.cs +++ b/src/Spring/Spring.Core/Expressions/OpBetween.cs @@ -1,75 +1,74 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical BETWEEN operator. - /// - /// Aleksandar Seovic - /// $Id: OpBetween.cs,v 1.5 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpBetween : BinaryOperator - { - /// - /// Create a new instance - /// - public OpBetween() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpBetween(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical IN operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// - /// true if the left operand is contained within the right operand, false otherwise. - /// - protected override object Get(object context, EvaluationContext evalContext) - { - object value = Left.GetValueInternal(context, evalContext); - IList range = Right.GetValueInternal(context, evalContext) as IList; - - if (range == null || range.Count != 2) - { - throw new ArgumentException("Right operand for the 'between' operator has to be a two-element list."); - } - - object low = range[0]; - object high = range[1]; - - return (CompareUtils.Compare(value, low) >= 0 && CompareUtils.Compare(value, high) <= 0); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical BETWEEN operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpBetween : BinaryOperator + { + /// + /// Create a new instance + /// + public OpBetween() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpBetween(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical IN operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// + /// true if the left operand is contained within the right operand, false otherwise. + /// + protected override object Get(object context, EvaluationContext evalContext) + { + object value = Left.GetValueInternal(context, evalContext); + IList range = Right.GetValueInternal(context, evalContext) as IList; + + if (range == null || range.Count != 2) + { + throw new ArgumentException("Right operand for the 'between' operator has to be a two-element list."); + } + + object low = range[0]; + object high = range[1]; + + return (CompareUtils.Compare(value, low) >= 0 && CompareUtils.Compare(value, high) <= 0); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpDIVIDE.cs b/src/Spring/Spring.Core/Expressions/OpDIVIDE.cs index d6f6ef72..e10e5a8c 100644 --- a/src/Spring/Spring.Core/Expressions/OpDIVIDE.cs +++ b/src/Spring/Spring.Core/Expressions/OpDIVIDE.cs @@ -1,76 +1,75 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents arithmetic division operator. - /// - /// Aleksandar Seovic - /// $Id: OpDIVIDE.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpDIVIDE : BinaryOperator - { - /// - /// Create a new instance - /// - public OpDIVIDE() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpDIVIDE(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the arithmetic division operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal(context, evalContext); - object right = Right.GetValueInternal(context, evalContext); - - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - return NumberUtils.Divide(left, right); - } - else - { - throw new ArgumentException("Cannot divide instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents arithmetic division operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpDIVIDE : BinaryOperator + { + /// + /// Create a new instance + /// + public OpDIVIDE() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpDIVIDE(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the arithmetic division operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal(context, evalContext); + object right = Right.GetValueInternal(context, evalContext); + + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + return NumberUtils.Divide(left, right); + } + else + { + throw new ArgumentException("Cannot divide instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpEqual.cs b/src/Spring/Spring.Core/Expressions/OpEqual.cs index e740cd1d..684c025f 100644 --- a/src/Spring/Spring.Core/Expressions/OpEqual.cs +++ b/src/Spring/Spring.Core/Expressions/OpEqual.cs @@ -1,94 +1,93 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical equality operator. - /// - /// Aleksandar Seovic - /// $Id: OpEqual.cs,v 1.12 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpEqual : BinaryOperator - { - /// - /// Create a new instance - /// - public OpEqual() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpEqual(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical equality operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (left == null) - { - return (right == null); - } - else if (right == null) - { - return false; - } - else if (left.GetType() == right.GetType()) - { - if (left is Array) - { - return ArrayUtils.AreEqual(left as Array, right as Array); - } - else - { - return left.Equals(right); - } - } - else if (left.GetType().IsEnum && right is string) - { - return left.Equals(Enum.Parse(left.GetType(), (string) right)); - } - else if (right.GetType().IsEnum && left is string) - { - return right.Equals(Enum.Parse(right.GetType(), (string) left)); - } - else - { - return CompareUtils.Compare(left, right) == 0; - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical equality operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpEqual : BinaryOperator + { + /// + /// Create a new instance + /// + public OpEqual() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpEqual(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical equality operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (left == null) + { + return (right == null); + } + else if (right == null) + { + return false; + } + else if (left.GetType() == right.GetType()) + { + if (left is Array) + { + return ArrayUtils.AreEqual(left as Array, right as Array); + } + else + { + return left.Equals(right); + } + } + else if (left.GetType().IsEnum && right is string) + { + return left.Equals(Enum.Parse(left.GetType(), (string) right)); + } + else if (right.GetType().IsEnum && left is string) + { + return right.Equals(Enum.Parse(right.GetType(), (string) left)); + } + else + { + return CompareUtils.Compare(left, right) == 0; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpGreater.cs b/src/Spring/Spring.Core/Expressions/OpGreater.cs index 5ca6a970..2b83b35d 100644 --- a/src/Spring/Spring.Core/Expressions/OpGreater.cs +++ b/src/Spring/Spring.Core/Expressions/OpGreater.cs @@ -1,64 +1,63 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical "greater than" operator. - /// - /// Aleksandar Seovic - /// $Id: OpGreater.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpGreater : BinaryOperator - { - /// - /// Create a new instance - /// - public OpGreater():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpGreater(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical "greater than" operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal(context, evalContext); - object right = Right.GetValueInternal(context, evalContext); - - return CompareUtils.Compare(left, right) > 0; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical "greater than" operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpGreater : BinaryOperator + { + /// + /// Create a new instance + /// + public OpGreater():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpGreater(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical "greater than" operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal(context, evalContext); + object right = Right.GetValueInternal(context, evalContext); + + return CompareUtils.Compare(left, right) > 0; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpGreaterOrEqual.cs b/src/Spring/Spring.Core/Expressions/OpGreaterOrEqual.cs index 756c453e..fa74264d 100644 --- a/src/Spring/Spring.Core/Expressions/OpGreaterOrEqual.cs +++ b/src/Spring/Spring.Core/Expressions/OpGreaterOrEqual.cs @@ -1,64 +1,63 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical "greater than or equal" operator. - /// - /// Aleksandar Seovic - /// $Id: OpGreaterOrEqual.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpGreaterOrEqual : BinaryOperator - { - /// - /// Create a new instance - /// - public OpGreaterOrEqual():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpGreaterOrEqual(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical "greater than or equal" operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - return CompareUtils.Compare(left, right) >= 0; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical "greater than or equal" operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpGreaterOrEqual : BinaryOperator + { + /// + /// Create a new instance + /// + public OpGreaterOrEqual():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpGreaterOrEqual(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical "greater than or equal" operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + return CompareUtils.Compare(left, right) >= 0; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpIn.cs b/src/Spring/Spring.Core/Expressions/OpIn.cs index 05488fce..856cb157 100644 --- a/src/Spring/Spring.Core/Expressions/OpIn.cs +++ b/src/Spring/Spring.Core/Expressions/OpIn.cs @@ -1,82 +1,81 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents logical IN operator. - /// - /// Aleksandar Seovic - /// $Id: OpIn.cs,v 1.5 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpIn : BinaryOperator - { - /// - /// Create a new instance - /// - public OpIn():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpIn(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical IN operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// - /// true if the left operand is contained within the right operand, false otherwise. - /// - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (right == null) - { - return false; - } - else if (right is IList) - { - return ((IList) right).Contains(left); - } - else if (right is IDictionary) - { - return ((IDictionary) right).Contains(left); - } - else - { - throw new ArgumentException( - "Right hand parameter for 'in' operator has to be an instance of IList or IDictionary."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents logical IN operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpIn : BinaryOperator + { + /// + /// Create a new instance + /// + public OpIn():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpIn(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical IN operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// + /// true if the left operand is contained within the right operand, false otherwise. + /// + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (right == null) + { + return false; + } + else if (right is IList) + { + return ((IList) right).Contains(left); + } + else if (right is IDictionary) + { + return ((IDictionary) right).Contains(left); + } + else + { + throw new ArgumentException( + "Right hand parameter for 'in' operator has to be an instance of IList or IDictionary."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpIs.cs b/src/Spring/Spring.Core/Expressions/OpIs.cs index abecd404..dadf8161 100644 --- a/src/Spring/Spring.Core/Expressions/OpIs.cs +++ b/src/Spring/Spring.Core/Expressions/OpIs.cs @@ -1,69 +1,68 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents logical IS operator. - /// - /// Aleksandar Seovic - /// $Id: OpIs.cs,v 1.4 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpIs : BinaryOperator - { - /// - /// Create a new instance - /// - public OpIs():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpIs(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical IS operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// - /// true if the left operand is contained within the right operand, false otherwise. - /// - protected override object Get(object context, EvaluationContext evalContext) - { - object instance = Left.GetValueInternal( context, evalContext ); - Type type = Right.GetValueInternal( context, evalContext ) as Type; - - if (instance == null || type == null) - { - return false; - } - return type.IsAssignableFrom(instance.GetType()); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents logical IS operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpIs : BinaryOperator + { + /// + /// Create a new instance + /// + public OpIs():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpIs(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical IS operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// + /// true if the left operand is contained within the right operand, false otherwise. + /// + protected override object Get(object context, EvaluationContext evalContext) + { + object instance = Left.GetValueInternal( context, evalContext ); + Type type = Right.GetValueInternal( context, evalContext ) as Type; + + if (instance == null || type == null) + { + return false; + } + return type.IsAssignableFrom(instance.GetType()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpLess.cs b/src/Spring/Spring.Core/Expressions/OpLess.cs index 80c460ec..22375c72 100644 --- a/src/Spring/Spring.Core/Expressions/OpLess.cs +++ b/src/Spring/Spring.Core/Expressions/OpLess.cs @@ -1,64 +1,63 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical "less than" operator. - /// - /// Aleksandar Seovic - /// $Id: OpLess.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpLess : BinaryOperator - { - /// - /// Create a new instance - /// - public OpLess():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpLess(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical "less than" operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - return CompareUtils.Compare(left, right) < 0; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical "less than" operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpLess : BinaryOperator + { + /// + /// Create a new instance + /// + public OpLess():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpLess(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical "less than" operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + return CompareUtils.Compare(left, right) < 0; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpLessOrEqual.cs b/src/Spring/Spring.Core/Expressions/OpLessOrEqual.cs index e93e67d5..75a4c2ce 100644 --- a/src/Spring/Spring.Core/Expressions/OpLessOrEqual.cs +++ b/src/Spring/Spring.Core/Expressions/OpLessOrEqual.cs @@ -1,65 +1,64 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical "less than or equal" operator. - /// - /// Aleksandar Seovic - /// $Id: OpLessOrEqual.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpLessOrEqual : BinaryOperator - { - /// - /// Create a new instance - /// - public OpLessOrEqual():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpLessOrEqual(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical "less than or equal" operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - return CompareUtils.Compare(left, right) <= 0; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical "less than or equal" operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpLessOrEqual : BinaryOperator + { + /// + /// Create a new instance + /// + public OpLessOrEqual():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpLessOrEqual(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical "less than or equal" operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + return CompareUtils.Compare(left, right) <= 0; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpLike.cs b/src/Spring/Spring.Core/Expressions/OpLike.cs index b8a92561..0b5af217 100644 --- a/src/Spring/Spring.Core/Expressions/OpLike.cs +++ b/src/Spring/Spring.Core/Expressions/OpLike.cs @@ -1,73 +1,72 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -#if NET_2_0 && !MONO -using Microsoft.VisualBasic; -using Microsoft.VisualBasic.CompilerServices; -#endif - -namespace Spring.Expressions -{ - /// - /// Represents VB-style logical LIKE operator. - /// - /// Aleksandar Seovic - /// $Id: OpLike.cs,v 1.5 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpLike : BinaryOperator - { - /// - /// Create a new instance - /// - public OpLike():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpLike(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical LIKE operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// - /// true if the left operand matches the right operand, false otherwise. - /// - protected override object Get(object context, EvaluationContext evalContext) - { -#if NET_2_0 && !MONO - string text = Left.GetValueInternal( context, evalContext ) as string; - string pattern = Right.GetValueInternal( context, evalContext ) as string; - - return LikeOperator.LikeString(text, pattern, CompareMethod.Text); -#else - throw new NotSupportedException("'like' operator is only supported in .NET 2.0 or higher."); -#endif - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +#if NET_2_0 && !MONO +using Microsoft.VisualBasic; +using Microsoft.VisualBasic.CompilerServices; +#endif + +namespace Spring.Expressions +{ + /// + /// Represents VB-style logical LIKE operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpLike : BinaryOperator + { + /// + /// Create a new instance + /// + public OpLike():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpLike(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical LIKE operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// + /// true if the left operand matches the right operand, false otherwise. + /// + protected override object Get(object context, EvaluationContext evalContext) + { +#if NET_2_0 && !MONO + string text = Left.GetValueInternal( context, evalContext ) as string; + string pattern = Right.GetValueInternal( context, evalContext ) as string; + + return LikeOperator.LikeString(text, pattern, CompareMethod.Text); +#else + throw new NotSupportedException("'like' operator is only supported in .NET 2.0 or higher."); +#endif + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpMODULUS.cs b/src/Spring/Spring.Core/Expressions/OpMODULUS.cs index c65316ca..86a845ac 100644 --- a/src/Spring/Spring.Core/Expressions/OpMODULUS.cs +++ b/src/Spring/Spring.Core/Expressions/OpMODULUS.cs @@ -1,75 +1,74 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents arithmetic modulus operator. - /// - /// Aleksandar Seovic - /// $Id: OpMODULUS.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpMODULUS : BinaryOperator - { - /// - /// Create a new instance - /// - public OpMODULUS():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpMODULUS(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the arithmetic modulus operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - return NumberUtils.Modulus(left, right); - } - else - { - throw new ArgumentException("Cannot calculate modulus for instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents arithmetic modulus operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpMODULUS : BinaryOperator + { + /// + /// Create a new instance + /// + public OpMODULUS():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpMODULUS(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the arithmetic modulus operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + return NumberUtils.Modulus(left, right); + } + else + { + throw new ArgumentException("Cannot calculate modulus for instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpMULTIPLY.cs b/src/Spring/Spring.Core/Expressions/OpMULTIPLY.cs index 575f48fa..a117238c 100644 --- a/src/Spring/Spring.Core/Expressions/OpMULTIPLY.cs +++ b/src/Spring/Spring.Core/Expressions/OpMULTIPLY.cs @@ -1,126 +1,125 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using Spring.Collections; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents arithmetic multiplication operator. - /// - /// Aleksandar Seovic - /// $Id: OpMULTIPLY.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpMULTIPLY : BinaryOperator - { - /// - /// Create a new instance - /// - public OpMULTIPLY():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpMULTIPLY(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the arithmetic multiplication operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - return NumberUtils.Multiply(left, right); - } - else if (left is IList || left is ISet) - { - ISet leftset = new HybridSet(left as ICollection); - ISet rightset; - if (right is IList || right is ISet) - { - rightset = new HybridSet(right as ICollection); - } - else if (right is IDictionary) - { - rightset = new HybridSet(((IDictionary)right).Keys); - } - else - { - throw new ArgumentException("Cannot subtract instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - return leftset.Intersect(rightset); - } - else if (left is IDictionary) - { - ISet leftset = new HybridSet(((IDictionary)left).Keys); - ISet rightset; - if (right is IList || right is ISet) - { - rightset = new HybridSet(right as ICollection); - } - else if (right is IDictionary) - { - rightset = new HybridSet(((IDictionary)right).Keys); - } - else - { - throw new ArgumentException("Cannot subtract instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - IDictionary result = new Hashtable(rightset.Count); - foreach (object key in leftset.Intersect(rightset)) - { - result.Add(key, ((IDictionary)left)[key]); - } - return result; - } - else - { - throw new ArgumentException("Cannot multiply instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using Spring.Collections; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents arithmetic multiplication operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpMULTIPLY : BinaryOperator + { + /// + /// Create a new instance + /// + public OpMULTIPLY():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpMULTIPLY(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the arithmetic multiplication operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + return NumberUtils.Multiply(left, right); + } + else if (left is IList || left is ISet) + { + ISet leftset = new HybridSet(left as ICollection); + ISet rightset; + if (right is IList || right is ISet) + { + rightset = new HybridSet(right as ICollection); + } + else if (right is IDictionary) + { + rightset = new HybridSet(((IDictionary)right).Keys); + } + else + { + throw new ArgumentException("Cannot subtract instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + return leftset.Intersect(rightset); + } + else if (left is IDictionary) + { + ISet leftset = new HybridSet(((IDictionary)left).Keys); + ISet rightset; + if (right is IList || right is ISet) + { + rightset = new HybridSet(right as ICollection); + } + else if (right is IDictionary) + { + rightset = new HybridSet(((IDictionary)right).Keys); + } + else + { + throw new ArgumentException("Cannot subtract instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + IDictionary result = new Hashtable(rightset.Count); + foreach (object key in leftset.Intersect(rightset)) + { + result.Add(key, ((IDictionary)left)[key]); + } + return result; + } + else + { + throw new ArgumentException("Cannot multiply instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpMatches.cs b/src/Spring/Spring.Core/Expressions/OpMatches.cs index 7a5d9037..25366b09 100644 --- a/src/Spring/Spring.Core/Expressions/OpMatches.cs +++ b/src/Spring/Spring.Core/Expressions/OpMatches.cs @@ -1,78 +1,77 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using System.Text.RegularExpressions; - -namespace Spring.Expressions -{ - /// - /// Represents logical MATCHES operator. - /// - /// Aleksandar Seovic - /// $Id: OpMatches.cs,v 1.5 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpMatches : BinaryOperator - { - private Regex regex; - - /// - /// Create a new instance - /// - public OpMatches():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpMatches(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical MATCHES operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// - /// true if the left operand matches the right operand, false otherwise. - /// - protected override object Get(object context, EvaluationContext evalContext) - { - if (regex == null) - { - lock (this) - { - if (regex == null) - { - string pattern = Right.GetValueInternal( context, evalContext ) as string; - regex = new Regex(pattern, RegexOptions.Compiled); - } - } - } - - string text = Left.GetValueInternal( context, evalContext ) as string; - return regex.IsMatch(text); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using System.Text.RegularExpressions; + +namespace Spring.Expressions +{ + /// + /// Represents logical MATCHES operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpMatches : BinaryOperator + { + private Regex regex; + + /// + /// Create a new instance + /// + public OpMatches():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpMatches(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical MATCHES operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// + /// true if the left operand matches the right operand, false otherwise. + /// + protected override object Get(object context, EvaluationContext evalContext) + { + if (regex == null) + { + lock (this) + { + if (regex == null) + { + string pattern = Right.GetValueInternal( context, evalContext ) as string; + regex = new Regex(pattern, RegexOptions.Compiled); + } + } + } + + string text = Left.GetValueInternal( context, evalContext ) as string; + return regex.IsMatch(text); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpNOT.cs b/src/Spring/Spring.Core/Expressions/OpNOT.cs index f923b7d0..9b966704 100644 --- a/src/Spring/Spring.Core/Expressions/OpNOT.cs +++ b/src/Spring/Spring.Core/Expressions/OpNOT.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents logical NOT operator. - /// - /// Aleksandar Seovic - /// $Id: OpNOT.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpNOT : UnaryOperator - { - /// - /// Create a new instance - /// - public OpNOT():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpNOT(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical NOT operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - return !Convert.ToBoolean(Operand.GetValueInternal(context, evalContext)); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents logical NOT operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpNOT : UnaryOperator + { + /// + /// Create a new instance + /// + public OpNOT():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpNOT(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical NOT operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + return !Convert.ToBoolean(Operand.GetValueInternal(context, evalContext)); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpNotEqual.cs b/src/Spring/Spring.Core/Expressions/OpNotEqual.cs index 88907771..80874b32 100644 --- a/src/Spring/Spring.Core/Expressions/OpNotEqual.cs +++ b/src/Spring/Spring.Core/Expressions/OpNotEqual.cs @@ -1,86 +1,85 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents logical inequality operator. - /// - /// Aleksandar Seovic - /// $Id: OpNotEqual.cs,v 1.11 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpNotEqual : BinaryOperator - { - /// - /// Create a new instance - /// - public OpNotEqual():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpNotEqual(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical inequality operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (left == null) - { - return (right != null); - } - else if (right == null) - { - return true; - } - else if (left.GetType() == right.GetType()) - { - if (left is Array) - { - return !ArrayUtils.AreEqual(left as Array, right as Array); - } - else - { - return !left.Equals(right); - } - } - else - { - return CompareUtils.Compare(left, right) != 0; - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents logical inequality operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpNotEqual : BinaryOperator + { + /// + /// Create a new instance + /// + public OpNotEqual():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpNotEqual(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical inequality operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (left == null) + { + return (right != null); + } + else if (right == null) + { + return true; + } + else if (left.GetType() == right.GetType()) + { + if (left is Array) + { + return !ArrayUtils.AreEqual(left as Array, right as Array); + } + else + { + return !left.Equals(right); + } + } + else + { + return CompareUtils.Compare(left, right) != 0; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpOR.cs b/src/Spring/Spring.Core/Expressions/OpOR.cs index 14ce8627..50df3696 100644 --- a/src/Spring/Spring.Core/Expressions/OpOR.cs +++ b/src/Spring/Spring.Core/Expressions/OpOR.cs @@ -1,61 +1,60 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents logical OR operator. - /// - /// Aleksandar Seovic - /// $Id: OpOR.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpOR : BinaryOperator - { - /// - /// Create a new instance - /// - public OpOR():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpOR(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the logical OR operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - return Convert.ToBoolean( Left.GetValueInternal( context, evalContext ) ) - || Convert.ToBoolean( Right.GetValueInternal( context, evalContext ) ); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents logical OR operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpOR : BinaryOperator + { + /// + /// Create a new instance + /// + public OpOR():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpOR(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the logical OR operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + return Convert.ToBoolean( Left.GetValueInternal( context, evalContext ) ) + || Convert.ToBoolean( Right.GetValueInternal( context, evalContext ) ); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpPOWER.cs b/src/Spring/Spring.Core/Expressions/OpPOWER.cs index 733578e0..dc8c8ed9 100644 --- a/src/Spring/Spring.Core/Expressions/OpPOWER.cs +++ b/src/Spring/Spring.Core/Expressions/OpPOWER.cs @@ -1,75 +1,74 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents arithmetic exponent operator. - /// - /// Aleksandar Seovic - /// $Id: OpPOWER.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpPOWER : BinaryOperator - { - /// - /// Create a new instance - /// - public OpPOWER():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpPOWER(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the arithmetic exponent operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - return NumberUtils.Power(left, right); - } - else - { - throw new ArgumentException("Cannot calculate exponent for the instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents arithmetic exponent operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpPOWER : BinaryOperator + { + /// + /// Create a new instance + /// + public OpPOWER():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpPOWER(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the arithmetic exponent operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + return NumberUtils.Power(left, right); + } + else + { + throw new ArgumentException("Cannot calculate exponent for the instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpSUBTRACT.cs b/src/Spring/Spring.Core/Expressions/OpSUBTRACT.cs index 1f029d26..49468c93 100644 --- a/src/Spring/Spring.Core/Expressions/OpSUBTRACT.cs +++ b/src/Spring/Spring.Core/Expressions/OpSUBTRACT.cs @@ -1,142 +1,141 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; -using Spring.Collections; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents arithmetic subtraction operator. - /// - /// Aleksandar Seovic - /// $Id: OpSUBTRACT.cs,v 1.10 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpSUBTRACT : BinaryOperator - { - /// - /// Create a new instance - /// - public OpSUBTRACT():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpSUBTRACT(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the arithmetic subtraction operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object left = Left.GetValueInternal( context, evalContext ); - object right = Right.GetValueInternal( context, evalContext ); - - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - return NumberUtils.Subtract(left, right); - } - else if (left is DateTime && (right is TimeSpan || right is string || NumberUtils.IsNumber(right))) - { - if (NumberUtils.IsNumber(right)) - { - right = TimeSpan.FromDays(Convert.ToDouble(right)); - } - else if (right is string) - { - right = TimeSpan.Parse((string) right); - } - return (DateTime) left - (TimeSpan) right; - } - else if (left is DateTime && right is DateTime) - { - return (DateTime) left - (DateTime) right; - } - else if (left is IList || left is ISet) - { - ISet leftset = new HybridSet(left as ICollection); - ISet rightset; - if(right is IList || right is ISet) - { - rightset = new HybridSet(right as ICollection); - } - else if (right is IDictionary) - { - rightset = new HybridSet(((IDictionary) right).Keys); - } - else - { - throw new ArgumentException("Cannot subtract instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - return leftset.Minus(rightset); - } - else if (left is IDictionary) - { - ISet leftset = new HybridSet(((IDictionary) left).Keys); - ISet rightset; - if (right is IList || right is ISet) - { - rightset = new HybridSet(right as ICollection); - } - else if (right is IDictionary) - { - rightset = new HybridSet(((IDictionary) right).Keys); - } - else - { - throw new ArgumentException("Cannot subtract instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - IDictionary result = new Hashtable(rightset.Count); - foreach(object key in leftset.Minus(rightset)) - { - result.Add(key, ((IDictionary)left)[key]); - } - return result; - } - else - { - throw new ArgumentException("Cannot subtract instances of '" - + left.GetType().FullName - + "' and '" - + right.GetType().FullName - + "'."); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; +using Spring.Collections; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents arithmetic subtraction operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpSUBTRACT : BinaryOperator + { + /// + /// Create a new instance + /// + public OpSUBTRACT():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpSUBTRACT(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the arithmetic subtraction operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object left = Left.GetValueInternal( context, evalContext ); + object right = Right.GetValueInternal( context, evalContext ); + + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + return NumberUtils.Subtract(left, right); + } + else if (left is DateTime && (right is TimeSpan || right is string || NumberUtils.IsNumber(right))) + { + if (NumberUtils.IsNumber(right)) + { + right = TimeSpan.FromDays(Convert.ToDouble(right)); + } + else if (right is string) + { + right = TimeSpan.Parse((string) right); + } + return (DateTime) left - (TimeSpan) right; + } + else if (left is DateTime && right is DateTime) + { + return (DateTime) left - (DateTime) right; + } + else if (left is IList || left is ISet) + { + ISet leftset = new HybridSet(left as ICollection); + ISet rightset; + if(right is IList || right is ISet) + { + rightset = new HybridSet(right as ICollection); + } + else if (right is IDictionary) + { + rightset = new HybridSet(((IDictionary) right).Keys); + } + else + { + throw new ArgumentException("Cannot subtract instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + return leftset.Minus(rightset); + } + else if (left is IDictionary) + { + ISet leftset = new HybridSet(((IDictionary) left).Keys); + ISet rightset; + if (right is IList || right is ISet) + { + rightset = new HybridSet(right as ICollection); + } + else if (right is IDictionary) + { + rightset = new HybridSet(((IDictionary) right).Keys); + } + else + { + throw new ArgumentException("Cannot subtract instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + IDictionary result = new Hashtable(rightset.Count); + foreach(object key in leftset.Minus(rightset)) + { + result.Add(key, ((IDictionary)left)[key]); + } + return result; + } + else + { + throw new ArgumentException("Cannot subtract instances of '" + + left.GetType().FullName + + "' and '" + + right.GetType().FullName + + "'."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpUnaryMinus.cs b/src/Spring/Spring.Core/Expressions/OpUnaryMinus.cs index 11121670..94ed5049 100644 --- a/src/Spring/Spring.Core/Expressions/OpUnaryMinus.cs +++ b/src/Spring/Spring.Core/Expressions/OpUnaryMinus.cs @@ -1,68 +1,67 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents unary minus operator. - /// - /// Aleksandar Seovic - /// $Id: OpUnaryMinus.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpUnaryMinus : UnaryOperator - { - /// - /// Create a new instance - /// - public OpUnaryMinus():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpUnaryMinus(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the unary plus operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object n = Operand.GetValueInternal( context, evalContext ); - - if (!NumberUtils.IsNumber(n)) - { - throw new ArgumentException( - "Specified operand is not a number. Only numbers support unary minus operator."); - } - return NumberUtils.Negate(n); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents unary minus operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpUnaryMinus : UnaryOperator + { + /// + /// Create a new instance + /// + public OpUnaryMinus():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpUnaryMinus(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the unary plus operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object n = Operand.GetValueInternal( context, evalContext ); + + if (!NumberUtils.IsNumber(n)) + { + throw new ArgumentException( + "Specified operand is not a number. Only numbers support unary minus operator."); + } + return NumberUtils.Negate(n); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/OpUnaryPlus.cs b/src/Spring/Spring.Core/Expressions/OpUnaryPlus.cs index d0c0c0c1..76ccd982 100644 --- a/src/Spring/Spring.Core/Expressions/OpUnaryPlus.cs +++ b/src/Spring/Spring.Core/Expressions/OpUnaryPlus.cs @@ -1,68 +1,67 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -namespace Spring.Expressions -{ - /// - /// Represents unary plus operator. - /// - /// Aleksandar Seovic - /// $Id: OpUnaryPlus.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class OpUnaryPlus : UnaryOperator - { - /// - /// Create a new instance - /// - public OpUnaryPlus():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected OpUnaryPlus(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the unary plus operator node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object n = Operand.GetValueInternal( context, evalContext ); - - if (!NumberUtils.IsNumber(n)) - { - throw new ArgumentException( - "Specified operand is not a number. Only numbers support unary plus operator."); - } - return n; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +namespace Spring.Expressions +{ + /// + /// Represents unary plus operator. + /// + /// Aleksandar Seovic + [Serializable] + public class OpUnaryPlus : UnaryOperator + { + /// + /// Create a new instance + /// + public OpUnaryPlus():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected OpUnaryPlus(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the unary plus operator node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + object n = Operand.GetValueInternal( context, evalContext ); + + if (!NumberUtils.IsNumber(n)) + { + throw new ArgumentException( + "Specified operand is not a number. Only numbers support unary plus operator."); + } + return n; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/AverageAggregator.cs b/src/Spring/Spring.Core/Expressions/Processors/AverageAggregator.cs index 36083ab1..dea79a85 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/AverageAggregator.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/AverageAggregator.cs @@ -1,69 +1,68 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Spring.Util; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the average aggregator. - /// - /// Aleksandar Seovic - /// $Id: AverageAggregator.cs,v 1.2 2006/12/04 08:58:33 aseovic Exp $ - public class AverageAggregator : ICollectionProcessor - { - /// - /// Returns the average of the numeric values in the source collection. - /// - /// - /// The source collection to process. - /// - /// - /// Ignored. - /// - /// - /// The average of the numeric values in the source collection. - /// - public object Process(ICollection source, object[] args) - { - int n = 0; - object total = 0d; - foreach (object item in source) - { - if (item != null) - { - if (NumberUtils.IsNumber(item)) - { - total = NumberUtils.Add(total, item); - n++; - } - else - { - throw new ArgumentException("Average can only be calculated for a collection of numeric values."); - } - } - } - - return NumberUtils.Divide(total, n); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Spring.Util; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the average aggregator. + /// + /// Aleksandar Seovic + public class AverageAggregator : ICollectionProcessor + { + /// + /// Returns the average of the numeric values in the source collection. + /// + /// + /// The source collection to process. + /// + /// + /// Ignored. + /// + /// + /// The average of the numeric values in the source collection. + /// + public object Process(ICollection source, object[] args) + { + int n = 0; + object total = 0d; + foreach (object item in source) + { + if (item != null) + { + if (NumberUtils.IsNumber(item)) + { + total = NumberUtils.Add(total, item); + n++; + } + else + { + throw new ArgumentException("Average can only be calculated for a collection of numeric values."); + } + } + } + + return NumberUtils.Divide(total, n); + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs index a6fd412d..0f3df3e5 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Core.TypeConversion; - -#endregion - -namespace Spring.Expressions.Processors -{ - /// - /// Converts all elements in the input list to a given target type. - /// - /// Erich Eichinger - /// $Id: ConversionProcessor.cs,v 1.1 2008/03/20 23:58:16 oakinger Exp $ - public class ConversionProcessor : ICollectionProcessor - { - /// - /// Processes a list of source items and returns a result. - /// - /// - /// The source list to process. - /// - /// - /// An optional processor arguments array. - /// - /// - /// The processing result. - /// - public object Process(ICollection source, object[] args) - { - if (source == null - || source.Count == 0) - { - return source; - } - - Type targetType = typeof(double); - if (args == null || args.Length == 0) - { - throw new ArgumentNullException("convert() processor requires a Type value argument."); - } - else if (args.Length == 1) - { - if (args[0] is Type) - { - targetType = (Type)args[0]; - } - else - { - throw new ArgumentException("convert() processor argument must be a Type value."); - } - } - else if (args.Length > 1) - { - throw new ArgumentException("Only a single argument can be specified for a convert() processor."); - } - - ArrayList result = new ArrayList(); - foreach(object val in source) - { - object newVal = TypeConversionUtils.ConvertValueIfNecessary(targetType, val, null); - result.Add(newVal); - } - - return result.ToArray(targetType); - } - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Core.TypeConversion; + +#endregion + +namespace Spring.Expressions.Processors +{ + /// + /// Converts all elements in the input list to a given target type. + /// + /// Erich Eichinger + public class ConversionProcessor : ICollectionProcessor + { + /// + /// Processes a list of source items and returns a result. + /// + /// + /// The source list to process. + /// + /// + /// An optional processor arguments array. + /// + /// + /// The processing result. + /// + public object Process(ICollection source, object[] args) + { + if (source == null + || source.Count == 0) + { + return source; + } + + Type targetType = typeof(double); + if (args == null || args.Length == 0) + { + throw new ArgumentNullException("convert() processor requires a Type value argument."); + } + else if (args.Length == 1) + { + if (args[0] is Type) + { + targetType = (Type)args[0]; + } + else + { + throw new ArgumentException("convert() processor argument must be a Type value."); + } + } + else if (args.Length > 1) + { + throw new ArgumentException("Only a single argument can be specified for a convert() processor."); + } + + ArrayList result = new ArrayList(); + foreach(object val in source) + { + object newVal = TypeConversionUtils.ConvertValueIfNecessary(targetType, val, null); + result.Add(newVal); + } + + return result.ToArray(targetType); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/CountAggregator.cs b/src/Spring/Spring.Core/Expressions/Processors/CountAggregator.cs index fe0beb81..127f4802 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/CountAggregator.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/CountAggregator.cs @@ -1,54 +1,53 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the count aggregator. - /// - /// Aleksandar Seovic - /// $Id: CountAggregator.cs,v 1.2 2006/12/04 08:58:33 aseovic Exp $ - public class CountAggregator : ICollectionProcessor - { - /// - /// Returns the number of items in the source collection. - /// - /// - /// The source collection to process. - /// - /// - /// Ignored. - /// - /// - /// The number of items in the source collection, - /// or zero if the collection is empty or null. - /// - public object Process(ICollection source, object[] args) - { - if (source == null) - { - return 0; - } - return source.Count; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the count aggregator. + /// + /// Aleksandar Seovic + public class CountAggregator : ICollectionProcessor + { + /// + /// Returns the number of items in the source collection. + /// + /// + /// The source collection to process. + /// + /// + /// Ignored. + /// + /// + /// The number of items in the source collection, + /// or zero if the collection is empty or null. + /// + public object Process(ICollection source, object[] args) + { + if (source == null) + { + return 0; + } + return source.Count; + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/Processors/DistinctProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/DistinctProcessor.cs index 01107a6d..953c037f 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/DistinctProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/DistinctProcessor.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Spring.Collections; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the distinct processor. - /// - /// Aleksandar Seovic - /// $Id: DistinctProcessor.cs,v 1.1 2006/12/04 08:58:33 aseovic Exp $ - public class DistinctProcessor : ICollectionProcessor - { - /// - /// Returns distinct items from the collection. - /// - /// - /// The source collection to process. - /// - /// - /// 0: boolean flag specifying whether to include null - /// in the results or not. Default is false, which means that - /// null values will not be included in the results. - /// - /// - /// A collection containing distinct source collection elements. - /// - /// - /// If there is more than one argument, or if the single optional argument - /// is not Boolean. - /// - public object Process(ICollection source, object[] args) - { - if (source == null) - { - return null; - } - - bool includeNulls = false; - if (args.Length == 1) - { - if (args[0] is bool) - { - includeNulls = (bool) args[0]; - } - else - { - throw new ArgumentException("distinct() processor argument must be a boolean value."); - } - } - else if (args.Length > 1) - { - throw new ArgumentException("Only a single argument can be specified for a distinct() processor."); - } - - HybridSet set = new HybridSet(source); - if (!includeNulls) - { - set.Remove(null); - } - return set; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Spring.Collections; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the distinct processor. + /// + /// Aleksandar Seovic + public class DistinctProcessor : ICollectionProcessor + { + /// + /// Returns distinct items from the collection. + /// + /// + /// The source collection to process. + /// + /// + /// 0: boolean flag specifying whether to include null + /// in the results or not. Default is false, which means that + /// null values will not be included in the results. + /// + /// + /// A collection containing distinct source collection elements. + /// + /// + /// If there is more than one argument, or if the single optional argument + /// is not Boolean. + /// + public object Process(ICollection source, object[] args) + { + if (source == null) + { + return null; + } + + bool includeNulls = false; + if (args.Length == 1) + { + if (args[0] is bool) + { + includeNulls = (bool) args[0]; + } + else + { + throw new ArgumentException("distinct() processor argument must be a boolean value."); + } + } + else if (args.Length > 1) + { + throw new ArgumentException("Only a single argument can be specified for a distinct() processor."); + } + + HybridSet set = new HybridSet(source); + if (!includeNulls) + { + set.Remove(null); + } + return set; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/ICollectionProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/ICollectionProcessor.cs index b7a2563d..249bdfd1 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/ICollectionProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/ICollectionProcessor.cs @@ -1,45 +1,45 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Expressions.Processors -{ - /// - /// Defines an interface that should be implemented - /// by all collection processors and aggregators. - /// - public interface ICollectionProcessor - { - /// - /// Processes a list of source items and returns a result. - /// - /// - /// The source list to process. - /// - /// - /// An optional processor arguments array. - /// - /// - /// The processing result. - /// - object Process(ICollection source, object[] args); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Expressions.Processors +{ + /// + /// Defines an interface that should be implemented + /// by all collection processors and aggregators. + /// + public interface ICollectionProcessor + { + /// + /// Processes a list of source items and returns a result. + /// + /// + /// The source list to process. + /// + /// + /// An optional processor arguments array. + /// + /// + /// The processing result. + /// + object Process(ICollection source, object[] args); + } +} diff --git a/src/Spring/Spring.Core/Expressions/Processors/MaxAggregator.cs b/src/Spring/Spring.Core/Expressions/Processors/MaxAggregator.cs index 4040e12a..f2de9926 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/MaxAggregator.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/MaxAggregator.cs @@ -1,58 +1,57 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using Spring.Util; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the maximum aggregator. - /// - /// Aleksandar Seovic - /// $Id: MaxAggregator.cs,v 1.2 2006/12/04 08:58:33 aseovic Exp $ - public class MaxAggregator : ICollectionProcessor - { - /// - /// Returns the largest item in the source collection. - /// - /// - /// The source collection to process. - /// - /// - /// Ignored. - /// - /// - /// The largest item in the source collection. - /// - public object Process(ICollection source, object[] args) - { - object maxItem = null; - foreach (object item in source) - { - if (CompareUtils.Compare(maxItem, item) < 0) - { - maxItem = item; - } - } - return maxItem; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using Spring.Util; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the maximum aggregator. + /// + /// Aleksandar Seovic + public class MaxAggregator : ICollectionProcessor + { + /// + /// Returns the largest item in the source collection. + /// + /// + /// The source collection to process. + /// + /// + /// Ignored. + /// + /// + /// The largest item in the source collection. + /// + public object Process(ICollection source, object[] args) + { + object maxItem = null; + foreach (object item in source) + { + if (CompareUtils.Compare(maxItem, item) < 0) + { + maxItem = item; + } + } + return maxItem; + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/Processors/MinAggregator.cs b/src/Spring/Spring.Core/Expressions/Processors/MinAggregator.cs index e606c568..30ae2c92 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/MinAggregator.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/MinAggregator.cs @@ -1,58 +1,57 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using Spring.Util; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the minimum aggregator. - /// - /// Aleksandar Seovic - /// $Id: MinAggregator.cs,v 1.2 2006/12/04 08:58:33 aseovic Exp $ - public class MinAggregator : ICollectionProcessor - { - /// - /// Returns the smallest item in the source collection. - /// - /// - /// The source collection to process. - /// - /// - /// Ignored. - /// - /// - /// The smallest item in the source collection. - /// - public object Process(ICollection source, object[] args) - { - object minItem = null; - foreach (object item in source) - { - if ((minItem == null && item != null) || (CompareUtils.Compare(minItem, item) > 0)) - { - minItem = item; - } - } - return minItem; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using Spring.Util; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the minimum aggregator. + /// + /// Aleksandar Seovic + public class MinAggregator : ICollectionProcessor + { + /// + /// Returns the smallest item in the source collection. + /// + /// + /// The source collection to process. + /// + /// + /// Ignored. + /// + /// + /// The smallest item in the source collection. + /// + public object Process(ICollection source, object[] args) + { + object minItem = null; + foreach (object item in source) + { + if ((minItem == null && item != null) || (CompareUtils.Compare(minItem, item) > 0)) + { + minItem = item; + } + } + return minItem; + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/Processors/NonNullProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/NonNullProcessor.cs index 7fd37c8b..4cdcebec 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/NonNullProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/NonNullProcessor.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the non-null processor. - /// - /// Aleksandar Seovic - /// $Id: NonNullProcessor.cs,v 1.2 2007/07/31 21:43:52 markpollack Exp $ - public class NonNullProcessor : ICollectionProcessor - { - /// - /// Returns non-null items from the collection. - /// - /// - /// The source collection to process. - /// - /// - /// Ignored. - /// - /// - /// A collection containing non-null source collection elements. - /// - public object Process(ICollection source, object[] args) - { - if (source == null) - { - return null; - } - - ArrayList list = new ArrayList(); - foreach (object item in source) - { - if (item != null) - { - list.Add(item); - } - } - return list.ToArray(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the non-null processor. + /// + /// Aleksandar Seovic + public class NonNullProcessor : ICollectionProcessor + { + /// + /// Returns non-null items from the collection. + /// + /// + /// The source collection to process. + /// + /// + /// Ignored. + /// + /// + /// A collection containing non-null source collection elements. + /// + public object Process(ICollection source, object[] args) + { + if (source == null) + { + return null; + } + + ArrayList list = new ArrayList(); + foreach (object item in source) + { + if (item != null) + { + list.Add(item); + } + } + return list.ToArray(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/OrderByProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/OrderByProcessor.cs index 57bce703..0cc8aedd 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/OrderByProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/OrderByProcessor.cs @@ -1,166 +1,165 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Spring.Util; - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the 'order by' processor. - /// - /// Aleksandar Seovic - /// Erich Eichinger - /// $Id: OrderByProcessor.cs,v 1.2 2008/03/20 23:58:16 oakinger Exp $ - public class OrderByProcessor : ICollectionProcessor - { - #region Comparer Helper Implementations - - private class SimpleExpressionComparer : IComparer - { - private readonly IExpression _expression; - - public SimpleExpressionComparer(IExpression expression) - { - _expression = expression; - } - - public int Compare(object x, object y) - { - x = _expression.GetValue(x); - y = _expression.GetValue(y); - - if (x==y) return 0; - - if (x != null) return ((IComparable) x).CompareTo(y); - - return ((IComparable)y).CompareTo(x)*-1; - } - } - - private class LambdaComparer : IComparer - { - private readonly Hashtable _variables; - private readonly IExpression _fn; - - public LambdaComparer(LambdaExpressionNode lambdaExpression) - { - FunctionNode functionNode = new FunctionNode(); - functionNode.Text = "compare"; - VariableNode x = new VariableNode(); - x.Text = "x"; - VariableNode y = new VariableNode(); - y.Text = "y"; - - functionNode.addChild(x); - functionNode.addChild(y); - - _fn = functionNode; - _variables = new Hashtable(); - _variables.Add( "compare", lambdaExpression ); - } - - public int Compare(object x, object y) - { - _variables["x"] = x; - _variables["y"] = y; - return (int) _fn.GetValue(null, _variables); - } - } - - private class DelegateComparer : IComparer - { - private readonly Delegate _fnCompare; - - public DelegateComparer(Delegate fnCompare) - { - _fnCompare = fnCompare; - } - - public int Compare(object x, object y) - { - return (int)_fnCompare.DynamicInvoke(new object[] { x, y }); - } - } - - #endregion - - /// - /// Sorts the source collection using custom sort criteria. - /// - /// - /// Please not that your compare function needs to take care about - /// proper conversion of types to be comparable! - /// - /// - /// The source collection to sort. - /// - /// - /// Sort criteria to use. - /// - /// - /// A sorted array containing collection elements. - /// - public object Process(ICollection source, object[] args) - { - if (source == null || source.Count == 0) - { - return source; - } - - if (args == null || args.Length != 1) - { - throw new ArgumentException("compare expression is a required argument for orderBy"); - } - - object arg = args[0]; - IComparer comparer = null; - if (arg is string) - { - IExpression expCompare = Expression.Parse((string) arg); - comparer = new SimpleExpressionComparer(expCompare); - } - else if (arg is IComparer) - { - comparer = (IComparer) arg; - } - else if (arg is LambdaExpressionNode) - { - LambdaExpressionNode fnCompare = (LambdaExpressionNode)arg; - if (fnCompare.ArgumentNames.Length != 2) - { - throw new ArgumentException("compare function must accept 2 arguments"); - } - comparer = new LambdaComparer(fnCompare); - } - else if (arg is Delegate) - { - comparer = new DelegateComparer((Delegate) arg); - } - - AssertUtils.ArgumentNotNull(comparer, "comparer", "orderBy(comparer) argument 'comparer' does not evaluate to a supported type"); - - ArrayList list = new ArrayList(source); - list.Sort(comparer); - return list; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Spring.Util; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the 'order by' processor. + /// + /// Aleksandar Seovic + /// Erich Eichinger + public class OrderByProcessor : ICollectionProcessor + { + #region Comparer Helper Implementations + + private class SimpleExpressionComparer : IComparer + { + private readonly IExpression _expression; + + public SimpleExpressionComparer(IExpression expression) + { + _expression = expression; + } + + public int Compare(object x, object y) + { + x = _expression.GetValue(x); + y = _expression.GetValue(y); + + if (x==y) return 0; + + if (x != null) return ((IComparable) x).CompareTo(y); + + return ((IComparable)y).CompareTo(x)*-1; + } + } + + private class LambdaComparer : IComparer + { + private readonly Hashtable _variables; + private readonly IExpression _fn; + + public LambdaComparer(LambdaExpressionNode lambdaExpression) + { + FunctionNode functionNode = new FunctionNode(); + functionNode.Text = "compare"; + VariableNode x = new VariableNode(); + x.Text = "x"; + VariableNode y = new VariableNode(); + y.Text = "y"; + + functionNode.addChild(x); + functionNode.addChild(y); + + _fn = functionNode; + _variables = new Hashtable(); + _variables.Add( "compare", lambdaExpression ); + } + + public int Compare(object x, object y) + { + _variables["x"] = x; + _variables["y"] = y; + return (int) _fn.GetValue(null, _variables); + } + } + + private class DelegateComparer : IComparer + { + private readonly Delegate _fnCompare; + + public DelegateComparer(Delegate fnCompare) + { + _fnCompare = fnCompare; + } + + public int Compare(object x, object y) + { + return (int)_fnCompare.DynamicInvoke(new object[] { x, y }); + } + } + + #endregion + + /// + /// Sorts the source collection using custom sort criteria. + /// + /// + /// Please not that your compare function needs to take care about + /// proper conversion of types to be comparable! + /// + /// + /// The source collection to sort. + /// + /// + /// Sort criteria to use. + /// + /// + /// A sorted array containing collection elements. + /// + public object Process(ICollection source, object[] args) + { + if (source == null || source.Count == 0) + { + return source; + } + + if (args == null || args.Length != 1) + { + throw new ArgumentException("compare expression is a required argument for orderBy"); + } + + object arg = args[0]; + IComparer comparer = null; + if (arg is string) + { + IExpression expCompare = Expression.Parse((string) arg); + comparer = new SimpleExpressionComparer(expCompare); + } + else if (arg is IComparer) + { + comparer = (IComparer) arg; + } + else if (arg is LambdaExpressionNode) + { + LambdaExpressionNode fnCompare = (LambdaExpressionNode)arg; + if (fnCompare.ArgumentNames.Length != 2) + { + throw new ArgumentException("compare function must accept 2 arguments"); + } + comparer = new LambdaComparer(fnCompare); + } + else if (arg is Delegate) + { + comparer = new DelegateComparer((Delegate) arg); + } + + AssertUtils.ArgumentNotNull(comparer, "comparer", "orderBy(comparer) argument 'comparer' does not evaluate to a supported type"); + + ArrayList list = new ArrayList(source); + list.Sort(comparer); + return list; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/ReverseProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/ReverseProcessor.cs index 40919670..1803cb6c 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/ReverseProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/ReverseProcessor.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Expressions.Processors -{ - /// - /// Reverts order of elements in the list - /// - /// Erich Eichinger - /// $Id: ReverseProcessor.cs,v 1.1 2008/03/20 23:58:16 oakinger Exp $ - public class ReverseProcessor : ICollectionProcessor - { - /// - /// Processes a list of source items and returns a result. - /// - /// - /// The source list to process. - /// - /// - /// An optional processor arguments array. - /// - /// - /// The processing result. - /// - public object Process(ICollection source, object[] args) - { - if (source == null || source.Count == 0) - { - return source; - } - - ArrayList list = new ArrayList(source); - list.Reverse(); - - return list; - } - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Expressions.Processors +{ + /// + /// Reverts order of elements in the list + /// + /// Erich Eichinger + public class ReverseProcessor : ICollectionProcessor + { + /// + /// Processes a list of source items and returns a result. + /// + /// + /// The source list to process. + /// + /// + /// An optional processor arguments array. + /// + /// + /// The processing result. + /// + public object Process(ICollection source, object[] args) + { + if (source == null || source.Count == 0) + { + return source; + } + + ArrayList list = new ArrayList(source); + list.Reverse(); + + return list; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/SortProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/SortProcessor.cs index 857db6f3..3fbd7776 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/SortProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/SortProcessor.cs @@ -1,96 +1,95 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Collections; - -#endregion - -namespace Spring.Expressions.Processors -{ - /// - /// Implementation of the sort processor. - /// - /// Aleksandar Seovic - /// $Id: SortProcessor.cs,v 1.4 2008/03/20 23:58:16 oakinger Exp $ - public class SortProcessor : ICollectionProcessor - { - /// - /// Sorts the source collection. - /// - /// - /// Please not that this processor requires that collection elements - /// are of a uniform type and that they implement - /// interface. - ///

- /// If you want to perform custom sorting based on element properties - /// you should consider using instead. - /// - /// - /// The source collection to sort. - /// - /// - /// Ignored. - /// - /// - /// An array containing sorted collection elements. - /// - /// - /// If collection is not empty and it is - /// neither nor . - /// - public object Process(ICollection source, object[] args) - { - if (source == null || source.Count == 0) - { - return source; - } - - bool sortAscending = true; - if (args != null && args.Length == 1 && args[0] is bool) - { - sortAscending = (bool) args[0]; - } - - ArrayList list = new ArrayList(source); - list.Sort(); - if (!sortAscending) - { - list.Reverse(); - } - - Type elementType = DetermineElementType(list); - return list.ToArray(elementType); - } - - private Type DetermineElementType(IList list) - { - for(int i=0;i + /// Implementation of the sort processor. + /// + /// Aleksandar Seovic + public class SortProcessor : ICollectionProcessor + { + ///

+ /// Sorts the source collection. + /// + /// + /// Please not that this processor requires that collection elements + /// are of a uniform type and that they implement + /// interface. + ///

+ /// If you want to perform custom sorting based on element properties + /// you should consider using instead. + /// + /// + /// The source collection to sort. + /// + /// + /// Ignored. + /// + /// + /// An array containing sorted collection elements. + /// + /// + /// If collection is not empty and it is + /// neither nor . + /// + public object Process(ICollection source, object[] args) + { + if (source == null || source.Count == 0) + { + return source; + } + + bool sortAscending = true; + if (args != null && args.Length == 1 && args[0] is bool) + { + sortAscending = (bool) args[0]; + } + + ArrayList list = new ArrayList(source); + list.Sort(); + if (!sortAscending) + { + list.Reverse(); + } + + Type elementType = DetermineElementType(list); + return list.ToArray(elementType); + } + + private Type DetermineElementType(IList list) + { + for(int i=0;i - /// Implementation of the sum aggregator. - /// - /// Aleksandar Seovic - /// $Id: SumAggregator.cs,v 1.2 2006/12/04 08:58:33 aseovic Exp $ - public class SumAggregator : ICollectionProcessor - { - ///

- /// Returns the sum of the numeric values in the source collection. - /// - /// - /// The source collection to process. - /// - /// - /// Ignored. - /// - /// - /// The sum of the numeric values in the source collection. - /// - public object Process(ICollection source, object[] args) - { - object total = 0d; - foreach (object item in source) - { - if (item != null) - { - if (NumberUtils.IsNumber(item)) - { - total = NumberUtils.Add(total, item); - } - else - { - throw new ArgumentException("Sum can only be calculated for a collection of numeric values."); - } - } - } - - return total; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Spring.Util; + +namespace Spring.Expressions.Processors +{ + /// + /// Implementation of the sum aggregator. + /// + /// Aleksandar Seovic + public class SumAggregator : ICollectionProcessor + { + /// + /// Returns the sum of the numeric values in the source collection. + /// + /// + /// The source collection to process. + /// + /// + /// Ignored. + /// + /// + /// The sum of the numeric values in the source collection. + /// + public object Process(ICollection source, object[] args) + { + object total = 0d; + foreach (object item in source) + { + if (item != null) + { + if (NumberUtils.IsNumber(item)) + { + total = NumberUtils.Add(total, item); + } + else + { + throw new ArgumentException("Sum can only be calculated for a collection of numeric values."); + } + } + } + + return total; + } + } +} diff --git a/src/Spring/Spring.Core/Expressions/ProjectionNode.cs b/src/Spring/Spring.Core/Expressions/ProjectionNode.cs index ec153876..707fe759 100644 --- a/src/Spring/Spring.Core/Expressions/ProjectionNode.cs +++ b/src/Spring/Spring.Core/Expressions/ProjectionNode.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed projection node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: ProjectionNode.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class ProjectionNode : BaseNode - { - /// - /// Create a new instance - /// - public ProjectionNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected ProjectionNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a containing results of evaluation - /// of projection expression against each node in the context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - IEnumerable enumerable = context as IEnumerable; - if(enumerable == null) - { - throw new ArgumentException( - "Projection can only be used on an instance of the type that implements IEnumerable."); - } - - BaseNode expression = (BaseNode) this.getFirstChild(); - IList projectedList = new ArrayList(); - using (evalContext.SwitchThisContext()) - { - foreach(object o in enumerable) - { - evalContext.ThisContext = o; - projectedList.Add(expression.GetValueInternal(o, evalContext)); - } - } - return projectedList; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed projection node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class ProjectionNode : BaseNode + { + /// + /// Create a new instance + /// + public ProjectionNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected ProjectionNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a containing results of evaluation + /// of projection expression against each node in the context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + IEnumerable enumerable = context as IEnumerable; + if(enumerable == null) + { + throw new ArgumentException( + "Projection can only be used on an instance of the type that implements IEnumerable."); + } + + BaseNode expression = (BaseNode) this.getFirstChild(); + IList projectedList = new ArrayList(); + using (evalContext.SwitchThisContext()) + { + foreach(object o in enumerable) + { + evalContext.ThisContext = o; + projectedList.Add(expression.GetValueInternal(o, evalContext)); + } + } + return projectedList; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs b/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs index b2c8bb08..ee62e639 100644 --- a/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs +++ b/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs @@ -1,725 +1,724 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Runtime.Remoting; -using System.Runtime.Serialization; - -using Spring.Collections; -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Core.TypeResolution; -using Spring.Util; -using Spring.Reflection.Dynamic; - -#endregion - -namespace Spring.Expressions -{ - /// - /// Represents node that navigates to object's property or public field. - /// - /// Aleksandar Seovic - /// $Id: PropertyOrFieldNode.cs,v 1.28 2007/09/14 13:48:53 oakinger Exp $ - [Serializable] - public class PropertyOrFieldNode : BaseNode - { - //private static readonly Common.Logging.ILog Log = Common.Logging.LogManager.GetLogger(typeof(PropertyOrFieldNode)); - - private const BindingFlags BINDING_FLAGS = - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | - BindingFlags.IgnoreCase; - - private string memberName; - private IValueAccessor accessor; - - /// - /// Create a new instance - /// - public PropertyOrFieldNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected PropertyOrFieldNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Initializes the node. - /// - /// The parent. - private void InitializeNode(object context) - { - Type contextType = (context == null || context is Type ? context as Type : context.GetType()); - - if (accessor == null || accessor.RequiresRefresh(contextType)) - { - memberName = this.getText(); - - // clear cached member info if context type has changed (for example, when ASP.NET page is recompiled) - if (accessor != null && accessor.RequiresRefresh(contextType)) - { - accessor = null; - } - - // initialize this node if necessary - if (contextType != null && accessor == null) - { - // try to initialize node as enum value first - if (contextType.IsEnum) - { - try - { - accessor = new EnumValueAccessor(Enum.Parse(contextType, memberName, true)); - } - catch (ArgumentException) - { - // ArgumentException will be thrown if specified member name is not a valid - // enum value for the context type. We should just ignore it and continue processing, - // because the specified member could be a property of a Type class (i.e. EnumType.FullName) - } - } - - // then try to initialize node as property or field value - if (accessor == null) - { - // check the context type first - accessor = GetPropertyOrFieldAccessor(contextType, memberName, BINDING_FLAGS); - - // if not found, probe the Type type - if (accessor == null && context is Type) - { - accessor = GetPropertyOrFieldAccessor(typeof(Type), memberName, BINDING_FLAGS); - } - } - } - - // if there is still no match, try to initialize node as type accessor - if (accessor == null) - { - try - { - accessor = new TypeValueAccessor(TypeResolutionUtils.ResolveType(memberName)); - } - catch (TypeLoadException) - { - if (context == null) - { - throw new NullValueInNestedPathException("Cannot initialize property or field node '" + - memberName + - "' because the specified context is null."); - } - else - { - throw new InvalidPropertyException(contextType, memberName, - "'" + memberName + - "' node cannot be resolved for the specified context [" + - context + "]."); - } - } - } - } - } - - /// - /// Attempts to resolve property or field. - /// - /// - /// Type to search for a property or a field. - /// - /// - /// Property or field name. - /// - /// - /// Binding flags to use. - /// - /// - /// Resolved property or field accessor, or null - /// if specified cannot be resolved. - /// - private static IValueAccessor GetPropertyOrFieldAccessor(Type contextType, string memberName, BindingFlags bindingFlags) - { - try - { - PropertyInfo pi = contextType.GetProperty(memberName, bindingFlags); - if (pi == null) - { - FieldInfo fi = contextType.GetField(memberName, bindingFlags); - if (fi != null) - { - return new FieldValueAccessor(fi); - } - } - else - { - return new PropertyValueAccessor(pi); - } - } - catch (AmbiguousMatchException) - { - PropertyInfo pi = null; - - // search type hierarchy - while (contextType != typeof(object)) - { - pi = contextType.GetProperty(memberName, bindingFlags | BindingFlags.DeclaredOnly); - if (pi == null) - { - FieldInfo fi = contextType.GetField(memberName, bindingFlags | BindingFlags.DeclaredOnly); - if (fi != null) - { - return new FieldValueAccessor(fi); - } - } - else - { - return new PropertyValueAccessor(pi); - } - contextType = contextType.BaseType; - } - } - - return null; - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - lock (this) - { - InitializeNode(context); - - if (context == null && accessor.RequiresContext) - { - throw new NullValueInNestedPathException( - "Cannot retrieve the value of a field or property '" + this.memberName - + "', because context for its resolution is null."); - } - if (IsProperty || IsField) - { - return GetPropertyOrFieldValue(context, evalContext); - } - else - { - return accessor.Get(context); - } - } - } - - /// - /// Sets node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// New value for this node. - protected override void Set(object context, EvaluationContext evalContext, object newValue) - { - lock (this) - { - InitializeNode(context); - - if (context == null && accessor.RequiresContext) - { - throw new NullValueInNestedPathException( - "Cannot set the value of a field or property '" + this.memberName - + "', because context for its resolution is null."); - } - if (IsProperty || IsField) - { - SetPropertyOrFieldValue(context, evalContext, newValue); - } - else - { - accessor.Set(context, newValue); - } - } - } - - /// - /// Gets a value indicating whether this node represents a property. - /// - /// - /// true if this node is a property; otherwise, false. - /// - private bool IsProperty - { - get { return accessor is PropertyValueAccessor; } - } - - /// - /// Gets a value indicating whether this node represents a field. - /// - /// - /// true if this node is a field; otherwise, false. - /// - private bool IsField - { - get { return accessor is FieldValueAccessor; } - } - - /// - /// Retrieves property or field value. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Property or field value. - private object GetPropertyOrFieldValue(object context, EvaluationContext evalContext) - { - try - { - return accessor.Get(context); - } - catch (InvalidOperationException) - { - throw new NotReadablePropertyException(evalContext.RootContextType, this.memberName); - } - catch (TargetInvocationException e) - { - throw new InvalidPropertyException(evalContext.RootContextType, this.memberName, - "Getter for property '" + this.memberName + "' threw an exception.", - e); - } - catch (UnauthorizedAccessException e) - { - throw new InvalidPropertyException(evalContext.RootContextType, this.memberName, - "Illegal attempt to get value for the property '" + this.memberName + - "'.", e); - } - } - - /// - /// Sets property value, doing any type conversions that are necessary along the way. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// New value for this node. - private void SetPropertyOrFieldValue(object context, EvaluationContext evalContext, object newValue) - { - bool isWriteable = accessor.IsWriteable; - Type targetType = accessor.TargetType; - - try - { - if (!isWriteable) - { - if (!AddToCollections(context, evalContext, newValue)) - { - throw new NotWritablePropertyException( - "Can't change the value of the read-only property or field '" + this.memberName + "'."); - } - } - else if (targetType.IsPrimitive && (newValue == null || String.Empty.Equals(newValue))) - { - throw new ArgumentException("Invalid value [" + newValue + "] for property or field '" + - this.memberName + "' of primitive type [" - + targetType + "]"); - } - else if (newValue == null || targetType.IsAssignableFrom(newValue.GetType())) - { - SetPropertyOrFieldValueInternal(context, newValue); - } - else if (!RemotingServices.IsTransparentProxy(newValue) && - (newValue is IList || newValue is IDictionary || newValue is ISet)) - { - if (!AddToCollections(context, evalContext, newValue)) - { - object tmpValue = - TypeConversionUtils.ConvertValueIfNecessary(targetType, newValue, this.memberName); - SetPropertyOrFieldValueInternal(context, tmpValue); - } - } - else - { - object tmpValue = TypeConversionUtils.ConvertValueIfNecessary(targetType, newValue, this.memberName); - SetPropertyOrFieldValueInternal(context, tmpValue); - } - } - catch (TargetInvocationException ex) - { - PropertyChangeEventArgs propertyChangeEvent = - new PropertyChangeEventArgs(this.memberName, null, newValue); - if (ex.GetBaseException() is InvalidCastException) - { - throw new TypeMismatchException(propertyChangeEvent, targetType, ex.GetBaseException()); - } - else - { - throw new MethodInvocationException(ex.GetBaseException(), propertyChangeEvent); - } - } - catch (UnauthorizedAccessException ex) - { - throw new FatalReflectionException("Illegal attempt to set property '" + this.memberName + "'", ex); - } - catch (NotWritablePropertyException) - { - throw; - } - catch (NotReadablePropertyException) - { - throw; - } - catch (ArgumentException ex) - { - PropertyChangeEventArgs propertyChangeEvent = - new PropertyChangeEventArgs(this.memberName, null, newValue); - throw new TypeMismatchException(propertyChangeEvent, targetType, ex); - } - } - - /// - /// Sets property or field value using either dynamic or standard reflection. - /// - /// Object to evaluate node against. - /// New value for this node, converted to appropriate type. - private void SetPropertyOrFieldValueInternal(object context, object newValue) - { - accessor.Set(context, newValue); - } - - /// - /// In the case of read only collections or custom collections that are not assignable from - /// IList, try to add to the collection. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// New value for this node. - /// true if was able add to IList, IDictionary, or ISet - private bool AddToCollections(object context, EvaluationContext evalContext, object newValue) - { - // short-circuit if accessor is not readable - if (!this.accessor.IsReadable) - { - return false; - } - - bool added = false; - - // try adding values if property is a list... - if (newValue is IList && !RemotingServices.IsTransparentProxy(newValue)) - { - IList currentValue = (IList)Get(context, evalContext); - if (currentValue != null && !currentValue.IsFixedSize && !currentValue.IsReadOnly) - { - foreach (object el in (IList)newValue) - { - currentValue.Add(el); - } - added = true; - } - } - // try adding values if property is a dictionary... - else if (newValue is IDictionary && !RemotingServices.IsTransparentProxy(newValue)) - { - IDictionary currentValue = (IDictionary)Get(context, evalContext); - if (currentValue != null && !currentValue.IsFixedSize && !currentValue.IsReadOnly) - { - foreach (DictionaryEntry entry in (IDictionary)newValue) - { - currentValue[entry.Key] = entry.Value; - } - added = true; - } - } - // try adding values if property is a set... - else if (newValue is ISet && !RemotingServices.IsTransparentProxy(newValue)) - { - ISet currentValue = (ISet)Get(context, evalContext); - if (currentValue != null) - { - currentValue.AddAll((ICollection)newValue); - added = true; - } - } - return added; - } - - /// - /// Utility method that is needed by ObjectWrapper and AbstractAutowireCapableObjectFactory. - /// We try as hard as we can, but there are instances when we won't be able to obtain PropertyInfo... - /// - /// Context to resolve property against. - /// PropertyInfo for this node. - internal MemberInfo GetMemberInfo(object context) - { - lock (this) - { - InitializeNode(context); - } - return accessor.MemberInfo; - - //if (IsProperty) - //{ - // return (((PropertyValueAccessor) accessor).MemberInfo); - //} - //else - //{ - // throw new FatalObjectException( - // "Cannot obtain PropertyInfo from an expression that does not resolve to a property."); - //} - } - - #region IValueAccessor interface - - private interface IValueAccessor - { - object Get(object context); - void Set(object context, object value); - - bool IsReadable { get; } - bool IsWriteable { get; } - bool RequiresContext { get; } - Type TargetType { get; } - MemberInfo MemberInfo { get; } - bool RequiresRefresh(Type contextType); - } - - #endregion - - #region BaseValueAccessor implementation - - private abstract class BaseValueAccessor : IValueAccessor - { - public abstract object Get(object context); - - public abstract void Set(object context, object value); - - public virtual bool IsReadable - { - get { return true; } - } - - public virtual bool IsWriteable - { - get { return false; } - } - - public virtual bool RequiresContext - { - get { return false; } - } - - public virtual Type TargetType - { - get { throw new NotSupportedException(); } - } - - public virtual MemberInfo MemberInfo - { - get { throw new NotSupportedException(); } - } - - public virtual bool RequiresRefresh(Type contextType) - { - return false; - } - } - - #endregion - - #region PropertyValueAccessor implementation - - private class PropertyValueAccessor : BaseValueAccessor - { - private SafeProperty property; - private string name; - private bool isReadable; - private bool isWriteable; - private Type targetType; - private Type contextType; - - public PropertyValueAccessor(PropertyInfo propertyInfo) - { - this.name = propertyInfo.Name; - this.isReadable = propertyInfo.CanRead; - this.isWriteable = propertyInfo.CanWrite; - this.targetType = propertyInfo.PropertyType; - this.contextType = propertyInfo.DeclaringType; - this.property = new SafeProperty(propertyInfo); - } - - public override object Get(object context) - { - if (!isReadable) - { - throw new NotReadablePropertyException("Cannot get a non-readable property [" + name + "]"); - } - return property.GetValue(context); - } - - public override void Set(object context, object value) - { - if (!isWriteable) - { - throw new NotWritablePropertyException("Cannot set a read-only property [" + name + "]"); - } - property.SetValue(context, value); - } - - public override bool IsReadable - { - get { return isReadable; } - } - - public override bool IsWriteable - { - get { return isWriteable; } - } - - public override bool RequiresContext - { - get { return true; } - } - - public override Type TargetType - { - get { return targetType; } - } - - public override MemberInfo MemberInfo - { - get { return property.PropertyInfo; } - } - - public override bool RequiresRefresh(Type contextType) - { - return this.contextType != contextType; - } - } - - #endregion - - #region FieldValueAccessor implementation - - private class FieldValueAccessor : BaseValueAccessor - { - private SafeField field; - private bool isWriteable; - private Type targetType; - private Type contextType; - - public FieldValueAccessor(FieldInfo fieldInfo) - { - this.field = new SafeField(fieldInfo); - this.isWriteable = !(fieldInfo.IsInitOnly || fieldInfo.IsLiteral); - this.targetType = fieldInfo.FieldType; - this.contextType = fieldInfo.DeclaringType; - } - - public override object Get(object context) - { - return field.GetValue(context); - } - - public override void Set(object context, object value) - { - field.SetValue(context, value); - } - - public override bool IsWriteable - { - get { return isWriteable; } - } - - public override bool RequiresContext - { - get { return true; } - } - - public override Type TargetType - { - get { return targetType; } - } - - public override MemberInfo MemberInfo - { - get { return field.FieldInfo; } - } - - public override bool RequiresRefresh(Type contextType) - { - return this.contextType != contextType; - } - } - - #endregion - - #region EnumValueAccessor implementation - - private class EnumValueAccessor : BaseValueAccessor - { - private object enumValue; - - public EnumValueAccessor(object enumValue) - { - this.enumValue = enumValue; - } - - public override object Get(object context) - { - return enumValue; - } - - public override void Set(object context, object value) - { - throw new NotSupportedException("Cannot set the value of an enum."); - } - } - - #endregion - - #region TypeValueAccessor implementation - - private class TypeValueAccessor : BaseValueAccessor - { - private Type type; - - public TypeValueAccessor(Type type) - { - this.type = type; - } - - public override object Get(object context) - { - return type; - } - - public override void Set(object context, object value) - { - throw new NotSupportedException("Cannot set the value of a type."); - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.Remoting; +using System.Runtime.Serialization; + +using Spring.Collections; +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Core.TypeResolution; +using Spring.Util; +using Spring.Reflection.Dynamic; + +#endregion + +namespace Spring.Expressions +{ + /// + /// Represents node that navigates to object's property or public field. + /// + /// Aleksandar Seovic + [Serializable] + public class PropertyOrFieldNode : BaseNode + { + //private static readonly Common.Logging.ILog Log = Common.Logging.LogManager.GetLogger(typeof(PropertyOrFieldNode)); + + private const BindingFlags BINDING_FLAGS = + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | + BindingFlags.IgnoreCase; + + private string memberName; + private IValueAccessor accessor; + + /// + /// Create a new instance + /// + public PropertyOrFieldNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected PropertyOrFieldNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Initializes the node. + /// + /// The parent. + private void InitializeNode(object context) + { + Type contextType = (context == null || context is Type ? context as Type : context.GetType()); + + if (accessor == null || accessor.RequiresRefresh(contextType)) + { + memberName = this.getText(); + + // clear cached member info if context type has changed (for example, when ASP.NET page is recompiled) + if (accessor != null && accessor.RequiresRefresh(contextType)) + { + accessor = null; + } + + // initialize this node if necessary + if (contextType != null && accessor == null) + { + // try to initialize node as enum value first + if (contextType.IsEnum) + { + try + { + accessor = new EnumValueAccessor(Enum.Parse(contextType, memberName, true)); + } + catch (ArgumentException) + { + // ArgumentException will be thrown if specified member name is not a valid + // enum value for the context type. We should just ignore it and continue processing, + // because the specified member could be a property of a Type class (i.e. EnumType.FullName) + } + } + + // then try to initialize node as property or field value + if (accessor == null) + { + // check the context type first + accessor = GetPropertyOrFieldAccessor(contextType, memberName, BINDING_FLAGS); + + // if not found, probe the Type type + if (accessor == null && context is Type) + { + accessor = GetPropertyOrFieldAccessor(typeof(Type), memberName, BINDING_FLAGS); + } + } + } + + // if there is still no match, try to initialize node as type accessor + if (accessor == null) + { + try + { + accessor = new TypeValueAccessor(TypeResolutionUtils.ResolveType(memberName)); + } + catch (TypeLoadException) + { + if (context == null) + { + throw new NullValueInNestedPathException("Cannot initialize property or field node '" + + memberName + + "' because the specified context is null."); + } + else + { + throw new InvalidPropertyException(contextType, memberName, + "'" + memberName + + "' node cannot be resolved for the specified context [" + + context + "]."); + } + } + } + } + } + + /// + /// Attempts to resolve property or field. + /// + /// + /// Type to search for a property or a field. + /// + /// + /// Property or field name. + /// + /// + /// Binding flags to use. + /// + /// + /// Resolved property or field accessor, or null + /// if specified cannot be resolved. + /// + private static IValueAccessor GetPropertyOrFieldAccessor(Type contextType, string memberName, BindingFlags bindingFlags) + { + try + { + PropertyInfo pi = contextType.GetProperty(memberName, bindingFlags); + if (pi == null) + { + FieldInfo fi = contextType.GetField(memberName, bindingFlags); + if (fi != null) + { + return new FieldValueAccessor(fi); + } + } + else + { + return new PropertyValueAccessor(pi); + } + } + catch (AmbiguousMatchException) + { + PropertyInfo pi = null; + + // search type hierarchy + while (contextType != typeof(object)) + { + pi = contextType.GetProperty(memberName, bindingFlags | BindingFlags.DeclaredOnly); + if (pi == null) + { + FieldInfo fi = contextType.GetField(memberName, bindingFlags | BindingFlags.DeclaredOnly); + if (fi != null) + { + return new FieldValueAccessor(fi); + } + } + else + { + return new PropertyValueAccessor(pi); + } + contextType = contextType.BaseType; + } + } + + return null; + } + + /// + /// Returns node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + lock (this) + { + InitializeNode(context); + + if (context == null && accessor.RequiresContext) + { + throw new NullValueInNestedPathException( + "Cannot retrieve the value of a field or property '" + this.memberName + + "', because context for its resolution is null."); + } + if (IsProperty || IsField) + { + return GetPropertyOrFieldValue(context, evalContext); + } + else + { + return accessor.Get(context); + } + } + } + + /// + /// Sets node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// New value for this node. + protected override void Set(object context, EvaluationContext evalContext, object newValue) + { + lock (this) + { + InitializeNode(context); + + if (context == null && accessor.RequiresContext) + { + throw new NullValueInNestedPathException( + "Cannot set the value of a field or property '" + this.memberName + + "', because context for its resolution is null."); + } + if (IsProperty || IsField) + { + SetPropertyOrFieldValue(context, evalContext, newValue); + } + else + { + accessor.Set(context, newValue); + } + } + } + + /// + /// Gets a value indicating whether this node represents a property. + /// + /// + /// true if this node is a property; otherwise, false. + /// + private bool IsProperty + { + get { return accessor is PropertyValueAccessor; } + } + + /// + /// Gets a value indicating whether this node represents a field. + /// + /// + /// true if this node is a field; otherwise, false. + /// + private bool IsField + { + get { return accessor is FieldValueAccessor; } + } + + /// + /// Retrieves property or field value. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Property or field value. + private object GetPropertyOrFieldValue(object context, EvaluationContext evalContext) + { + try + { + return accessor.Get(context); + } + catch (InvalidOperationException) + { + throw new NotReadablePropertyException(evalContext.RootContextType, this.memberName); + } + catch (TargetInvocationException e) + { + throw new InvalidPropertyException(evalContext.RootContextType, this.memberName, + "Getter for property '" + this.memberName + "' threw an exception.", + e); + } + catch (UnauthorizedAccessException e) + { + throw new InvalidPropertyException(evalContext.RootContextType, this.memberName, + "Illegal attempt to get value for the property '" + this.memberName + + "'.", e); + } + } + + /// + /// Sets property value, doing any type conversions that are necessary along the way. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// New value for this node. + private void SetPropertyOrFieldValue(object context, EvaluationContext evalContext, object newValue) + { + bool isWriteable = accessor.IsWriteable; + Type targetType = accessor.TargetType; + + try + { + if (!isWriteable) + { + if (!AddToCollections(context, evalContext, newValue)) + { + throw new NotWritablePropertyException( + "Can't change the value of the read-only property or field '" + this.memberName + "'."); + } + } + else if (targetType.IsPrimitive && (newValue == null || String.Empty.Equals(newValue))) + { + throw new ArgumentException("Invalid value [" + newValue + "] for property or field '" + + this.memberName + "' of primitive type [" + + targetType + "]"); + } + else if (newValue == null || targetType.IsAssignableFrom(newValue.GetType())) + { + SetPropertyOrFieldValueInternal(context, newValue); + } + else if (!RemotingServices.IsTransparentProxy(newValue) && + (newValue is IList || newValue is IDictionary || newValue is ISet)) + { + if (!AddToCollections(context, evalContext, newValue)) + { + object tmpValue = + TypeConversionUtils.ConvertValueIfNecessary(targetType, newValue, this.memberName); + SetPropertyOrFieldValueInternal(context, tmpValue); + } + } + else + { + object tmpValue = TypeConversionUtils.ConvertValueIfNecessary(targetType, newValue, this.memberName); + SetPropertyOrFieldValueInternal(context, tmpValue); + } + } + catch (TargetInvocationException ex) + { + PropertyChangeEventArgs propertyChangeEvent = + new PropertyChangeEventArgs(this.memberName, null, newValue); + if (ex.GetBaseException() is InvalidCastException) + { + throw new TypeMismatchException(propertyChangeEvent, targetType, ex.GetBaseException()); + } + else + { + throw new MethodInvocationException(ex.GetBaseException(), propertyChangeEvent); + } + } + catch (UnauthorizedAccessException ex) + { + throw new FatalReflectionException("Illegal attempt to set property '" + this.memberName + "'", ex); + } + catch (NotWritablePropertyException) + { + throw; + } + catch (NotReadablePropertyException) + { + throw; + } + catch (ArgumentException ex) + { + PropertyChangeEventArgs propertyChangeEvent = + new PropertyChangeEventArgs(this.memberName, null, newValue); + throw new TypeMismatchException(propertyChangeEvent, targetType, ex); + } + } + + /// + /// Sets property or field value using either dynamic or standard reflection. + /// + /// Object to evaluate node against. + /// New value for this node, converted to appropriate type. + private void SetPropertyOrFieldValueInternal(object context, object newValue) + { + accessor.Set(context, newValue); + } + + /// + /// In the case of read only collections or custom collections that are not assignable from + /// IList, try to add to the collection. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// New value for this node. + /// true if was able add to IList, IDictionary, or ISet + private bool AddToCollections(object context, EvaluationContext evalContext, object newValue) + { + // short-circuit if accessor is not readable + if (!this.accessor.IsReadable) + { + return false; + } + + bool added = false; + + // try adding values if property is a list... + if (newValue is IList && !RemotingServices.IsTransparentProxy(newValue)) + { + IList currentValue = (IList)Get(context, evalContext); + if (currentValue != null && !currentValue.IsFixedSize && !currentValue.IsReadOnly) + { + foreach (object el in (IList)newValue) + { + currentValue.Add(el); + } + added = true; + } + } + // try adding values if property is a dictionary... + else if (newValue is IDictionary && !RemotingServices.IsTransparentProxy(newValue)) + { + IDictionary currentValue = (IDictionary)Get(context, evalContext); + if (currentValue != null && !currentValue.IsFixedSize && !currentValue.IsReadOnly) + { + foreach (DictionaryEntry entry in (IDictionary)newValue) + { + currentValue[entry.Key] = entry.Value; + } + added = true; + } + } + // try adding values if property is a set... + else if (newValue is ISet && !RemotingServices.IsTransparentProxy(newValue)) + { + ISet currentValue = (ISet)Get(context, evalContext); + if (currentValue != null) + { + currentValue.AddAll((ICollection)newValue); + added = true; + } + } + return added; + } + + /// + /// Utility method that is needed by ObjectWrapper and AbstractAutowireCapableObjectFactory. + /// We try as hard as we can, but there are instances when we won't be able to obtain PropertyInfo... + /// + /// Context to resolve property against. + /// PropertyInfo for this node. + internal MemberInfo GetMemberInfo(object context) + { + lock (this) + { + InitializeNode(context); + } + return accessor.MemberInfo; + + //if (IsProperty) + //{ + // return (((PropertyValueAccessor) accessor).MemberInfo); + //} + //else + //{ + // throw new FatalObjectException( + // "Cannot obtain PropertyInfo from an expression that does not resolve to a property."); + //} + } + + #region IValueAccessor interface + + private interface IValueAccessor + { + object Get(object context); + void Set(object context, object value); + + bool IsReadable { get; } + bool IsWriteable { get; } + bool RequiresContext { get; } + Type TargetType { get; } + MemberInfo MemberInfo { get; } + bool RequiresRefresh(Type contextType); + } + + #endregion + + #region BaseValueAccessor implementation + + private abstract class BaseValueAccessor : IValueAccessor + { + public abstract object Get(object context); + + public abstract void Set(object context, object value); + + public virtual bool IsReadable + { + get { return true; } + } + + public virtual bool IsWriteable + { + get { return false; } + } + + public virtual bool RequiresContext + { + get { return false; } + } + + public virtual Type TargetType + { + get { throw new NotSupportedException(); } + } + + public virtual MemberInfo MemberInfo + { + get { throw new NotSupportedException(); } + } + + public virtual bool RequiresRefresh(Type contextType) + { + return false; + } + } + + #endregion + + #region PropertyValueAccessor implementation + + private class PropertyValueAccessor : BaseValueAccessor + { + private SafeProperty property; + private string name; + private bool isReadable; + private bool isWriteable; + private Type targetType; + private Type contextType; + + public PropertyValueAccessor(PropertyInfo propertyInfo) + { + this.name = propertyInfo.Name; + this.isReadable = propertyInfo.CanRead; + this.isWriteable = propertyInfo.CanWrite; + this.targetType = propertyInfo.PropertyType; + this.contextType = propertyInfo.DeclaringType; + this.property = new SafeProperty(propertyInfo); + } + + public override object Get(object context) + { + if (!isReadable) + { + throw new NotReadablePropertyException("Cannot get a non-readable property [" + name + "]"); + } + return property.GetValue(context); + } + + public override void Set(object context, object value) + { + if (!isWriteable) + { + throw new NotWritablePropertyException("Cannot set a read-only property [" + name + "]"); + } + property.SetValue(context, value); + } + + public override bool IsReadable + { + get { return isReadable; } + } + + public override bool IsWriteable + { + get { return isWriteable; } + } + + public override bool RequiresContext + { + get { return true; } + } + + public override Type TargetType + { + get { return targetType; } + } + + public override MemberInfo MemberInfo + { + get { return property.PropertyInfo; } + } + + public override bool RequiresRefresh(Type contextType) + { + return this.contextType != contextType; + } + } + + #endregion + + #region FieldValueAccessor implementation + + private class FieldValueAccessor : BaseValueAccessor + { + private SafeField field; + private bool isWriteable; + private Type targetType; + private Type contextType; + + public FieldValueAccessor(FieldInfo fieldInfo) + { + this.field = new SafeField(fieldInfo); + this.isWriteable = !(fieldInfo.IsInitOnly || fieldInfo.IsLiteral); + this.targetType = fieldInfo.FieldType; + this.contextType = fieldInfo.DeclaringType; + } + + public override object Get(object context) + { + return field.GetValue(context); + } + + public override void Set(object context, object value) + { + field.SetValue(context, value); + } + + public override bool IsWriteable + { + get { return isWriteable; } + } + + public override bool RequiresContext + { + get { return true; } + } + + public override Type TargetType + { + get { return targetType; } + } + + public override MemberInfo MemberInfo + { + get { return field.FieldInfo; } + } + + public override bool RequiresRefresh(Type contextType) + { + return this.contextType != contextType; + } + } + + #endregion + + #region EnumValueAccessor implementation + + private class EnumValueAccessor : BaseValueAccessor + { + private object enumValue; + + public EnumValueAccessor(object enumValue) + { + this.enumValue = enumValue; + } + + public override object Get(object context) + { + return enumValue; + } + + public override void Set(object context, object value) + { + throw new NotSupportedException("Cannot set the value of an enum."); + } + } + + #endregion + + #region TypeValueAccessor implementation + + private class TypeValueAccessor : BaseValueAccessor + { + private Type type; + + public TypeValueAccessor(Type type) + { + this.type = type; + } + + public override object Get(object context) + { + return type; + } + + public override void Set(object context, object value) + { + throw new NotSupportedException("Cannot set the value of a type."); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/QualifiedIdentifier.cs b/src/Spring/Spring.Core/Expressions/QualifiedIdentifier.cs index 94a11604..04cf208f 100644 --- a/src/Spring/Spring.Core/Expressions/QualifiedIdentifier.cs +++ b/src/Spring/Spring.Core/Expressions/QualifiedIdentifier.cs @@ -1,98 +1,97 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents parsed named argument node in the expression. - /// - /// Aleksandar Seovic - /// $Id: QualifiedIdentifier.cs,v 1.7 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class QualifiedIdentifier : BaseNode - { - private const string ESCAPE_CHAR = "\\"; - - private string identifier; - - /// - /// Create a new instance - /// - public QualifiedIdentifier():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected QualifiedIdentifier(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns the value of the named argument defined by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (identifier == null) - { - lock (this) - { - if (identifier == null) - { - identifier = base.getText(); - if (identifier != null) - { - identifier = identifier.Replace(ESCAPE_CHAR,""); // remove all occurrences of escape char - } - AST node = this.getFirstChild(); - while (node != null) - { - identifier += node.getText(); - node = node.getNextSibling(); - } - } - } - } - - return identifier; - } - - /// - /// Overrides getText to allow easy way to get fully - /// qualified identifier. - /// - /// - /// Fully qualified identifier as a string. - /// - public override string getText() - { - return (string) Get(null, null); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents parsed named argument node in the expression. + /// + /// Aleksandar Seovic + [Serializable] + public class QualifiedIdentifier : BaseNode + { + private const string ESCAPE_CHAR = "\\"; + + private string identifier; + + /// + /// Create a new instance + /// + public QualifiedIdentifier():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected QualifiedIdentifier(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns the value of the named argument defined by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (identifier == null) + { + lock (this) + { + if (identifier == null) + { + identifier = base.getText(); + if (identifier != null) + { + identifier = identifier.Replace(ESCAPE_CHAR,""); // remove all occurrences of escape char + } + AST node = this.getFirstChild(); + while (node != null) + { + identifier += node.getText(); + node = node.getNextSibling(); + } + } + } + } + + return identifier; + } + + /// + /// Overrides getText to allow easy way to get fully + /// qualified identifier. + /// + /// + /// Fully qualified identifier as a string. + /// + public override string getText() + { + return (string) Get(null, null); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/RealLiteralNode.cs b/src/Spring/Spring.Core/Expressions/RealLiteralNode.cs index 86468131..cf845e95 100644 --- a/src/Spring/Spring.Core/Expressions/RealLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/RealLiteralNode.cs @@ -1,95 +1,94 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed real literal node. - /// - /// Aleksandar Seovic - /// $Id: RealLiteralNode.cs,v 1.11 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class RealLiteralNode : BaseNode - { - private object nodeValue; - - /// - /// Create a new instance - /// - public RealLiteralNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected RealLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the real literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (nodeValue == null) - { - lock (this) - { - if (nodeValue == null) - { - string n = this.getText(); - char lastChar = n.ToLower()[n.Length - 1]; - if (Char.IsDigit(lastChar)) - { - nodeValue = Double.Parse(n, NumberFormatInfo.InvariantInfo); - } - else - { - n = n.Substring(0, n.Length - 1); - if (lastChar == 'm') - { - nodeValue = Decimal.Parse(n, NumberFormatInfo.InvariantInfo); - } - else if (lastChar == 'f') - { - nodeValue = Single.Parse(n, NumberFormatInfo.InvariantInfo); - } - else - { - nodeValue = Double.Parse(n, NumberFormatInfo.InvariantInfo); - } - } - } - } - } - - return nodeValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed real literal node. + /// + /// Aleksandar Seovic + [Serializable] + public class RealLiteralNode : BaseNode + { + private object nodeValue; + + /// + /// Create a new instance + /// + public RealLiteralNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected RealLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the real literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (nodeValue == null) + { + lock (this) + { + if (nodeValue == null) + { + string n = this.getText(); + char lastChar = n.ToLower()[n.Length - 1]; + if (Char.IsDigit(lastChar)) + { + nodeValue = Double.Parse(n, NumberFormatInfo.InvariantInfo); + } + else + { + n = n.Substring(0, n.Length - 1); + if (lastChar == 'm') + { + nodeValue = Decimal.Parse(n, NumberFormatInfo.InvariantInfo); + } + else if (lastChar == 'f') + { + nodeValue = Single.Parse(n, NumberFormatInfo.InvariantInfo); + } + else + { + nodeValue = Double.Parse(n, NumberFormatInfo.InvariantInfo); + } + } + } + } + } + + return nodeValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/ReferenceNode.cs b/src/Spring/Spring.Core/Expressions/ReferenceNode.cs index b5440338..8bdb98fa 100644 --- a/src/Spring/Spring.Core/Expressions/ReferenceNode.cs +++ b/src/Spring/Spring.Core/Expressions/ReferenceNode.cs @@ -1,96 +1,95 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using Spring.Expressions; -using Spring.Objects.Factory; - -namespace Spring.Context.Support -{ - /// - /// Represents a reference to a Spring-managed object. - /// - /// Aleksandar Seovic - /// $Id: ReferenceNode.cs,v 1.13 2008/03/20 10:35:54 oakinger Exp $ - [Serializable] - public class ReferenceNode : BaseNode - { - /// - /// Create a new instance - /// - public ReferenceNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected ReferenceNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the integer literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - IApplicationContext ctx; - string objectName; - - if (this.getNumberOfChildren() == 2) - { - string contextName = this.getFirstChild().getText(); - objectName = this.getFirstChild().getNextSibling().getText(); - ctx = ContextRegistry.GetContext(contextName); - if (ctx == null) - { - throw new ArgumentException(string.Format("Context '{0}' is not registered.", contextName)); - } - } - else - { - objectName = this.getFirstChild().getText(); - IObjectFactory currentObjectFactory = (evalContext.Variables != null) - ? (IObjectFactory)evalContext.Variables[Expression.ReservedVariableNames.CurrentObjectFactory] - : null; - - // this is a local reference within an object factory - if (currentObjectFactory != null) - { - return currentObjectFactory.GetObject(objectName); - } - - // else lookup in default context - ctx = ContextRegistry.GetContext(); - if (ctx == null) - { - throw new ArgumentException("No context registered."); - } - } - - return ctx.GetObject(objectName); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using Spring.Expressions; +using Spring.Objects.Factory; + +namespace Spring.Context.Support +{ + /// + /// Represents a reference to a Spring-managed object. + /// + /// Aleksandar Seovic + [Serializable] + public class ReferenceNode : BaseNode + { + /// + /// Create a new instance + /// + public ReferenceNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected ReferenceNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the integer literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + IApplicationContext ctx; + string objectName; + + if (this.getNumberOfChildren() == 2) + { + string contextName = this.getFirstChild().getText(); + objectName = this.getFirstChild().getNextSibling().getText(); + ctx = ContextRegistry.GetContext(contextName); + if (ctx == null) + { + throw new ArgumentException(string.Format("Context '{0}' is not registered.", contextName)); + } + } + else + { + objectName = this.getFirstChild().getText(); + IObjectFactory currentObjectFactory = (evalContext.Variables != null) + ? (IObjectFactory)evalContext.Variables[Expression.ReservedVariableNames.CurrentObjectFactory] + : null; + + // this is a local reference within an object factory + if (currentObjectFactory != null) + { + return currentObjectFactory.GetObject(objectName); + } + + // else lookup in default context + ctx = ContextRegistry.GetContext(); + if (ctx == null) + { + throw new ArgumentException("No context registered."); + } + } + + return ctx.GetObject(objectName); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/SelectionFirstNode.cs b/src/Spring/Spring.Core/Expressions/SelectionFirstNode.cs index 31273dde..f7e0aec0 100644 --- a/src/Spring/Spring.Core/Expressions/SelectionFirstNode.cs +++ b/src/Spring/Spring.Core/Expressions/SelectionFirstNode.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed selection node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: SelectionFirstNode.cs,v 1.5 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class SelectionFirstNode : BaseNode - { - /// - /// Create a new instance - /// - public SelectionFirstNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected SelectionFirstNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns the first context item that matches selection expression. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - IEnumerable enumerable = context as IEnumerable; - if (enumerable == null) - { - throw new ArgumentException( - "Selection can only be used on an instance of the type that implements IEnumerable."); - } - - BaseNode expression = (BaseNode) this.getFirstChild(); - using (evalContext.SwitchThisContext()) - { - foreach (object o in enumerable) - { - evalContext.ThisContext = o; - bool isMatch = (bool) expression.GetValueInternal(o, evalContext); - if (isMatch) - { - return o; - } - } - } - return null; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed selection node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class SelectionFirstNode : BaseNode + { + /// + /// Create a new instance + /// + public SelectionFirstNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected SelectionFirstNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns the first context item that matches selection expression. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + IEnumerable enumerable = context as IEnumerable; + if (enumerable == null) + { + throw new ArgumentException( + "Selection can only be used on an instance of the type that implements IEnumerable."); + } + + BaseNode expression = (BaseNode) this.getFirstChild(); + using (evalContext.SwitchThisContext()) + { + foreach (object o in enumerable) + { + evalContext.ThisContext = o; + bool isMatch = (bool) expression.GetValueInternal(o, evalContext); + if (isMatch) + { + return o; + } + } + } + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/SelectionLastNode.cs b/src/Spring/Spring.Core/Expressions/SelectionLastNode.cs index e0aee460..0b6af921 100644 --- a/src/Spring/Spring.Core/Expressions/SelectionLastNode.cs +++ b/src/Spring/Spring.Core/Expressions/SelectionLastNode.cs @@ -1,83 +1,82 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed selection node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: SelectionLastNode.cs,v 1.5 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class SelectionLastNode : BaseNode - { - /// - /// Create a new instance - /// - public SelectionLastNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected SelectionLastNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns the last context item that matches selection expression. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - IList list = context as IList; - - if (list == null) - { - throw new ArgumentException( - "Selection can only be used on an instance of the type that implements IList."); - } - - using (evalContext.SwitchThisContext()) - { - BaseNode expression = (BaseNode) this.getFirstChild(); - for (int i = list.Count - 1; i >= 0; i--) - { - object listItem = list[i]; - evalContext.ThisContext = listItem; - bool isMatch = (bool)expression.GetValueInternal( listItem, evalContext ); - if (isMatch) - { - return listItem; - } - } - } - return null; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed selection node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class SelectionLastNode : BaseNode + { + /// + /// Create a new instance + /// + public SelectionLastNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected SelectionLastNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns the last context item that matches selection expression. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + IList list = context as IList; + + if (list == null) + { + throw new ArgumentException( + "Selection can only be used on an instance of the type that implements IList."); + } + + using (evalContext.SwitchThisContext()) + { + BaseNode expression = (BaseNode) this.getFirstChild(); + for (int i = list.Count - 1; i >= 0; i--) + { + object listItem = list[i]; + evalContext.ThisContext = listItem; + bool isMatch = (bool)expression.GetValueInternal( listItem, evalContext ); + if (isMatch) + { + return listItem; + } + } + } + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/SelectionNode.cs b/src/Spring/Spring.Core/Expressions/SelectionNode.cs index ec3c2a9a..454ce117 100644 --- a/src/Spring/Spring.Core/Expressions/SelectionNode.cs +++ b/src/Spring/Spring.Core/Expressions/SelectionNode.cs @@ -1,105 +1,104 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed selection node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: SelectionNode.cs,v 1.6 2008/03/25 22:33:04 oakinger Exp $ - [Serializable] - public class SelectionNode : BaseNode - { - /// - /// Create a new instance - /// - public SelectionNode() - : base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected SelectionNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a containing results of evaluation - /// of selection expression against each node in the context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - IEnumerable enumerable = context as IEnumerable; - if (enumerable == null) - { - throw new ArgumentException( - "Selection can only be used on an instance of the type that implements IEnumerable."); - } - - BaseNode expression = (BaseNode)this.getFirstChild(); - BaseNode minIndexExpression = (BaseNode)expression.getNextSibling(); - BaseNode maxIndexExpression = (minIndexExpression == null) ? null : (BaseNode)minIndexExpression.getNextSibling(); - - int minIndex = (int)((minIndexExpression == null) - ? Int32.MinValue - : minIndexExpression.GetValueInternal(context, evalContext)); - int maxIndex = (int)((maxIndexExpression == null) - ? Int32.MaxValue - : maxIndexExpression.GetValueInternal(context, evalContext)); - - IList selectionList = new ArrayList(); - - using (evalContext.SwitchThisContext()) - { - int found = 0; - foreach (object o in enumerable) - { - evalContext.ThisContext = o; - bool isMatch = (bool)expression.GetValueInternal(o, evalContext); - if (isMatch) - { - if (minIndex <= found && found <= maxIndex) - { - selectionList.Add(o); - } - found++; - - if (found>maxIndex) - { - break; // don't look any further - } - } - } - } - return selectionList; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed selection node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class SelectionNode : BaseNode + { + /// + /// Create a new instance + /// + public SelectionNode() + : base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected SelectionNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a containing results of evaluation + /// of selection expression against each node in the context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + IEnumerable enumerable = context as IEnumerable; + if (enumerable == null) + { + throw new ArgumentException( + "Selection can only be used on an instance of the type that implements IEnumerable."); + } + + BaseNode expression = (BaseNode)this.getFirstChild(); + BaseNode minIndexExpression = (BaseNode)expression.getNextSibling(); + BaseNode maxIndexExpression = (minIndexExpression == null) ? null : (BaseNode)minIndexExpression.getNextSibling(); + + int minIndex = (int)((minIndexExpression == null) + ? Int32.MinValue + : minIndexExpression.GetValueInternal(context, evalContext)); + int maxIndex = (int)((maxIndexExpression == null) + ? Int32.MaxValue + : maxIndexExpression.GetValueInternal(context, evalContext)); + + IList selectionList = new ArrayList(); + + using (evalContext.SwitchThisContext()) + { + int found = 0; + foreach (object o in enumerable) + { + evalContext.ThisContext = o; + bool isMatch = (bool)expression.GetValueInternal(o, evalContext); + if (isMatch) + { + if (minIndex <= found && found <= maxIndex) + { + selectionList.Add(o); + } + found++; + + if (found>maxIndex) + { + break; // don't look any further + } + } + } + } + return selectionList; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/SpringAST.cs b/src/Spring/Spring.Core/Expressions/SpringAST.cs index 46a5d4ce..0feaeff4 100644 --- a/src/Spring/Spring.Core/Expressions/SpringAST.cs +++ b/src/Spring/Spring.Core/Expressions/SpringAST.cs @@ -1,152 +1,152 @@ -using System; -using System.Runtime.Serialization; -using antlr; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// For internal purposes only. Use for expression node implementations. - /// - /// - /// This class is only required to enable serialization of parsed Spring expressions since antlr.CommonAST - /// unfortunately is not marked as [Serializable].
- ///
- /// Note:Since SpringAST implements , deriving classes - /// have to explicitely override if they need to persist additional - /// data during serialization. - ///
- [Serializable] - public class SpringAST : antlr.BaseAST, ISerializable - { - #region Global SpringAST Factory - - internal class SpringASTCreator : antlr.ASTNodeCreator - { - public override antlr.collections.AST Create() - { - return new SpringAST(); - } - - public override string ASTNodeTypeName - { - get { return typeof(SpringAST).FullName; } - } - } - - /// - /// The global SpringAST node factory - /// - internal static readonly SpringASTCreator Creator = new SpringASTCreator(); - - #endregion - - #region Members - - private string text; - private int ttype; - - #endregion - - /// - /// Create an instance - /// - public SpringAST() - {} - - /// - /// Create an instance from a token - /// - public SpringAST(IToken token) - { - initialize(token); - } - - /// - /// initialize this instance from an AST - /// - public override void initialize(AST t) - { - this.setText(t.getText()); - this.Type = t.Type; - } - - /// - /// initialize this instance from an IToken - /// - public override void initialize(IToken tok) - { - this.setText(tok.getText()); - this.Type = tok.Type; - } - - /// - /// initialize this instance from a token type number and a text - /// - public override void initialize(int t, string txt) - { - this.Type = t; - this.setText(txt); - } - - /// - /// gets or sets the token type of this node - /// - public override int Type - { - get { return this.ttype; } - set { this.ttype = value; } - } - - /// - /// gets or sets the text of this node - /// - public string Text - { - get { return this.getText(); } - set { this.setText(value); } - } - - /// - /// sets the text of this node - /// - public override void setText(string txt) - { - this.text = txt; - } - - /// - /// gets the text of this node - /// - public override string getText() - { - return this.text; - } - - #region ISerializable Implementation - - /// - /// Create a new instance from SerializationInfo - /// - protected SpringAST(SerializationInfo info, StreamingContext context) - { - base.down = (BaseAST)info.GetValue("down", typeof(BaseAST)); - base.right = (BaseAST)info.GetValue("right", typeof(BaseAST)); - this.ttype = info.GetInt32("ttype"); - this.text = info.GetString("text"); - } - - /// - /// populate SerializationInfo from this instance - /// - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("down", base.down, typeof(SpringAST)); - info.AddValue("right", base.right, typeof(SpringAST)); - info.AddValue("ttype", this.Type, typeof(int)); - info.AddValue("text", this.Text, typeof(string)); - } - - #endregion - } +using System; +using System.Runtime.Serialization; +using antlr; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// For internal purposes only. Use for expression node implementations. + /// + /// + /// This class is only required to enable serialization of parsed Spring expressions since antlr.CommonAST + /// unfortunately is not marked as [Serializable].
+ ///
+ /// Note:Since SpringAST implements , deriving classes + /// have to explicitely override if they need to persist additional + /// data during serialization. + ///
+ [Serializable] + public class SpringAST : antlr.BaseAST, ISerializable + { + #region Global SpringAST Factory + + internal class SpringASTCreator : antlr.ASTNodeCreator + { + public override antlr.collections.AST Create() + { + return new SpringAST(); + } + + public override string ASTNodeTypeName + { + get { return typeof(SpringAST).FullName; } + } + } + + /// + /// The global SpringAST node factory + /// + internal static readonly SpringASTCreator Creator = new SpringASTCreator(); + + #endregion + + #region Members + + private string text; + private int ttype; + + #endregion + + /// + /// Create an instance + /// + public SpringAST() + {} + + /// + /// Create an instance from a token + /// + public SpringAST(IToken token) + { + initialize(token); + } + + /// + /// initialize this instance from an AST + /// + public override void initialize(AST t) + { + this.setText(t.getText()); + this.Type = t.Type; + } + + /// + /// initialize this instance from an IToken + /// + public override void initialize(IToken tok) + { + this.setText(tok.getText()); + this.Type = tok.Type; + } + + /// + /// initialize this instance from a token type number and a text + /// + public override void initialize(int t, string txt) + { + this.Type = t; + this.setText(txt); + } + + /// + /// gets or sets the token type of this node + /// + public override int Type + { + get { return this.ttype; } + set { this.ttype = value; } + } + + /// + /// gets or sets the text of this node + /// + public string Text + { + get { return this.getText(); } + set { this.setText(value); } + } + + /// + /// sets the text of this node + /// + public override void setText(string txt) + { + this.text = txt; + } + + /// + /// gets the text of this node + /// + public override string getText() + { + return this.text; + } + + #region ISerializable Implementation + + /// + /// Create a new instance from SerializationInfo + /// + protected SpringAST(SerializationInfo info, StreamingContext context) + { + base.down = (BaseAST)info.GetValue("down", typeof(BaseAST)); + base.right = (BaseAST)info.GetValue("right", typeof(BaseAST)); + this.ttype = info.GetInt32("ttype"); + this.text = info.GetString("text"); + } + + /// + /// populate SerializationInfo from this instance + /// + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("down", base.down, typeof(SpringAST)); + info.AddValue("right", base.right, typeof(SpringAST)); + info.AddValue("ttype", this.Type, typeof(int)); + info.AddValue("text", this.Text, typeof(string)); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/StringLiteralNode.cs b/src/Spring/Spring.Core/Expressions/StringLiteralNode.cs index 4c0394a6..bae9e633 100644 --- a/src/Spring/Spring.Core/Expressions/StringLiteralNode.cs +++ b/src/Spring/Spring.Core/Expressions/StringLiteralNode.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed string literal node. - /// - /// Aleksandar Seovic - /// $Id: StringLiteralNode.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class StringLiteralNode : BaseNode - { - /// - /// Create a new instance - /// - public StringLiteralNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected StringLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the string literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - return this.getText(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed string literal node. + /// + /// Aleksandar Seovic + [Serializable] + public class StringLiteralNode : BaseNode + { + /// + /// Create a new instance + /// + public StringLiteralNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected StringLiteralNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the string literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + return this.getText(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/TernaryNode.cs b/src/Spring/Spring.Core/Expressions/TernaryNode.cs index 39d90af3..a9850b90 100644 --- a/src/Spring/Spring.Core/Expressions/TernaryNode.cs +++ b/src/Spring/Spring.Core/Expressions/TernaryNode.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; -using antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents ternary expression node. - /// - /// Aleksandar Seovic - /// $Id: TernaryNode.cs,v 1.9 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class TernaryNode : BaseNode - { - private bool initialized = false; - private BaseNode condition; - private BaseNode trueExp; - private BaseNode falseExp; - - /// - /// Create a new instance - /// - public TernaryNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected TernaryNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns a value for the string literal node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (!initialized) - { - lock (this) - { - if (!initialized) - { - AST node = this.getFirstChild(); - condition = (BaseNode) node; - node = node.getNextSibling(); - trueExp = (BaseNode) node; - node = node.getNextSibling(); - falseExp = (BaseNode) node; - - initialized = true; - } - } - } - - if (Convert.ToBoolean(condition.GetValueInternal(context, evalContext))) - { - return trueExp.GetValueInternal(context, evalContext); - } - else - { - return falseExp.GetValueInternal(context, evalContext); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; +using antlr.collections; + +namespace Spring.Expressions +{ + /// + /// Represents ternary expression node. + /// + /// Aleksandar Seovic + [Serializable] + public class TernaryNode : BaseNode + { + private bool initialized = false; + private BaseNode condition; + private BaseNode trueExp; + private BaseNode falseExp; + + /// + /// Create a new instance + /// + public TernaryNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected TernaryNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns a value for the string literal node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (!initialized) + { + lock (this) + { + if (!initialized) + { + AST node = this.getFirstChild(); + condition = (BaseNode) node; + node = node.getNextSibling(); + trueExp = (BaseNode) node; + node = node.getNextSibling(); + falseExp = (BaseNode) node; + + initialized = true; + } + } + } + + if (Convert.ToBoolean(condition.GetValueInternal(context, evalContext))) + { + return trueExp.GetValueInternal(context, evalContext); + } + else + { + return falseExp.GetValueInternal(context, evalContext); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/TypeNode.cs b/src/Spring/Spring.Core/Expressions/TypeNode.cs index a1c82055..1808d53d 100644 --- a/src/Spring/Spring.Core/Expressions/TypeNode.cs +++ b/src/Spring/Spring.Core/Expressions/TypeNode.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -using antlr.collections; -using Spring.Core.TypeResolution; - -namespace Spring.Expressions -{ - /// - /// Represents parsed type node in the navigation expression. - /// - /// Aleksandar Seovic - /// $Id: TypeNode.cs,v 1.11 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class TypeNode : BaseNode - { - private Type type; - - /// - /// Create a new instance - /// - public TypeNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected TypeNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (type == null) - { - lock (this) - { - if (type == null) - { - string typeName = this.getText(); - AST node = this.getFirstChild(); - while (node != null) - { - typeName += node.getText(); - node = node.getNextSibling(); - } - - type = TypeResolutionUtils.ResolveType(typeName); - } - } - } - - return type; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +using antlr.collections; +using Spring.Core.TypeResolution; + +namespace Spring.Expressions +{ + /// + /// Represents parsed type node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class TypeNode : BaseNode + { + private Type type; + + /// + /// Create a new instance + /// + public TypeNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected TypeNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + if (type == null) + { + lock (this) + { + if (type == null) + { + string typeName = this.getText(); + AST node = this.getFirstChild(); + while (node != null) + { + typeName += node.getText(); + node = node.getNextSibling(); + } + + type = TypeResolutionUtils.ResolveType(typeName); + } + } + } + + return type; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/UnaryOperator.cs b/src/Spring/Spring.Core/Expressions/UnaryOperator.cs index b13ef61e..6040f429 100644 --- a/src/Spring/Spring.Core/Expressions/UnaryOperator.cs +++ b/src/Spring/Spring.Core/Expressions/UnaryOperator.cs @@ -1,57 +1,56 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Base class for unary operators. - /// - /// Aleksandar Seovic - /// $Id: UnaryOperator.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - //[Serializable] - public abstract class UnaryOperator : BaseNode - { - /// - /// Create a new instance - /// - public UnaryOperator():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected UnaryOperator(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Gets the operand. - /// - /// The operand. - public BaseNode Operand - { - get { return (BaseNode) this.getFirstChild(); } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Base class for unary operators. + /// + /// Aleksandar Seovic + //[Serializable] + public abstract class UnaryOperator : BaseNode + { + /// + /// Create a new instance + /// + public UnaryOperator():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected UnaryOperator(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Gets the operand. + /// + /// The operand. + public BaseNode Operand + { + get { return (BaseNode) this.getFirstChild(); } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/VariableNode.cs b/src/Spring/Spring.Core/Expressions/VariableNode.cs index 2a7db702..1970ca36 100644 --- a/src/Spring/Spring.Core/Expressions/VariableNode.cs +++ b/src/Spring/Spring.Core/Expressions/VariableNode.cs @@ -1,90 +1,89 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Expressions -{ - /// - /// Represents parsed variable node. - /// - /// Aleksandar Seovic - /// $Id: VariableNode.cs,v 1.8 2007/09/07 03:01:26 markpollack Exp $ - [Serializable] - public class VariableNode : BaseNode - { - /// - /// Create a new instance - /// - public VariableNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected VariableNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns value of the variable represented by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - string varName = this.getText(); - if (varName == "this") - { - return evalContext.ThisContext; - } - else if (varName == "root") - { - return evalContext.RootContext; - } - return evalContext.Variables[varName]; - } - - /// - /// Sets value of the variable represented by this node. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// New value for this node. - protected override void Set(object context, EvaluationContext evalContext, object newValue) - { - string varName = this.getText(); - if (varName == "this" || varName == "root") - { - throw new ArgumentException("You cannot assign a value to intrinsic variable '" + varName + "'."); - } - if (evalContext.Variables == null) - { - throw new InvalidOperationException( - "You need to provide variables dictionary to expression evaluation engine in order to be able to set variable values."); - } - evalContext.Variables[varName] = newValue; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Expressions +{ + /// + /// Represents parsed variable node. + /// + /// Aleksandar Seovic + [Serializable] + public class VariableNode : BaseNode + { + /// + /// Create a new instance + /// + public VariableNode():base() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected VariableNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns value of the variable represented by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + string varName = this.getText(); + if (varName == "this") + { + return evalContext.ThisContext; + } + else if (varName == "root") + { + return evalContext.RootContext; + } + return evalContext.Variables[varName]; + } + + /// + /// Sets value of the variable represented by this node. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// New value for this node. + protected override void Set(object context, EvaluationContext evalContext, object newValue) + { + string varName = this.getText(); + if (varName == "this" || varName == "root") + { + throw new ArgumentException("You cannot assign a value to intrinsic variable '" + varName + "'."); + } + if (evalContext.Variables == null) + { + throw new InvalidOperationException( + "You need to provide variables dictionary to expression evaluation engine in order to be able to set variable values."); + } + evalContext.Variables[varName] = newValue; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/AbstractLocalizer.cs b/src/Spring/Spring.Core/Globalization/AbstractLocalizer.cs index d472a870..7dbe10e9 100644 --- a/src/Spring/Spring.Core/Globalization/AbstractLocalizer.cs +++ b/src/Spring/Spring.Core/Globalization/AbstractLocalizer.cs @@ -1,124 +1,123 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using System.Globalization; -using System.Threading; - -using Spring.Context; -using Spring.Util; - -namespace Spring.Globalization -{ - /// - /// Abstract base class that all localizers should extend - /// - /// - ///

- /// This class contains the bulk of the localizer logic, including implementation - /// of the ApplyResources methods that are defined in - /// interface. - ///

- ///

- /// All specific localizers need to do is inherit this class and implement - /// GetResources method that will return a list of - /// objects that should be applied to a specified target. - ///

- ///

- /// Custom implementations can use whatever type of resource storage they want, - /// such as standard .NET resource sets, custom XML files, database, etc. - ///

- ///
- /// Aleksandar Seovic - /// $Id: AbstractLocalizer.cs,v 1.5 2007/07/24 17:26:25 oakinger Exp $ - public abstract class AbstractLocalizer : ILocalizer - { - private IResourceCache resourceCache = new NullResourceCache(); - - /// - /// Gets or sets the resource cache instance. - /// - /// The resource cache instance. - public IResourceCache ResourceCache - { - get { return resourceCache; } - set { resourceCache = value; } - } - - /// - /// Applies resources of the specified culture to the specified target object. - /// - /// Target object to apply resources to. - /// instance to retrieve resources from. - /// Resource culture to use for resource lookup. - public void ApplyResources(object target, IMessageSource messageSource, CultureInfo culture) - { - AssertUtils.ArgumentNotNull(target, "target"); - AssertUtils.ArgumentNotNull(culture, "culture"); - - IList resources = GetResources(target, messageSource, culture); - foreach (Resource resource in resources) - { - resource.Target.SetValue(target, null, resource.Value); - } - } - - /// - /// Applies resources to the specified target object, using current thread's uiCulture to resolve resources. - /// - /// Target object to apply resources to. - /// instance to retrieve resources from. - public void ApplyResources(object target, IMessageSource messageSource) - { - AssertUtils.ArgumentNotNull(target, "target"); - ApplyResources(target, messageSource, Thread.CurrentThread.CurrentUICulture); - } - - /// - /// Returns a list of instances that should be applied to the target. - /// - /// Target to get a list of resources for. - /// instance to retrieve resources from. - /// Resource locale. - /// A list of resources to apply. - private IList GetResources(object target, IMessageSource messageSource, CultureInfo culture) - { - IList resources = resourceCache.GetResources(target, culture); - - if (resources == null) - { - resources = LoadResources(target, messageSource, culture); - resourceCache.PutResources(target, culture, resources); - } - - return resources; - } - - /// - /// Loads resources from the storage and creates a list of instances that should be applied to the target. - /// - /// Target to get a list of resources for. - /// instance to retrieve resources from. - /// Resource locale. - /// A list of resources to apply. - protected abstract IList LoadResources(object target, IMessageSource messageSource, CultureInfo culture); - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using System.Globalization; +using System.Threading; + +using Spring.Context; +using Spring.Util; + +namespace Spring.Globalization +{ + /// + /// Abstract base class that all localizers should extend + /// + /// + ///

+ /// This class contains the bulk of the localizer logic, including implementation + /// of the ApplyResources methods that are defined in + /// interface. + ///

+ ///

+ /// All specific localizers need to do is inherit this class and implement + /// GetResources method that will return a list of + /// objects that should be applied to a specified target. + ///

+ ///

+ /// Custom implementations can use whatever type of resource storage they want, + /// such as standard .NET resource sets, custom XML files, database, etc. + ///

+ ///
+ /// Aleksandar Seovic + public abstract class AbstractLocalizer : ILocalizer + { + private IResourceCache resourceCache = new NullResourceCache(); + + /// + /// Gets or sets the resource cache instance. + /// + /// The resource cache instance. + public IResourceCache ResourceCache + { + get { return resourceCache; } + set { resourceCache = value; } + } + + /// + /// Applies resources of the specified culture to the specified target object. + /// + /// Target object to apply resources to. + /// instance to retrieve resources from. + /// Resource culture to use for resource lookup. + public void ApplyResources(object target, IMessageSource messageSource, CultureInfo culture) + { + AssertUtils.ArgumentNotNull(target, "target"); + AssertUtils.ArgumentNotNull(culture, "culture"); + + IList resources = GetResources(target, messageSource, culture); + foreach (Resource resource in resources) + { + resource.Target.SetValue(target, null, resource.Value); + } + } + + /// + /// Applies resources to the specified target object, using current thread's uiCulture to resolve resources. + /// + /// Target object to apply resources to. + /// instance to retrieve resources from. + public void ApplyResources(object target, IMessageSource messageSource) + { + AssertUtils.ArgumentNotNull(target, "target"); + ApplyResources(target, messageSource, Thread.CurrentThread.CurrentUICulture); + } + + /// + /// Returns a list of instances that should be applied to the target. + /// + /// Target to get a list of resources for. + /// instance to retrieve resources from. + /// Resource locale. + /// A list of resources to apply. + private IList GetResources(object target, IMessageSource messageSource, CultureInfo culture) + { + IList resources = resourceCache.GetResources(target, culture); + + if (resources == null) + { + resources = LoadResources(target, messageSource, culture); + resourceCache.PutResources(target, culture, resources); + } + + return resources; + } + + /// + /// Loads resources from the storage and creates a list of instances that should be applied to the target. + /// + /// Target to get a list of resources for. + /// instance to retrieve resources from. + /// Resource locale. + /// A list of resources to apply. + protected abstract IList LoadResources(object target, IMessageSource messageSource, CultureInfo culture); + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/AbstractResourceCache.cs b/src/Spring/Spring.Core/Globalization/AbstractResourceCache.cs index 306d46ef..580f0719 100644 --- a/src/Spring/Spring.Core/Globalization/AbstractResourceCache.cs +++ b/src/Spring/Spring.Core/Globalization/AbstractResourceCache.cs @@ -1,82 +1,81 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using System.Globalization; - -namespace Spring.Globalization -{ - /// - /// Abstract base class that all resource cache implementations should extend. - /// - /// Aleksandar Seovic - /// $Id: AbstractResourceCache.cs,v 1.3 2006/04/09 07:18:47 markpollack Exp $ - public abstract class AbstractResourceCache : IResourceCache - { - /// - /// Gets the list of resources from the cache. - /// - /// Target to get a list of resources for. - /// Resource culture. - /// A list of cached resources for the specified target object and culture. - public IList GetResources(object target, CultureInfo culture) - { - return GetResources(CreateCacheKey(target, culture)); - } - - /// - /// Puts the list of resources in the cache. - /// - /// Target to cache a list of resources for. - /// Resource culture. - /// A list of resources to cache. - /// A list of cached resources for the specified target object and culture. - public void PutResources(object target, CultureInfo culture, IList resources) - { - PutResources(CreateCacheKey(target, culture), resources); - } - - /// - /// Crates resource cache key for the specified target object and culture. - /// - /// Target object to apply resources to. - /// Resource culture to use for resource lookup. - protected virtual string CreateCacheKey(object target, CultureInfo culture) - { - return target.GetType().FullName + "." + culture.Name + ".resources"; - } - - /// - /// Gets the list of resources from cache. - /// - /// Cache key to use for lookup. - /// A list of cached resources for the specified target object and culture. - protected abstract IList GetResources(string cacheKey); - - /// - /// Puts the list of resources in the cache. - /// - /// Cache key to use for the specified resources. - /// A list of resources to cache. - /// A list of cached resources for the specified target object and culture. - protected abstract void PutResources(string cacheKey, IList resources); - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using System.Globalization; + +namespace Spring.Globalization +{ + /// + /// Abstract base class that all resource cache implementations should extend. + /// + /// Aleksandar Seovic + public abstract class AbstractResourceCache : IResourceCache + { + /// + /// Gets the list of resources from the cache. + /// + /// Target to get a list of resources for. + /// Resource culture. + /// A list of cached resources for the specified target object and culture. + public IList GetResources(object target, CultureInfo culture) + { + return GetResources(CreateCacheKey(target, culture)); + } + + /// + /// Puts the list of resources in the cache. + /// + /// Target to cache a list of resources for. + /// Resource culture. + /// A list of resources to cache. + /// A list of cached resources for the specified target object and culture. + public void PutResources(object target, CultureInfo culture, IList resources) + { + PutResources(CreateCacheKey(target, culture), resources); + } + + /// + /// Crates resource cache key for the specified target object and culture. + /// + /// Target object to apply resources to. + /// Resource culture to use for resource lookup. + protected virtual string CreateCacheKey(object target, CultureInfo culture) + { + return target.GetType().FullName + "." + culture.Name + ".resources"; + } + + /// + /// Gets the list of resources from cache. + /// + /// Cache key to use for lookup. + /// A list of cached resources for the specified target object and culture. + protected abstract IList GetResources(string cacheKey); + + /// + /// Puts the list of resources in the cache. + /// + /// Cache key to use for the specified resources. + /// A list of resources to cache. + /// A list of cached resources for the specified target object and culture. + protected abstract void PutResources(string cacheKey, IList resources); + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Formatters/BooleanFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/BooleanFormatter.cs index e6ddbd43..c37c8547 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/BooleanFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/BooleanFormatter.cs @@ -1,146 +1,145 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse boolean values. - /// - /// Erich Eichinger - /// $Id: BooleanFormatter.cs,v 1.1 2007/06/01 08:59:31 oakinger Exp $ - public class BooleanFormatter:IFormatter - { - private string trueString; - private string falseString; - private bool ignoreCase; - - #region Constructors - - /// - /// Initializes a new instance of the class - /// using default values - /// - public BooleanFormatter() - : this(true,bool.TrueString,bool.FalseString) - { } - - /// - /// Initializes a new instance of the class - /// - public BooleanFormatter(bool ignoreCase,string trueString,string falseString) - { - this.trueString = trueString; - this.falseString = falseString; - this.ignoreCase = ignoreCase; - } - - #endregion - - #region Properties - - /// - /// Set/Get value to control casesensitivity of - /// - /// - /// Defaults to true - /// - public bool IgnoreCase - { - get { return this.ignoreCase; } - set { this.ignoreCase = value; } - } - - /// - /// Set/Get value to recognize as boolean "true" value - /// - /// - /// Defaults to - /// - public string TrueString - { - get { return this.trueString; } - set { this.trueString = value; } - } - - /// - /// Set/Get value to recognize as boolean "false" value - /// - /// - /// Defaults to - /// - public string FalseString - { - get { return this.falseString; } - set { this.falseString = value; } - } - - #endregion - - /// - /// Formats the specified boolean value. - /// - /// The value to format. - /// Formatted boolean value. - /// If is null. - /// If is not of type . - public string Format(object value) - { - AssertUtils.ArgumentNotNull( value,"value" ); - if(!(value is bool)) - { - throw new ArgumentException( "BooleanFormatter can only be used to format instances of [System.Boolean]" ); - } - return ((bool) value) ? this.trueString : this.falseString; - } - - /// - /// Parses the specified boolean value according to settings of and - /// - /// The boolean value to parse. - /// Parsed boolean value as a . - /// If does not match or . - public object Parse(string value) - { - if(!StringUtils.HasText( value )) - { - return false; - } - - if ( 0 == string.Compare( value, this.trueString, this.ignoreCase )) - { - return true; - } - else if(0 == string.Compare( value,this.falseString,this.ignoreCase )) - { - return false; - } - else - { - throw new ArgumentException( string.Format("input value '{0}' is not recognized as a boolean", value) ); - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse boolean values. + /// + /// Erich Eichinger + public class BooleanFormatter:IFormatter + { + private string trueString; + private string falseString; + private bool ignoreCase; + + #region Constructors + + /// + /// Initializes a new instance of the class + /// using default values + /// + public BooleanFormatter() + : this(true,bool.TrueString,bool.FalseString) + { } + + /// + /// Initializes a new instance of the class + /// + public BooleanFormatter(bool ignoreCase,string trueString,string falseString) + { + this.trueString = trueString; + this.falseString = falseString; + this.ignoreCase = ignoreCase; + } + + #endregion + + #region Properties + + /// + /// Set/Get value to control casesensitivity of + /// + /// + /// Defaults to true + /// + public bool IgnoreCase + { + get { return this.ignoreCase; } + set { this.ignoreCase = value; } + } + + /// + /// Set/Get value to recognize as boolean "true" value + /// + /// + /// Defaults to + /// + public string TrueString + { + get { return this.trueString; } + set { this.trueString = value; } + } + + /// + /// Set/Get value to recognize as boolean "false" value + /// + /// + /// Defaults to + /// + public string FalseString + { + get { return this.falseString; } + set { this.falseString = value; } + } + + #endregion + + /// + /// Formats the specified boolean value. + /// + /// The value to format. + /// Formatted boolean value. + /// If is null. + /// If is not of type . + public string Format(object value) + { + AssertUtils.ArgumentNotNull( value,"value" ); + if(!(value is bool)) + { + throw new ArgumentException( "BooleanFormatter can only be used to format instances of [System.Boolean]" ); + } + return ((bool) value) ? this.trueString : this.falseString; + } + + /// + /// Parses the specified boolean value according to settings of and + /// + /// The boolean value to parse. + /// Parsed boolean value as a . + /// If does not match or . + public object Parse(string value) + { + if(!StringUtils.HasText( value )) + { + return false; + } + + if ( 0 == string.Compare( value, this.trueString, this.ignoreCase )) + { + return true; + } + else if(0 == string.Compare( value,this.falseString,this.ignoreCase )) + { + return false; + } + else + { + throw new ArgumentException( string.Format("input value '{0}' is not recognized as a boolean", value) ); + } + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/Formatters/CurrencyFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/CurrencyFormatter.cs index a7e47d42..03674608 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/CurrencyFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/CurrencyFormatter.cs @@ -1,209 +1,208 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse currency values. - /// - /// - /// - /// CurrencyFormatter uses currency related properties of the - /// to format and parse currency values. - /// - /// - /// If you use one of the constructors that accept culture as a parameter - /// to create an instance of CurrencyFormatter, default NumberFormatInfo - /// for the specified culture will be used. - /// - /// - /// You can also use properties exposed by the CurrencyFormatter in order - /// to override some of the default currency formatting parameters. - /// - /// - /// Aleksandar Seovic - /// $Id: CurrencyFormatter.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class CurrencyFormatter : IFormatter - { - private NumberFormatInfo formatInfo; - - #region Constructors - - /// - /// Initializes a new instance of the class - /// using default for the current thread's culture. - /// - public CurrencyFormatter() : this(CultureInfo.CurrentCulture) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// The culture name. - public CurrencyFormatter(string cultureName) : this(CultureInfo.CreateSpecificCulture(cultureName)) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// The culture. - public CurrencyFormatter(CultureInfo culture) - { - formatInfo = culture.NumberFormat; - } - - /// - /// Initializes a new instance of the class - /// using specified . - /// - /// - /// The instance that defines how - /// currency values are formatted. - /// - public CurrencyFormatter(NumberFormatInfo formatInfo) - { - this.formatInfo = formatInfo; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the currency decimal digits. - /// - /// The currency decimal digits. - /// - public int DecimalDigits - { - get { return formatInfo.CurrencyDecimalDigits; } - set { formatInfo.CurrencyDecimalDigits = value; } - } - - /// - /// Gets or sets the currency decimal separator. - /// - /// The currency decimal separator. - /// - public string DecimalSeparator - { - get { return formatInfo.CurrencyDecimalSeparator; } - set { formatInfo.CurrencyDecimalSeparator = value; } - } - - /// - /// Gets or sets the currency group sizes. - /// - /// The currency group sizes. - /// - public int[] GroupSizes - { - get { return formatInfo.CurrencyGroupSizes; } - set { formatInfo.CurrencyGroupSizes = value; } - } - - /// - /// Gets or sets the currency group separator. - /// - /// The currency group separator. - /// - public string GroupSeparator - { - get { return formatInfo.CurrencyGroupSeparator; } - set { formatInfo.CurrencyGroupSeparator = value; } - } - - /// - /// Gets or sets the currency symbol. - /// - /// The currency symbol. - /// - public string CurrencySymbol - { - get { return formatInfo.CurrencySymbol; } - set { formatInfo.CurrencySymbol = value; } - } - - /// - /// Gets or sets the currency negative pattern. - /// - /// The currency negative pattern. - /// - public int NegativePattern - { - get { return formatInfo.CurrencyNegativePattern; } - set { formatInfo.CurrencyNegativePattern = value; } - } - - /// - /// Gets or sets the currency positive pattern. - /// - /// The currency positive pattern. - /// - public int PositivePattern - { - get { return formatInfo.CurrencyPositivePattern; } - set { formatInfo.CurrencyPositivePattern = value; } - } - - #endregion - - /// - /// Formats the specified currency value. - /// - /// The value to format. - /// Formatted currency . - /// If is null. - /// If is not a number. - public string Format(object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!NumberUtils.IsNumber(value)) - { - throw new ArgumentException("CurrencyFormatter can only be used to format numbers."); - } - - return String.Format(formatInfo, "{0:C}", value); - } - - /// - /// Parses the specified currency value. - /// - /// The currency value to parse. - /// Parsed currency value as a . - public object Parse(string value) - { - if (!StringUtils.HasText(value)) - { - return 0d; - } - - return Double.Parse(value, NumberStyles.Currency, formatInfo); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse currency values. + /// + /// + /// + /// CurrencyFormatter uses currency related properties of the + /// to format and parse currency values. + /// + /// + /// If you use one of the constructors that accept culture as a parameter + /// to create an instance of CurrencyFormatter, default NumberFormatInfo + /// for the specified culture will be used. + /// + /// + /// You can also use properties exposed by the CurrencyFormatter in order + /// to override some of the default currency formatting parameters. + /// + /// + /// Aleksandar Seovic + public class CurrencyFormatter : IFormatter + { + private NumberFormatInfo formatInfo; + + #region Constructors + + /// + /// Initializes a new instance of the class + /// using default for the current thread's culture. + /// + public CurrencyFormatter() : this(CultureInfo.CurrentCulture) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// The culture name. + public CurrencyFormatter(string cultureName) : this(CultureInfo.CreateSpecificCulture(cultureName)) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// The culture. + public CurrencyFormatter(CultureInfo culture) + { + formatInfo = culture.NumberFormat; + } + + /// + /// Initializes a new instance of the class + /// using specified . + /// + /// + /// The instance that defines how + /// currency values are formatted. + /// + public CurrencyFormatter(NumberFormatInfo formatInfo) + { + this.formatInfo = formatInfo; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the currency decimal digits. + /// + /// The currency decimal digits. + /// + public int DecimalDigits + { + get { return formatInfo.CurrencyDecimalDigits; } + set { formatInfo.CurrencyDecimalDigits = value; } + } + + /// + /// Gets or sets the currency decimal separator. + /// + /// The currency decimal separator. + /// + public string DecimalSeparator + { + get { return formatInfo.CurrencyDecimalSeparator; } + set { formatInfo.CurrencyDecimalSeparator = value; } + } + + /// + /// Gets or sets the currency group sizes. + /// + /// The currency group sizes. + /// + public int[] GroupSizes + { + get { return formatInfo.CurrencyGroupSizes; } + set { formatInfo.CurrencyGroupSizes = value; } + } + + /// + /// Gets or sets the currency group separator. + /// + /// The currency group separator. + /// + public string GroupSeparator + { + get { return formatInfo.CurrencyGroupSeparator; } + set { formatInfo.CurrencyGroupSeparator = value; } + } + + /// + /// Gets or sets the currency symbol. + /// + /// The currency symbol. + /// + public string CurrencySymbol + { + get { return formatInfo.CurrencySymbol; } + set { formatInfo.CurrencySymbol = value; } + } + + /// + /// Gets or sets the currency negative pattern. + /// + /// The currency negative pattern. + /// + public int NegativePattern + { + get { return formatInfo.CurrencyNegativePattern; } + set { formatInfo.CurrencyNegativePattern = value; } + } + + /// + /// Gets or sets the currency positive pattern. + /// + /// The currency positive pattern. + /// + public int PositivePattern + { + get { return formatInfo.CurrencyPositivePattern; } + set { formatInfo.CurrencyPositivePattern = value; } + } + + #endregion + + /// + /// Formats the specified currency value. + /// + /// The value to format. + /// Formatted currency . + /// If is null. + /// If is not a number. + public string Format(object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!NumberUtils.IsNumber(value)) + { + throw new ArgumentException("CurrencyFormatter can only be used to format numbers."); + } + + return String.Format(formatInfo, "{0:C}", value); + } + + /// + /// Parses the specified currency value. + /// + /// The currency value to parse. + /// Parsed currency value as a . + public object Parse(string value) + { + if (!StringUtils.HasText(value)) + { + return 0d; + } + + return Double.Parse(value, NumberStyles.Currency, formatInfo); + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/Formatters/DateTimeFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/DateTimeFormatter.cs index 1ea2c588..f1501d79 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/DateTimeFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/DateTimeFormatter.cs @@ -1,120 +1,119 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse values. - /// - /// - /// - /// DateTimeFormatter uses properties of the - /// to format and parse values. - /// - /// - /// If you use one of the constructors that accept culture as a parameter - /// to create an instance of DateTimeFormatter, default DateTimeFormatInfo - /// for the specified culture will be used. - /// - /// - /// You can also use properties exposed by the DateTimeFormatter in order - /// to override some of the default formatting parameters. - /// - /// - /// Aleksandar Seovic - /// $Id: DateTimeFormatter.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class DateTimeFormatter : IFormatter - { - private DateTimeFormatInfo formatInfo; - private string format; - - #region Constructors - - /// - /// Initializes a new instance of the class - /// using default for the current thread's culture. - /// - /// Date/time format string. - public DateTimeFormatter(string format) : this(format, CultureInfo.CurrentCulture) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// Date/time format string. - /// The culture name. - public DateTimeFormatter(string format, string cultureName) : this(format, CultureInfo.CreateSpecificCulture(cultureName)) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// Date/time format string. - /// The culture. - public DateTimeFormatter(string format, CultureInfo culture) - { - this.format = format; - this.formatInfo = culture.DateTimeFormat; - } - - #endregion - - /// - /// Formats the specified value. - /// - /// The value to format. - /// Formatted value. - /// If is null. - /// If is not an instance of . - public string Format(object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!(value is DateTime)) - { - throw new ArgumentException("DateTimeFormatter can only be used to format instances of [System.DateTime]."); - } - - return ((DateTime) value).ToString(format, formatInfo); - } - - /// - /// Parses the specified value. - /// - /// The string to parse. - /// Parsed value. - public object Parse(string value) - { - if (!StringUtils.HasText(value)) - { - return DateTime.MinValue; - } - - return DateTime.ParseExact(value, format, formatInfo, DateTimeStyles.AllowWhiteSpaces); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse values. + /// + /// + /// + /// DateTimeFormatter uses properties of the + /// to format and parse values. + /// + /// + /// If you use one of the constructors that accept culture as a parameter + /// to create an instance of DateTimeFormatter, default DateTimeFormatInfo + /// for the specified culture will be used. + /// + /// + /// You can also use properties exposed by the DateTimeFormatter in order + /// to override some of the default formatting parameters. + /// + /// + /// Aleksandar Seovic + public class DateTimeFormatter : IFormatter + { + private DateTimeFormatInfo formatInfo; + private string format; + + #region Constructors + + /// + /// Initializes a new instance of the class + /// using default for the current thread's culture. + /// + /// Date/time format string. + public DateTimeFormatter(string format) : this(format, CultureInfo.CurrentCulture) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// Date/time format string. + /// The culture name. + public DateTimeFormatter(string format, string cultureName) : this(format, CultureInfo.CreateSpecificCulture(cultureName)) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// Date/time format string. + /// The culture. + public DateTimeFormatter(string format, CultureInfo culture) + { + this.format = format; + this.formatInfo = culture.DateTimeFormat; + } + + #endregion + + /// + /// Formats the specified value. + /// + /// The value to format. + /// Formatted value. + /// If is null. + /// If is not an instance of . + public string Format(object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!(value is DateTime)) + { + throw new ArgumentException("DateTimeFormatter can only be used to format instances of [System.DateTime]."); + } + + return ((DateTime) value).ToString(format, formatInfo); + } + + /// + /// Parses the specified value. + /// + /// The string to parse. + /// Parsed value. + public object Parse(string value) + { + if (!StringUtils.HasText(value)) + { + return DateTime.MinValue; + } + + return DateTime.ParseExact(value, format, formatInfo, DateTimeStyles.AllowWhiteSpaces); + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/Formatters/FilteringFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/FilteringFormatter.cs index e54af5f1..ba09670a 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/FilteringFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/FilteringFormatter.cs @@ -1,101 +1,100 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Util; - -#endregion - -namespace Spring.Globalization.Formatters -{ - /// - /// Provides base functionality for filtering values before they actually get parsed/formatted. - /// - /// Erich Eichinger - /// $Id: FilteringFormatter.cs,v 1.1 2008/03/20 13:19:47 oakinger Exp $ - public abstract class FilteringFormatter : IFormatter - { - private readonly IFormatter _underlyingFormatter; - - /// - /// Creates a new instance of this FilteringFormatter. - /// - ///an optional underlying formatter - /// - /// If no underlying formatter is specified, the values - /// get passed through "as-is" after being filtered - /// - public FilteringFormatter(IFormatter underlyingFormatter) - { - _underlyingFormatter = underlyingFormatter; - } - - /// - /// Parses the specified value. - /// - /// The value to parse. - /// Parsed . - public object Parse(string value) - { - value = FilterValueToParse(value); - - if (_underlyingFormatter != null) - { - return _underlyingFormatter.Parse(value); - } - - return value; - } - - /// - /// Formats the specified value. - /// - /// The value to format. - /// Formatted . - public string Format(object value) - { - value = FilterValueToFormat(value); - - if (_underlyingFormatter != null) - { - return _underlyingFormatter.Format(value); - } - - return (value != null) ? value.ToString() : null; - } - - /// - /// Allows to rewrite a value before it gets parsed by the underlying formatter - /// - protected virtual string FilterValueToParse(string value) - { - return value; - } - - /// - /// Allows to change a value before it gets formatted by the underlying formatter - /// - protected virtual object FilterValueToFormat(object value) - { - return value; - } - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Util; + +#endregion + +namespace Spring.Globalization.Formatters +{ + /// + /// Provides base functionality for filtering values before they actually get parsed/formatted. + /// + /// Erich Eichinger + public abstract class FilteringFormatter : IFormatter + { + private readonly IFormatter _underlyingFormatter; + + /// + /// Creates a new instance of this FilteringFormatter. + /// + ///an optional underlying formatter + /// + /// If no underlying formatter is specified, the values + /// get passed through "as-is" after being filtered + /// + public FilteringFormatter(IFormatter underlyingFormatter) + { + _underlyingFormatter = underlyingFormatter; + } + + /// + /// Parses the specified value. + /// + /// The value to parse. + /// Parsed . + public object Parse(string value) + { + value = FilterValueToParse(value); + + if (_underlyingFormatter != null) + { + return _underlyingFormatter.Parse(value); + } + + return value; + } + + /// + /// Formats the specified value. + /// + /// The value to format. + /// Formatted . + public string Format(object value) + { + value = FilterValueToFormat(value); + + if (_underlyingFormatter != null) + { + return _underlyingFormatter.Format(value); + } + + return (value != null) ? value.ToString() : null; + } + + /// + /// Allows to rewrite a value before it gets parsed by the underlying formatter + /// + protected virtual string FilterValueToParse(string value) + { + return value; + } + + /// + /// Allows to change a value before it gets formatted by the underlying formatter + /// + protected virtual object FilterValueToFormat(object value) + { + return value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Formatters/FloatFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/FloatFormatter.cs index d55df1b6..b7a418b9 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/FloatFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/FloatFormatter.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse floating point numbers. - /// - /// - /// - /// This formatter allows you to format and parse numbers that conform - /// to number style (leading and trailing - /// white space, leading sign, decimal point, exponent). - /// - /// - /// Aleksandar Seovic - /// $Id: FloatFormatter.cs,v 1.4 2006/04/09 07:18:47 markpollack Exp $ - public class FloatFormatter : IFormatter - { - /// - /// Default format string. - /// - public const string DefaultFormat = "{0:F}"; - - private string format; - private NumberFormatInfo numberInfo; - - #region Constructors - - /// - /// Initializes a new instance of the class, - /// using default format string of '{0:F}' and current thread's culture. - /// - public FloatFormatter() : this(DefaultFormat, CultureInfo.CurrentCulture) - {} - - /// - /// Initializes a new instance of the class, - /// using specified format string and current thread's culture. - /// - /// The format string. - public FloatFormatter(string format) : this(format, CultureInfo.CurrentCulture) - {} - - /// - /// Initializes a new instance of the class, - /// using default format string of '{0:F}' and specified culture. - /// - /// The culture. - public FloatFormatter(CultureInfo culture) : this(DefaultFormat, culture) - {} - - /// - /// Initializes a new instance of the class, - /// using specified format string and current thread's culture. - /// - /// The format string. - /// The culture name. - public FloatFormatter(string format, string cultureName) : this(format, CultureInfo.CreateSpecificCulture(cultureName)) - {} - - /// - /// Initializes a new instance of the class, - /// using specified format string and culture. - /// - /// The format string. - /// The culture. - public FloatFormatter(string format, CultureInfo culture) - { - this.format = format; - this.numberInfo = culture.NumberFormat; - } - - #endregion - - /// - /// Formats the specified float value. - /// - /// The value to format. - /// Formatted floating point number. - /// If is null. - /// If is not a number. - public string Format(object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!NumberUtils.IsNumber(value)) - { - throw new ArgumentException("FloatFormatter can only be used to format numbers."); - } - - return String.Format(numberInfo, format, value); - } - - /// - /// Parses the specified float value. - /// - /// The float value to parse. - /// Parsed float value as a . - public object Parse(string value) - { - if (!StringUtils.HasText(value)) - { - return 0d; - } - return Double.Parse(value, NumberStyles.Float, numberInfo); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse floating point numbers. + /// + /// + /// + /// This formatter allows you to format and parse numbers that conform + /// to number style (leading and trailing + /// white space, leading sign, decimal point, exponent). + /// + /// + /// Aleksandar Seovic + public class FloatFormatter : IFormatter + { + /// + /// Default format string. + /// + public const string DefaultFormat = "{0:F}"; + + private string format; + private NumberFormatInfo numberInfo; + + #region Constructors + + /// + /// Initializes a new instance of the class, + /// using default format string of '{0:F}' and current thread's culture. + /// + public FloatFormatter() : this(DefaultFormat, CultureInfo.CurrentCulture) + {} + + /// + /// Initializes a new instance of the class, + /// using specified format string and current thread's culture. + /// + /// The format string. + public FloatFormatter(string format) : this(format, CultureInfo.CurrentCulture) + {} + + /// + /// Initializes a new instance of the class, + /// using default format string of '{0:F}' and specified culture. + /// + /// The culture. + public FloatFormatter(CultureInfo culture) : this(DefaultFormat, culture) + {} + + /// + /// Initializes a new instance of the class, + /// using specified format string and current thread's culture. + /// + /// The format string. + /// The culture name. + public FloatFormatter(string format, string cultureName) : this(format, CultureInfo.CreateSpecificCulture(cultureName)) + {} + + /// + /// Initializes a new instance of the class, + /// using specified format string and culture. + /// + /// The format string. + /// The culture. + public FloatFormatter(string format, CultureInfo culture) + { + this.format = format; + this.numberInfo = culture.NumberFormat; + } + + #endregion + + /// + /// Formats the specified float value. + /// + /// The value to format. + /// Formatted floating point number. + /// If is null. + /// If is not a number. + public string Format(object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!NumberUtils.IsNumber(value)) + { + throw new ArgumentException("FloatFormatter can only be used to format numbers."); + } + + return String.Format(numberInfo, format, value); + } + + /// + /// Parses the specified float value. + /// + /// The float value to parse. + /// Parsed float value as a . + public object Parse(string value) + { + if (!StringUtils.HasText(value)) + { + return 0d; + } + return Double.Parse(value, NumberStyles.Float, numberInfo); + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/Formatters/HasTextFilteringFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/HasTextFilteringFormatter.cs index 296bb688..15982eda 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/HasTextFilteringFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/HasTextFilteringFormatter.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Util; - -#endregion - -namespace Spring.Globalization.Formatters -{ - /// - /// Replaces input strings with a given default value, - /// if they are null or contain whitespaces only, - /// - /// Erich Eichinger - /// $Id: HasTextFilteringFormatter.cs,v 1.1 2008/03/20 13:19:47 oakinger Exp $ - public class HasTextFilteringFormatter : FilteringFormatter - { - private readonly string _defaultValue; - - /// - /// Creates a new instance of this HasTextFilteringFormatter using null as default value. - /// - ///an optional underlying formatter - /// - /// If no underlying formatter is specified, the values - /// get passed through "as-is" after being filtered - /// - public HasTextFilteringFormatter(IFormatter underlyingFormatter) - : this(null, underlyingFormatter) - { - } - - /// - /// Creates a new instance of this HasTextFilteringFormatter. - /// - /// the default value to be returned, if input text doesn't contain text - ///an optional underlying formatter - /// - /// If no underlying formatter is specified, the values - /// get passed through "as-is" after being filtered - /// - public HasTextFilteringFormatter(string defaultValue, IFormatter underlyingFormatter) - : base(underlyingFormatter) - { - _defaultValue = defaultValue; - } - - /// - /// If value contains no text, it will be replaced by a defaultValue. - /// - protected override string FilterValueToParse(string value) - { - if (!StringUtils.HasText(value)) - { - value = _defaultValue; - } - return value; - } - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Util; + +#endregion + +namespace Spring.Globalization.Formatters +{ + /// + /// Replaces input strings with a given default value, + /// if they are null or contain whitespaces only, + /// + /// Erich Eichinger + public class HasTextFilteringFormatter : FilteringFormatter + { + private readonly string _defaultValue; + + /// + /// Creates a new instance of this HasTextFilteringFormatter using null as default value. + /// + ///an optional underlying formatter + /// + /// If no underlying formatter is specified, the values + /// get passed through "as-is" after being filtered + /// + public HasTextFilteringFormatter(IFormatter underlyingFormatter) + : this(null, underlyingFormatter) + { + } + + /// + /// Creates a new instance of this HasTextFilteringFormatter. + /// + /// the default value to be returned, if input text doesn't contain text + ///an optional underlying formatter + /// + /// If no underlying formatter is specified, the values + /// get passed through "as-is" after being filtered + /// + public HasTextFilteringFormatter(string defaultValue, IFormatter underlyingFormatter) + : base(underlyingFormatter) + { + _defaultValue = defaultValue; + } + + /// + /// If value contains no text, it will be replaced by a defaultValue. + /// + protected override string FilterValueToParse(string value) + { + if (!StringUtils.HasText(value)) + { + value = _defaultValue; + } + return value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Formatters/IntegerFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/IntegerFormatter.cs index 12a91aff..69c97442 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/IntegerFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/IntegerFormatter.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse integer numbers. - /// - /// - /// - /// This formatter allows you to format and parse numbers that conform - /// to number style (leading and trailing - /// white space, leading sign). - /// - /// - /// Aleksandar Seovic - /// $Id: IntegerFormatter.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class IntegerFormatter : IFormatter - { - private string format = "{0:D}"; - - #region Constructors - - /// - /// Initializes a new instance of the class, - /// using default format string of '{0:D}'. - /// - public IntegerFormatter() - {} - - /// - /// Initializes a new instance of the class, - /// using specified format string. - /// - public IntegerFormatter(string format) - { - this.format = format; - } - - #endregion - - /// - /// Formats the specified integer value. - /// - /// The value to format. - /// Formatted integer number. - /// If is null. - /// If is not an integer number. - public string Format(object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!NumberUtils.IsInteger(value)) - { - throw new ArgumentException("IntegerFormatter can only be used to format integer numbers."); - } - - return String.Format(format, value); - } - - /// - /// Parses the specified integer value. - /// - /// The integer value to parse. - /// Parsed number value as a . - public object Parse(string value) - { - if (!StringUtils.HasText(value)) - { - return 0; - } - return Int32.Parse(value, NumberStyles.Integer); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse integer numbers. + /// + /// + /// + /// This formatter allows you to format and parse numbers that conform + /// to number style (leading and trailing + /// white space, leading sign). + /// + /// + /// Aleksandar Seovic + public class IntegerFormatter : IFormatter + { + private string format = "{0:D}"; + + #region Constructors + + /// + /// Initializes a new instance of the class, + /// using default format string of '{0:D}'. + /// + public IntegerFormatter() + {} + + /// + /// Initializes a new instance of the class, + /// using specified format string. + /// + public IntegerFormatter(string format) + { + this.format = format; + } + + #endregion + + /// + /// Formats the specified integer value. + /// + /// The value to format. + /// Formatted integer number. + /// If is null. + /// If is not an integer number. + public string Format(object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!NumberUtils.IsInteger(value)) + { + throw new ArgumentException("IntegerFormatter can only be used to format integer numbers."); + } + + return String.Format(format, value); + } + + /// + /// Parses the specified integer value. + /// + /// The integer value to parse. + /// Parsed number value as a . + public object Parse(string value) + { + if (!StringUtils.HasText(value)) + { + return 0; + } + return Int32.Parse(value, NumberStyles.Integer); + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/Formatters/NullFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/NullFormatter.cs index b11c5c52..b52b9598 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/NullFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/NullFormatter.cs @@ -1,66 +1,65 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that simply calls . - /// - /// - /// This formatter is a no-operation implementation. - /// - /// Erich Eichinger - /// $Id: NullFormatter.cs,v 1.1 2007/05/19 00:23:18 oakinger Exp $ - public class NullFormatter : IFormatter - { - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - public NullFormatter() - { - } - - #endregion - - /// - /// Converts the passed value to a string by calling . - /// - /// The value to convert. - /// to string converted value. - public string Format(object value) - { - return value != null ? value.ToString() : null; - } - - /// - /// Returns the passed string "as is". - /// - /// The value to return. - /// The value passed into this method. - public object Parse(string value) - { - return value; - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that simply calls . + /// + /// + /// This formatter is a no-operation implementation. + /// + /// Erich Eichinger + public class NullFormatter : IFormatter + { + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public NullFormatter() + { + } + + #endregion + + /// + /// Converts the passed value to a string by calling . + /// + /// The value to convert. + /// to string converted value. + public string Format(object value) + { + return value != null ? value.ToString() : null; + } + + /// + /// Returns the passed string "as is". + /// + /// The value to return. + /// The value passed into this method. + public object Parse(string value) + { + return value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Formatters/NumberFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/NumberFormatter.cs index 6fd0f2b6..8d7c7467 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/NumberFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/NumberFormatter.cs @@ -1,199 +1,198 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse numbers. - /// - /// - /// - /// NumberFormatter uses number-related properties of the - /// to format and parse numbers. - /// - /// - /// This formatter works with both integer and decimal numbers and allows - /// you to format and parse numbers that conform to - /// number style (leading and trailing white space and/or sign, thousands separator, - /// decimal point) - /// - /// - /// If you use one of the constructors that accept culture as a parameter - /// to create an instance of NumberFormatter, default NumberFormatInfo - /// for the specified culture will be used. - /// - /// - /// You can also use properties exposed by the NumberFormatter in order - /// to override some of the default number formatting parameters. - /// - /// - /// Aleksandar Seovic - /// $Id: NumberFormatter.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class NumberFormatter : IFormatter - { - private NumberFormatInfo formatInfo; - - #region Constructors - - /// - /// Initializes a new instance of the class - /// using default for the current thread's culture. - /// - public NumberFormatter() : this(CultureInfo.CurrentCulture) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// The culture name. - public NumberFormatter(string cultureName) : this(CultureInfo.CreateSpecificCulture(cultureName)) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// The culture. - public NumberFormatter(CultureInfo culture) - { - formatInfo = culture.NumberFormat; - } - - /// - /// Initializes a new instance of the class - /// using specified . - /// - /// - /// The instance that defines how - /// numbers are formatted and parsed. - /// - public NumberFormatter(NumberFormatInfo formatInfo) - { - this.formatInfo = formatInfo; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the number of decimal digits. - /// - /// The number of decimal digits. - /// - public int DecimalDigits - { - get { return formatInfo.NumberDecimalDigits; } - set { formatInfo.NumberDecimalDigits = value; } - } - - /// - /// Gets or sets the decimal separator. - /// - /// The decimal separator. - /// - public string DecimalSeparator - { - get { return formatInfo.NumberDecimalSeparator; } - set { formatInfo.NumberDecimalSeparator = value; } - } - - /// - /// Gets or sets the number group sizes. - /// - /// The number group sizes. - /// - public int[] GroupSizes - { - get { return formatInfo.NumberGroupSizes; } - set { formatInfo.NumberGroupSizes = value; } - } - - /// - /// Gets or sets the number group separator. - /// - /// The number group separator. - /// - public string GroupSeparator - { - get { return formatInfo.NumberGroupSeparator; } - set { formatInfo.NumberGroupSeparator = value; } - } - - /// - /// Gets or sets the negative pattern. - /// - /// The number negative pattern. - /// - public int NegativePattern - { - get { return formatInfo.NumberNegativePattern; } - set { formatInfo.NumberNegativePattern = value; } - } - - #endregion - - /// - /// Formats the specified number value. - /// - /// The value to format. - /// Formatted number . - /// If is null. - /// If is not a number. - public string Format(object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!NumberUtils.IsNumber(value)) - { - throw new ArgumentException("NumberFormatter can only be used to format numbers."); - } - - return String.Format(formatInfo, "{0:N}", value); - } - - /// - /// Parses the specified number value. - /// - /// The number value to parse. - /// Parsed number value as a . - public object Parse(string value) - { - if (!StringUtils.HasText(value)) - { - return 0d; - } - - NumberStyles numberStyle = NumberStyles.Number; - if (formatInfo.NumberNegativePattern == 0) - { - numberStyle |= NumberStyles.AllowParentheses; - } - - return Double.Parse(value, numberStyle, formatInfo); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse numbers. + /// + /// + /// + /// NumberFormatter uses number-related properties of the + /// to format and parse numbers. + /// + /// + /// This formatter works with both integer and decimal numbers and allows + /// you to format and parse numbers that conform to + /// number style (leading and trailing white space and/or sign, thousands separator, + /// decimal point) + /// + /// + /// If you use one of the constructors that accept culture as a parameter + /// to create an instance of NumberFormatter, default NumberFormatInfo + /// for the specified culture will be used. + /// + /// + /// You can also use properties exposed by the NumberFormatter in order + /// to override some of the default number formatting parameters. + /// + /// + /// Aleksandar Seovic + public class NumberFormatter : IFormatter + { + private NumberFormatInfo formatInfo; + + #region Constructors + + /// + /// Initializes a new instance of the class + /// using default for the current thread's culture. + /// + public NumberFormatter() : this(CultureInfo.CurrentCulture) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// The culture name. + public NumberFormatter(string cultureName) : this(CultureInfo.CreateSpecificCulture(cultureName)) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// The culture. + public NumberFormatter(CultureInfo culture) + { + formatInfo = culture.NumberFormat; + } + + /// + /// Initializes a new instance of the class + /// using specified . + /// + /// + /// The instance that defines how + /// numbers are formatted and parsed. + /// + public NumberFormatter(NumberFormatInfo formatInfo) + { + this.formatInfo = formatInfo; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the number of decimal digits. + /// + /// The number of decimal digits. + /// + public int DecimalDigits + { + get { return formatInfo.NumberDecimalDigits; } + set { formatInfo.NumberDecimalDigits = value; } + } + + /// + /// Gets or sets the decimal separator. + /// + /// The decimal separator. + /// + public string DecimalSeparator + { + get { return formatInfo.NumberDecimalSeparator; } + set { formatInfo.NumberDecimalSeparator = value; } + } + + /// + /// Gets or sets the number group sizes. + /// + /// The number group sizes. + /// + public int[] GroupSizes + { + get { return formatInfo.NumberGroupSizes; } + set { formatInfo.NumberGroupSizes = value; } + } + + /// + /// Gets or sets the number group separator. + /// + /// The number group separator. + /// + public string GroupSeparator + { + get { return formatInfo.NumberGroupSeparator; } + set { formatInfo.NumberGroupSeparator = value; } + } + + /// + /// Gets or sets the negative pattern. + /// + /// The number negative pattern. + /// + public int NegativePattern + { + get { return formatInfo.NumberNegativePattern; } + set { formatInfo.NumberNegativePattern = value; } + } + + #endregion + + /// + /// Formats the specified number value. + /// + /// The value to format. + /// Formatted number . + /// If is null. + /// If is not a number. + public string Format(object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!NumberUtils.IsNumber(value)) + { + throw new ArgumentException("NumberFormatter can only be used to format numbers."); + } + + return String.Format(formatInfo, "{0:N}", value); + } + + /// + /// Parses the specified number value. + /// + /// The number value to parse. + /// Parsed number value as a . + public object Parse(string value) + { + if (!StringUtils.HasText(value)) + { + return 0d; + } + + NumberStyles numberStyle = NumberStyles.Number; + if (formatInfo.NumberNegativePattern == 0) + { + numberStyle |= NumberStyles.AllowParentheses; + } + + return Double.Parse(value, numberStyle, formatInfo); + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/Formatters/PercentFormatter.cs b/src/Spring/Spring.Core/Globalization/Formatters/PercentFormatter.cs index 6c678c9a..5095151f 100644 --- a/src/Spring/Spring.Core/Globalization/Formatters/PercentFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/Formatters/PercentFormatter.cs @@ -1,233 +1,232 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; - -using Spring.Util; - -namespace Spring.Globalization.Formatters -{ - /// - /// Implementation of that can be used to - /// format and parse numbers. - /// - /// - /// - /// PercentFormatter uses percent-related properties of the - /// to format and parse percentages. - /// - /// - /// If you use one of the constructors that accept culture as a parameter - /// to create an instance of PercentFormatter, default NumberFormatInfo - /// for the specified culture will be used. - /// - /// - /// You can also use properties exposed by the PercentFormatter in order - /// to override some of the default number formatting parameters. - /// - /// - /// Aleksandar Seovic - /// $Id: PercentFormatter.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class PercentFormatter : IFormatter - { - private static int[] positivePatterns = new int[] {3, 1, 0}; - private static int[] negativePatterns = new int[] {8, 5, 1}; - - private NumberFormatInfo formatInfo; - - #region Constructors - - /// - /// Initializes a new instance of the class - /// using default for the current thread's culture. - /// - public PercentFormatter() : this(CultureInfo.CurrentCulture) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// The culture name. - public PercentFormatter(string cultureName) : this(CultureInfo.CreateSpecificCulture(cultureName)) - {} - - /// - /// Initializes a new instance of the class - /// using default for the specified culture. - /// - /// The culture. - public PercentFormatter(CultureInfo culture) - { - formatInfo = culture.NumberFormat; - } - - /// - /// Initializes a new instance of the class - /// using specified . - /// - /// - /// The instance that defines how - /// numbers are formatted and parsed. - /// - public PercentFormatter(NumberFormatInfo formatInfo) - { - this.formatInfo = formatInfo; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the number of decimal digits. - /// - /// The number of decimal digits. - /// - public int DecimalDigits - { - get { return formatInfo.PercentDecimalDigits; } - set { formatInfo.PercentDecimalDigits = value; } - } - - /// - /// Gets or sets the decimal separator. - /// - /// The decimal separator. - /// - public string DecimalSeparator - { - get { return formatInfo.PercentDecimalSeparator; } - set { formatInfo.PercentDecimalSeparator = value; } - } - - /// - /// Gets or sets the percent group sizes. - /// - /// The percent group sizes. - /// - public int[] GroupSizes - { - get { return formatInfo.PercentGroupSizes; } - set { formatInfo.PercentGroupSizes = value; } - } - - /// - /// Gets or sets the percent group separator. - /// - /// The percent group separator. - /// - public string GroupSeparator - { - get { return formatInfo.PercentGroupSeparator; } - set { formatInfo.PercentGroupSeparator = value; } - } - - /// - /// Gets or sets the negative pattern. - /// - /// The percent negative pattern. - /// - public int NegativePattern - { - get { return formatInfo.PercentNegativePattern; } - set { formatInfo.PercentNegativePattern = value; } - } - - /// - /// Gets or sets the positive pattern. - /// - /// The percent positive pattern. - /// - public int PositivePattern - { - get { return formatInfo.PercentPositivePattern; } - set { formatInfo.PercentPositivePattern = value; } - } - - /// - /// Gets or sets the percent symbol. - /// - /// The percent symbol. - /// - public string PercentSymbol - { - get { return formatInfo.PercentSymbol; } - set { formatInfo.PercentSymbol = value; } - } - - /// - /// Gets or sets the per mille symbol. - /// - /// The per mille symbol. - /// - public string PerMilleSymbol - { - get { return formatInfo.PerMilleSymbol; } - set { formatInfo.PerMilleSymbol = value; } - } - - #endregion - - /// - /// Formats the specified percentage value. - /// - /// The value to format. - /// Formatted percentage. - /// If is null. - /// If is not a number. - public string Format(object value) - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!NumberUtils.IsNumber(value)) - { - throw new ArgumentException("PercentFormatter can only be used to format numbers."); - } - - return String.Format(formatInfo, "{0:P}", value); - } - - /// - /// Parses the specified percentage value. - /// - /// The percentage value to parse. - /// Parsed percentage value as a . - public object Parse(string value) - { - if (!StringUtils.HasText(value)) - { - return 0d; - } - - // there is no percentage parser in .NET, so we use currency parser to achieve the goal - NumberFormatInfo fi = (NumberFormatInfo) formatInfo.Clone(); - fi.CurrencyDecimalDigits = formatInfo.PercentDecimalDigits; - fi.CurrencyDecimalSeparator = formatInfo.PercentDecimalSeparator; - fi.CurrencyGroupSeparator = formatInfo.PercentGroupSeparator; - fi.CurrencyGroupSizes = formatInfo.PercentGroupSizes; - fi.CurrencyNegativePattern = negativePatterns[formatInfo.PercentNegativePattern]; - fi.CurrencyPositivePattern = positivePatterns[formatInfo.PercentPositivePattern]; - fi.CurrencySymbol = formatInfo.PercentSymbol; - - return Double.Parse(value, NumberStyles.Currency, fi) / 100; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; + +using Spring.Util; + +namespace Spring.Globalization.Formatters +{ + /// + /// Implementation of that can be used to + /// format and parse numbers. + /// + /// + /// + /// PercentFormatter uses percent-related properties of the + /// to format and parse percentages. + /// + /// + /// If you use one of the constructors that accept culture as a parameter + /// to create an instance of PercentFormatter, default NumberFormatInfo + /// for the specified culture will be used. + /// + /// + /// You can also use properties exposed by the PercentFormatter in order + /// to override some of the default number formatting parameters. + /// + /// + /// Aleksandar Seovic + public class PercentFormatter : IFormatter + { + private static int[] positivePatterns = new int[] {3, 1, 0}; + private static int[] negativePatterns = new int[] {8, 5, 1}; + + private NumberFormatInfo formatInfo; + + #region Constructors + + /// + /// Initializes a new instance of the class + /// using default for the current thread's culture. + /// + public PercentFormatter() : this(CultureInfo.CurrentCulture) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// The culture name. + public PercentFormatter(string cultureName) : this(CultureInfo.CreateSpecificCulture(cultureName)) + {} + + /// + /// Initializes a new instance of the class + /// using default for the specified culture. + /// + /// The culture. + public PercentFormatter(CultureInfo culture) + { + formatInfo = culture.NumberFormat; + } + + /// + /// Initializes a new instance of the class + /// using specified . + /// + /// + /// The instance that defines how + /// numbers are formatted and parsed. + /// + public PercentFormatter(NumberFormatInfo formatInfo) + { + this.formatInfo = formatInfo; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the number of decimal digits. + /// + /// The number of decimal digits. + /// + public int DecimalDigits + { + get { return formatInfo.PercentDecimalDigits; } + set { formatInfo.PercentDecimalDigits = value; } + } + + /// + /// Gets or sets the decimal separator. + /// + /// The decimal separator. + /// + public string DecimalSeparator + { + get { return formatInfo.PercentDecimalSeparator; } + set { formatInfo.PercentDecimalSeparator = value; } + } + + /// + /// Gets or sets the percent group sizes. + /// + /// The percent group sizes. + /// + public int[] GroupSizes + { + get { return formatInfo.PercentGroupSizes; } + set { formatInfo.PercentGroupSizes = value; } + } + + /// + /// Gets or sets the percent group separator. + /// + /// The percent group separator. + /// + public string GroupSeparator + { + get { return formatInfo.PercentGroupSeparator; } + set { formatInfo.PercentGroupSeparator = value; } + } + + /// + /// Gets or sets the negative pattern. + /// + /// The percent negative pattern. + /// + public int NegativePattern + { + get { return formatInfo.PercentNegativePattern; } + set { formatInfo.PercentNegativePattern = value; } + } + + /// + /// Gets or sets the positive pattern. + /// + /// The percent positive pattern. + /// + public int PositivePattern + { + get { return formatInfo.PercentPositivePattern; } + set { formatInfo.PercentPositivePattern = value; } + } + + /// + /// Gets or sets the percent symbol. + /// + /// The percent symbol. + /// + public string PercentSymbol + { + get { return formatInfo.PercentSymbol; } + set { formatInfo.PercentSymbol = value; } + } + + /// + /// Gets or sets the per mille symbol. + /// + /// The per mille symbol. + /// + public string PerMilleSymbol + { + get { return formatInfo.PerMilleSymbol; } + set { formatInfo.PerMilleSymbol = value; } + } + + #endregion + + /// + /// Formats the specified percentage value. + /// + /// The value to format. + /// Formatted percentage. + /// If is null. + /// If is not a number. + public string Format(object value) + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!NumberUtils.IsNumber(value)) + { + throw new ArgumentException("PercentFormatter can only be used to format numbers."); + } + + return String.Format(formatInfo, "{0:P}", value); + } + + /// + /// Parses the specified percentage value. + /// + /// The percentage value to parse. + /// Parsed percentage value as a . + public object Parse(string value) + { + if (!StringUtils.HasText(value)) + { + return 0d; + } + + // there is no percentage parser in .NET, so we use currency parser to achieve the goal + NumberFormatInfo fi = (NumberFormatInfo) formatInfo.Clone(); + fi.CurrencyDecimalDigits = formatInfo.PercentDecimalDigits; + fi.CurrencyDecimalSeparator = formatInfo.PercentDecimalSeparator; + fi.CurrencyGroupSeparator = formatInfo.PercentGroupSeparator; + fi.CurrencyGroupSizes = formatInfo.PercentGroupSizes; + fi.CurrencyNegativePattern = negativePatterns[formatInfo.PercentNegativePattern]; + fi.CurrencyPositivePattern = positivePatterns[formatInfo.PercentPositivePattern]; + fi.CurrencySymbol = formatInfo.PercentSymbol; + + return Double.Parse(value, NumberStyles.Currency, fi) / 100; + } + } +} diff --git a/src/Spring/Spring.Core/Globalization/ICultureResolver.cs b/src/Spring/Spring.Core/Globalization/ICultureResolver.cs index d86facb2..b2f0027d 100644 --- a/src/Spring/Spring.Core/Globalization/ICultureResolver.cs +++ b/src/Spring/Spring.Core/Globalization/ICultureResolver.cs @@ -1,71 +1,70 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Globalization; - -#endregion - -namespace Spring.Globalization -{ - /// - /// Strategy interface for - /// resolution. - /// - /// Aleksandar Seovic - /// $Id: ICultureResolver.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public interface ICultureResolver - { - /// - /// Resolves the - /// from some context. - /// - /// - ///

- /// The 'context' is determined by the appropriate implementation class. - /// An example of such a context might be a thread local bound - /// , or a - /// sourced from an HTTP - /// session. - ///

- ///
- /// - /// The that should be used - /// by the caller. - /// - CultureInfo ResolveCulture(); - - /// - /// Sets the . - /// - /// - ///

- /// This is an optional operation and does not need to be implemented - /// such that it actually does anything useful (i.e. it can be a no-op). - ///

- ///
- /// - /// The new or - /// to clear the current . - /// - void SetCulture(CultureInfo culture); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Globalization; + +#endregion + +namespace Spring.Globalization +{ + /// + /// Strategy interface for + /// resolution. + /// + /// Aleksandar Seovic + public interface ICultureResolver + { + /// + /// Resolves the + /// from some context. + /// + /// + ///

+ /// The 'context' is determined by the appropriate implementation class. + /// An example of such a context might be a thread local bound + /// , or a + /// sourced from an HTTP + /// session. + ///

+ ///
+ /// + /// The that should be used + /// by the caller. + /// + CultureInfo ResolveCulture(); + + /// + /// Sets the . + /// + /// + ///

+ /// This is an optional operation and does not need to be implemented + /// such that it actually does anything useful (i.e. it can be a no-op). + ///

+ ///
+ /// + /// The new or + /// to clear the current . + /// + void SetCulture(CultureInfo culture); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/IFormatter.cs b/src/Spring/Spring.Core/Globalization/IFormatter.cs index a51a0eec..320dd33d 100644 --- a/src/Spring/Spring.Core/Globalization/IFormatter.cs +++ b/src/Spring/Spring.Core/Globalization/IFormatter.cs @@ -1,51 +1,50 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Globalization -{ - /// - /// Interface that should be implemented by all formatters. - /// - /// - /// - /// Formatters assume that source value is a string, and make no assumptions - /// about the target value's type, which means that Parse method can return - /// object of any type. - /// - /// - /// Aleksandar Seovic - /// $Id: IFormatter.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public interface IFormatter - { - /// - /// Formats the specified value. - /// - /// The value to format. - /// Formatted . - string Format(object value); - - /// - /// Parses the specified value. - /// - /// The value to parse. - /// Parsed . - object Parse(string value); - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Globalization +{ + /// + /// Interface that should be implemented by all formatters. + /// + /// + /// + /// Formatters assume that source value is a string, and make no assumptions + /// about the target value's type, which means that Parse method can return + /// object of any type. + /// + /// + /// Aleksandar Seovic + public interface IFormatter + { + /// + /// Formats the specified value. + /// + /// The value to format. + /// Formatted . + string Format(object value); + + /// + /// Parses the specified value. + /// + /// The value to parse. + /// Parsed . + object Parse(string value); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/ILocalizer.cs b/src/Spring/Spring.Core/Globalization/ILocalizer.cs index 7e41875a..f2e028ff 100644 --- a/src/Spring/Spring.Core/Globalization/ILocalizer.cs +++ b/src/Spring/Spring.Core/Globalization/ILocalizer.cs @@ -1,61 +1,60 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Globalization; - -using Spring.Context; - -namespace Spring.Globalization -{ - /// - /// Defines an interface that localizers have to implement. - /// - /// - ///

- /// Localizers are used to automatically apply resources to object's members - /// using reflection. - ///

- ///
- /// Aleksandar Seovic - /// $Id: ILocalizer.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public interface ILocalizer - { - /// - /// Gets or sets the resource cache instance. - /// - /// The resource cache instance. - IResourceCache ResourceCache { get; set; } - - /// - /// Applies resources of the specified culture to the specified target object. - /// - /// Target object to apply resources to. - /// instance to retrieve resources from. - /// Resource culture to use for resource lookup. - void ApplyResources(object target, IMessageSource messageSource, CultureInfo culture); - - /// - /// Applies resources to the specified target object, using current thread's culture to resolve resources. - /// - /// Target object to apply resources to. - /// instance to retrieve resources from. - void ApplyResources(object target, IMessageSource messageSource); - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Globalization; + +using Spring.Context; + +namespace Spring.Globalization +{ + /// + /// Defines an interface that localizers have to implement. + /// + /// + ///

+ /// Localizers are used to automatically apply resources to object's members + /// using reflection. + ///

+ ///
+ /// Aleksandar Seovic + public interface ILocalizer + { + /// + /// Gets or sets the resource cache instance. + /// + /// The resource cache instance. + IResourceCache ResourceCache { get; set; } + + /// + /// Applies resources of the specified culture to the specified target object. + /// + /// Target object to apply resources to. + /// instance to retrieve resources from. + /// Resource culture to use for resource lookup. + void ApplyResources(object target, IMessageSource messageSource, CultureInfo culture); + + /// + /// Applies resources to the specified target object, using current thread's culture to resolve resources. + /// + /// Target object to apply resources to. + /// instance to retrieve resources from. + void ApplyResources(object target, IMessageSource messageSource); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/IResourceCache.cs b/src/Spring/Spring.Core/Globalization/IResourceCache.cs index 5a171804..c489d8c4 100644 --- a/src/Spring/Spring.Core/Globalization/IResourceCache.cs +++ b/src/Spring/Spring.Core/Globalization/IResourceCache.cs @@ -1,50 +1,49 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using System.Globalization; - -namespace Spring.Globalization -{ - /// - /// Defines an interface that resource cache adapters have to implement. - /// - /// Aleksandar Seovic - /// $Id: IResourceCache.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public interface IResourceCache - { - /// - /// Gets the list of resources from cache. - /// - /// Target to get a list of resources for. - /// Resource culture. - /// A list of cached resources for the specified target object and culture. - IList GetResources(object target, CultureInfo culture); - - /// - /// Puts the list of resources in the cache. - /// - /// Target to cache a list of resources for. - /// Resource culture. - /// A list of resources to cache. - /// A list of cached resources for the specified target object and culture. - void PutResources(object target, CultureInfo culture, IList resources); - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using System.Globalization; + +namespace Spring.Globalization +{ + /// + /// Defines an interface that resource cache adapters have to implement. + /// + /// Aleksandar Seovic + public interface IResourceCache + { + /// + /// Gets the list of resources from cache. + /// + /// Target to get a list of resources for. + /// Resource culture. + /// A list of cached resources for the specified target object and culture. + IList GetResources(object target, CultureInfo culture); + + /// + /// Puts the list of resources in the cache. + /// + /// Target to cache a list of resources for. + /// Resource culture. + /// A list of resources to cache. + /// A list of cached resources for the specified target object and culture. + void PutResources(object target, CultureInfo culture, IList resources); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Localizers/ResourceSetLocalizer.cs b/src/Spring/Spring.Core/Globalization/Localizers/ResourceSetLocalizer.cs index f1e13f4c..eaf5057a 100644 --- a/src/Spring/Spring.Core/Globalization/Localizers/ResourceSetLocalizer.cs +++ b/src/Spring/Spring.Core/Globalization/Localizers/ResourceSetLocalizer.cs @@ -1,112 +1,111 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Globalization; -using System.Resources; -using Common.Logging; -using Spring.Context; -using Spring.Context.Support; -using Spring.Expressions; - -namespace Spring.Globalization.Localizers -{ - /// - /// Loads a list of resources that should be applied from the .NET . - /// - /// - ///

- /// This implementation will iterate over all resource managers - /// within the message source and return a list of all the resources whose name starts with '$this'. - ///

- ///

- /// All other resources will be ignored, but you can retrieve them by calling one of - /// GetMessage methods on the message source directly. - ///

- ///
- /// Aleksandar Seovic - /// $Id: ResourceSetLocalizer.cs,v 1.11 2007/07/24 17:26:25 oakinger Exp $ - public class ResourceSetLocalizer : AbstractLocalizer - { - private static readonly ILog log = LogManager.GetLogger(typeof(ResourceSetLocalizer)); - - private static readonly IList ignoreList = - new string[] {"$this.DefaultModifiers", "$this.TrayAutoArrange", "$this.TrayLargeIcon"}; - - /// - /// Loads resources from the storage and creates a list of instances that should be applied to the target. - /// - /// - /// This feature is not currently supported on version 1.0 of the .NET platform. - /// - /// Target to get a list of resources for. - /// instance to retrieve resources from. - /// Resource locale. - /// A list of resources to apply. - protected override IList LoadResources(object target, IMessageSource messageSource, CultureInfo culture) - { -#if ! NET_1_0 - IList resources; - resources = new ArrayList(); - - if (messageSource is ResourceSetMessageSource) - { - for (int i = 0; i < ((ResourceSetMessageSource) messageSource).ResourceManagers.Count; i++) - { - ResourceManager rm = ((ResourceSetMessageSource) messageSource).ResourceManagers[i] as ResourceManager; - ResourceSet invariantResources = null; - try - { - invariantResources = rm.GetResourceSet(CultureInfo.InvariantCulture, true, true); - } - catch (MissingManifestResourceException mmrex) - { - // ignore but log missing ResourceSet - log.Debug("No ResourceSet available for invariant culture", mmrex); - } - - if (invariantResources != null) - { - foreach (DictionaryEntry resource in invariantResources) - { - string resourceName = (string)resource.Key; - if (resourceName.StartsWith("$this") && !ignoreList.Contains(resourceName)) - { - // redirect resource resolution if necessary - object resourceValue = rm.GetObject(resourceName, culture); - if (resourceValue is String && ((String)resourceValue).StartsWith("$messageSource")) - { - resourceValue = messageSource.GetResourceObject(((String)resourceValue).Substring(15), culture); - } - resources.Add(new Resource(Expression.ParsePrimary(resourceName.Substring(6)), resourceValue)); - } - } - } - } - } - return resources; -#else - throw new NotSupportedException("Operation not supported in .NET 1.0 Release."); -#endif - } - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Globalization; +using System.Resources; +using Common.Logging; +using Spring.Context; +using Spring.Context.Support; +using Spring.Expressions; + +namespace Spring.Globalization.Localizers +{ + /// + /// Loads a list of resources that should be applied from the .NET . + /// + /// + ///

+ /// This implementation will iterate over all resource managers + /// within the message source and return a list of all the resources whose name starts with '$this'. + ///

+ ///

+ /// All other resources will be ignored, but you can retrieve them by calling one of + /// GetMessage methods on the message source directly. + ///

+ ///
+ /// Aleksandar Seovic + public class ResourceSetLocalizer : AbstractLocalizer + { + private static readonly ILog log = LogManager.GetLogger(typeof(ResourceSetLocalizer)); + + private static readonly IList ignoreList = + new string[] {"$this.DefaultModifiers", "$this.TrayAutoArrange", "$this.TrayLargeIcon"}; + + /// + /// Loads resources from the storage and creates a list of instances that should be applied to the target. + /// + /// + /// This feature is not currently supported on version 1.0 of the .NET platform. + /// + /// Target to get a list of resources for. + /// instance to retrieve resources from. + /// Resource locale. + /// A list of resources to apply. + protected override IList LoadResources(object target, IMessageSource messageSource, CultureInfo culture) + { +#if ! NET_1_0 + IList resources; + resources = new ArrayList(); + + if (messageSource is ResourceSetMessageSource) + { + for (int i = 0; i < ((ResourceSetMessageSource) messageSource).ResourceManagers.Count; i++) + { + ResourceManager rm = ((ResourceSetMessageSource) messageSource).ResourceManagers[i] as ResourceManager; + ResourceSet invariantResources = null; + try + { + invariantResources = rm.GetResourceSet(CultureInfo.InvariantCulture, true, true); + } + catch (MissingManifestResourceException mmrex) + { + // ignore but log missing ResourceSet + log.Debug("No ResourceSet available for invariant culture", mmrex); + } + + if (invariantResources != null) + { + foreach (DictionaryEntry resource in invariantResources) + { + string resourceName = (string)resource.Key; + if (resourceName.StartsWith("$this") && !ignoreList.Contains(resourceName)) + { + // redirect resource resolution if necessary + object resourceValue = rm.GetObject(resourceName, culture); + if (resourceValue is String && ((String)resourceValue).StartsWith("$messageSource")) + { + resourceValue = messageSource.GetResourceObject(((String)resourceValue).Substring(15), culture); + } + resources.Add(new Resource(Expression.ParsePrimary(resourceName.Substring(6)), resourceValue)); + } + } + } + } + } + return resources; +#else + throw new NotSupportedException("Operation not supported in .NET 1.0 Release."); +#endif + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/NullResourceCache.cs b/src/Spring/Spring.Core/Globalization/NullResourceCache.cs index d7f58477..d3797199 100644 --- a/src/Spring/Spring.Core/Globalization/NullResourceCache.cs +++ b/src/Spring/Spring.Core/Globalization/NullResourceCache.cs @@ -1,50 +1,49 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -namespace Spring.Globalization -{ - /// - /// Resource cache implementation that doesn't cache resources. - /// - /// Aleksandar Seovic - /// $Id: NullResourceCache.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class NullResourceCache : AbstractResourceCache - { - /// - /// Gets the list of resources from cache. - /// - /// Cache key to use for lookup. - /// Always returns null. - protected override IList GetResources(string cacheKey) - { - return null; - } - - /// - /// Puts the list of resources in the cache. - /// - /// Cache key to use for the specified resources. - /// A list of resources to cache. - protected override void PutResources(string cacheKey, IList resources) - {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +namespace Spring.Globalization +{ + /// + /// Resource cache implementation that doesn't cache resources. + /// + /// Aleksandar Seovic + public class NullResourceCache : AbstractResourceCache + { + /// + /// Gets the list of resources from cache. + /// + /// Cache key to use for lookup. + /// Always returns null. + protected override IList GetResources(string cacheKey) + { + return null; + } + + /// + /// Puts the list of resources in the cache. + /// + /// Cache key to use for the specified resources. + /// A list of resources to cache. + protected override void PutResources(string cacheKey, IList resources) + {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Resolvers/DefaultCultureResolver.cs b/src/Spring/Spring.Core/Globalization/Resolvers/DefaultCultureResolver.cs index df2a064c..37114ac3 100644 --- a/src/Spring/Spring.Core/Globalization/Resolvers/DefaultCultureResolver.cs +++ b/src/Spring/Spring.Core/Globalization/Resolvers/DefaultCultureResolver.cs @@ -1,123 +1,122 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Globalization; -using System.Threading; - -#endregion - -namespace Spring.Globalization.Resolvers -{ - /// - /// implementation - /// that simply returns the - /// value of the - /// - /// property (if said property value is not ), or the - /// of the current thread if it is - /// . - /// - /// Aleksandar Seovic - /// $Id: DefaultCultureResolver.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public class DefaultCultureResolver : ICultureResolver - { - private CultureInfo defaultCulture; - - /// - /// The default . - /// - /// - /// The default . - /// - public CultureInfo DefaultCulture - { - get { return defaultCulture; } - set { defaultCulture = value; } - } - - /// - /// Returns the default . - /// - /// - ///

- /// It tries to get the - /// from the value of the - /// - /// property and falls back to the of the - /// current thread if the - /// - /// is . - ///

- ///
- /// - /// The default - /// - protected virtual CultureInfo GetDefaultLocale() - { - if (defaultCulture != null) - { - return defaultCulture; - } - else - { - return Thread.CurrentThread.CurrentUICulture; - } - } - - /// - /// Resolves the - /// from some context. - /// - /// - ///

- /// The 'context' in this implementation is the - /// value of the - /// - /// property (if said property value is not ), or the - /// of the current thread if it is - /// . - ///

- ///
- /// - /// The that should be used - /// by the caller. - /// - public virtual CultureInfo ResolveCulture() - { - return GetDefaultLocale(); - } - - /// - /// Sets the . - /// - /// - /// The new or - /// to clear the current . - /// - /// - /// - public virtual void SetCulture(CultureInfo culture) - { - defaultCulture = culture; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Globalization; +using System.Threading; + +#endregion + +namespace Spring.Globalization.Resolvers +{ + /// + /// implementation + /// that simply returns the + /// value of the + /// + /// property (if said property value is not ), or the + /// of the current thread if it is + /// . + /// + /// Aleksandar Seovic + public class DefaultCultureResolver : ICultureResolver + { + private CultureInfo defaultCulture; + + /// + /// The default . + /// + /// + /// The default . + /// + public CultureInfo DefaultCulture + { + get { return defaultCulture; } + set { defaultCulture = value; } + } + + /// + /// Returns the default . + /// + /// + ///

+ /// It tries to get the + /// from the value of the + /// + /// property and falls back to the of the + /// current thread if the + /// + /// is . + ///

+ ///
+ /// + /// The default + /// + protected virtual CultureInfo GetDefaultLocale() + { + if (defaultCulture != null) + { + return defaultCulture; + } + else + { + return Thread.CurrentThread.CurrentUICulture; + } + } + + /// + /// Resolves the + /// from some context. + /// + /// + ///

+ /// The 'context' in this implementation is the + /// value of the + /// + /// property (if said property value is not ), or the + /// of the current thread if it is + /// . + ///

+ ///
+ /// + /// The that should be used + /// by the caller. + /// + public virtual CultureInfo ResolveCulture() + { + return GetDefaultLocale(); + } + + /// + /// Sets the . + /// + /// + /// The new or + /// to clear the current . + /// + /// + /// + public virtual void SetCulture(CultureInfo culture) + { + defaultCulture = culture; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Globalization/Resource.cs b/src/Spring/Spring.Core/Globalization/Resource.cs index 98fc094f..96188108 100644 --- a/src/Spring/Spring.Core/Globalization/Resource.cs +++ b/src/Spring/Spring.Core/Globalization/Resource.cs @@ -1,67 +1,66 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -using Spring.Expressions; - -namespace Spring.Globalization -{ - /// - /// Holds mapping between control property and it's value - /// as read from the resource file. - /// - /// Aleksandar Seovic - /// $Id: Resource.cs,v 1.3 2006/04/09 07:18:47 markpollack Exp $ - [Serializable] - public class Resource - { - private IExpression target; - private object resourceValue; - - /// - /// Creates instance of resource mapper. - /// - /// Target property. - /// Resource value. - public Resource(IExpression target, object resourceValue) - { - this.target = target; - this.resourceValue = resourceValue; - } - - /// - /// Gets parsed target property expression. See - /// for more information on object navigation expressions. - /// - public IExpression Target - { - get { return target; } - } - - /// - /// Value of the resource that target property should be set to. - /// - public object Value - { - get { return resourceValue; } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +using Spring.Expressions; + +namespace Spring.Globalization +{ + /// + /// Holds mapping between control property and it's value + /// as read from the resource file. + /// + /// Aleksandar Seovic + [Serializable] + public class Resource + { + private IExpression target; + private object resourceValue; + + /// + /// Creates instance of resource mapper. + /// + /// Target property. + /// Resource value. + public Resource(IExpression target, object resourceValue) + { + this.target = target; + this.resourceValue = resourceValue; + } + + /// + /// Gets parsed target property expression. See + /// for more information on object navigation expressions. + /// + public IExpression Target + { + get { return target; } + } + + /// + /// Value of the resource that target property should be set to. + /// + public object Value + { + get { return resourceValue; } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs b/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs index 382ce538..be7c29a1 100644 --- a/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs +++ b/src/Spring/Spring.Core/Objects/Events/IEventRegistry.cs @@ -1,59 +1,58 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Events -{ - /// - /// A registry that manages subscriptions to and the - /// publishing of events. - /// - /// Griffin Caprio - /// $Id: IEventRegistry.cs,v 1.5 2006/04/09 07:18:47 markpollack Exp $ - public interface IEventRegistry - { - /// - /// Publishes all events of the source object. - /// - /// - /// The source object containing events to publish. - /// - void PublishEvents(object sourceObject); - - /// - /// Subscribes to all events published, if the subscriber - /// implements compatible handler methods. - /// - /// The subscriber to use. - void Subscribe(object subscriber); - - /// - /// Subscribes to the published events of all objects of a given - /// , if the subscriber implements - /// compatible handler methods. - /// - /// The subscriber to use. - /// - /// The target to subscribe to. - /// - void Subscribe(object subscriber, Type targetSourceType); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Events +{ + /// + /// A registry that manages subscriptions to and the + /// publishing of events. + /// + /// Griffin Caprio + public interface IEventRegistry + { + /// + /// Publishes all events of the source object. + /// + /// + /// The source object containing events to publish. + /// + void PublishEvents(object sourceObject); + + /// + /// Subscribes to all events published, if the subscriber + /// implements compatible handler methods. + /// + /// The subscriber to use. + void Subscribe(object subscriber); + + /// + /// Subscribes to the published events of all objects of a given + /// , if the subscriber implements + /// compatible handler methods. + /// + /// The subscriber to use. + /// + /// The target to subscribe to. + /// + void Subscribe(object subscriber, Type targetSourceType); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Events/IEventRegistryAware.cs b/src/Spring/Spring.Core/Objects/Events/IEventRegistryAware.cs index 2037464e..f740c32b 100644 --- a/src/Spring/Spring.Core/Objects/Events/IEventRegistryAware.cs +++ b/src/Spring/Spring.Core/Objects/Events/IEventRegistryAware.cs @@ -1,64 +1,63 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Events -{ - /// - /// To be implemented by any object that wishes to receive a reference to - /// an . - /// - /// - ///

- /// This interface only applies to objects that have been instantiated - /// within the context of an - /// . This interface does - /// not typically need to be implemented by application code, but is rather - /// used by classes internal to Spring.NET. - ///

- ///
- /// Mark Pollack - /// Rick Evans - /// $Id: IEventRegistryAware.cs,v 1.2 2006/04/09 07:18:47 markpollack Exp $ - public interface IEventRegistryAware - { - /// - /// Set the - /// associated with the - /// that created this - /// object. - /// - /// - ///

- /// This property will be set by the relevant - /// after all of this - /// object's dependencies have been resolved. This object can use the - /// supplied - /// immediately to publish or subscribe to one or more events. - ///

- ///
- IEventRegistry EventRegistry { set; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Events +{ + /// + /// To be implemented by any object that wishes to receive a reference to + /// an . + /// + /// + ///

+ /// This interface only applies to objects that have been instantiated + /// within the context of an + /// . This interface does + /// not typically need to be implemented by application code, but is rather + /// used by classes internal to Spring.NET. + ///

+ ///
+ /// Mark Pollack + /// Rick Evans + public interface IEventRegistryAware + { + /// + /// Set the + /// associated with the + /// that created this + /// object. + /// + /// + ///

+ /// This property will be set by the relevant + /// after all of this + /// object's dependencies have been resolved. This object can use the + /// supplied + /// immediately to publish or subscribe to one or more events. + ///

+ ///
+ IEventRegistry EventRegistry { set; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Events/Support/EventManipulationUtils.cs b/src/Spring/Spring.Core/Objects/Events/Support/EventManipulationUtils.cs index 8eca6c13..4ae002b4 100644 --- a/src/Spring/Spring.Core/Objects/Events/Support/EventManipulationUtils.cs +++ b/src/Spring/Spring.Core/Objects/Events/Support/EventManipulationUtils.cs @@ -1,120 +1,119 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Core; -using Spring.Objects.Support; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Events.Support -{ - /// - /// Utility class to aid in the manipulation of events and delegates. - /// - /// Griffin Caprio - /// $Id: EventManipulationUtils.cs,v 1.3 2007/07/31 01:35:12 markpollack Exp $ - public sealed class EventManipulationUtils - { - /// - /// Returns a new instance of the requested . - /// - /// - ///

- /// Often used to wire subscribers to event publishers. - ///

- ///
- /// - /// The of delegate to create. - /// - /// - /// The target subscriber object that contains the delegate implementation. - /// - /// - /// referencing the delegate method on the subscriber. - /// - /// - /// A delegate handler that can be added to an events list of handlers, or called directly. - /// - public static Delegate GetHandlerDelegate( - Type delegateType, object targetSubscriber, MethodInfo targetSubscriberDelegateMethod) - { - return Delegate.CreateDelegate( - delegateType, targetSubscriber, targetSubscriberDelegateMethod.Name); - } - - /// - /// Queries the input type for a signature matching the input - /// signature. - /// - /// - /// Typically used to query a potential subscriber to see if they implement an event handler. - /// - /// to match against - /// to query - /// - /// matching input - /// signature, or if there is no match. - /// - public static MethodInfo GetMethodInfoMatchingSignature( - MethodInfo invoke, Type subscriberType) - { - ComposedCriteria criteria = new ComposedCriteria(); - criteria.Add(new MethodReturnTypeCriteria(invoke.ReturnType)); - criteria.Add(new MethodParametersCountCriteria(invoke.GetParameters().Length)); - criteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(invoke))); - - MemberInfo[] methods = subscriberType.FindMembers( - MemberTypes.Method, ReflectionUtils.AllMembersCaseInsensitiveFlags, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - criteria); - if (methods != null - && methods.Length > 0) - { - return methods[0] as MethodInfo; - } - return null; - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the EventManipulationUtilities class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible constructors. - ///

- ///
- private EventManipulationUtils() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Core; +using Spring.Objects.Support; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Events.Support +{ + /// + /// Utility class to aid in the manipulation of events and delegates. + /// + /// Griffin Caprio + public sealed class EventManipulationUtils + { + /// + /// Returns a new instance of the requested . + /// + /// + ///

+ /// Often used to wire subscribers to event publishers. + ///

+ ///
+ /// + /// The of delegate to create. + /// + /// + /// The target subscriber object that contains the delegate implementation. + /// + /// + /// referencing the delegate method on the subscriber. + /// + /// + /// A delegate handler that can be added to an events list of handlers, or called directly. + /// + public static Delegate GetHandlerDelegate( + Type delegateType, object targetSubscriber, MethodInfo targetSubscriberDelegateMethod) + { + return Delegate.CreateDelegate( + delegateType, targetSubscriber, targetSubscriberDelegateMethod.Name); + } + + /// + /// Queries the input type for a signature matching the input + /// signature. + /// + /// + /// Typically used to query a potential subscriber to see if they implement an event handler. + /// + /// to match against + /// to query + /// + /// matching input + /// signature, or if there is no match. + /// + public static MethodInfo GetMethodInfoMatchingSignature( + MethodInfo invoke, Type subscriberType) + { + ComposedCriteria criteria = new ComposedCriteria(); + criteria.Add(new MethodReturnTypeCriteria(invoke.ReturnType)); + criteria.Add(new MethodParametersCountCriteria(invoke.GetParameters().Length)); + criteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(invoke))); + + MemberInfo[] methods = subscriberType.FindMembers( + MemberTypes.Method, ReflectionUtils.AllMembersCaseInsensitiveFlags, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + criteria); + if (methods != null + && methods.Length > 0) + { + return methods[0] as MethodInfo; + } + return null; + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the EventManipulationUtilities class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible constructors. + ///

+ ///
+ private EventManipulationUtils() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs b/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs index edf21d49..55253488 100644 --- a/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs +++ b/src/Spring/Spring.Core/Objects/Events/Support/EventRegistry.cs @@ -1,125 +1,124 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -#endregion - -namespace Spring.Objects.Events.Support -{ - /// - /// Default implementation of the - /// interface. - /// - /// Griffin Caprio - /// $Id: EventRegistry.cs,v 1.7 2006/04/09 07:18:47 markpollack Exp $ - public class EventRegistry : IEventRegistry - { - private IList _publishers; - - /// - /// Creates a new instance of the EventRegistry class. - /// - public EventRegistry() - { - _publishers = new ArrayList(); - } - - /// - /// The list of event publishers. - /// - /// The list of event publishers. - protected IList Publishers - { - get { return _publishers; } - } - - /// - /// Adds the input object to the list of publishers. - /// - /// - /// This publishes all events of the source object to any object - /// wishing to subscribe - /// - /// The source object to publish. - public virtual void PublishEvents(object source) - { - Publishers.Add(source); - } - - /// - /// Subscribes to all events published, if the subscriber implements - /// compatible handler methods. - /// - /// The subscriber to use. - public virtual void Subscribe(object subscriber) - { - Subscribe(subscriber, null); - } - - /// - /// Subscribes to published events of all objects of a given type, if the - /// subscriber implements compatible handler methods. - /// - /// The subscriber to use. - /// - /// The target to subscribe to. - /// - public virtual void Subscribe(object subscriber, Type sourceType) - { - Type currentSubscriberType = subscriber.GetType(); - foreach (object currentPublisher in _publishers) - { - if (null == sourceType - || sourceType.IsAssignableFrom(currentPublisher.GetType())) - { - wireSubscriberToPublisher( - currentPublisher, currentSubscriberType, subscriber); - } - } - } - - private static void wireSubscriberToPublisher( - object currentPublisher, Type currentSubscriberType, object subscriber) - { - Type currentPublisherType = currentPublisher.GetType(); - EventInfo[] events = currentPublisherType.GetEvents(); - foreach (EventInfo currentEvent in events) - { - Type eventHandlerType = currentEvent.EventHandlerType; - MethodInfo invoke = eventHandlerType.GetMethod("Invoke"); - MethodInfo eventHandler - = EventManipulationUtils.GetMethodInfoMatchingSignature( - invoke, currentSubscriberType); - if (eventHandler != null) - { - currentEvent.AddEventHandler( - currentPublisher, - EventManipulationUtils.GetHandlerDelegate( - eventHandlerType, subscriber, eventHandler)); - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +#endregion + +namespace Spring.Objects.Events.Support +{ + /// + /// Default implementation of the + /// interface. + /// + /// Griffin Caprio + public class EventRegistry : IEventRegistry + { + private IList _publishers; + + /// + /// Creates a new instance of the EventRegistry class. + /// + public EventRegistry() + { + _publishers = new ArrayList(); + } + + /// + /// The list of event publishers. + /// + /// The list of event publishers. + protected IList Publishers + { + get { return _publishers; } + } + + /// + /// Adds the input object to the list of publishers. + /// + /// + /// This publishes all events of the source object to any object + /// wishing to subscribe + /// + /// The source object to publish. + public virtual void PublishEvents(object source) + { + Publishers.Add(source); + } + + /// + /// Subscribes to all events published, if the subscriber implements + /// compatible handler methods. + /// + /// The subscriber to use. + public virtual void Subscribe(object subscriber) + { + Subscribe(subscriber, null); + } + + /// + /// Subscribes to published events of all objects of a given type, if the + /// subscriber implements compatible handler methods. + /// + /// The subscriber to use. + /// + /// The target to subscribe to. + /// + public virtual void Subscribe(object subscriber, Type sourceType) + { + Type currentSubscriberType = subscriber.GetType(); + foreach (object currentPublisher in _publishers) + { + if (null == sourceType + || sourceType.IsAssignableFrom(currentPublisher.GetType())) + { + wireSubscriberToPublisher( + currentPublisher, currentSubscriberType, subscriber); + } + } + } + + private static void wireSubscriberToPublisher( + object currentPublisher, Type currentSubscriberType, object subscriber) + { + Type currentPublisherType = currentPublisher.GetType(); + EventInfo[] events = currentPublisherType.GetEvents(); + foreach (EventInfo currentEvent in events) + { + Type eventHandlerType = currentEvent.EventHandlerType; + MethodInfo invoke = eventHandlerType.GetMethod("Invoke"); + MethodInfo eventHandler + = EventManipulationUtils.GetMethodInfoMatchingSignature( + invoke, currentSubscriberType); + if (eventHandler != null) + { + currentEvent.AddEventHandler( + currentPublisher, + EventManipulationUtils.GetHandlerDelegate( + eventHandlerType, subscriber, eventHandler)); + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttribute.cs b/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttribute.cs index 29a66e32..3b68b369 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttribute.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttribute.cs @@ -1,40 +1,39 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Attributes -{ - /// - /// Marks a property as being 'required': that is, the setter property - /// must be configured to be dependency-injected with a value. - /// - /// Consult the SDK documentation for , - /// which, by default, checks for the presence of this annotation. - /// - /// Rob Harrop - /// Mark Pollack - /// $Id: RequiredAttribute.cs,v 1.1 2008/04/02 18:02:24 markpollack Exp $ - [AttributeUsage(AttributeTargets.Property, Inherited = true)] - public class RequiredAttribute : Attribute - { - - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Attributes +{ + /// + /// Marks a property as being 'required': that is, the setter property + /// must be configured to be dependency-injected with a value. + /// + /// Consult the SDK documentation for , + /// which, by default, checks for the presence of this annotation. + /// + /// Rob Harrop + /// Mark Pollack + [AttributeUsage(AttributeTargets.Property, Inherited = true)] + public class RequiredAttribute : Attribute + { + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessor.cs b/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessor.cs index e76c1e99..fd3f4801 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessor.cs @@ -1,186 +1,185 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - - -using System; -using System.Collections; -using System.Reflection; -using System.Text; -using Spring.Collections; -using Spring.Objects; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Attributes; -using Spring.Objects.Factory.Config; -using Spring.Util; - -namespace Spring.Objects.Factory.Attributes -{ - /// - /// A implementation that enforces required properties to have been configured. - /// Required properties are detected through an attribute, by default, Spring's - /// attribute. - /// - /// - /// The motivation for the existence of this IObjectPostProcessor is to allow - /// developers to annotate the setter properties of their own classes with an - /// arbitrary attribute to indicate that the container must check - /// for the configuration of a dependency injected value. This neatly pushes - /// responsibility for such checking onto the container (where it arguably belongs), - /// and obviates the need (in part) for a developer to code a method that - /// simply checks that all required properties have actually been set. - /// - /// Please note that an 'init' method may still need to implemented (and may - /// still be desirable), because all that this class does is enforce that a - /// 'required' property has actually been configured with a value. It does - /// not check anything else... In particular, it does not check that a - /// configured value is not null. - /// - /// - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: RequiredAttributeObjectPostProcessor.cs,v 1.2 2008/04/08 19:29:07 markpollack Exp $ - public class RequiredAttributeObjectPostProcessor : InstantiationAwareObjectPostProcessorAdapter - { - private Type requiredAttributeType = typeof (RequiredAttribute); - - /// - /// Cache for validated object names, skipping re-validation for the same object - /// - private ISet validatedObjectNames = new SynchronizedSet(new HashedSet()); - - /// - /// Sets the type of the required attribute, to be used on a property setter - /// - /// - /// The default required attribute type is the Spring-provided attribute. - /// This setter property exists so that developers can provide their own - /// (non-Spring-specific) annotation type to indicate that a property value is required. - /// - /// The type of the required attribute. - public Type RequiredAttributeType - { - set - { - AssertUtils.ArgumentNotNull(value, "RequiredAttributeType", "RequiredAttributeType property must not be null"); - if (!typeof(Attribute).IsAssignableFrom(value)) - { - throw new ArgumentException( - string.Format("[{0}] does not inherit from System.Attribute (it must).", value.FullName)); - } - requiredAttributeType = value; - } - get - { - return requiredAttributeType; - } - } - - - /// - /// Post-process the given property values before the factory applies them - /// to the given object. Checks for the attribute specified by this PostProcessor's RequiredAttributeType. - /// - /// The property values that the factory is about to apply (never null). - /// The relevant property infos for the target object (with ignored - /// dependency types - which the factory handles specifically - already filtered out) - /// The object instance created, but whose properties have not yet - /// been set. - /// Name of the object. - /// - /// The actual property values to apply to the given object (can be the - /// passed-in PropertyValues instances or null to skip property population. - /// - /// If a required property value has not been specified - /// in the configuration metadata. - public override IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, - string objectName) - { - if (!validatedObjectNames.Contains(objectName)) - { - ArrayList invalidProperties = new ArrayList(); - - foreach (PropertyInfo pi in pis) - { - if (IsRequiredProperty(pi) && !pvs.Contains(pi.Name)) - { - invalidProperties.Add(pi.Name); - } - } - if (invalidProperties.Count != 0) - { - throw new ObjectInitializationException( - BuildExceptionMessage((string[]) invalidProperties.ToArray(typeof (string)), objectName)); - } - validatedObjectNames.Add(objectName); - } - return pvs; - } - - /// - /// Determines whether the supplied property is required to have a value, that is to be dependency injected. - /// - /// - /// This implementation looks for the existence of a "required" attribute on the supplied PropertyInfo and that - /// the property has a setter method. - /// - /// The target PropertyInfo - /// - /// true if the supplied property has been marked as being required;; otherwise, false if - /// not or if the supplied property does not have a setter method - /// - protected virtual bool IsRequiredProperty(PropertyInfo pi) - { - return (pi.GetSetMethod() != null && pi.GetCustomAttributes(RequiredAttributeType, true).Length > 0); - } - - /// - /// Builds an exception message for the given list of invalid properties. - /// - /// The list of names of invalid properties. - /// Name of the object. - /// The exception message - private string BuildExceptionMessage(string[] invalidProperties, ICloneable objectName) - { - int size = invalidProperties.Length; - StringBuilder sb = new StringBuilder(); - sb.Append(size == 1 ? "Property" : "Properties"); - for (int i=0; i < size; i++) - { - string propName = invalidProperties[i]; - if (i > 0) - { - if (i == (size -1 )) - { - sb.Append(" and"); - } - else - { - sb.Append(", "); - } - } - sb.Append(" '").Append(propName).Append("'"); - } - sb.Append(" required for object '").Append(objectName).Append("'"); - return sb.ToString(); - - } - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + + +using System; +using System.Collections; +using System.Reflection; +using System.Text; +using Spring.Collections; +using Spring.Objects; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Attributes; +using Spring.Objects.Factory.Config; +using Spring.Util; + +namespace Spring.Objects.Factory.Attributes +{ + /// + /// A implementation that enforces required properties to have been configured. + /// Required properties are detected through an attribute, by default, Spring's + /// attribute. + /// + /// + /// The motivation for the existence of this IObjectPostProcessor is to allow + /// developers to annotate the setter properties of their own classes with an + /// arbitrary attribute to indicate that the container must check + /// for the configuration of a dependency injected value. This neatly pushes + /// responsibility for such checking onto the container (where it arguably belongs), + /// and obviates the need (in part) for a developer to code a method that + /// simply checks that all required properties have actually been set. + /// + /// Please note that an 'init' method may still need to implemented (and may + /// still be desirable), because all that this class does is enforce that a + /// 'required' property has actually been configured with a value. It does + /// not check anything else... In particular, it does not check that a + /// configured value is not null. + /// + /// + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class RequiredAttributeObjectPostProcessor : InstantiationAwareObjectPostProcessorAdapter + { + private Type requiredAttributeType = typeof (RequiredAttribute); + + /// + /// Cache for validated object names, skipping re-validation for the same object + /// + private ISet validatedObjectNames = new SynchronizedSet(new HashedSet()); + + /// + /// Sets the type of the required attribute, to be used on a property setter + /// + /// + /// The default required attribute type is the Spring-provided attribute. + /// This setter property exists so that developers can provide their own + /// (non-Spring-specific) annotation type to indicate that a property value is required. + /// + /// The type of the required attribute. + public Type RequiredAttributeType + { + set + { + AssertUtils.ArgumentNotNull(value, "RequiredAttributeType", "RequiredAttributeType property must not be null"); + if (!typeof(Attribute).IsAssignableFrom(value)) + { + throw new ArgumentException( + string.Format("[{0}] does not inherit from System.Attribute (it must).", value.FullName)); + } + requiredAttributeType = value; + } + get + { + return requiredAttributeType; + } + } + + + /// + /// Post-process the given property values before the factory applies them + /// to the given object. Checks for the attribute specified by this PostProcessor's RequiredAttributeType. + /// + /// The property values that the factory is about to apply (never null). + /// The relevant property infos for the target object (with ignored + /// dependency types - which the factory handles specifically - already filtered out) + /// The object instance created, but whose properties have not yet + /// been set. + /// Name of the object. + /// + /// The actual property values to apply to the given object (can be the + /// passed-in PropertyValues instances or null to skip property population. + /// + /// If a required property value has not been specified + /// in the configuration metadata. + public override IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, + string objectName) + { + if (!validatedObjectNames.Contains(objectName)) + { + ArrayList invalidProperties = new ArrayList(); + + foreach (PropertyInfo pi in pis) + { + if (IsRequiredProperty(pi) && !pvs.Contains(pi.Name)) + { + invalidProperties.Add(pi.Name); + } + } + if (invalidProperties.Count != 0) + { + throw new ObjectInitializationException( + BuildExceptionMessage((string[]) invalidProperties.ToArray(typeof (string)), objectName)); + } + validatedObjectNames.Add(objectName); + } + return pvs; + } + + /// + /// Determines whether the supplied property is required to have a value, that is to be dependency injected. + /// + /// + /// This implementation looks for the existence of a "required" attribute on the supplied PropertyInfo and that + /// the property has a setter method. + /// + /// The target PropertyInfo + /// + /// true if the supplied property has been marked as being required;; otherwise, false if + /// not or if the supplied property does not have a setter method + /// + protected virtual bool IsRequiredProperty(PropertyInfo pi) + { + return (pi.GetSetMethod() != null && pi.GetCustomAttributes(RequiredAttributeType, true).Length > 0); + } + + /// + /// Builds an exception message for the given list of invalid properties. + /// + /// The list of names of invalid properties. + /// Name of the object. + /// The exception message + private string BuildExceptionMessage(string[] invalidProperties, ICloneable objectName) + { + int size = invalidProperties.Length; + StringBuilder sb = new StringBuilder(); + sb.Append(size == 1 ? "Property" : "Properties"); + for (int i=0; i < size; i++) + { + string propName = invalidProperties[i]; + if (i > 0) + { + if (i == (size -1 )) + { + sb.Append(" and"); + } + else + { + sb.Append(", "); + } + } + sb.Append(" '").Append(propName).Append("'"); + } + sb.Append(" required for object '").Append(objectName).Append("'"); + return sb.ToString(); + + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/AbstractConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/AbstractConfigurer.cs index e7642b6f..1db97716 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/AbstractConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/AbstractConfigurer.cs @@ -1,123 +1,122 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -using Spring.Core; -using Spring.Core.TypeResolution; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Base class that provides common functionality needed for several IObjectFactoryPostProcessor - /// implementations - /// - /// Mark Pollack - /// $Id: AbstractConfigurer.cs,v 1.3 2007/07/31 18:16:49 bbaia Exp $ - [Serializable] - public abstract class AbstractConfigurer : IOrdered, IObjectFactoryPostProcessor - { - private int order = Int32.MaxValue; // default: same as non-Ordered - - /// - /// Return the order value of this object, with a higher value meaning - /// greater in terms of sorting. - /// - /// The order value. - /// - public int Order - { - get { return order; } - set { order = value; } - } - - /// - /// Modify the application context's internal object factory after its - /// standard initialization. - /// - /// The object factory used by the application context. - /// - ///

- /// All object definitions will have been loaded, but no objects will have - /// been instantiated yet. This allows for overriding or adding properties - /// even to eager-initializing objects. - ///

- ///
- /// - /// In case of errors. - /// - public abstract void PostProcessObjectFactory( - IConfigurableListableObjectFactory factory); - - /// - /// Resolves the supplied into a - /// instance. - /// - /// The object that is to be resolved into a - /// instance. - /// The error context source. - /// The error context string. - /// A resolved . - /// - ///

- /// This (default) implementation supports resolving - /// s and s. - /// Only override this method if you want to key your type alias - /// on something other than s - /// and s. - ///

- ///
- /// - /// If the supplied is , - /// or the supplied cannot be resolved. - /// - protected virtual Type ResolveRequiredType(object value, string errorContextSource, string errorContext) - { - Type requiredType = value as Type; - if (requiredType == null) - { - string typeName = value as string; - if (typeName != null) - { - try - { - requiredType = TypeResolutionUtils.ResolveType(typeName); - } - catch (TypeLoadException ex) - { - throw new ObjectInitializationException( - string.Format( - "Could not load required type [{0}] for {1}.", - typeName, errorContext), ex); - } - } - else - { - throw new ObjectInitializationException( - string.Format( - "Invalid value '{0}' for {1} - " + - "must be a System.String or System.Type.", - value, errorContext)); - } - } - return requiredType; - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +using Spring.Core; +using Spring.Core.TypeResolution; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Base class that provides common functionality needed for several IObjectFactoryPostProcessor + /// implementations + /// + /// Mark Pollack + [Serializable] + public abstract class AbstractConfigurer : IOrdered, IObjectFactoryPostProcessor + { + private int order = Int32.MaxValue; // default: same as non-Ordered + + /// + /// Return the order value of this object, with a higher value meaning + /// greater in terms of sorting. + /// + /// The order value. + /// + public int Order + { + get { return order; } + set { order = value; } + } + + /// + /// Modify the application context's internal object factory after its + /// standard initialization. + /// + /// The object factory used by the application context. + /// + ///

+ /// All object definitions will have been loaded, but no objects will have + /// been instantiated yet. This allows for overriding or adding properties + /// even to eager-initializing objects. + ///

+ ///
+ /// + /// In case of errors. + /// + public abstract void PostProcessObjectFactory( + IConfigurableListableObjectFactory factory); + + /// + /// Resolves the supplied into a + /// instance. + /// + /// The object that is to be resolved into a + /// instance. + /// The error context source. + /// The error context string. + /// A resolved . + /// + ///

+ /// This (default) implementation supports resolving + /// s and s. + /// Only override this method if you want to key your type alias + /// on something other than s + /// and s. + ///

+ ///
+ /// + /// If the supplied is , + /// or the supplied cannot be resolved. + /// + protected virtual Type ResolveRequiredType(object value, string errorContextSource, string errorContext) + { + Type requiredType = value as Type; + if (requiredType == null) + { + string typeName = value as string; + if (typeName != null) + { + try + { + requiredType = TypeResolutionUtils.ResolveType(typeName); + } + catch (TypeLoadException ex) + { + throw new ObjectInitializationException( + string.Format( + "Could not load required type [{0}] for {1}.", + typeName, errorContext), ex); + } + } + else + { + throw new ObjectInitializationException( + string.Format( + "Invalid value '{0}' for {1} - " + + "must be a System.String or System.Type.", + value, errorContext)); + } + } + return requiredType; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/AbstractFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/AbstractFactoryObject.cs index e5f71ce4..a70a4873 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/AbstractFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/AbstractFactoryObject.cs @@ -1,163 +1,162 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Simple template superclass for - /// implementations that allows for the creation of a singleton or a prototype - /// instance (depending on a flag). - /// - /// - /// If the value of the - /// - /// property is (this is the default), this class - /// will create a single instance of it's object upon initialization and - /// subsequently return the singleton instance; else, this class will - /// create a new instance each time (prototype mode). Subclasses must - /// implement the - /// - /// template method to actually create objects. - /// - /// Juergen Hoeller - /// Keith Donald - /// Simon White (.NET) - /// $Id: AbstractFactoryObject.cs,v 1.13 2007/03/16 04:01:34 aseovic Exp $ - [Serializable] - public abstract class AbstractFactoryObject : IFactoryObject, IInitializingObject, IDisposable - { - private bool isSingleton = true; - private object singletonInstance; - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - /// - ///

- /// Please note that changing the value of this property after - /// this factory object instance has been created by an enclosing - /// Spring.NET IoC container really is a programming error. This - /// property should really only be set once, prior to the invocation - /// of the - /// - /// callback method. - ///

- ///
- /// - public bool IsSingleton - { - get { return this.isSingleton; } - set { this.isSingleton = value; } - } - - /// - /// Return the of object that this - /// creates, or - /// if not known in advance. - /// - /// - public abstract Type ObjectType { get; } - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - /// - public virtual void AfterPropertiesSet() - { - if (this.isSingleton && this.singletonInstance == null) - { - this.singletonInstance = CreateInstance(); - } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - /// - public object GetObject() - { - if (this.isSingleton) - { - return this.singletonInstance; - } - else - { - return CreateInstance(); - } - } - - /// - /// Template method that subclasses must override to construct - /// the object returned by this factory. - /// - /// - /// Invoked once immediately after the initialization of this - /// in the case of - /// a singleton; else, on each call to the - /// - /// method. - /// - /// - /// If an exception occured during object creation. - /// - /// - /// A distinct instance of the object created by this factory. - /// - protected abstract object CreateInstance(); - - /// - /// Performs cleanup on any cached singleton object. - /// - /// - ///

- /// Only makes sense in the context of a singleton object. - ///

- ///
- /// - /// - public virtual void Dispose() - { - if (this.isSingleton && this.singletonInstance != null) - { - IDisposable disposableSingletonInstance = this.singletonInstance as IDisposable; - if (disposableSingletonInstance != null) - { - disposableSingletonInstance.Dispose(); - } - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Simple template superclass for + /// implementations that allows for the creation of a singleton or a prototype + /// instance (depending on a flag). + /// + /// + /// If the value of the + /// + /// property is (this is the default), this class + /// will create a single instance of it's object upon initialization and + /// subsequently return the singleton instance; else, this class will + /// create a new instance each time (prototype mode). Subclasses must + /// implement the + /// + /// template method to actually create objects. + /// + /// Juergen Hoeller + /// Keith Donald + /// Simon White (.NET) + [Serializable] + public abstract class AbstractFactoryObject : IFactoryObject, IInitializingObject, IDisposable + { + private bool isSingleton = true; + private object singletonInstance; + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + /// + ///

+ /// Please note that changing the value of this property after + /// this factory object instance has been created by an enclosing + /// Spring.NET IoC container really is a programming error. This + /// property should really only be set once, prior to the invocation + /// of the + /// + /// callback method. + ///

+ ///
+ /// + public bool IsSingleton + { + get { return this.isSingleton; } + set { this.isSingleton = value; } + } + + /// + /// Return the of object that this + /// creates, or + /// if not known in advance. + /// + /// + public abstract Type ObjectType { get; } + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + /// + public virtual void AfterPropertiesSet() + { + if (this.isSingleton && this.singletonInstance == null) + { + this.singletonInstance = CreateInstance(); + } + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + /// + public object GetObject() + { + if (this.isSingleton) + { + return this.singletonInstance; + } + else + { + return CreateInstance(); + } + } + + /// + /// Template method that subclasses must override to construct + /// the object returned by this factory. + /// + /// + /// Invoked once immediately after the initialization of this + /// in the case of + /// a singleton; else, on each call to the + /// + /// method. + /// + /// + /// If an exception occured during object creation. + /// + /// + /// A distinct instance of the object created by this factory. + /// + protected abstract object CreateInstance(); + + /// + /// Performs cleanup on any cached singleton object. + /// + /// + ///

+ /// Only makes sense in the context of a singleton object. + ///

+ ///
+ /// + /// + public virtual void Dispose() + { + if (this.isSingleton && this.singletonInstance != null) + { + IDisposable disposableSingletonInstance = this.singletonInstance as IDisposable; + if (disposableSingletonInstance != null) + { + disposableSingletonInstance.Dispose(); + } + } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/AutoWiringMode.cs b/src/Spring/Spring.Core/Objects/Factory/Config/AutoWiringMode.cs index ef9a0403..5bb56874 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/AutoWiringMode.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/AutoWiringMode.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Config -{ - - /// - /// The various autowiring modes. - /// - /// Rick Evans - /// $Id: AutoWiringMode.cs,v 1.8 2007/03/16 04:01:34 aseovic Exp $ - [Serializable] - public enum AutoWiringMode - { - /// - /// Do not autowire. - /// - No = 0, - - /// - /// Autowire by name. - /// - ByName = 1, - - /// - /// Autowire by . - /// - ByType = 2, - - /// - /// Autowiring by constructor. - /// - Constructor = 3, - - /// - /// The autowiring strategy is to be determined by introspection - /// of the object's . - /// - AutoDetect = 4 - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Config +{ + + /// + /// The various autowiring modes. + /// + /// Rick Evans + [Serializable] + public enum AutoWiringMode + { + /// + /// Do not autowire. + /// + No = 0, + + /// + /// Autowire by name. + /// + ByName = 1, + + /// + /// Autowire by . + /// + ByType = 2, + + /// + /// Autowiring by constructor. + /// + Constructor = 3, + + /// + /// The autowiring strategy is to be determined by introspection + /// of the object's . + /// + AutoDetect = 4 + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/CommandLineArgsVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/CommandLineArgsVariableSource.cs index 57a8fe39..1a9fd8c4 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/CommandLineArgsVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/CommandLineArgsVariableSource.cs @@ -1,128 +1,127 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Collections.Specialized; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name against command line arguments. - /// - /// Aleksandar Seovic - /// $Id: CommandLineArgsVariableSource.cs,v 1.3 2007/08/02 22:18:32 markpollack Exp $ - [Serializable] - public class CommandLineArgsVariableSource : IVariableSource - { - private const string DEFAULT_ARG_PREFIX = "/"; - private const string DEFAULT_VALUE_SEPARATOR = ":"; - - private string argumentPrefix = DEFAULT_ARG_PREFIX; - private string valueSeparator = DEFAULT_VALUE_SEPARATOR; - - private string[] commandLineArgs; - private IDictionary arguments; - - /// - /// Default constructor. - /// Initializes command line arguments from the environment. - /// - public CommandLineArgsVariableSource() - { - this.commandLineArgs = Environment.GetCommandLineArgs(); - } - - /// - /// Constructor that allows arguments to be passed externally. - /// Useful for testing. - /// - public CommandLineArgsVariableSource(string[] commandLineArgs) - { - this.commandLineArgs = commandLineArgs; - } - - /// - /// Gets or sets a prefix that should be used to - /// identify arguments to extract values from. - /// - /// - /// A prefix that should be used to identify arguments - /// to extract values from. Defaults to slash ("/"). - /// - public string ArgumentPrefix - { - get { return argumentPrefix; } - set { argumentPrefix = value; } - } - - /// - /// Gets or sets a character that should be used to - /// separate argument name from its value. - /// - /// - /// A character that should be used to separate argument - /// name from its value. Defaults to colon (":"). - /// - public string ValueSeparator - { - get { return valueSeparator; } - set { valueSeparator = value; } - } - - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - if (arguments == null) - { - InitArguments(); - } - return (string) this.arguments[name]; - } - - /// - /// Initializes command line arguments dictionary. - /// - private void InitArguments() - { - this.arguments = CollectionsUtil.CreateCaseInsensitiveHashtable(commandLineArgs.Length); - - foreach (string arg in commandLineArgs) - { - int separatorIndex = arg.IndexOf(valueSeparator); - if (arg.StartsWith(argumentPrefix) && separatorIndex > argumentPrefix.Length) - { - string argName = arg.Substring(argumentPrefix.Length, separatorIndex - argumentPrefix.Length); - string argValue = arg.Substring(separatorIndex + valueSeparator.Length); - this.arguments[argName] = argValue; - } - } - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Collections.Specialized; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name against command line arguments. + /// + /// Aleksandar Seovic + [Serializable] + public class CommandLineArgsVariableSource : IVariableSource + { + private const string DEFAULT_ARG_PREFIX = "/"; + private const string DEFAULT_VALUE_SEPARATOR = ":"; + + private string argumentPrefix = DEFAULT_ARG_PREFIX; + private string valueSeparator = DEFAULT_VALUE_SEPARATOR; + + private string[] commandLineArgs; + private IDictionary arguments; + + /// + /// Default constructor. + /// Initializes command line arguments from the environment. + /// + public CommandLineArgsVariableSource() + { + this.commandLineArgs = Environment.GetCommandLineArgs(); + } + + /// + /// Constructor that allows arguments to be passed externally. + /// Useful for testing. + /// + public CommandLineArgsVariableSource(string[] commandLineArgs) + { + this.commandLineArgs = commandLineArgs; + } + + /// + /// Gets or sets a prefix that should be used to + /// identify arguments to extract values from. + /// + /// + /// A prefix that should be used to identify arguments + /// to extract values from. Defaults to slash ("/"). + /// + public string ArgumentPrefix + { + get { return argumentPrefix; } + set { argumentPrefix = value; } + } + + /// + /// Gets or sets a character that should be used to + /// separate argument name from its value. + /// + /// + /// A character that should be used to separate argument + /// name from its value. Defaults to colon (":"). + /// + public string ValueSeparator + { + get { return valueSeparator; } + set { valueSeparator = value; } + } + + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + if (arguments == null) + { + InitArguments(); + } + return (string) this.arguments[name]; + } + + /// + /// Initializes command line arguments dictionary. + /// + private void InitArguments() + { + this.arguments = CollectionsUtil.CreateCaseInsensitiveHashtable(commandLineArgs.Length); + + foreach (string arg in commandLineArgs) + { + int separatorIndex = arg.IndexOf(valueSeparator); + if (arg.StartsWith(argumentPrefix) && separatorIndex > argumentPrefix.Length) + { + string argName = arg.Substring(argumentPrefix.Length, separatorIndex - argumentPrefix.Length); + string argValue = arg.Substring(separatorIndex + valueSeparator.Length); + this.arguments[argName] = argValue; + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ConfigSectionVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ConfigSectionVariableSource.cs index 108f2b7c..7c0c1e31 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ConfigSectionVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ConfigSectionVariableSource.cs @@ -1,136 +1,135 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections.Specialized; -using System.Configuration; -using Spring.Util; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name against name-value sections in - /// the standard .NET configuration file. - /// - /// Aleksandar Seovic - /// $Id: ConfigSectionVariableSource.cs,v 1.4 2007/08/22 20:16:27 oakinger Exp $ - [Serializable] - public class ConfigSectionVariableSource : IVariableSource - { - private string[] sectionNames; - private NameValueCollection variables; - - /// - /// Initializes a new instance of - /// - public ConfigSectionVariableSource() - { - } - - /// - /// Initializes a new instance of from the given - /// - public ConfigSectionVariableSource(string sectionName) - { - this.SectionName = sectionName; - } - - /// - /// Initializes a new instance of from the given - /// - public ConfigSectionVariableSource(string[] sectionNames) - { - this.SectionNames = sectionNames; - } - - /// - /// Gets or sets a list of section names variables should be loaded from. - /// - /// - /// All sections specified need to be handled by the - /// in order to be processed successfully. - /// - /// - /// A list of section names variables should be loaded from. - /// - public string[] SectionNames - { - get { return sectionNames; } - set { sectionNames = value; } - } - - /// - /// Convinience property. Gets or sets a single section - /// to read properties from. - /// - /// - /// The section specified needs to be handled by the - /// in order to be processed successfully. - /// - /// - /// A section to read properties from. - /// - public string SectionName - { - set { sectionNames = new string[] { value }; } - } - - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - if (variables == null) - { - InitVariables(); - } - return variables.Get(name); - } - - /// - /// Initializes properties based on the specified - /// property file locations. - /// - private void InitVariables() - { - variables = new NameValueCollection(); - foreach (string sectionName in sectionNames) - { - object section = ConfigurationUtils.GetSection(sectionName); - if (section is NameValueCollection) - { - variables.Add((NameValueCollection) section); - } - else - { - throw new ArgumentException("Section [" + sectionName + - "] is not handled by the NameValueSectionHandler."); - } - } - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections.Specialized; +using System.Configuration; +using Spring.Util; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name against name-value sections in + /// the standard .NET configuration file. + /// + /// Aleksandar Seovic + [Serializable] + public class ConfigSectionVariableSource : IVariableSource + { + private string[] sectionNames; + private NameValueCollection variables; + + /// + /// Initializes a new instance of + /// + public ConfigSectionVariableSource() + { + } + + /// + /// Initializes a new instance of from the given + /// + public ConfigSectionVariableSource(string sectionName) + { + this.SectionName = sectionName; + } + + /// + /// Initializes a new instance of from the given + /// + public ConfigSectionVariableSource(string[] sectionNames) + { + this.SectionNames = sectionNames; + } + + /// + /// Gets or sets a list of section names variables should be loaded from. + /// + /// + /// All sections specified need to be handled by the + /// in order to be processed successfully. + /// + /// + /// A list of section names variables should be loaded from. + /// + public string[] SectionNames + { + get { return sectionNames; } + set { sectionNames = value; } + } + + /// + /// Convinience property. Gets or sets a single section + /// to read properties from. + /// + /// + /// The section specified needs to be handled by the + /// in order to be processed successfully. + /// + /// + /// A section to read properties from. + /// + public string SectionName + { + set { sectionNames = new string[] { value }; } + } + + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + if (variables == null) + { + InitVariables(); + } + return variables.Get(name); + } + + /// + /// Initializes properties based on the specified + /// property file locations. + /// + private void InitVariables() + { + variables = new NameValueCollection(); + foreach (string sectionName in sectionNames) + { + object section = ConfigurationUtils.GetSection(sectionName); + if (section is NameValueCollection) + { + variables.Add((NameValueCollection) section); + } + else + { + throw new ArgumentException("Section [" + sectionName + + "] is not handled by the NameValueSectionHandler."); + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ConfigurationReader.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ConfigurationReader.cs index 73146a93..e7c74623 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ConfigurationReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ConfigurationReader.cs @@ -1,347 +1,346 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections.Specialized; -using System.Configuration; -using System.IO; -using System.Xml; - -using Common.Logging; -using Spring.Core; -using Spring.Core.IO; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Various utility methods for .NET style .config files. - /// - /// - ///

- /// Currently supports reading custom configuration sections and returning them as - /// objects. - ///

- ///
- /// Simon White - /// Mark Pollack - /// $Id: ConfigurationReader.cs,v 1.18 2007/08/08 17:47:13 bbaia Exp $ - public sealed class ConfigurationReader - { - private const string ConfigSectionTypeAttribute = "type"; - private const string ConfigurationElement = "configuration"; - private const string ConfigSectionsElement = "configSections"; - private const string ConfigSectionElement = "section"; - private const string ConfigSectionNameAttribute = "name"; - - private static readonly ILog _log = LogManager.GetLogger(typeof (ConfigurationReader)); - - /// - /// Reads the specified configuration section into a - /// . - /// - /// The resource to read. - /// The section name. - /// - /// A newly populated - /// . - /// - /// - /// If any errors are encountered while attempting to open a stream - /// from the supplied . - /// - /// - /// If any errors are encountered while loading or reading (this only applies to - /// v1.1 and greater of the .NET Framework) the actual XML. - /// - /// - /// If any errors are encountered while loading or reading (this only applies to - /// v1.0 of the .NET Framework). - /// - /// - /// If the configuration section was otherwise invalid. - /// - public static NameValueCollection Read(IResource resource, string configSection) - { - return ConfigurationReader.Read(resource, configSection, new NameValueCollection()); - } - - /// - /// Reads the specified configuration section into the supplied - /// . - /// - /// The resource to read. - /// The section name. - /// - /// The collection that is to be populated. May be - /// . - /// - /// - /// A newly populated - /// . - /// - /// - /// If any errors are encountered while attempting to open a stream - /// from the supplied . - /// - /// - /// If any errors are encountered while loading or reading (this only applies to - /// v1.1 and greater of the .NET Framework) the actual XML. - /// - /// - /// If any errors are encountered while loading or reading (this only applies to - /// v1.0 of the .NET Framework). - /// - /// - /// If the configuration section was otherwise invalid. - /// - public static NameValueCollection Read( - IResource resource, string configSection, NameValueCollection properties) - { - return ConfigurationReader.Read(resource, configSection, properties, true); - } - - /// - /// Reads the specified configuration section into the supplied - /// . - /// - /// The resource to read. - /// The section name. - /// - /// The collection that is to be populated. May be - /// . - /// - /// - /// If a key already exists, is its value to be appended to the current - /// value or replaced? - /// - /// - /// The populated - /// . - /// - /// - /// If any errors are encountered while attempting to open a stream - /// from the supplied . - /// - /// - /// If any errors are encountered while loading or reading (this only applies to - /// v1.1 and greater of the .NET Framework) the actual XML. - /// - /// - /// If any errors are encountered while loading or reading (this only applies to - /// v1.0 of the .NET Framework). - /// - /// - /// If the configuration section was otherwise invalid. - /// - public static NameValueCollection Read( - IResource resource, string configSection, NameValueCollection properties, bool overrideValues) - { - if (properties == null) - { - properties = new NameValueCollection(); - } - Stream stream = null; - try - { - XmlDocument doc = new XmlDocument(); - stream = resource.InputStream; - doc.Load(stream); - NameValueCollection newProperties = ReadFromXmlDocument(doc, configSection); - if(newProperties != null) - { - PopulateProperties(overrideValues, properties, newProperties); - } - } - finally - { - if (stream != null) - { - try - { - stream.Close(); - } - catch (IOException ex) - { - #region Instrumentation - - if (_log.IsWarnEnabled) - { - _log.Warn("Could not close stream from resource " + resource.Description, ex); - } - - #endregion - } - } - } - return properties; - } - - /// - /// Read from the specified configuration from the supplied XML - /// into a - /// . - /// - /// - /// - /// Does not support section grouping. The supplied XML - /// must already be loaded. - /// - /// - /// - /// The to read from. - /// - /// - /// The configuration section name to read. - /// - /// - /// A newly populated - /// . - /// - /// - /// If any errors are encountered while reading (this only applies to - /// v1.1 and greater of the .NET Framework). - /// - /// - /// If any errors are encountered while reading (this only applies to - /// v1.0 of the .NET Framework). - /// - /// - /// If the configuration section was otherwise invalid. - /// - public static NameValueCollection ReadFromXmlDocument(XmlDocument document, - string configSectionName) - { - // find the config section declaration (if one exists)... - XmlNode xmlConfig = document.SelectSingleNode( - string.Format("//{0}//{1}//{2}[@{3}='{4}']", - ConfigurationElement, ConfigSectionsElement, - ConfigSectionElement, ConfigSectionNameAttribute, configSectionName)); - - // create appropriate configuration section handler... - NameValueSectionHandler handler = null; - if (xmlConfig == null) - { - // none specified, so use the default... - handler = new NameValueSectionHandler(); - } - else - { - XmlAttribute xmlConfigType = xmlConfig.Attributes[ConfigSectionTypeAttribute]; - Type cshType = TypeResolutionUtils.ResolveType(xmlConfigType.Value); - object o = ObjectUtils.InstantiateType(cshType); - handler = o as NameValueSectionHandler; - if (handler == null) - { - throw ConfigurationUtils.CreateConfigurationException("Configuration section '" + configSectionName + "' not of type NameValueCollection."); - } - - } - XmlNode collectionNode = document.SelectSingleNode( - string.Format("//{0}//{1}", ConfigurationElement, configSectionName)); - if (collectionNode == null) - { - throw ConfigurationUtils.CreateConfigurationException("Cannot read properties; config section '" + configSectionName + "' not found."); - } - else - { - return (NameValueCollection) handler.Create(null, null, collectionNode); - } - } - - /// - /// Populates the supplied with values from - /// a .NET application configuration file. - /// - /// - /// The - /// to add any key-value pairs to. - /// - /// - /// The configuration section name in the a .NET application configuration - /// file. - /// - /// - /// If a key already exists, is its value to be appended to the current - /// value or replaced? - /// - /// - /// if the supplied - /// was found. - /// - public static bool PopulateFromAppConfig( - NameValueCollection properties, string configSectionName, bool overrideValues) - { - bool sectionFound = false; - - NameValueCollection newProperties - = ConfigurationUtils.GetSection(configSectionName) as NameValueCollection; - - if (newProperties != null) - { - sectionFound = true; - PopulateProperties(overrideValues, properties, newProperties); - } - return sectionFound; - } - - private static void PopulateProperties( - bool overrideValues, NameValueCollection properties, NameValueCollection newProperties) - { - if (!overrideValues) - { - properties.Add(newProperties); - } - else - { - foreach (string key in newProperties.AllKeys) - { - properties.Set(key, newProperties.Get(key)); - } - } - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the ConfigurationReader class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible - /// constructors. - ///

- ///
- private ConfigurationReader() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections.Specialized; +using System.Configuration; +using System.IO; +using System.Xml; + +using Common.Logging; +using Spring.Core; +using Spring.Core.IO; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Various utility methods for .NET style .config files. + /// + /// + ///

+ /// Currently supports reading custom configuration sections and returning them as + /// objects. + ///

+ ///
+ /// Simon White + /// Mark Pollack + public sealed class ConfigurationReader + { + private const string ConfigSectionTypeAttribute = "type"; + private const string ConfigurationElement = "configuration"; + private const string ConfigSectionsElement = "configSections"; + private const string ConfigSectionElement = "section"; + private const string ConfigSectionNameAttribute = "name"; + + private static readonly ILog _log = LogManager.GetLogger(typeof (ConfigurationReader)); + + /// + /// Reads the specified configuration section into a + /// . + /// + /// The resource to read. + /// The section name. + /// + /// A newly populated + /// . + /// + /// + /// If any errors are encountered while attempting to open a stream + /// from the supplied . + /// + /// + /// If any errors are encountered while loading or reading (this only applies to + /// v1.1 and greater of the .NET Framework) the actual XML. + /// + /// + /// If any errors are encountered while loading or reading (this only applies to + /// v1.0 of the .NET Framework). + /// + /// + /// If the configuration section was otherwise invalid. + /// + public static NameValueCollection Read(IResource resource, string configSection) + { + return ConfigurationReader.Read(resource, configSection, new NameValueCollection()); + } + + /// + /// Reads the specified configuration section into the supplied + /// . + /// + /// The resource to read. + /// The section name. + /// + /// The collection that is to be populated. May be + /// . + /// + /// + /// A newly populated + /// . + /// + /// + /// If any errors are encountered while attempting to open a stream + /// from the supplied . + /// + /// + /// If any errors are encountered while loading or reading (this only applies to + /// v1.1 and greater of the .NET Framework) the actual XML. + /// + /// + /// If any errors are encountered while loading or reading (this only applies to + /// v1.0 of the .NET Framework). + /// + /// + /// If the configuration section was otherwise invalid. + /// + public static NameValueCollection Read( + IResource resource, string configSection, NameValueCollection properties) + { + return ConfigurationReader.Read(resource, configSection, properties, true); + } + + /// + /// Reads the specified configuration section into the supplied + /// . + /// + /// The resource to read. + /// The section name. + /// + /// The collection that is to be populated. May be + /// . + /// + /// + /// If a key already exists, is its value to be appended to the current + /// value or replaced? + /// + /// + /// The populated + /// . + /// + /// + /// If any errors are encountered while attempting to open a stream + /// from the supplied . + /// + /// + /// If any errors are encountered while loading or reading (this only applies to + /// v1.1 and greater of the .NET Framework) the actual XML. + /// + /// + /// If any errors are encountered while loading or reading (this only applies to + /// v1.0 of the .NET Framework). + /// + /// + /// If the configuration section was otherwise invalid. + /// + public static NameValueCollection Read( + IResource resource, string configSection, NameValueCollection properties, bool overrideValues) + { + if (properties == null) + { + properties = new NameValueCollection(); + } + Stream stream = null; + try + { + XmlDocument doc = new XmlDocument(); + stream = resource.InputStream; + doc.Load(stream); + NameValueCollection newProperties = ReadFromXmlDocument(doc, configSection); + if(newProperties != null) + { + PopulateProperties(overrideValues, properties, newProperties); + } + } + finally + { + if (stream != null) + { + try + { + stream.Close(); + } + catch (IOException ex) + { + #region Instrumentation + + if (_log.IsWarnEnabled) + { + _log.Warn("Could not close stream from resource " + resource.Description, ex); + } + + #endregion + } + } + } + return properties; + } + + /// + /// Read from the specified configuration from the supplied XML + /// into a + /// . + /// + /// + /// + /// Does not support section grouping. The supplied XML + /// must already be loaded. + /// + /// + /// + /// The to read from. + /// + /// + /// The configuration section name to read. + /// + /// + /// A newly populated + /// . + /// + /// + /// If any errors are encountered while reading (this only applies to + /// v1.1 and greater of the .NET Framework). + /// + /// + /// If any errors are encountered while reading (this only applies to + /// v1.0 of the .NET Framework). + /// + /// + /// If the configuration section was otherwise invalid. + /// + public static NameValueCollection ReadFromXmlDocument(XmlDocument document, + string configSectionName) + { + // find the config section declaration (if one exists)... + XmlNode xmlConfig = document.SelectSingleNode( + string.Format("//{0}//{1}//{2}[@{3}='{4}']", + ConfigurationElement, ConfigSectionsElement, + ConfigSectionElement, ConfigSectionNameAttribute, configSectionName)); + + // create appropriate configuration section handler... + NameValueSectionHandler handler = null; + if (xmlConfig == null) + { + // none specified, so use the default... + handler = new NameValueSectionHandler(); + } + else + { + XmlAttribute xmlConfigType = xmlConfig.Attributes[ConfigSectionTypeAttribute]; + Type cshType = TypeResolutionUtils.ResolveType(xmlConfigType.Value); + object o = ObjectUtils.InstantiateType(cshType); + handler = o as NameValueSectionHandler; + if (handler == null) + { + throw ConfigurationUtils.CreateConfigurationException("Configuration section '" + configSectionName + "' not of type NameValueCollection."); + } + + } + XmlNode collectionNode = document.SelectSingleNode( + string.Format("//{0}//{1}", ConfigurationElement, configSectionName)); + if (collectionNode == null) + { + throw ConfigurationUtils.CreateConfigurationException("Cannot read properties; config section '" + configSectionName + "' not found."); + } + else + { + return (NameValueCollection) handler.Create(null, null, collectionNode); + } + } + + /// + /// Populates the supplied with values from + /// a .NET application configuration file. + /// + /// + /// The + /// to add any key-value pairs to. + /// + /// + /// The configuration section name in the a .NET application configuration + /// file. + /// + /// + /// If a key already exists, is its value to be appended to the current + /// value or replaced? + /// + /// + /// if the supplied + /// was found. + /// + public static bool PopulateFromAppConfig( + NameValueCollection properties, string configSectionName, bool overrideValues) + { + bool sectionFound = false; + + NameValueCollection newProperties + = ConfigurationUtils.GetSection(configSectionName) as NameValueCollection; + + if (newProperties != null) + { + sectionFound = true; + PopulateProperties(overrideValues, properties, newProperties); + } + return sectionFound; + } + + private static void PopulateProperties( + bool overrideValues, NameValueCollection properties, NameValueCollection newProperties) + { + if (!overrideValues) + { + properties.Add(newProperties); + } + else + { + foreach (string key in newProperties.AllKeys) + { + properties.Set(key, newProperties.Get(key)); + } + } + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the ConfigurationReader class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible + /// constructors. + ///

+ ///
+ private ConfigurationReader() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ConnectionStringsVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ConnectionStringsVariableSource.cs index cc9bb027..6a79bc79 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ConnectionStringsVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ConnectionStringsVariableSource.cs @@ -1,96 +1,95 @@ -#if NET_2_0 -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections.Specialized; -using System.Configuration; -using Spring.Util; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name connection strings defined in - /// the standard .NET configuration file. - /// - /// - ///

- /// When the <connectionStrings> configuration section is processed by this class, - /// two variables are defined for each connection string: one for connection string and - /// the second one for the provider name.

- ///

- /// Variable names are generated by appending '.connectionString' and '.providerName' - /// literals to the value of the name attribute of the connection string element. - /// For example:

- ///
-    /// 
-    ///    
-    /// 
-    /// 
- ///

- /// will result in two variables being created: myConn.connectionString and myConn.providerName. - /// You can reference these variables within your object definitions, just like any other variable.

- ///
- /// Aleksandar Seovic - /// $Id: ConnectionStringsVariableSource.cs,v 1.4 2007/08/02 22:18:32 markpollack Exp $ - [Serializable] - public class ConnectionStringsVariableSource : IVariableSource - { - private NameValueCollection variables; - - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - if (variables == null) - { - InitVariables(); - } - return variables.Get(name); - } - - /// - /// Initializes properties based on the specified - /// property file locations. - /// - private void InitVariables() - { - variables = new NameValueCollection(); - ConnectionStringSettingsCollection settings = ConfigurationManager.ConnectionStrings; - foreach (ConnectionStringSettings setting in settings) - { - string providerName = setting.ProviderName; - - variables.Add(setting.Name + ".connectionString", setting.ConnectionString); - variables.Add(setting.Name + ".providerName", - StringUtils.HasText(providerName) ? providerName : "System.Data.SqlClient"); - } - } - } -} +#if NET_2_0 +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections.Specialized; +using System.Configuration; +using Spring.Util; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name connection strings defined in + /// the standard .NET configuration file. + /// + /// + ///

+ /// When the <connectionStrings> configuration section is processed by this class, + /// two variables are defined for each connection string: one for connection string and + /// the second one for the provider name.

+ ///

+ /// Variable names are generated by appending '.connectionString' and '.providerName' + /// literals to the value of the name attribute of the connection string element. + /// For example:

+ ///
+    /// 
+    ///    
+    /// 
+    /// 
+ ///

+ /// will result in two variables being created: myConn.connectionString and myConn.providerName. + /// You can reference these variables within your object definitions, just like any other variable.

+ ///
+ /// Aleksandar Seovic + [Serializable] + public class ConnectionStringsVariableSource : IVariableSource + { + private NameValueCollection variables; + + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + if (variables == null) + { + InitVariables(); + } + return variables.Get(name); + } + + /// + /// Initializes properties based on the specified + /// property file locations. + /// + private void InitVariables() + { + variables = new NameValueCollection(); + ConnectionStringSettingsCollection settings = ConfigurationManager.ConnectionStrings; + foreach (ConnectionStringSettings setting in settings) + { + string providerName = setting.ProviderName; + + variables.Add(setting.Name + ".connectionString", setting.ConnectionString); + variables.Add(setting.Name + ".providerName", + StringUtils.HasText(providerName) ? providerName : "System.Data.SqlClient"); + } + } + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ConstructorArgumentValues.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ConstructorArgumentValues.cs index 5ac02f1c..7e585b42 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ConstructorArgumentValues.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ConstructorArgumentValues.cs @@ -1,659 +1,658 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using Spring.Collections; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Holder for constructor argument values for an object. - /// - /// - ///

- /// Supports values for a specific index or parameter name (case - /// insensitive) in the constructor argument list, and generic matches by - /// . - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ConstructorArgumentValues.cs,v 1.16 2008/03/03 09:29:07 bbaia Exp $ - /// - [Serializable] - public class ConstructorArgumentValues - { - /// - /// Can be used as an argument filler for the - /// - /// overload when one is not looking for an argument by index. - /// - public const int NoIndex = -1289; // yes, the number really is wholly arbitrary... - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - public ConstructorArgumentValues() - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The - /// to be used to populate this instance. - /// - public ConstructorArgumentValues(ConstructorArgumentValues other) - { - AddAll(other); - } - - #endregion - - #region Fields - - private CultureInfo enUSCultureInfo = new CultureInfo("en-US", false); - private IDictionary _indexedArgumentValues = new Hashtable(); - private IList _genericArgumentValues = new LinkedList(); - private IDictionary _namedArgumentValues = new Hashtable(); - - #endregion - - #region Properties - - /// - /// Return the map of indexed argument values. - /// - /// - /// An with - /// indices as keys and - /// s - /// as values. - /// - public virtual IDictionary IndexedArgumentValues - { - get { return _indexedArgumentValues; } - } - - /// - /// Return the map of named argument values. - /// - /// - /// An with - /// named arguments as keys and - /// s - /// as values. - /// - public virtual IDictionary NamedArgumentValues - { - get { return _namedArgumentValues; } - } - - /// - /// Return the set of generic argument values. - /// - /// - /// A of - /// s. - /// - public virtual IList GenericArgumentValues - { - get { return _genericArgumentValues; } - - } - - /// - /// Return the number of arguments held in this instance. - /// - public virtual int ArgumentCount - { - get - { - return IndexedArgumentValues.Count - + GenericArgumentValues.Count - + NamedArgumentValues.Count; - } - - } - - /// - /// Returns true if this holder does not contain any argument values, - /// neither indexed ones nor generic ones. - /// - public virtual bool Empty - { - get - { - return IndexedArgumentValues.Count == 0 - && GenericArgumentValues.Count == 0 - && NamedArgumentValues.Count == 0; - } - } - - #endregion - - #region Methods - - /// - /// Copy all given argument values into this object. - /// - /// - /// The - /// to be used to populate this instance. - /// - public void AddAll(ConstructorArgumentValues other) - { - if (other != null) - { - foreach (object o in other.GenericArgumentValues) - { - GenericArgumentValues.Add(o); - } - foreach (DictionaryEntry entry in other.IndexedArgumentValues) - { - IndexedArgumentValues.Add(entry.Key, entry.Value); - } - foreach (DictionaryEntry entry in other.NamedArgumentValues) - { - NamedArgumentValues.Add(entry.Key, entry.Value); - } - } - } - - /// - /// Add argument value for the given index in the constructor argument list. - /// - /// - /// The index in the constructor argument list. - /// - /// - /// The argument value. - /// - public virtual void AddIndexedArgumentValue(int index, object value) - { - IndexedArgumentValues[index] = new ValueHolder(value); - } - - /// - /// Add argument value for the given index in the constructor argument list. - /// - /// The index in the constructor argument list. - /// The argument value. - /// - /// The of the argument - /// . - /// - public virtual void AddIndexedArgumentValue(int index, object value, string type) - { - IndexedArgumentValues[index] = new ValueHolder(value, type); - } - - /// - /// Add argument value for the given name in the constructor argument list. - /// - /// The name in the constructor argument list. - /// The argument value. - /// - /// If the supplied is - /// or is composed wholly of whitespace. - /// - public virtual void AddNamedArgumentValue(string name, object value) - { - AssertUtils.ArgumentHasText(name, "name"); - NamedArgumentValues[GetCanonicalNamedArgument(name)] = new ValueHolder(value); - } - - /// - /// Get argument value for the given index in the constructor argument list. - /// - /// The index in the constructor argument list. - /// - /// The required of the argument. - /// - /// - /// The - /// - /// for the argument, or if none set. - /// - public virtual ValueHolder GetIndexedArgumentValue(int index, Type requiredType) - { - ValueHolder valueHolder = (ValueHolder) IndexedArgumentValues[index]; - if (valueHolder != null) - { - if (valueHolder.Type == null - || requiredType.FullName.Equals(valueHolder.Type) - || requiredType.AssemblyQualifiedName.Equals(valueHolder.Type)) - { - return valueHolder; - } - } - return null; - } - - /// - /// Get argument value for the given name in the constructor argument list. - /// - /// The name in the constructor argument list. - /// - /// The - /// - /// for the argument, or if none set. - /// - public virtual ValueHolder GetNamedArgumentValue(string name) - { - ValueHolder valueHolder = null; - if (name != null && ContainsNamedArgument(name)) - { - valueHolder = (ValueHolder)NamedArgumentValues[GetCanonicalNamedArgument(name)]; - } - return valueHolder; - } - - /// - /// Does this set of constructor arguments contain a named argument matching the - /// supplied name? - /// - /// - /// - /// The comparison is performed in a case-insensitive fashion. - /// - /// - /// The named argument to look up. - /// - /// if this set of constructor arguments - /// contains a named argument matching the supplied - /// name. - /// - public bool ContainsNamedArgument(string argument) - { - return NamedArgumentValues.Contains(GetCanonicalNamedArgument(argument)); - } - - /// - /// Add generic argument value to be matched by type. - /// - /// - /// The argument value. - /// - public virtual void AddGenericArgumentValue(object value) - { - GenericArgumentValues.Add(new ValueHolder(value)); - } - - /// - /// Add generic argument value to be matched by type. - /// - /// The argument value. - /// - /// The of the argument - /// . - /// - public virtual void AddGenericArgumentValue(object value, string type) - { - GenericArgumentValues.Add(new ValueHolder(value, type)); - } - - /// - /// Look for a generic argument value that matches the given - /// . - /// - /// - /// The to match. - /// - /// - /// The - /// - /// for the argument, or if none set. - /// - public virtual ValueHolder GetGenericArgumentValue(Type requiredType) - { - return GetGenericArgumentValue(requiredType, null); - } - - /// - /// Look for a generic argument value that matches the given - /// . - /// - /// - /// The to match. - /// - /// - /// A of - /// - /// objects that have already been used in the current resolution - /// process and should therefore not be returned again; this allows one - /// to return the next generic argument match in the case of multiple - /// generic argument values of the same type. - /// - /// - /// The - /// - /// for the argument, or if none set. - /// - public virtual ValueHolder GetGenericArgumentValue( - Type requiredType, ISet usedValues) - { - foreach (ValueHolder valueHolder in GenericArgumentValues) - { - if (usedValues == null || !usedValues.Contains(valueHolder)) - { - if (requiredType != null) - { - if (StringUtils.HasText(valueHolder.Type)) - { - if (valueHolder.Type.Equals(requiredType.FullName) - || valueHolder.Type.Equals(requiredType.AssemblyQualifiedName)) - { - return valueHolder; - } - } - else if (requiredType.IsInstanceOfType(valueHolder.Value) - || (requiredType.IsArray - && typeof (IList).IsInstanceOfType(valueHolder.Value))) - { - return valueHolder; - } - } - // if the value holder is (pretty much) untyped, that's ok to return... - else if (StringUtils.IsNullOrEmpty(valueHolder.Type)) - { - return valueHolder; - } - } - } - return null; - } - - /// - /// Look for an argument value that either corresponds to the given index - /// in the constructor argument list or generically matches by - /// . - /// - /// - /// The index in the constructor argument list. - /// - /// - /// The to match. - /// - /// - /// The - /// - /// for the argument, or if none is set. - /// - public virtual ValueHolder GetArgumentValue(int index, Type requiredType) - { - return GetArgumentValue(index, string.Empty, requiredType, null); - } - - /// - /// Look for an argument value that either corresponds to the given index - /// in the constructor argument list or generically matches by - /// . - /// - /// - /// The index in the constructor argument list. - /// - /// - /// The to match. - /// - /// - /// A of - /// - /// objects that have already been used in the current resolution - /// process and should therefore not be returned again; this allows one - /// to return the next generic argument match in the case of multiple - /// generic argument values of the same type. - /// - /// - /// The - /// - /// for the argument, or if none is set. - /// - public virtual ValueHolder GetArgumentValue(int index, Type requiredType, ISet usedValues) - { - return GetArgumentValue(index, string.Empty, requiredType, usedValues); - } - - /// - /// Look for an argument value that either corresponds to the given index - /// in the constructor argument list or generically matches by - /// . - /// - /// - /// The name of the argument in the constructor argument list. May be - /// , in which case generic matching by - /// is assumed. - /// - /// - /// The to match. - /// - /// - /// The - /// - /// for the argument, or if none is set. - /// - public virtual ValueHolder GetArgumentValue(string name, Type requiredType) - { - return GetArgumentValue(NoIndex, name, requiredType, null); - } - - /// - /// Look for an argument value that either corresponds to the given index - /// in the constructor argument list or generically matches by - /// . - /// - /// - /// The name of the argument in the constructor argument list. May be - /// , in which case generic matching by - /// is assumed. - /// - /// - /// The to match. - /// - /// - /// A of - /// - /// objects that have already been used in the current resolution - /// process and should therefore not be returned again; this allows one - /// to return the next generic argument match in the case of multiple - /// generic argument values of the same type. - /// - /// - /// The - /// - /// for the argument, or if none is set. - /// - public virtual ValueHolder GetArgumentValue( - string name, Type requiredType, ISet usedValues) - { - return GetArgumentValue(NoIndex, name, requiredType, usedValues); - } - - /// - /// Look for an argument value that either corresponds to the given index - /// in the constructor argument list, or to the named argument, or - /// generically matches by . - /// - /// - /// The index of the argument in the constructor argument list. May be - /// negative, to denote the fact that we are not looking for an - /// argument by index (see - /// . - /// - /// - /// The name of the argument in the constructor argument list. May be - /// . - /// - /// - /// The to match. - /// - /// - /// A of - /// - /// objects that have already been used in the current resolution - /// process and should therefore not be returned again; this allows one - /// to return the next generic argument match in the case of multiple - /// generic argument values of the same type. - /// - /// - /// The - /// - /// for the argument, or if none is set. - /// - public virtual ValueHolder GetArgumentValue( - int index, string name, Type requiredType, ISet usedValues) - { - ValueHolder valueHolder = null; - if(index != NoIndex) - { - valueHolder = GetIndexedArgumentValue(index, requiredType); - } - if (valueHolder == null) - { - valueHolder = GetNamedArgumentValue(name); - if (valueHolder == null) - { - valueHolder = GetGenericArgumentValue(requiredType, usedValues); - } - } - return valueHolder; - } - - private string GetCanonicalNamedArgument(string argument) - { - return argument != null ? argument.ToLower(enUSCultureInfo) : argument; - } - - #endregion - - #region Inner Class : ValueHolder - - /// - /// Holder for a constructor argument value, with an optional - /// attribute indicating the target - /// of the actual constructor argument. - /// - [Serializable] - public class ValueHolder - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the ValueHolder class. - /// - /// - /// The value of the constructor argument. - /// - internal ValueHolder(object value) - { - Value = value; - } - - /// - /// Creates a new instance of the ValueHolder class. - /// - /// - /// The value of the constructor argument. - /// - /// - /// The of the argument - /// . Can also be one of the common - /// aliases (int, bool, - /// float, etc). - /// - internal ValueHolder(object value, string typeName) - { - Value = value; - this.typeName = typeName; - } - - #endregion - - #region Methods - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, - "'{0}' [{1}]", Value, Type); - } - - #endregion - - #region Properties - - /// - /// Gets and sets the value for the constructor argument. - /// - /// - ///

- /// Only necessary for manipulating a registered value, for example in - /// s. - ///

- ///
- public object Value - { - get { return _ctorValue; } - set { _ctorValue = value; } - } - - /// - /// Return the of the constructor - /// argument. - /// - public string Type - { - get { return typeName; } - } - - #endregion - - #region Fields - - private object _ctorValue; - private string typeName; - - #endregion - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using Spring.Collections; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Holder for constructor argument values for an object. + /// + /// + ///

+ /// Supports values for a specific index or parameter name (case + /// insensitive) in the constructor argument list, and generic matches by + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// + [Serializable] + public class ConstructorArgumentValues + { + /// + /// Can be used as an argument filler for the + /// + /// overload when one is not looking for an argument by index. + /// + public const int NoIndex = -1289; // yes, the number really is wholly arbitrary... + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + public ConstructorArgumentValues() + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The + /// to be used to populate this instance. + /// + public ConstructorArgumentValues(ConstructorArgumentValues other) + { + AddAll(other); + } + + #endregion + + #region Fields + + private CultureInfo enUSCultureInfo = new CultureInfo("en-US", false); + private IDictionary _indexedArgumentValues = new Hashtable(); + private IList _genericArgumentValues = new LinkedList(); + private IDictionary _namedArgumentValues = new Hashtable(); + + #endregion + + #region Properties + + /// + /// Return the map of indexed argument values. + /// + /// + /// An with + /// indices as keys and + /// s + /// as values. + /// + public virtual IDictionary IndexedArgumentValues + { + get { return _indexedArgumentValues; } + } + + /// + /// Return the map of named argument values. + /// + /// + /// An with + /// named arguments as keys and + /// s + /// as values. + /// + public virtual IDictionary NamedArgumentValues + { + get { return _namedArgumentValues; } + } + + /// + /// Return the set of generic argument values. + /// + /// + /// A of + /// s. + /// + public virtual IList GenericArgumentValues + { + get { return _genericArgumentValues; } + + } + + /// + /// Return the number of arguments held in this instance. + /// + public virtual int ArgumentCount + { + get + { + return IndexedArgumentValues.Count + + GenericArgumentValues.Count + + NamedArgumentValues.Count; + } + + } + + /// + /// Returns true if this holder does not contain any argument values, + /// neither indexed ones nor generic ones. + /// + public virtual bool Empty + { + get + { + return IndexedArgumentValues.Count == 0 + && GenericArgumentValues.Count == 0 + && NamedArgumentValues.Count == 0; + } + } + + #endregion + + #region Methods + + /// + /// Copy all given argument values into this object. + /// + /// + /// The + /// to be used to populate this instance. + /// + public void AddAll(ConstructorArgumentValues other) + { + if (other != null) + { + foreach (object o in other.GenericArgumentValues) + { + GenericArgumentValues.Add(o); + } + foreach (DictionaryEntry entry in other.IndexedArgumentValues) + { + IndexedArgumentValues.Add(entry.Key, entry.Value); + } + foreach (DictionaryEntry entry in other.NamedArgumentValues) + { + NamedArgumentValues.Add(entry.Key, entry.Value); + } + } + } + + /// + /// Add argument value for the given index in the constructor argument list. + /// + /// + /// The index in the constructor argument list. + /// + /// + /// The argument value. + /// + public virtual void AddIndexedArgumentValue(int index, object value) + { + IndexedArgumentValues[index] = new ValueHolder(value); + } + + /// + /// Add argument value for the given index in the constructor argument list. + /// + /// The index in the constructor argument list. + /// The argument value. + /// + /// The of the argument + /// . + /// + public virtual void AddIndexedArgumentValue(int index, object value, string type) + { + IndexedArgumentValues[index] = new ValueHolder(value, type); + } + + /// + /// Add argument value for the given name in the constructor argument list. + /// + /// The name in the constructor argument list. + /// The argument value. + /// + /// If the supplied is + /// or is composed wholly of whitespace. + /// + public virtual void AddNamedArgumentValue(string name, object value) + { + AssertUtils.ArgumentHasText(name, "name"); + NamedArgumentValues[GetCanonicalNamedArgument(name)] = new ValueHolder(value); + } + + /// + /// Get argument value for the given index in the constructor argument list. + /// + /// The index in the constructor argument list. + /// + /// The required of the argument. + /// + /// + /// The + /// + /// for the argument, or if none set. + /// + public virtual ValueHolder GetIndexedArgumentValue(int index, Type requiredType) + { + ValueHolder valueHolder = (ValueHolder) IndexedArgumentValues[index]; + if (valueHolder != null) + { + if (valueHolder.Type == null + || requiredType.FullName.Equals(valueHolder.Type) + || requiredType.AssemblyQualifiedName.Equals(valueHolder.Type)) + { + return valueHolder; + } + } + return null; + } + + /// + /// Get argument value for the given name in the constructor argument list. + /// + /// The name in the constructor argument list. + /// + /// The + /// + /// for the argument, or if none set. + /// + public virtual ValueHolder GetNamedArgumentValue(string name) + { + ValueHolder valueHolder = null; + if (name != null && ContainsNamedArgument(name)) + { + valueHolder = (ValueHolder)NamedArgumentValues[GetCanonicalNamedArgument(name)]; + } + return valueHolder; + } + + /// + /// Does this set of constructor arguments contain a named argument matching the + /// supplied name? + /// + /// + /// + /// The comparison is performed in a case-insensitive fashion. + /// + /// + /// The named argument to look up. + /// + /// if this set of constructor arguments + /// contains a named argument matching the supplied + /// name. + /// + public bool ContainsNamedArgument(string argument) + { + return NamedArgumentValues.Contains(GetCanonicalNamedArgument(argument)); + } + + /// + /// Add generic argument value to be matched by type. + /// + /// + /// The argument value. + /// + public virtual void AddGenericArgumentValue(object value) + { + GenericArgumentValues.Add(new ValueHolder(value)); + } + + /// + /// Add generic argument value to be matched by type. + /// + /// The argument value. + /// + /// The of the argument + /// . + /// + public virtual void AddGenericArgumentValue(object value, string type) + { + GenericArgumentValues.Add(new ValueHolder(value, type)); + } + + /// + /// Look for a generic argument value that matches the given + /// . + /// + /// + /// The to match. + /// + /// + /// The + /// + /// for the argument, or if none set. + /// + public virtual ValueHolder GetGenericArgumentValue(Type requiredType) + { + return GetGenericArgumentValue(requiredType, null); + } + + /// + /// Look for a generic argument value that matches the given + /// . + /// + /// + /// The to match. + /// + /// + /// A of + /// + /// objects that have already been used in the current resolution + /// process and should therefore not be returned again; this allows one + /// to return the next generic argument match in the case of multiple + /// generic argument values of the same type. + /// + /// + /// The + /// + /// for the argument, or if none set. + /// + public virtual ValueHolder GetGenericArgumentValue( + Type requiredType, ISet usedValues) + { + foreach (ValueHolder valueHolder in GenericArgumentValues) + { + if (usedValues == null || !usedValues.Contains(valueHolder)) + { + if (requiredType != null) + { + if (StringUtils.HasText(valueHolder.Type)) + { + if (valueHolder.Type.Equals(requiredType.FullName) + || valueHolder.Type.Equals(requiredType.AssemblyQualifiedName)) + { + return valueHolder; + } + } + else if (requiredType.IsInstanceOfType(valueHolder.Value) + || (requiredType.IsArray + && typeof (IList).IsInstanceOfType(valueHolder.Value))) + { + return valueHolder; + } + } + // if the value holder is (pretty much) untyped, that's ok to return... + else if (StringUtils.IsNullOrEmpty(valueHolder.Type)) + { + return valueHolder; + } + } + } + return null; + } + + /// + /// Look for an argument value that either corresponds to the given index + /// in the constructor argument list or generically matches by + /// . + /// + /// + /// The index in the constructor argument list. + /// + /// + /// The to match. + /// + /// + /// The + /// + /// for the argument, or if none is set. + /// + public virtual ValueHolder GetArgumentValue(int index, Type requiredType) + { + return GetArgumentValue(index, string.Empty, requiredType, null); + } + + /// + /// Look for an argument value that either corresponds to the given index + /// in the constructor argument list or generically matches by + /// . + /// + /// + /// The index in the constructor argument list. + /// + /// + /// The to match. + /// + /// + /// A of + /// + /// objects that have already been used in the current resolution + /// process and should therefore not be returned again; this allows one + /// to return the next generic argument match in the case of multiple + /// generic argument values of the same type. + /// + /// + /// The + /// + /// for the argument, or if none is set. + /// + public virtual ValueHolder GetArgumentValue(int index, Type requiredType, ISet usedValues) + { + return GetArgumentValue(index, string.Empty, requiredType, usedValues); + } + + /// + /// Look for an argument value that either corresponds to the given index + /// in the constructor argument list or generically matches by + /// . + /// + /// + /// The name of the argument in the constructor argument list. May be + /// , in which case generic matching by + /// is assumed. + /// + /// + /// The to match. + /// + /// + /// The + /// + /// for the argument, or if none is set. + /// + public virtual ValueHolder GetArgumentValue(string name, Type requiredType) + { + return GetArgumentValue(NoIndex, name, requiredType, null); + } + + /// + /// Look for an argument value that either corresponds to the given index + /// in the constructor argument list or generically matches by + /// . + /// + /// + /// The name of the argument in the constructor argument list. May be + /// , in which case generic matching by + /// is assumed. + /// + /// + /// The to match. + /// + /// + /// A of + /// + /// objects that have already been used in the current resolution + /// process and should therefore not be returned again; this allows one + /// to return the next generic argument match in the case of multiple + /// generic argument values of the same type. + /// + /// + /// The + /// + /// for the argument, or if none is set. + /// + public virtual ValueHolder GetArgumentValue( + string name, Type requiredType, ISet usedValues) + { + return GetArgumentValue(NoIndex, name, requiredType, usedValues); + } + + /// + /// Look for an argument value that either corresponds to the given index + /// in the constructor argument list, or to the named argument, or + /// generically matches by . + /// + /// + /// The index of the argument in the constructor argument list. May be + /// negative, to denote the fact that we are not looking for an + /// argument by index (see + /// . + /// + /// + /// The name of the argument in the constructor argument list. May be + /// . + /// + /// + /// The to match. + /// + /// + /// A of + /// + /// objects that have already been used in the current resolution + /// process and should therefore not be returned again; this allows one + /// to return the next generic argument match in the case of multiple + /// generic argument values of the same type. + /// + /// + /// The + /// + /// for the argument, or if none is set. + /// + public virtual ValueHolder GetArgumentValue( + int index, string name, Type requiredType, ISet usedValues) + { + ValueHolder valueHolder = null; + if(index != NoIndex) + { + valueHolder = GetIndexedArgumentValue(index, requiredType); + } + if (valueHolder == null) + { + valueHolder = GetNamedArgumentValue(name); + if (valueHolder == null) + { + valueHolder = GetGenericArgumentValue(requiredType, usedValues); + } + } + return valueHolder; + } + + private string GetCanonicalNamedArgument(string argument) + { + return argument != null ? argument.ToLower(enUSCultureInfo) : argument; + } + + #endregion + + #region Inner Class : ValueHolder + + /// + /// Holder for a constructor argument value, with an optional + /// attribute indicating the target + /// of the actual constructor argument. + /// + [Serializable] + public class ValueHolder + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the ValueHolder class. + /// + /// + /// The value of the constructor argument. + /// + internal ValueHolder(object value) + { + Value = value; + } + + /// + /// Creates a new instance of the ValueHolder class. + /// + /// + /// The value of the constructor argument. + /// + /// + /// The of the argument + /// . Can also be one of the common + /// aliases (int, bool, + /// float, etc). + /// + internal ValueHolder(object value, string typeName) + { + Value = value; + this.typeName = typeName; + } + + #endregion + + #region Methods + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, + "'{0}' [{1}]", Value, Type); + } + + #endregion + + #region Properties + + /// + /// Gets and sets the value for the constructor argument. + /// + /// + ///

+ /// Only necessary for manipulating a registered value, for example in + /// s. + ///

+ ///
+ public object Value + { + get { return _ctorValue; } + set { _ctorValue = value; } + } + + /// + /// Return the of the constructor + /// argument. + /// + public string Type + { + get { return typeName; } + } + + #endregion + + #region Fields + + private object _ctorValue; + private string typeName; + + #endregion + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/CustomConverterConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/CustomConverterConfigurer.cs index 22e44910..64be6219 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/CustomConverterConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/CustomConverterConfigurer.cs @@ -1,304 +1,303 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.ComponentModel; -using System.Globalization; -using Spring.Core; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// - /// implementation that allows for convenient registration of custom - /// s. - /// - /// - /// - /// The use of this class is typically not required; the .NET - /// mechanism of associating a - /// with a - /// via the use of the - /// is the - /// recommended (and standard) way. This class primarily exists to cover - /// those cases where third party classes to which one does not have the - /// source need to be exposed to the type conversion mechanism. - /// - ///

- /// Because the - /// - /// class implements the - /// - /// interface, instances of this class that have been exposed in the - /// scope of an - /// will - /// automatically be picked up by the application context and made - /// available to the IoC container whenever type conversion is required. If - /// one is using a - /// - /// object definition within the scope of an - /// , no such automatic - /// pickup of the - /// - /// is performed (custom converters will have to be added manually using the - /// - /// method). For most application scenarios, one will get better - /// mileage using the - /// abstraction. - ///

- ///
- /// - ///

- /// The following examples all assume XML based configuration, and use - /// inner object definitions to define the custom - /// objects (nominally to - /// avoid polluting the object name space, but also because the - /// configuration simply reads better that way). - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// The following example illustrates a complete (albeit naieve) use case - /// for this class, including a custom - /// implementation, said - /// converters domain class, and the XML configuration that hooks the - /// converter in place and makes it available to a Spring.NET container for - /// use during object resolution. - ///

- ///

- /// The domain class is a simple data-only object that contains the data - /// required to send an email message (such as the host and user account - /// name). A developer would prefer to use a string of the form - /// UserName=administrator,Password=r1l0k1l3y,Host=localhost to - /// configure the mail settings and just let the container take care of the - /// conversion. - ///

- /// - /// namespace ExampleNamespace - /// { - /// public sealed class MailSettings - /// { - /// private string _userName; - /// private string _password; - /// private string _host; - /// - /// public string Host - /// { - /// get { return _host; } - /// set { _host = value; } - /// } - /// - /// public string UserName - /// { - /// get { return _userName; } - /// set { _userName = value; } - /// } - /// - /// public string Password - /// { - /// get { return _password; } - /// set { _password = value; } - /// } - /// } - /// - /// public sealed class MailSettingsConverter : TypeConverter - /// { - /// public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - /// { - /// if (typeof (string) == sourceType) - /// { - /// return true; - /// } - /// return base.CanConvertFrom(context, sourceType); - /// } - /// - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - /// { - /// string text = value as string; - /// if(text != null) - /// { - /// MailSettings mailSettings = new MailSettings(); - /// string[] tokens = text.Split(','); - /// for (int i = 0; i < tokens.Length; ++i) - /// { - /// string token = tokens[i]; - /// string[] settings = token.Split('='); - /// typeof(MailSettings).GetProperty(settings[0]) - /// .SetValue(mailSettings, settings[1], null); - /// } - /// return mailSettings; - /// } - /// return base.ConvertFrom(context, culture, value); - /// } - /// } - /// - /// // a very naieve class that uses the MailSettings class... - /// public sealed class ExceptionLogger - /// { - /// private MailSettings _mailSettings; - /// - /// public MailSettings MailSettings { - /// { - /// set { _mailSettings = value; } - /// } - /// - /// public void Log(object value) - /// { - /// Exception ex = value as Exception; - /// if(ex != null) - /// { - /// // use _mailSettings instance... - /// } - /// } - /// } - /// } - /// - ///

- /// The attendant XML configuration for the above classes would be... - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: CustomConverterConfigurer.cs,v 1.14 2007/05/11 02:32:14 markpollack Exp $ - /// - /// - /// - [Serializable] - public class CustomConverterConfigurer : AbstractConfigurer - { - private IDictionary _customConverters; - - /// - /// The custom converters to register. - /// - /// - ///

- /// The uses the type name - /// of the class that requires conversion as the key, and an - /// instance of the - /// that will effect - /// the conversion. Alternatively, the actual - /// of the class that requires conversion - /// can be used as the key. - ///

- ///
- /// - ///

- /// - /// IDictionary converters = new Hashtable(); - /// converters.Add( "System.Date", new MyCustomDateConverter() ); - /// // a System.Type instance can also be used as the key... - /// converters.Add( typeof(Color), new MyCustomRBGColorConverter() ); - /// - ///

- ///
- public IDictionary CustomConverters - { - set { this._customConverters = value; } - } - - /// - /// Registers any custom converters with the supplied - /// . - /// - /// - /// The object factory to register the converters with. - /// - /// - /// In case of errors. - /// - public override void PostProcessObjectFactory( - IConfigurableListableObjectFactory factory) - { - if (_customConverters != null) - { - foreach (DictionaryEntry entry in _customConverters) - { - Type requiredType = ResolveRequiredType(entry.Key, "key", "custom type converter"); - TypeConverter converter = ResolveConverter(entry.Value); - factory.RegisterCustomConverter(requiredType, converter); - } - } - } - - /// - /// Resolves the supplied into a - /// instance. - /// - /// - /// The object that is to be resolved into a - /// instance. - /// - /// - /// A resolved instance. - /// - /// - /// If the supplied is , - /// or the supplied cannot be resolved. - /// - protected virtual TypeConverter ResolveConverter(object value) - { - TypeConverter converter = value as TypeConverter; - if (converter == null) - { - throw new ObjectInitializationException( - "Mapped value for custom converter is not a " + - "[System.ComponentModel.TypeConverter] instance."); - } - return converter; - } - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using Spring.Core; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// + /// implementation that allows for convenient registration of custom + /// s. + /// + /// + /// + /// The use of this class is typically not required; the .NET + /// mechanism of associating a + /// with a + /// via the use of the + /// is the + /// recommended (and standard) way. This class primarily exists to cover + /// those cases where third party classes to which one does not have the + /// source need to be exposed to the type conversion mechanism. + /// + ///

+ /// Because the + /// + /// class implements the + /// + /// interface, instances of this class that have been exposed in the + /// scope of an + /// will + /// automatically be picked up by the application context and made + /// available to the IoC container whenever type conversion is required. If + /// one is using a + /// + /// object definition within the scope of an + /// , no such automatic + /// pickup of the + /// + /// is performed (custom converters will have to be added manually using the + /// + /// method). For most application scenarios, one will get better + /// mileage using the + /// abstraction. + ///

+ ///
+ /// + ///

+ /// The following examples all assume XML based configuration, and use + /// inner object definitions to define the custom + /// objects (nominally to + /// avoid polluting the object name space, but also because the + /// configuration simply reads better that way). + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// The following example illustrates a complete (albeit naieve) use case + /// for this class, including a custom + /// implementation, said + /// converters domain class, and the XML configuration that hooks the + /// converter in place and makes it available to a Spring.NET container for + /// use during object resolution. + ///

+ ///

+ /// The domain class is a simple data-only object that contains the data + /// required to send an email message (such as the host and user account + /// name). A developer would prefer to use a string of the form + /// UserName=administrator,Password=r1l0k1l3y,Host=localhost to + /// configure the mail settings and just let the container take care of the + /// conversion. + ///

+ /// + /// namespace ExampleNamespace + /// { + /// public sealed class MailSettings + /// { + /// private string _userName; + /// private string _password; + /// private string _host; + /// + /// public string Host + /// { + /// get { return _host; } + /// set { _host = value; } + /// } + /// + /// public string UserName + /// { + /// get { return _userName; } + /// set { _userName = value; } + /// } + /// + /// public string Password + /// { + /// get { return _password; } + /// set { _password = value; } + /// } + /// } + /// + /// public sealed class MailSettingsConverter : TypeConverter + /// { + /// public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + /// { + /// if (typeof (string) == sourceType) + /// { + /// return true; + /// } + /// return base.CanConvertFrom(context, sourceType); + /// } + /// + /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + /// { + /// string text = value as string; + /// if(text != null) + /// { + /// MailSettings mailSettings = new MailSettings(); + /// string[] tokens = text.Split(','); + /// for (int i = 0; i < tokens.Length; ++i) + /// { + /// string token = tokens[i]; + /// string[] settings = token.Split('='); + /// typeof(MailSettings).GetProperty(settings[0]) + /// .SetValue(mailSettings, settings[1], null); + /// } + /// return mailSettings; + /// } + /// return base.ConvertFrom(context, culture, value); + /// } + /// } + /// + /// // a very naieve class that uses the MailSettings class... + /// public sealed class ExceptionLogger + /// { + /// private MailSettings _mailSettings; + /// + /// public MailSettings MailSettings { + /// { + /// set { _mailSettings = value; } + /// } + /// + /// public void Log(object value) + /// { + /// Exception ex = value as Exception; + /// if(ex != null) + /// { + /// // use _mailSettings instance... + /// } + /// } + /// } + /// } + /// + ///

+ /// The attendant XML configuration for the above classes would be... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Juergen Hoeller + /// Simon White (.NET) + /// + /// + /// + [Serializable] + public class CustomConverterConfigurer : AbstractConfigurer + { + private IDictionary _customConverters; + + /// + /// The custom converters to register. + /// + /// + ///

+ /// The uses the type name + /// of the class that requires conversion as the key, and an + /// instance of the + /// that will effect + /// the conversion. Alternatively, the actual + /// of the class that requires conversion + /// can be used as the key. + ///

+ ///
+ /// + ///

+ /// + /// IDictionary converters = new Hashtable(); + /// converters.Add( "System.Date", new MyCustomDateConverter() ); + /// // a System.Type instance can also be used as the key... + /// converters.Add( typeof(Color), new MyCustomRBGColorConverter() ); + /// + ///

+ ///
+ public IDictionary CustomConverters + { + set { this._customConverters = value; } + } + + /// + /// Registers any custom converters with the supplied + /// . + /// + /// + /// The object factory to register the converters with. + /// + /// + /// In case of errors. + /// + public override void PostProcessObjectFactory( + IConfigurableListableObjectFactory factory) + { + if (_customConverters != null) + { + foreach (DictionaryEntry entry in _customConverters) + { + Type requiredType = ResolveRequiredType(entry.Key, "key", "custom type converter"); + TypeConverter converter = ResolveConverter(entry.Value); + factory.RegisterCustomConverter(requiredType, converter); + } + } + } + + /// + /// Resolves the supplied into a + /// instance. + /// + /// + /// The object that is to be resolved into a + /// instance. + /// + /// + /// A resolved instance. + /// + /// + /// If the supplied is , + /// or the supplied cannot be resolved. + /// + protected virtual TypeConverter ResolveConverter(object value) + { + TypeConverter converter = value as TypeConverter; + if (converter == null) + { + throw new ObjectInitializationException( + "Mapped value for custom converter is not a " + + "[System.ComponentModel.TypeConverter] instance."); + } + return converter; + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/DelegateFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/DelegateFactoryObject.cs index 7f6d7627..46b51d73 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/DelegateFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/DelegateFactoryObject.cs @@ -1,179 +1,178 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// implementation that - /// creates delegates. - /// - /// - ///

- /// Supports the creation of s for both - /// instance and methods. - ///

- ///
- /// Rick Evans - /// $Id: DelegateFactoryObject.cs,v 1.6 2007/03/16 04:01:35 aseovic Exp $ - [Serializable] - public class DelegateFactoryObject : AbstractFactoryObject - { - /// - /// Callback method called once all factory properties have been set. - /// - /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - /// - public override void AfterPropertiesSet() - { - if (DelegateType == null) - { - throw new ArgumentException( - "The 'DelegateType' property is required."); - } - if (!typeof (Delegate).IsAssignableFrom(DelegateType)) - { - throw new ArgumentException( - "The 'DelegateType' property must (obviously) be a Type derived from [System.Delegate]."); - } - if (TargetType == null && TargetObject == null) - { - throw new ArgumentException( - "Exactly one of either the 'TargetType' or 'TargetObject' properties is required."); - } - if (TargetType != null && TargetObject != null) - { - throw new ArgumentException( - "Exactly one of either the 'TargetType' or 'TargetObject' properties is required (not both)."); - } - if (StringUtils.IsNullOrEmpty(MethodName)) - { - throw new ArgumentException( - "The 'MethodName' property is required."); - } - base.AfterPropertiesSet(); - } - - /// - /// Creates the delegate. - /// - /// - /// If an exception occured during object creation. - /// - /// The object returned by this factory. - /// - protected override object CreateInstance() - { - Delegate instance = null; - if (TargetType != null) - { - instance = Delegate.CreateDelegate(DelegateType, TargetType, MethodName); - } - else - { - instance = Delegate.CreateDelegate(DelegateType, TargetObject, MethodName); - } - return instance; - } - - #region Properties - - /// - /// The of - /// created by this factory. - /// - /// - ///

- /// Returns the - /// if accessed prior to the method - /// being called. - ///

- ///
- public override Type ObjectType - { - get - { - return (DelegateType != null) - ? DelegateType - : typeof (Delegate); - } - } - - /// - /// The of the - /// created by this factory. - /// - public Type DelegateType - { - get { return _delegateType; } - set { _delegateType = value; } - } - - /// - /// The name of the method that is to be invoked by the created - /// delegate. - /// - public string MethodName - { - get { return _methodName; } - set { _methodName = value; } - } - - /// - /// The target if the - /// refers to a method. - /// - public Type TargetType - { - get { return _targetType; } - set { _targetType = value; } - } - - /// - /// The target object if the - /// refers to an instance method. - /// - public object TargetObject - { - get { return _targetObject; } - set { _targetObject = value; } - } - - #endregion - - #region Fields - - private Type _delegateType; - private string _methodName; - private Type _targetType; - private object _targetObject; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// implementation that + /// creates delegates. + /// + /// + ///

+ /// Supports the creation of s for both + /// instance and methods. + ///

+ ///
+ /// Rick Evans + [Serializable] + public class DelegateFactoryObject : AbstractFactoryObject + { + /// + /// Callback method called once all factory properties have been set. + /// + /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + /// + public override void AfterPropertiesSet() + { + if (DelegateType == null) + { + throw new ArgumentException( + "The 'DelegateType' property is required."); + } + if (!typeof (Delegate).IsAssignableFrom(DelegateType)) + { + throw new ArgumentException( + "The 'DelegateType' property must (obviously) be a Type derived from [System.Delegate]."); + } + if (TargetType == null && TargetObject == null) + { + throw new ArgumentException( + "Exactly one of either the 'TargetType' or 'TargetObject' properties is required."); + } + if (TargetType != null && TargetObject != null) + { + throw new ArgumentException( + "Exactly one of either the 'TargetType' or 'TargetObject' properties is required (not both)."); + } + if (StringUtils.IsNullOrEmpty(MethodName)) + { + throw new ArgumentException( + "The 'MethodName' property is required."); + } + base.AfterPropertiesSet(); + } + + /// + /// Creates the delegate. + /// + /// + /// If an exception occured during object creation. + /// + /// The object returned by this factory. + /// + protected override object CreateInstance() + { + Delegate instance = null; + if (TargetType != null) + { + instance = Delegate.CreateDelegate(DelegateType, TargetType, MethodName); + } + else + { + instance = Delegate.CreateDelegate(DelegateType, TargetObject, MethodName); + } + return instance; + } + + #region Properties + + /// + /// The of + /// created by this factory. + /// + /// + ///

+ /// Returns the + /// if accessed prior to the method + /// being called. + ///

+ ///
+ public override Type ObjectType + { + get + { + return (DelegateType != null) + ? DelegateType + : typeof (Delegate); + } + } + + /// + /// The of the + /// created by this factory. + /// + public Type DelegateType + { + get { return _delegateType; } + set { _delegateType = value; } + } + + /// + /// The name of the method that is to be invoked by the created + /// delegate. + /// + public string MethodName + { + get { return _methodName; } + set { _methodName = value; } + } + + /// + /// The target if the + /// refers to a method. + /// + public Type TargetType + { + get { return _targetType; } + set { _targetType = value; } + } + + /// + /// The target object if the + /// refers to an instance method. + /// + public object TargetObject + { + get { return _targetObject; } + set { _targetObject = value; } + } + + #endregion + + #region Fields + + private Type _delegateType; + private string _methodName; + private Type _targetType; + private object _targetObject; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/DictionaryFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/DictionaryFactoryObject.cs index b427b9d0..e3ef1206 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/DictionaryFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/DictionaryFactoryObject.cs @@ -1,132 +1,131 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Globalization; -using Spring.Core; -using Spring.Util; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Simple factory for shared instances. - /// - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: DictionaryFactoryObject.cs,v 1.7 2007/07/31 03:47:39 markpollack Exp $ - [Serializable] - public class DictionaryFactoryObject : AbstractFactoryObject - { - private IDictionary _sourceDictionary; - private Type _targetDictionaryType = typeof (Hashtable); - - /// - /// Set the source . - /// - /// - ///

- /// This value will be used to populate the - /// returned by this factory. - ///

- ///
- public IDictionary SourceDictionary - { - set { this._sourceDictionary = value; } - } - - /// - /// Set the of the - /// implementation to use. - /// - /// - ///

- /// The default is the . - ///

- ///
- /// - /// If the value is . - /// - /// - /// If the value is an . - /// - /// - /// If the value is an interface. - /// - public Type TargetDictionaryType - { - set - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!typeof (IDictionary).IsAssignableFrom(value)) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetDictionaryType property must implement the '{0}' interface.", - ObjectType.FullName)); - } - if (value.IsInterface) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetDictionaryType property cannot be an interface; it must be a concrete class that implements the '{0}' interface.", - ObjectType.FullName)); - } - if (value.IsAbstract) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetDictionaryType property cannot be abstract (MustInherit in VisualBasic.NET); it must be a concrete class that implements the '{0}' interface.", - ObjectType.FullName)); - } - this._targetDictionaryType = value; - } - } - - /// - /// The of objects created by this factory. - /// - /// - /// Always returns the . - /// - public override Type ObjectType - { - get { return typeof (IDictionary); } - } - - /// - /// Constructs a new instance of the target dictionary. - /// - /// The new instance. - protected override object CreateInstance() - { - if (this._sourceDictionary == null) - { - throw new ArgumentException("The 'SourceDictionary' property cannot be null (Nothing in Visual Basic.NET)."); - } - IDictionary result = (IDictionary) ObjectUtils.InstantiateType(this._targetDictionaryType); - foreach (DictionaryEntry de in _sourceDictionary) - { - result[de.Key] = de.Value; - } - return result; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Globalization; +using Spring.Core; +using Spring.Util; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Simple factory for shared instances. + /// + /// Juergen Hoeller + /// Simon White (.NET) + [Serializable] + public class DictionaryFactoryObject : AbstractFactoryObject + { + private IDictionary _sourceDictionary; + private Type _targetDictionaryType = typeof (Hashtable); + + /// + /// Set the source . + /// + /// + ///

+ /// This value will be used to populate the + /// returned by this factory. + ///

+ ///
+ public IDictionary SourceDictionary + { + set { this._sourceDictionary = value; } + } + + /// + /// Set the of the + /// implementation to use. + /// + /// + ///

+ /// The default is the . + ///

+ ///
+ /// + /// If the value is . + /// + /// + /// If the value is an . + /// + /// + /// If the value is an interface. + /// + public Type TargetDictionaryType + { + set + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!typeof (IDictionary).IsAssignableFrom(value)) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetDictionaryType property must implement the '{0}' interface.", + ObjectType.FullName)); + } + if (value.IsInterface) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetDictionaryType property cannot be an interface; it must be a concrete class that implements the '{0}' interface.", + ObjectType.FullName)); + } + if (value.IsAbstract) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetDictionaryType property cannot be abstract (MustInherit in VisualBasic.NET); it must be a concrete class that implements the '{0}' interface.", + ObjectType.FullName)); + } + this._targetDictionaryType = value; + } + } + + /// + /// The of objects created by this factory. + /// + /// + /// Always returns the . + /// + public override Type ObjectType + { + get { return typeof (IDictionary); } + } + + /// + /// Constructs a new instance of the target dictionary. + /// + /// The new instance. + protected override object CreateInstance() + { + if (this._sourceDictionary == null) + { + throw new ArgumentException("The 'SourceDictionary' property cannot be null (Nothing in Visual Basic.NET)."); + } + IDictionary result = (IDictionary) ObjectUtils.InstantiateType(this._targetDictionaryType); + foreach (DictionaryEntry de in _sourceDictionary) + { + result[de.Key] = de.Value; + } + return result; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableMode.cs b/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableMode.cs index eb81471c..d48a6079 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableMode.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableMode.cs @@ -1,52 +1,51 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Specifies how instances of the - /// - /// class must apply environment variables when replacing values. - /// - /// Mark Pollack - /// $Id: EnvironmentVariableMode.cs,v 1.6 2007/03/16 04:01:35 aseovic Exp $ - [Serializable] - public enum EnvironmentVariableMode - { - /// - /// Never replace environment variables. - /// - Never = 1, - - /// - /// If properties are not specified via a resource, - /// then resolve using environment variables. - /// - Fallback = 2, - - /// - /// Apply environment variables first before applying properties from a - /// resource. - /// - Override = 3 - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Specifies how instances of the + /// + /// class must apply environment variables when replacing values. + /// + /// Mark Pollack + [Serializable] + public enum EnvironmentVariableMode + { + /// + /// Never replace environment variables. + /// + Never = 1, + + /// + /// If properties are not specified via a resource, + /// then resolve using environment variables. + /// + Fallback = 2, + + /// + /// Apply environment variables first before applying properties from a + /// resource. + /// + Override = 3 + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableSource.cs index dcf59a82..b94170a0 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/EnvironmentVariableSource.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name against environment variables. - /// - /// Aleksandar Seovic - /// $Id: EnvironmentVariableSource.cs,v 1.3 2007/08/02 22:18:32 markpollack Exp $ - [Serializable] - public class EnvironmentVariableSource : IVariableSource - { - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - return Environment.GetEnvironmentVariable(name); - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name against environment variables. + /// + /// Aleksandar Seovic + [Serializable] + public class EnvironmentVariableSource : IVariableSource + { + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + return Environment.GetEnvironmentVariable(name); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/EventValues.cs b/src/Spring/Spring.Core/Objects/Factory/Config/EventValues.cs index 9555be8f..d036491a 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/EventValues.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/EventValues.cs @@ -1,151 +1,150 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Holder for event handler values for an object. - /// - /// Rick Evans (.NET) - /// $Id: EventValues.cs,v 1.8 2007/03/16 04:01:38 aseovic Exp $ - [Serializable] - public class EventValues - { - #region Constants - /// - /// The empty array of s. - /// - private static readonly IEventHandlerValue [] EmptyHandlers - = new IEventHandlerValue [] {}; - #endregion - - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public EventValues() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// to be used to populate this instance. - /// - public EventValues(EventValues other) - { - AddAll (other); - } - #endregion - - #region Properties - /// - /// The mapping of event names to an - /// of - /// s. - /// - protected IDictionary EventHandlers - { - get - { - return _eventHandlers; - } - } - - /// - /// Gets the of events - /// that have handlers associated with them. - /// - public ICollection Events - { - get - { - return EventHandlers.Keys; - } - } - - /// - /// Gets the of - /// s for the supplied - /// event name. - /// - public ICollection this [string eventName] - { - get - { - return EventHandlers.Contains (eventName) ? - EventHandlers [eventName] as ICollection : - EventValues.EmptyHandlers; - } - } - #endregion - - #region Methods - /// - /// Copy all given argument values into this object. - /// - /// - /// The - /// to be used to populate this instance. - /// - public void AddAll (EventValues other) - { - if (other != null) - { - foreach (IList handlers in other.EventHandlers.Values) - { - foreach (IEventHandlerValue handler in handlers) - { - AddHandler (handler); - } - } - } - } - - /// - /// Adds the supplied handler to the collection of event handlers. - /// - /// The handler to be added. - public void AddHandler (IEventHandlerValue handler) - { - IList handlers = EventHandlers [handler.EventName] as IList; - if (handlers == null) - { - handlers = new ArrayList (); - EventHandlers [handler.EventName] = handlers; - } - handlers.Add (handler); - } - #endregion - - #region Fields - private IDictionary _eventHandlers = new Hashtable(); - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Holder for event handler values for an object. + /// + /// Rick Evans (.NET) + [Serializable] + public class EventValues + { + #region Constants + /// + /// The empty array of s. + /// + private static readonly IEventHandlerValue [] EmptyHandlers + = new IEventHandlerValue [] {}; + #endregion + + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public EventValues() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// to be used to populate this instance. + /// + public EventValues(EventValues other) + { + AddAll (other); + } + #endregion + + #region Properties + /// + /// The mapping of event names to an + /// of + /// s. + /// + protected IDictionary EventHandlers + { + get + { + return _eventHandlers; + } + } + + /// + /// Gets the of events + /// that have handlers associated with them. + /// + public ICollection Events + { + get + { + return EventHandlers.Keys; + } + } + + /// + /// Gets the of + /// s for the supplied + /// event name. + /// + public ICollection this [string eventName] + { + get + { + return EventHandlers.Contains (eventName) ? + EventHandlers [eventName] as ICollection : + EventValues.EmptyHandlers; + } + } + #endregion + + #region Methods + /// + /// Copy all given argument values into this object. + /// + /// + /// The + /// to be used to populate this instance. + /// + public void AddAll (EventValues other) + { + if (other != null) + { + foreach (IList handlers in other.EventHandlers.Values) + { + foreach (IEventHandlerValue handler in handlers) + { + AddHandler (handler); + } + } + } + } + + /// + /// Adds the supplied handler to the collection of event handlers. + /// + /// The handler to be added. + public void AddHandler (IEventHandlerValue handler) + { + IList handlers = EventHandlers [handler.EventName] as IList; + if (handlers == null) + { + handlers = new ArrayList (); + EventHandlers [handler.EventName] = handlers; + } + handlers.Add (handler); + } + #endregion + + #region Fields + private IDictionary _eventHandlers = new Hashtable(); + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ExpressionHolder.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ExpressionHolder.cs index 2ae29e8f..46102f54 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ExpressionHolder.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ExpressionHolder.cs @@ -1,110 +1,109 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Spring.Expressions; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Immutable placeholder class used for the value of a - /// object when it's a reference - /// to a Spring that should be evaluated at runtime. - /// - /// Aleksandar Seovic - /// $Id: ExpressionHolder.cs,v 1.5 2007/08/21 19:28:33 markpollack Exp $ - [Serializable] - public class ExpressionHolder - { - #region Fields - - private IExpression expression; - private string expressionString; - private MutablePropertyValues properties; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// The expression to resolve. - public ExpressionHolder(string expression) - { - expressionString = expression; - this.expression = Spring.Expressions.Expression.Parse(expression); - } - - #endregion - - #region Properties - - /// - /// Gets or sets the expression string. Setting the expression string will cause - /// the expression to be parsed. - /// - /// The expression string. - public string ExpressionString - { - get { return expressionString; } - } - - /// - /// Return the expression. - /// - public IExpression Expression - { - get { return expression; } - } - - /// - /// Properties for this expression node. - /// - public MutablePropertyValues Properties - { - get { return properties; } - set { properties = value; } - } - - #endregion - - #region Methods - - /// - /// Returns a string representation of this instance. - /// - /// A string representation of this instance. - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, "<{0}>", expressionString); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Spring.Expressions; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Immutable placeholder class used for the value of a + /// object when it's a reference + /// to a Spring that should be evaluated at runtime. + /// + /// Aleksandar Seovic + [Serializable] + public class ExpressionHolder + { + #region Fields + + private IExpression expression; + private string expressionString; + private MutablePropertyValues properties; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// The expression to resolve. + public ExpressionHolder(string expression) + { + expressionString = expression; + this.expression = Spring.Expressions.Expression.Parse(expression); + } + + #endregion + + #region Properties + + /// + /// Gets or sets the expression string. Setting the expression string will cause + /// the expression to be parsed. + /// + /// The expression string. + public string ExpressionString + { + get { return expressionString; } + } + + /// + /// Return the expression. + /// + public IExpression Expression + { + get { return expression; } + } + + /// + /// Properties for this expression node. + /// + public MutablePropertyValues Properties + { + get { return properties; } + set { properties = value; } + } + + #endregion + + #region Methods + + /// + /// Returns a string representation of this instance. + /// + /// A string representation of this instance. + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, "<{0}>", expressionString); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/FieldRetrievingFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/FieldRetrievingFactoryObject.cs index 645cc7a8..300a476b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/FieldRetrievingFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/FieldRetrievingFactoryObject.cs @@ -1,311 +1,310 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; -using System.Text; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// implementation that - /// retrieves a static or non-static public field value. - /// - /// - ///

- /// Typically used for retrieving public constants. - ///

- ///
- /// - ///

- /// The following example retrieves the field value... - ///

- /// - /// - /// - /// - /// - /// - ///

- /// The previous example could also have been written using the convenience - /// - /// property, like so... - ///

- /// - /// - /// - /// - /// - ///

- /// This class also implements the - /// interface - /// (). - /// If the id (or name) of one's - /// - /// object definition is set to the - /// of the field to be retrieved, then the id (or - /// name) of one's object definition will be used for the name of the - /// field lookup. See below for an example of this - /// concise style of definition. - ///

- /// - /// - /// - /// - /// - /// - /// - ///

- /// The usage for retrieving instance fields is similar. No example is shown - /// because public instance fields are generally bad practice; but if - /// you have some legacy code that exposes public instance fields, or if you - /// just really like coding public instance fields, then you can use this - /// implementation to - /// retrieve such field values. - ///

- /// - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: FieldRetrievingFactoryObject.cs,v 1.8 2007/07/31 18:16:49 bbaia Exp $ - [Serializable] - public class FieldRetrievingFactoryObject : IFactoryObject, IInitializingObject, IObjectNameAware - { - private string targetField; - private object targetObject; - private Type targetType; - private FieldInfo field; - private string objectName; - private string staticField; - - /// - /// The of the - /// field to be retrieved. - /// - public string StaticField - { - set { this.staticField = value; } - } - - /// - /// Set the name of the object in the object factory that created this object. - /// - /// - /// The name of the object in the factory. - /// - /// - ///

- /// In the context of the - /// - /// class, the - /// - /// value will be interepreted as the value of the - /// - /// property if no value has been explicitly assigned to the - /// - /// property. This allows for concise object definitions with just an id or name; - /// see the class documentation for - /// - /// for an example of this style of usage. - ///

- ///
- public string ObjectName - { - set { this.objectName = value; } - } - - /// - /// The name of the field the value of which is to be retrieved. - /// - /// - ///

- /// If the - /// - /// has been set (and is not ), then the value of this property - /// refers to an instance field name; it otherwise refers to a - /// field name. - ///

- ///
- public string TargetField - { - get { return targetField; } - set { targetField = value; } - } - - /// - /// The object instance on which the field is defined. - /// - public object TargetObject - { - get { return targetObject; } - set { targetObject = value; } - } - - /// - /// The on which the field is defined. - /// - public Type TargetType - { - get { return targetType; } - set { targetType = value; } - } - - /// - /// The of object that this - /// creates, or - /// if not known in advance. - /// - public Type ObjectType - { - get { return (this.field == null) ? null : this.field.FieldType; } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - public bool IsSingleton - { - get { return true; } - } - - /// - /// Invoked by an - /// after it has set all object properties supplied - /// (and satisfied - /// and ApplicationContextAware). - /// - /// - ///

- /// This method allows the object instance to perform initialization only - /// possible when all object properties have been set and to throw an - /// exception in the event of misconfiguration. - ///

- ///
- /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - public void AfterPropertiesSet() - { - if (TargetType != null && TargetObject != null) - { - throw new ArgumentException( - "Only one of the TargetType or TargetObject properties can be set, not both."); - } - if (TargetType == null && TargetObject == null) - { - if (TargetField != null) - { - throw new ArgumentException( - "Specify the TargetType or TargetObject property in combination with the TargetField property."); - } - - // if no other property specified, use the object name for the static field expression... - if (StringUtils.IsNullOrEmpty(this.staticField)) - { - this.staticField = this.objectName; - } - ParseAndSetFromStaticFieldValue(); - } - if (TargetField == null) - { - throw new ArgumentException("The TargetField property is required."); - } - BindingFlags fieldFlags = BindingFlags.Public | BindingFlags.IgnoreCase; - if (TargetObject == null) - { - // a static field... - fieldFlags |= BindingFlags.Static; - } - else - { - // an instance field... - fieldFlags |= BindingFlags.Instance; - TargetType = TargetObject.GetType(); - } - this.field = targetType.GetField(TargetField, fieldFlags); - if (this.field == null) - { - throw new ObjectDefinitionStoreException( - string.Format( - CultureInfo.InvariantCulture, - "No such field '{0}' on [{1}].", TargetField, - TargetObject == null ? TargetType : TargetObject)); - } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - /// - public object GetObject() - { - if (TargetObject != null) - { - return this.field.GetValue(TargetObject); - } - else - { - return this.field.GetValue(null); - } - } - - private void ParseAndSetFromStaticFieldValue() - { - TypeAssemblyHolder info = new TypeAssemblyHolder(this.staticField); - // the info.TypeName should now contains the Type name, followed by a - // period, followed by the name of the field - int lastDotIndex = info.TypeName.LastIndexOf('.'); - if (lastDotIndex == -1 - || lastDotIndex == info.TypeName.Length) - { - throw new ArgumentException( - "The value passed to the StaticField property must be a fully " + - "qualified Type plus field name: " + - "e.g. 'Example.MyExampleClass.MyField, MyAssembly'"); - } - string typeName = info.TypeName.Substring(0, lastDotIndex); - string fieldName = info.TypeName.Substring(lastDotIndex + 1); - StringBuilder buffer = new StringBuilder(typeName); - if (info.IsAssemblyQualified) - { - buffer.Append(TypeAssemblyHolder.TypeAssemblySeparator); - buffer.Append(info.AssemblyName); - } - TargetType = TypeResolutionUtils.ResolveType(buffer.ToString()); - TargetField = fieldName; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; +using System.Text; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// implementation that + /// retrieves a static or non-static public field value. + /// + /// + ///

+ /// Typically used for retrieving public constants. + ///

+ ///
+ /// + ///

+ /// The following example retrieves the field value... + ///

+ /// + /// + /// + /// + /// + /// + ///

+ /// The previous example could also have been written using the convenience + /// + /// property, like so... + ///

+ /// + /// + /// + /// + /// + ///

+ /// This class also implements the + /// interface + /// (). + /// If the id (or name) of one's + /// + /// object definition is set to the + /// of the field to be retrieved, then the id (or + /// name) of one's object definition will be used for the name of the + /// field lookup. See below for an example of this + /// concise style of definition. + ///

+ /// + /// + /// + /// + /// + /// + /// + ///

+ /// The usage for retrieving instance fields is similar. No example is shown + /// because public instance fields are generally bad practice; but if + /// you have some legacy code that exposes public instance fields, or if you + /// just really like coding public instance fields, then you can use this + /// implementation to + /// retrieve such field values. + ///

+ /// + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class FieldRetrievingFactoryObject : IFactoryObject, IInitializingObject, IObjectNameAware + { + private string targetField; + private object targetObject; + private Type targetType; + private FieldInfo field; + private string objectName; + private string staticField; + + /// + /// The of the + /// field to be retrieved. + /// + public string StaticField + { + set { this.staticField = value; } + } + + /// + /// Set the name of the object in the object factory that created this object. + /// + /// + /// The name of the object in the factory. + /// + /// + ///

+ /// In the context of the + /// + /// class, the + /// + /// value will be interepreted as the value of the + /// + /// property if no value has been explicitly assigned to the + /// + /// property. This allows for concise object definitions with just an id or name; + /// see the class documentation for + /// + /// for an example of this style of usage. + ///

+ ///
+ public string ObjectName + { + set { this.objectName = value; } + } + + /// + /// The name of the field the value of which is to be retrieved. + /// + /// + ///

+ /// If the + /// + /// has been set (and is not ), then the value of this property + /// refers to an instance field name; it otherwise refers to a + /// field name. + ///

+ ///
+ public string TargetField + { + get { return targetField; } + set { targetField = value; } + } + + /// + /// The object instance on which the field is defined. + /// + public object TargetObject + { + get { return targetObject; } + set { targetObject = value; } + } + + /// + /// The on which the field is defined. + /// + public Type TargetType + { + get { return targetType; } + set { targetType = value; } + } + + /// + /// The of object that this + /// creates, or + /// if not known in advance. + /// + public Type ObjectType + { + get { return (this.field == null) ? null : this.field.FieldType; } + } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + public bool IsSingleton + { + get { return true; } + } + + /// + /// Invoked by an + /// after it has set all object properties supplied + /// (and satisfied + /// and ApplicationContextAware). + /// + /// + ///

+ /// This method allows the object instance to perform initialization only + /// possible when all object properties have been set and to throw an + /// exception in the event of misconfiguration. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + public void AfterPropertiesSet() + { + if (TargetType != null && TargetObject != null) + { + throw new ArgumentException( + "Only one of the TargetType or TargetObject properties can be set, not both."); + } + if (TargetType == null && TargetObject == null) + { + if (TargetField != null) + { + throw new ArgumentException( + "Specify the TargetType or TargetObject property in combination with the TargetField property."); + } + + // if no other property specified, use the object name for the static field expression... + if (StringUtils.IsNullOrEmpty(this.staticField)) + { + this.staticField = this.objectName; + } + ParseAndSetFromStaticFieldValue(); + } + if (TargetField == null) + { + throw new ArgumentException("The TargetField property is required."); + } + BindingFlags fieldFlags = BindingFlags.Public | BindingFlags.IgnoreCase; + if (TargetObject == null) + { + // a static field... + fieldFlags |= BindingFlags.Static; + } + else + { + // an instance field... + fieldFlags |= BindingFlags.Instance; + TargetType = TargetObject.GetType(); + } + this.field = targetType.GetField(TargetField, fieldFlags); + if (this.field == null) + { + throw new ObjectDefinitionStoreException( + string.Format( + CultureInfo.InvariantCulture, + "No such field '{0}' on [{1}].", TargetField, + TargetObject == null ? TargetType : TargetObject)); + } + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + /// + public object GetObject() + { + if (TargetObject != null) + { + return this.field.GetValue(TargetObject); + } + else + { + return this.field.GetValue(null); + } + } + + private void ParseAndSetFromStaticFieldValue() + { + TypeAssemblyHolder info = new TypeAssemblyHolder(this.staticField); + // the info.TypeName should now contains the Type name, followed by a + // period, followed by the name of the field + int lastDotIndex = info.TypeName.LastIndexOf('.'); + if (lastDotIndex == -1 + || lastDotIndex == info.TypeName.Length) + { + throw new ArgumentException( + "The value passed to the StaticField property must be a fully " + + "qualified Type plus field name: " + + "e.g. 'Example.MyExampleClass.MyField, MyAssembly'"); + } + string typeName = info.TypeName.Substring(0, lastDotIndex); + string fieldName = info.TypeName.Substring(lastDotIndex + 1); + StringBuilder buffer = new StringBuilder(typeName); + if (info.IsAssemblyQualified) + { + buffer.Append(TypeAssemblyHolder.TypeAssemblySeparator); + buffer.Append(info.AssemblyName); + } + TargetType = TypeResolutionUtils.ResolveType(buffer.ToString()); + TargetField = fieldName; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IAutowireCapableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IAutowireCapableObjectFactory.cs index 74924aff..651e7f69 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IAutowireCapableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IAutowireCapableObjectFactory.cs @@ -1,134 +1,134 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Extension of the - /// interface to be implemented by object factories that are capable of - /// autowiring and expose this functionality for existing object instances. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - public interface IAutowireCapableObjectFactory : IObjectFactory - { - /// - /// Create a new object instance of the given class with the specified - /// autowire strategy. - /// - /// - /// The of the object to instantiate. - /// - /// - /// The desired autowiring mode. - /// - /// - /// Whether to perform a dependency check for objects (not applicable to - /// autowiring a constructor, thus ignored there). - /// - /// The new object instance. - /// - /// If the wiring fails. - /// - /// - object Autowire ( - Type type, AutoWiringMode autowireMode, bool dependencyCheck); - - /// - /// Autowire the object properties of the given object instance by name or - /// . - /// - /// - /// The existing object instance. - /// - /// - /// The desired autowiring mode. - /// - /// - /// Whether to perform a dependency check for the object. - /// - /// - /// If the wiring fails. - /// - /// - void AutowireObjectProperties ( - object instance, AutoWiringMode autowireMode, bool dependencyCheck); - - /// - /// Apply s - /// to the given existing object instance, invoking their - /// - /// methods. - /// - /// - ///

- /// The returned object instance may be a wrapper around the original. - ///

- ///
- /// - /// The existing object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// If any post-processing failed. - /// - /// - object ApplyObjectPostProcessorsBeforeInitialization ( - object instance, string name); - - /// - /// Apply s - /// to the given existing object instance, invoking their - /// - /// methods. - /// - /// - ///

- /// The returned object instance may be a wrapper around the original. - ///

- ///
- /// - /// The existing object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// If any post-processing failed. - /// - /// - object ApplyObjectPostProcessorsAfterInitialization ( - object instance, string name); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Extension of the + /// interface to be implemented by object factories that are capable of + /// autowiring and expose this functionality for existing object instances. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IAutowireCapableObjectFactory : IObjectFactory + { + /// + /// Create a new object instance of the given class with the specified + /// autowire strategy. + /// + /// + /// The of the object to instantiate. + /// + /// + /// The desired autowiring mode. + /// + /// + /// Whether to perform a dependency check for objects (not applicable to + /// autowiring a constructor, thus ignored there). + /// + /// The new object instance. + /// + /// If the wiring fails. + /// + /// + object Autowire ( + Type type, AutoWiringMode autowireMode, bool dependencyCheck); + + /// + /// Autowire the object properties of the given object instance by name or + /// . + /// + /// + /// The existing object instance. + /// + /// + /// The desired autowiring mode. + /// + /// + /// Whether to perform a dependency check for the object. + /// + /// + /// If the wiring fails. + /// + /// + void AutowireObjectProperties ( + object instance, AutoWiringMode autowireMode, bool dependencyCheck); + + /// + /// Apply s + /// to the given existing object instance, invoking their + /// + /// methods. + /// + /// + ///

+ /// The returned object instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The existing object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// If any post-processing failed. + /// + /// + object ApplyObjectPostProcessorsBeforeInitialization ( + object instance, string name); + + /// + /// Apply s + /// to the given existing object instance, invoking their + /// + /// methods. + /// + /// + ///

+ /// The returned object instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The existing object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// If any post-processing failed. + /// + /// + object ApplyObjectPostProcessorsAfterInitialization ( + object instance, string name); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableFactoryObject.cs index a84e3e12..faf9d850 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableFactoryObject.cs @@ -1,43 +1,42 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Extension of the interface - /// that injects dependencies into the object managed by the factory. - /// - /// Bruno Baia - /// $Id: IConfigurableFactoryObject.cs,v 1.1 2007/07/29 19:39:27 markpollack Exp $ - public interface IConfigurableFactoryObject : IFactoryObject - { - /// - /// Gets the template object definition that should be used - /// to configure the instance of the object managed by this factory. - /// - IObjectDefinition ProductTemplate { get; } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Extension of the interface + /// that injects dependencies into the object managed by the factory. + /// + /// Bruno Baia + public interface IConfigurableFactoryObject : IFactoryObject + { + /// + /// Gets the template object definition that should be used + /// to configure the instance of the object managed by this factory. + /// + IObjectDefinition ProductTemplate { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableListableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableListableObjectFactory.cs index e0d16c2d..aba03ad5 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableListableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableListableObjectFactory.cs @@ -1,123 +1,123 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// SPI interface to be implemented by most if not all listable object factories. - /// - /// - ///

- /// Allows for framework-internal plug'n'play, e.g. in - /// . - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - public interface IConfigurableListableObjectFactory - : IListableObjectFactory, - IConfigurableObjectFactory, - IAutowireCapableObjectFactory - { - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - IObjectDefinition GetObjectDefinition(string name); - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// Whether to search parent object factories. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - IObjectDefinition GetObjectDefinition(string name, bool includeAncestors); - - - /// - /// Injects dependencies into the supplied instance - /// using the supplied . - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// An object definition that should be used to configure object. - /// - /// - object ConfigureObject(object target, string name, IObjectDefinition definition); - - /// - /// Ensure that all non-lazy-init singletons are instantiated, also - /// considering s. - /// - /// - ///

- /// Typically invoked at the end of factory setup, if desired. - ///

- ///

- /// As this is a startup method, it should destroy already created singletons if - /// it fails, to avoid dangling resources. In other words, after invocation - /// of that method, either all or no singletons at all should be - /// instantiated. - ///

- ///
- /// - /// If one of the singleton objects could not be created. - /// - void PreInstantiateSingletons (); - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// SPI interface to be implemented by most if not all listable object factories. + /// + /// + ///

+ /// Allows for framework-internal plug'n'play, e.g. in + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IConfigurableListableObjectFactory + : IListableObjectFactory, + IConfigurableObjectFactory, + IAutowireCapableObjectFactory + { + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + IObjectDefinition GetObjectDefinition(string name); + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// Whether to search parent object factories. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + IObjectDefinition GetObjectDefinition(string name, bool includeAncestors); + + + /// + /// Injects dependencies into the supplied instance + /// using the supplied . + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// An object definition that should be used to configure object. + /// + /// + object ConfigureObject(object target, string name, IObjectDefinition definition); + + /// + /// Ensure that all non-lazy-init singletons are instantiated, also + /// considering s. + /// + /// + ///

+ /// Typically invoked at the end of factory setup, if desired. + ///

+ ///

+ /// As this is a startup method, it should destroy already created singletons if + /// it fails, to avoid dangling resources. In other words, after invocation + /// of that method, either all or no singletons at all should be + /// instantiated. + ///

+ ///
+ /// + /// If one of the singleton objects could not be created. + /// + void PreInstantiateSingletons (); + + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs index 9ac4faab..f0fedd67 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs @@ -1,235 +1,234 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Configuration interface to be implemented by most if not all object - /// factories. - /// - /// - ///

- /// Provides the means to configure an object factory in addition to the - /// object factory client methods in the - /// interface. - ///

- ///

- /// Allows for framework-internal plug'n'play even when needing access to object - /// factory configuration methods. - ///

- ///

- /// When disposed, it will destroy all cached singletons in this factory. Call - /// when you want to shutdown - /// the factory. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IConfigurableObjectFactory.cs,v 1.14 2007/07/16 21:06:21 markpollack Exp $ - public interface IConfigurableObjectFactory : IHierarchicalObjectFactory - { - /// - /// Set the parent of this object factory. - /// - /// - ///

- /// Note that the parent shouldn't be changed: it should only be set outside - /// a constructor if it isn't available when an object of this class is - /// created. - ///

- ///
- new IObjectFactory ParentObjectFactory { set; } - - /// - /// Ignore the given dependency type for autowiring. - /// - /// - ///

- /// To be invoked during factory configuration. - ///

- ///

- /// This will typically be used for dependencies that are resolved - /// in other ways, like - /// through . - ///

- ///
- /// - /// The to be ignored. - /// - void IgnoreDependencyType(Type type); - - - /// - /// Determines whether the specified object name is currently in creation.. - /// - /// Name of the object. - /// - /// true if the specified object name is currently in creation; otherwise, false. - /// - bool IsCurrentlyInCreation(string objectName); - - /// - /// Add a new - /// that will get applied to objects created by this factory. - /// - /// - ///

- /// To be invoked during factory configuration. - ///

- ///
- /// - /// The - /// to register. - /// - void AddObjectPostProcessor(IObjectPostProcessor processor); - - /// - /// Returns the current number of registered - /// s. - /// - /// - /// The current number of registered - /// s. - /// - int ObjectPostProcessorCount - { - get; - } - - /// - /// Given an object name, create an alias. - /// - /// - ///

- /// This is typically used to support names that are illegal within - /// XML ids (which are used for object names). - ///

- ///

- /// Typically invoked during factory configuration, but can also be - /// used for runtime registration of aliases. Therefore, a factory - /// implementation should synchronize alias access. - ///

- ///
- /// The name of the object. - /// - /// - /// The alias that will behave the same as the object name. - /// - /// - /// If there is no object with the given name. - /// - /// - /// If the alias is already in use. - /// - void RegisterAlias(string name, string theAlias); - - /// - /// Register the given existing object as singleton in the object factory, - /// under the given object name. - /// - /// - ///

- /// Typically invoked during factory configuration, but can also be - /// used for runtime registration of singletons. Therefore, a factory - /// implementation should synchronize singleton access; it will have - /// to do this anyway if it supports lazy initialization of singletons. - ///

- ///
- /// - /// The name of the object. - /// - /// The existing object. - /// - /// If the singleton could not be registered. - /// - void RegisterSingleton(string name, object singleton); - - /// - /// Register the given custom - /// for all properties of the given . - /// - /// - ///

- /// To be invoked during factory configuration. - ///

- ///
- /// - /// The required of the property. - /// - /// - /// The to register. - /// - void RegisterCustomConverter(Type requiredType, TypeConverter converter); - - /// - /// Does this object factory contains a singleton instance with the - /// supplied ? - /// - /// - ///

- /// Only checks already instantiated singletons; does not return - /// for singleton object definitions that have - /// not been instantiated yet. - ///

- ///

- /// The main purpose of this method is to check manually registered - /// singletons (). This - /// method can also be used to check whether a singleton defined by an - /// object definition has already been created. - ///

- ///

- /// To check whether an object factory contains an object definition - /// with a given name, use the - /// - /// method. Calling both - /// - /// and definitively answers - /// the question of whether a specific object factory contains a - /// singleton object with the given name. - ///

- ///

- /// Use the - /// - /// method for general checks as to whether a factory knows about an - /// object with a given name (regrdless of whether the object in - /// question is a manually registed singleton instance or created by - /// an object definition)... this also has the happy bonus of also - /// checking any ancestor factories. - ///

- ///
- /// - /// The name of the (singleton) object to look for. - /// - /// - /// if this object factory contains a singleton - /// instance with the given . - /// - /// - /// - bool ContainsSingleton(string name); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Configuration interface to be implemented by most if not all object + /// factories. + /// + /// + ///

+ /// Provides the means to configure an object factory in addition to the + /// object factory client methods in the + /// interface. + ///

+ ///

+ /// Allows for framework-internal plug'n'play even when needing access to object + /// factory configuration methods. + ///

+ ///

+ /// When disposed, it will destroy all cached singletons in this factory. Call + /// when you want to shutdown + /// the factory. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IConfigurableObjectFactory : IHierarchicalObjectFactory + { + /// + /// Set the parent of this object factory. + /// + /// + ///

+ /// Note that the parent shouldn't be changed: it should only be set outside + /// a constructor if it isn't available when an object of this class is + /// created. + ///

+ ///
+ new IObjectFactory ParentObjectFactory { set; } + + /// + /// Ignore the given dependency type for autowiring. + /// + /// + ///

+ /// To be invoked during factory configuration. + ///

+ ///

+ /// This will typically be used for dependencies that are resolved + /// in other ways, like + /// through . + ///

+ ///
+ /// + /// The to be ignored. + /// + void IgnoreDependencyType(Type type); + + + /// + /// Determines whether the specified object name is currently in creation.. + /// + /// Name of the object. + /// + /// true if the specified object name is currently in creation; otherwise, false. + /// + bool IsCurrentlyInCreation(string objectName); + + /// + /// Add a new + /// that will get applied to objects created by this factory. + /// + /// + ///

+ /// To be invoked during factory configuration. + ///

+ ///
+ /// + /// The + /// to register. + /// + void AddObjectPostProcessor(IObjectPostProcessor processor); + + /// + /// Returns the current number of registered + /// s. + /// + /// + /// The current number of registered + /// s. + /// + int ObjectPostProcessorCount + { + get; + } + + /// + /// Given an object name, create an alias. + /// + /// + ///

+ /// This is typically used to support names that are illegal within + /// XML ids (which are used for object names). + ///

+ ///

+ /// Typically invoked during factory configuration, but can also be + /// used for runtime registration of aliases. Therefore, a factory + /// implementation should synchronize alias access. + ///

+ ///
+ /// The name of the object. + /// + /// + /// The alias that will behave the same as the object name. + /// + /// + /// If there is no object with the given name. + /// + /// + /// If the alias is already in use. + /// + void RegisterAlias(string name, string theAlias); + + /// + /// Register the given existing object as singleton in the object factory, + /// under the given object name. + /// + /// + ///

+ /// Typically invoked during factory configuration, but can also be + /// used for runtime registration of singletons. Therefore, a factory + /// implementation should synchronize singleton access; it will have + /// to do this anyway if it supports lazy initialization of singletons. + ///

+ ///
+ /// + /// The name of the object. + /// + /// The existing object. + /// + /// If the singleton could not be registered. + /// + void RegisterSingleton(string name, object singleton); + + /// + /// Register the given custom + /// for all properties of the given . + /// + /// + ///

+ /// To be invoked during factory configuration. + ///

+ ///
+ /// + /// The required of the property. + /// + /// + /// The to register. + /// + void RegisterCustomConverter(Type requiredType, TypeConverter converter); + + /// + /// Does this object factory contains a singleton instance with the + /// supplied ? + /// + /// + ///

+ /// Only checks already instantiated singletons; does not return + /// for singleton object definitions that have + /// not been instantiated yet. + ///

+ ///

+ /// The main purpose of this method is to check manually registered + /// singletons (). This + /// method can also be used to check whether a singleton defined by an + /// object definition has already been created. + ///

+ ///

+ /// To check whether an object factory contains an object definition + /// with a given name, use the + /// + /// method. Calling both + /// + /// and definitively answers + /// the question of whether a specific object factory contains a + /// singleton object with the given name. + ///

+ ///

+ /// Use the + /// + /// method for general checks as to whether a factory knows about an + /// object with a given name (regrdless of whether the object in + /// question is a manually registed singleton instance or created by + /// an object definition)... this also has the happy bonus of also + /// checking any ancestor factories. + ///

+ ///
+ /// + /// The name of the (singleton) object to look for. + /// + /// + /// if this object factory contains a singleton + /// instance with the given . + /// + /// + /// + bool ContainsSingleton(string name); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IDestructionAwareObjectPostProcessor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IDestructionAwareObjectPostProcessor.cs index 8e72247e..ef7ae3a1 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IDestructionAwareObjectPostProcessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IDestructionAwareObjectPostProcessor.cs @@ -1,56 +1,55 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Subinterface of - /// that adds - /// a before-destruction callback. - /// - /// - /// The typical usage will be to invoke custom destruction callbacks on - /// specific object types, matching corresponding initialization callbacks. - /// - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: IDestructionAwareObjectPostProcessor.cs,v 1.4 2006/04/09 07:18:47 markpollack Exp $ - public interface IDestructionAwareObjectPostProcessor : IObjectPostProcessor - { - /// - /// Apply this - /// to the - /// given new object instance before its destruction. Can invoke custom - /// destruction callbacks. - /// - /// The new object instance. - /// The name of the object. - /// - /// In case of errors. - /// - void PostProcessBeforeDestruction (object instance, string name); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Subinterface of + /// that adds + /// a before-destruction callback. + /// + /// + /// The typical usage will be to invoke custom destruction callbacks on + /// specific object types, matching corresponding initialization callbacks. + /// + /// Juergen Hoeller + /// Simon White (.NET) + public interface IDestructionAwareObjectPostProcessor : IObjectPostProcessor + { + /// + /// Apply this + /// to the + /// given new object instance before its destruction. Can invoke custom + /// destruction callbacks. + /// + /// The new object instance. + /// The name of the object. + /// + /// In case of errors. + /// + void PostProcessBeforeDestruction (object instance, string name); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IInstantiationAwareObjectPostProcessor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IInstantiationAwareObjectPostProcessor.cs index fca758e3..b661cbc1 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IInstantiationAwareObjectPostProcessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IInstantiationAwareObjectPostProcessor.cs @@ -1,125 +1,124 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using Spring.Objects.Factory.Support; - -namespace Spring.Objects.Factory.Config { - - /// - /// Subinterface of - /// - /// that adds a before-instantiation callback. - /// - /// - ///

- /// Typical use cases might include being used to suppress the default - /// instantiation of specific target objects, perhaps in favour of creating - /// proxies with special Spring.Aop.ITargetSources (pooling targets, - /// lazily initializing targets, etc). - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IInstantiationAwareObjectPostProcessor.cs,v 1.4 2007/08/22 08:49:39 markpollack Exp $ - public interface IInstantiationAwareObjectPostProcessor : IObjectPostProcessor - { - /// - /// Apply this - /// - /// before the target object gets instantiated. - /// - /// - ///

- /// The returned object may be a proxy to use instead of the target - /// object, effectively suppressing the default instantiation of the - /// target object. - ///

- ///

- /// If the object is returned by this method is not - /// , the object creation process will be - /// short-circuited. The returned object will not be processed any - /// further; in particular, no further - /// - /// callbacks will be applied to it. This mechanism is mainly intended - /// for exposing a proxy instead of an actual target object. - ///

- ///

- /// This callback will only be applied to object definitions with an - /// object class. In particular, it will not be applied to - /// objects with a "factory-method" (i.e. objects that are to be - /// instantiated via a layer of indirection anyway). - ///

- ///
- /// - /// The of the target object that is to be - /// instantiated. - /// - /// - /// The name of the target object. - /// - /// - /// The object to expose instead of a default instance of the target - /// object. - /// - /// - /// In the case of any errors. - /// - /// - /// - object PostProcessBeforeInstantiation(Type objectType, string objectName); - - - /// - /// Perform operations after the object has been instantiated, via a constructor or factory method, - /// but before Spring property population (from explicit properties or autowiring) occurs. - /// - /// The object instance created, but whose properties have not yet been set - /// Name of the object. - /// true if properties should be set on the object; false if property population - /// should be skipped. Normal implementations should return true. Returning false will also - /// prevent any subsequent InstantiationAwareObjectPostProcessor instances from being - /// invoked on this object instance. - bool PostProcessAfterInstantiation(object objectInstance, string objectName); - - /// - /// Post-process the given property values before the factory applies them - /// to the given object. - /// - /// Allows for checking whether all dependencies have been - /// satisfied, for example based on a "Required" annotation on bean property setters. - /// Also allows for replacing the property values to apply, typically through - /// creating a new MutablePropertyValues instance based on the original PropertyValues, - /// adding or removing specific values. - /// - /// - /// The property values that the factory is about to apply (never null). - /// he relevant property infos for the target object (with ignored - /// dependency types - which the factory handles specifically - already filtered out) - /// The object instance created, but whose properties have not yet - /// been set. - /// Name of the object. - /// The actual property values to apply to the given object (can be the - /// passed-in PropertyValues instances0 or null to skip property population. - IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, - string objectName); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using Spring.Objects.Factory.Support; + +namespace Spring.Objects.Factory.Config { + + /// + /// Subinterface of + /// + /// that adds a before-instantiation callback. + /// + /// + ///

+ /// Typical use cases might include being used to suppress the default + /// instantiation of specific target objects, perhaps in favour of creating + /// proxies with special Spring.Aop.ITargetSources (pooling targets, + /// lazily initializing targets, etc). + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IInstantiationAwareObjectPostProcessor : IObjectPostProcessor + { + /// + /// Apply this + /// + /// before the target object gets instantiated. + /// + /// + ///

+ /// The returned object may be a proxy to use instead of the target + /// object, effectively suppressing the default instantiation of the + /// target object. + ///

+ ///

+ /// If the object is returned by this method is not + /// , the object creation process will be + /// short-circuited. The returned object will not be processed any + /// further; in particular, no further + /// + /// callbacks will be applied to it. This mechanism is mainly intended + /// for exposing a proxy instead of an actual target object. + ///

+ ///

+ /// This callback will only be applied to object definitions with an + /// object class. In particular, it will not be applied to + /// objects with a "factory-method" (i.e. objects that are to be + /// instantiated via a layer of indirection anyway). + ///

+ ///
+ /// + /// The of the target object that is to be + /// instantiated. + /// + /// + /// The name of the target object. + /// + /// + /// The object to expose instead of a default instance of the target + /// object. + /// + /// + /// In the case of any errors. + /// + /// + /// + object PostProcessBeforeInstantiation(Type objectType, string objectName); + + + /// + /// Perform operations after the object has been instantiated, via a constructor or factory method, + /// but before Spring property population (from explicit properties or autowiring) occurs. + /// + /// The object instance created, but whose properties have not yet been set + /// Name of the object. + /// true if properties should be set on the object; false if property population + /// should be skipped. Normal implementations should return true. Returning false will also + /// prevent any subsequent InstantiationAwareObjectPostProcessor instances from being + /// invoked on this object instance. + bool PostProcessAfterInstantiation(object objectInstance, string objectName); + + /// + /// Post-process the given property values before the factory applies them + /// to the given object. + /// + /// Allows for checking whether all dependencies have been + /// satisfied, for example based on a "Required" annotation on bean property setters. + /// Also allows for replacing the property values to apply, typically through + /// creating a new MutablePropertyValues instance based on the original PropertyValues, + /// adding or removing specific values. + /// + /// + /// The property values that the factory is about to apply (never null). + /// he relevant property infos for the target object (with ignored + /// dependency types - which the factory handles specifically - already filtered out) + /// The object instance created, but whose properties have not yet + /// been set. + /// Name of the object. + /// The actual property values to apply to the given object (can be the + /// passed-in PropertyValues instances0 or null to skip property population. + IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, + string objectName); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IObjectDefinition.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IObjectDefinition.cs index a570193e..099d7234 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IObjectDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IObjectDefinition.cs @@ -1,208 +1,207 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Describes an object instance, which has property values, constructor - /// argument values, and further information supplied by concrete implementations. - /// - /// - ///

- /// This is just a minimal interface: the main intention is to allow - /// - /// (like PropertyPlaceholderConfigurer) to access and modify property values. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IObjectDefinition.cs,v 1.14 2007/07/30 17:52:22 markpollack Exp $ - public interface IObjectDefinition - { - /// - /// Return the property values to be applied to a new instance of the object. - /// - MutablePropertyValues PropertyValues { get; } - - /// - /// Return the constructor argument values for this object. - /// - ConstructorArgumentValues ConstructorArgumentValues { get; } - - /// - /// Return the event handlers for any events exposed by this object. - /// - EventValues EventHandlerValues { get; } - - /// - /// Return a description of the resource that this object definition - /// came from (for the purpose of showing context in case of errors). - /// - string ResourceDescription { get; } - - /// - /// Is this object definition a "template", i.e. not meant to be instantiated - /// itself but rather just serving as an object definition for configuration - /// templates used by . - /// - /// - /// if this object definition is a "template". - /// - bool IsTemplate { get; } - - /// - /// Is this object definition "abstract", i.e. not meant to be instantiated - /// itself but rather just serving as parent for concrete child object - /// definitions. - /// - /// - /// if this object definition is "abstract". - /// - bool IsAbstract { get; } - - /// - /// Return whether this a Singleton, with a single, shared instance - /// returned on all calls. - /// - /// - ///

- /// If , an object factory will apply the Prototype - /// design pattern, with each caller requesting an instance getting an - /// independent instance. How this is defined will depend on the - /// object factory implementation. Singletons are the commoner type. - ///

- ///
- bool IsSingleton { get; } - - /// - /// Is this object lazily initialized? - /// - ///

- /// Only applicable to a singleton object. - ///

- ///

- /// If , it will get instantiated on startup by object factories - /// that perform eager initialization of singletons. - ///

- ///
- bool IsLazyInit { get; } - - /// - /// Returns the of the object definition (if any). - /// - /// - /// A resolved object . - /// - /// - /// If the of the object definition is not a - /// resolved or . - /// - Type ObjectType { get; } - - /// - /// Returns the of the - /// of the object definition. - /// - /// Note that this does not have to be the actual type name used at runtime, - /// in case of a child definition overrding/inheriting the the type name from its - /// parent. It can be modifed during object factory post-processing, typically - /// replacing the original class name with a parsed variant of it. - /// Hence, do not consider this to be the definitive bean type at runtime - /// but rather only use it for parsing purposes at the individual object - /// definition level. - /// - string ObjectTypeName { get; set;} - - /// - /// The autowire mode as specified in the object definition. - /// - /// - ///

- /// This determines whether any automagical detection and setting of - /// object references will happen. Default is - /// , - /// which means there's no autowire. - ///

- ///
- AutoWiringMode AutowireMode { get; } - - /// - /// The object names that this object depends on. - /// - /// - ///

- /// The object factory will guarantee that these objects get initialized - /// before. - ///

- ///

- /// Note that dependencies are normally expressed through object properties - /// or constructor arguments. This property should just be necessary for - /// other kinds of dependencies like statics (*ugh*) or database - /// preparation on startup. - ///

- ///
- string[] DependsOn { get; } - - /// - /// The name of the initializer method. - /// - /// - ///

- /// The default is , in which case there is no initializer method. - ///

- ///
- string InitMethodName { get; } - - /// - /// Return the name of the destroy method. - /// - /// - ///

- /// The default is , in which case there is no destroy method. - ///

- ///
- string DestroyMethodName { get; } - - /// - /// The name of the factory method to use (if any). - /// - /// - ///

- /// This method will be invoked with constructor arguments, or with no - /// arguments if none are specified. The static method will be invoked on - /// the specified . - ///

- ///
- string FactoryMethodName { get; } - - /// - /// The name of the factory object to use (if any). - /// - string FactoryObjectName { get; } - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Describes an object instance, which has property values, constructor + /// argument values, and further information supplied by concrete implementations. + /// + /// + ///

+ /// This is just a minimal interface: the main intention is to allow + /// + /// (like PropertyPlaceholderConfigurer) to access and modify property values. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IObjectDefinition + { + /// + /// Return the property values to be applied to a new instance of the object. + /// + MutablePropertyValues PropertyValues { get; } + + /// + /// Return the constructor argument values for this object. + /// + ConstructorArgumentValues ConstructorArgumentValues { get; } + + /// + /// Return the event handlers for any events exposed by this object. + /// + EventValues EventHandlerValues { get; } + + /// + /// Return a description of the resource that this object definition + /// came from (for the purpose of showing context in case of errors). + /// + string ResourceDescription { get; } + + /// + /// Is this object definition a "template", i.e. not meant to be instantiated + /// itself but rather just serving as an object definition for configuration + /// templates used by . + /// + /// + /// if this object definition is a "template". + /// + bool IsTemplate { get; } + + /// + /// Is this object definition "abstract", i.e. not meant to be instantiated + /// itself but rather just serving as parent for concrete child object + /// definitions. + /// + /// + /// if this object definition is "abstract". + /// + bool IsAbstract { get; } + + /// + /// Return whether this a Singleton, with a single, shared instance + /// returned on all calls. + /// + /// + ///

+ /// If , an object factory will apply the Prototype + /// design pattern, with each caller requesting an instance getting an + /// independent instance. How this is defined will depend on the + /// object factory implementation. Singletons are the commoner type. + ///

+ ///
+ bool IsSingleton { get; } + + /// + /// Is this object lazily initialized? + /// + ///

+ /// Only applicable to a singleton object. + ///

+ ///

+ /// If , it will get instantiated on startup by object factories + /// that perform eager initialization of singletons. + ///

+ ///
+ bool IsLazyInit { get; } + + /// + /// Returns the of the object definition (if any). + /// + /// + /// A resolved object . + /// + /// + /// If the of the object definition is not a + /// resolved or . + /// + Type ObjectType { get; } + + /// + /// Returns the of the + /// of the object definition. + /// + /// Note that this does not have to be the actual type name used at runtime, + /// in case of a child definition overrding/inheriting the the type name from its + /// parent. It can be modifed during object factory post-processing, typically + /// replacing the original class name with a parsed variant of it. + /// Hence, do not consider this to be the definitive bean type at runtime + /// but rather only use it for parsing purposes at the individual object + /// definition level. + /// + string ObjectTypeName { get; set;} + + /// + /// The autowire mode as specified in the object definition. + /// + /// + ///

+ /// This determines whether any automagical detection and setting of + /// object references will happen. Default is + /// , + /// which means there's no autowire. + ///

+ ///
+ AutoWiringMode AutowireMode { get; } + + /// + /// The object names that this object depends on. + /// + /// + ///

+ /// The object factory will guarantee that these objects get initialized + /// before. + ///

+ ///

+ /// Note that dependencies are normally expressed through object properties + /// or constructor arguments. This property should just be necessary for + /// other kinds of dependencies like statics (*ugh*) or database + /// preparation on startup. + ///

+ ///
+ string[] DependsOn { get; } + + /// + /// The name of the initializer method. + /// + /// + ///

+ /// The default is , in which case there is no initializer method. + ///

+ ///
+ string InitMethodName { get; } + + /// + /// Return the name of the destroy method. + /// + /// + ///

+ /// The default is , in which case there is no destroy method. + ///

+ ///
+ string DestroyMethodName { get; } + + /// + /// The name of the factory method to use (if any). + /// + /// + ///

+ /// This method will be invoked with constructor arguments, or with no + /// arguments if none are specified. The static method will be invoked on + /// the specified . + ///

+ ///
+ string FactoryMethodName { get; } + + /// + /// The name of the factory object to use (if any). + /// + string FactoryObjectName { get; } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IObjectFactoryPostProcessor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IObjectFactoryPostProcessor.cs index f9d00094..b3f73b83 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IObjectFactoryPostProcessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IObjectFactoryPostProcessor.cs @@ -1,72 +1,72 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Allows for custom modification of an application context's object - /// definitions, adapting the object property values of the context's - /// underlying object factory. - /// - /// - ///

- /// Application contexts can auto-detect - /// IObjectFactoryPostProcessor objects in their object definitions and - /// apply them before any other objects get created. - ///

- ///

- /// Useful for custom config files targeted at system administrators that - /// override object properties configured in the application context. - ///

- ///

- /// See PropertyResourceConfigurer and its concrete implementations for - /// out-of-the-box solutions that address such configuration needs. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.Net) - public interface IObjectFactoryPostProcessor - { - /// - /// Modify the application context's internal object factory after its - /// standard initialization. - /// - /// - ///

- /// All object definitions will have been loaded, but no objects will have - /// been instantiated yet. This allows for overriding or adding properties - /// even to eager-initializing objects. - ///

- ///
- /// - /// The object factory used by the application context. - /// - /// - /// In case of errors. - /// - void PostProcessObjectFactory (IConfigurableListableObjectFactory factory); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Allows for custom modification of an application context's object + /// definitions, adapting the object property values of the context's + /// underlying object factory. + /// + /// + ///

+ /// Application contexts can auto-detect + /// IObjectFactoryPostProcessor objects in their object definitions and + /// apply them before any other objects get created. + ///

+ ///

+ /// Useful for custom config files targeted at system administrators that + /// override object properties configured in the application context. + ///

+ ///

+ /// See PropertyResourceConfigurer and its concrete implementations for + /// out-of-the-box solutions that address such configuration needs. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.Net) + public interface IObjectFactoryPostProcessor + { + /// + /// Modify the application context's internal object factory after its + /// standard initialization. + /// + /// + ///

+ /// All object definitions will have been loaded, but no objects will have + /// been instantiated yet. This allows for overriding or adding properties + /// even to eager-initializing objects. + ///

+ ///
+ /// + /// The object factory used by the application context. + /// + /// + /// In case of errors. + /// + void PostProcessObjectFactory (IConfigurableListableObjectFactory factory); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IObjectPostProcessor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IObjectPostProcessor.cs index aef66001..1dc879f1 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IObjectPostProcessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IObjectPostProcessor.cs @@ -1,99 +1,98 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Allows for custom modification of new object instances, e.g. - /// checking for marker interfaces or wrapping them with proxies. - /// - /// - ///

- /// Application contexts can auto-detect - /// - /// objects in their object definitions and apply them before any other - /// objects get created. Plain object factories allow for programmatic - /// registration of post-processors. - ///

- ///

- /// Typically, post-processors that populate objects via marker interfaces - /// or the like will implement - /// , - /// and post-processors that wrap objects with proxies will normally implement - /// . - ///

- ///
- /// Juergen Hoeller - /// Aleksandar Seovic (.NET) - /// $Id: IObjectPostProcessor.cs,v 1.9 2007/08/22 08:49:39 markpollack Exp $ - /// - public interface IObjectPostProcessor - { - /// - /// Apply this - /// to the given new object instance before any object initialization callbacks. - /// - /// - ///

- /// The object will already be populated with property values. - /// The returned object instance may be a wrapper around the original. - ///

- ///
- /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - object PostProcessBeforeInitialization(object instance, string name); - - /// - /// Apply this to the - /// given new object instance after any object initialization callbacks. - /// - /// - ///

- /// The object will already be populated with property values. The returned object - /// instance may be a wrapper around the original. - ///

- ///
- /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - object PostProcessAfterInitialization(object instance, string objectName); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Allows for custom modification of new object instances, e.g. + /// checking for marker interfaces or wrapping them with proxies. + /// + /// + ///

+ /// Application contexts can auto-detect + /// + /// objects in their object definitions and apply them before any other + /// objects get created. Plain object factories allow for programmatic + /// registration of post-processors. + ///

+ ///

+ /// Typically, post-processors that populate objects via marker interfaces + /// or the like will implement + /// , + /// and post-processors that wrap objects with proxies will normally implement + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Aleksandar Seovic (.NET) + /// + public interface IObjectPostProcessor + { + /// + /// Apply this + /// to the given new object instance before any object initialization callbacks. + /// + /// + ///

+ /// The object will already be populated with property values. + /// The returned object instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + object PostProcessBeforeInitialization(object instance, string name); + + /// + /// Apply this to the + /// given new object instance after any object initialization callbacks. + /// + /// + ///

+ /// The object will already be populated with property values. The returned object + /// instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + object PostProcessAfterInitialization(object instance, string objectName); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IVariableSource.cs index 6494a0c8..4fe30385 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/IVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/IVariableSource.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Defines contract that different variable sources have to implement. - /// - /// - ///

- /// The "variable sources" are objects containing name-value pairs - /// that allow a variable value to be retrieved for the given name.

- ///

- /// Out of the box, Spring.NET supports a number of variable sources, - /// that allow users to obtain variable values from .NET config files, - /// Java-style property files, environment, registry, etc.

- ///

- /// Users can always write their own variable sources implementations, - /// that will allow them to load variable values from the database or - /// other proprietary data source.

- ///
- /// - /// - /// - /// - /// - /// - /// Aleksandar Seovic - /// $Id: IVariableSource.cs,v 1.3 2007/08/02 22:18:32 markpollack Exp $ - public interface IVariableSource - { - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - string ResolveVariable(string name); - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Defines contract that different variable sources have to implement. + /// + /// + ///

+ /// The "variable sources" are objects containing name-value pairs + /// that allow a variable value to be retrieved for the given name.

+ ///

+ /// Out of the box, Spring.NET supports a number of variable sources, + /// that allow users to obtain variable values from .NET config files, + /// Java-style property files, environment, registry, etc.

+ ///

+ /// Users can always write their own variable sources implementations, + /// that will allow them to load variable values from the database or + /// other proprietary data source.

+ ///
+ /// + /// + /// + /// + /// + /// + /// Aleksandar Seovic + public interface IVariableSource + { + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + string ResolveVariable(string name); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/InstantiationAwareObjectPostProcessorAdapter.cs b/src/Spring/Spring.Core/Objects/Factory/Config/InstantiationAwareObjectPostProcessorAdapter.cs index f69ad6b1..c4301563 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/InstantiationAwareObjectPostProcessorAdapter.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/InstantiationAwareObjectPostProcessorAdapter.cs @@ -1,224 +1,223 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using Spring.Objects.Factory.Support; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Adapter that implements all methods on - /// as no-ops, which will not change normal processing of each object instantiated - /// by the container. Subclasses may override merely those methods that they are - /// actually interested in. - /// - /// - /// Note that this base class is only recommendable if you actually require - /// functionality. If all you need - /// is plain functionality, prefer a straight - /// implementation of that (simpler) interface. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: InstantiationAwareObjectPostProcessorAdapter.cs,v 1.1 2008/04/02 18:02:24 markpollack Exp $ - public abstract class InstantiationAwareObjectPostProcessorAdapter : SmartInstantiationAwareObjectPostProcessor - { - #region SmartInstantiationAwareObjectPostProcessor Members - - /// - /// Predicts the type of the object to be eventually returned from this - /// processors PostProcessBeforeInstantiation callback. - /// - /// The raw Type of the object. - /// Name of the object. - /// The type of the object, or null if not predictable. - /// in case of errors - public virtual Type PredictObjectType(Type objectType, string objectName) - { - return null; - } - - /// - /// Determines the candidate constructors to use for the given object. - /// - /// The raw Type of the object. - /// Name of the object. - /// The candidate constructors, or null if none specified - /// in case of errors - public virtual ConstructorInfo[] DetermineCandidateConstructors(Type objectType, string objectName) - { - return null; - } - - #endregion - - #region IInstantiationAwareObjectPostProcessor Members - - /// - /// Apply this - /// - /// before the target object gets instantiated. - /// - /// - ///

- /// The returned object may be a proxy to use instead of the target - /// object, effectively suppressing the default instantiation of the - /// target object. - ///

- ///

- /// If the object is returned by this method is not - /// , the object creation process will be - /// short-circuited. The returned object will not be processed any - /// further; in particular, no further - /// - /// callbacks will be applied to it. This mechanism is mainly intended - /// for exposing a proxy instead of an actual target object. - ///

- ///

- /// This callback will only be applied to object definitions with an - /// object class. In particular, it will not be applied to - /// objects with a "factory-method" (i.e. objects that are to be - /// instantiated via a layer of indirection anyway). - ///

- ///
- /// - /// The of the target object that is to be - /// instantiated. - /// - /// - /// The name of the target object. - /// - /// - /// The object to expose instead of a default instance of the target - /// object. - /// - /// - /// In the case of any errors. - /// - /// - /// - public virtual object PostProcessBeforeInstantiation(Type objectType, string objectName) - { - return null; - } - - /// - /// Perform operations after the object has been instantiated, via a constructor or factory method, - /// but before Spring property population (from explicit properties or autowiring) occurs. - /// - /// The object instance created, but whose properties have not yet been set - /// Name of the object. - /// true if properties should be set on the object; false if property population - /// should be skipped. Normal implementations should return true. Returning false will also - /// prevent any subsequent InstantiationAwareObjectPostProcessor instances from being - /// invoked on this object instance. - public virtual bool PostProcessAfterInstantiation(object objectInstance, string objectName) - { - return true; - } - - /// - /// Post-process the given property values before the factory applies them - /// to the given object. - /// - /// Allows for checking whether all dependencies have been - /// satisfied, for example based on a "Required" annotation on bean property setters. - /// Also allows for replacing the property values to apply, typically through - /// creating a new MutablePropertyValues instance based on the original PropertyValues, - /// adding or removing specific values. - /// - /// - /// The property values that the factory is about to apply (never null). - /// he relevant property infos for the target object (with ignored - /// dependency types - which the factory handles specifically - already filtered out) - /// The object instance created, but whose properties have not yet - /// been set. - /// Name of the object. - /// The actual property values to apply to the given object (can be the - /// passed-in PropertyValues instances0 or null to skip property population. - public virtual IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, - string objectName) - { - return pvs; - } - - #endregion - - #region IObjectPostProcessor Members - - /// - /// Apply this - /// to the given new object instance before any object initialization callbacks. - /// - /// - ///

- /// The object will already be populated with property values. - /// The returned object instance may be a wrapper around the original. - ///

- ///
- /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - public virtual object PostProcessBeforeInitialization(object instance, string name) - { - return instance; - } - - /// - /// Apply this to the - /// given new object instance after any object initialization callbacks. - /// - /// - ///

- /// The object will already be populated with property values. The returned object - /// instance may be a wrapper around the original. - ///

- ///
- /// - /// The new object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// In case of errors. - /// - public virtual object PostProcessAfterInitialization(object instance, string objectName) - { - return instance; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using Spring.Objects.Factory.Support; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Adapter that implements all methods on + /// as no-ops, which will not change normal processing of each object instantiated + /// by the container. Subclasses may override merely those methods that they are + /// actually interested in. + /// + /// + /// Note that this base class is only recommendable if you actually require + /// functionality. If all you need + /// is plain functionality, prefer a straight + /// implementation of that (simpler) interface. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + public abstract class InstantiationAwareObjectPostProcessorAdapter : SmartInstantiationAwareObjectPostProcessor + { + #region SmartInstantiationAwareObjectPostProcessor Members + + /// + /// Predicts the type of the object to be eventually returned from this + /// processors PostProcessBeforeInstantiation callback. + /// + /// The raw Type of the object. + /// Name of the object. + /// The type of the object, or null if not predictable. + /// in case of errors + public virtual Type PredictObjectType(Type objectType, string objectName) + { + return null; + } + + /// + /// Determines the candidate constructors to use for the given object. + /// + /// The raw Type of the object. + /// Name of the object. + /// The candidate constructors, or null if none specified + /// in case of errors + public virtual ConstructorInfo[] DetermineCandidateConstructors(Type objectType, string objectName) + { + return null; + } + + #endregion + + #region IInstantiationAwareObjectPostProcessor Members + + /// + /// Apply this + /// + /// before the target object gets instantiated. + /// + /// + ///

+ /// The returned object may be a proxy to use instead of the target + /// object, effectively suppressing the default instantiation of the + /// target object. + ///

+ ///

+ /// If the object is returned by this method is not + /// , the object creation process will be + /// short-circuited. The returned object will not be processed any + /// further; in particular, no further + /// + /// callbacks will be applied to it. This mechanism is mainly intended + /// for exposing a proxy instead of an actual target object. + ///

+ ///

+ /// This callback will only be applied to object definitions with an + /// object class. In particular, it will not be applied to + /// objects with a "factory-method" (i.e. objects that are to be + /// instantiated via a layer of indirection anyway). + ///

+ ///
+ /// + /// The of the target object that is to be + /// instantiated. + /// + /// + /// The name of the target object. + /// + /// + /// The object to expose instead of a default instance of the target + /// object. + /// + /// + /// In the case of any errors. + /// + /// + /// + public virtual object PostProcessBeforeInstantiation(Type objectType, string objectName) + { + return null; + } + + /// + /// Perform operations after the object has been instantiated, via a constructor or factory method, + /// but before Spring property population (from explicit properties or autowiring) occurs. + /// + /// The object instance created, but whose properties have not yet been set + /// Name of the object. + /// true if properties should be set on the object; false if property population + /// should be skipped. Normal implementations should return true. Returning false will also + /// prevent any subsequent InstantiationAwareObjectPostProcessor instances from being + /// invoked on this object instance. + public virtual bool PostProcessAfterInstantiation(object objectInstance, string objectName) + { + return true; + } + + /// + /// Post-process the given property values before the factory applies them + /// to the given object. + /// + /// Allows for checking whether all dependencies have been + /// satisfied, for example based on a "Required" annotation on bean property setters. + /// Also allows for replacing the property values to apply, typically through + /// creating a new MutablePropertyValues instance based on the original PropertyValues, + /// adding or removing specific values. + /// + /// + /// The property values that the factory is about to apply (never null). + /// he relevant property infos for the target object (with ignored + /// dependency types - which the factory handles specifically - already filtered out) + /// The object instance created, but whose properties have not yet + /// been set. + /// Name of the object. + /// The actual property values to apply to the given object (can be the + /// passed-in PropertyValues instances0 or null to skip property population. + public virtual IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, PropertyInfo[] pis, object objectInstance, + string objectName) + { + return pvs; + } + + #endregion + + #region IObjectPostProcessor Members + + /// + /// Apply this + /// to the given new object instance before any object initialization callbacks. + /// + /// + ///

+ /// The object will already be populated with property values. + /// The returned object instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + public virtual object PostProcessBeforeInitialization(object instance, string name) + { + return instance; + } + + /// + /// Apply this to the + /// given new object instance after any object initialization callbacks. + /// + /// + ///

+ /// The object will already be populated with property values. The returned object + /// instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The new object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// In case of errors. + /// + public virtual object PostProcessAfterInitialization(object instance, string objectName) + { + return instance; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ListFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ListFactoryObject.cs index db1ededc..76b04b3c 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ListFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ListFactoryObject.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Simple factory for shared instances. - /// - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: ListFactoryObject.cs,v 1.8 2007/07/31 03:47:39 markpollack Exp $ - [Serializable] - public class ListFactoryObject : AbstractFactoryObject - { - private IList _sourceList; - private Type _targetListType = typeof (ArrayList); - - #region Properties - - /// - /// Set the source . - /// - /// - ///

- /// This value will be used to populate the - /// returned by this factory. - ///

- ///
- public IList SourceList - { - set { this._sourceList = value; } - } - - /// - /// Set the of the - /// implementation to use. - /// - /// - ///

- /// The default is the . - ///

- ///
- public Type TargetListType - { - set - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!typeof (IList).IsAssignableFrom(value)) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetListType property must implement the '{0}' interface.", - ObjectType.FullName)); - } - if (value.IsInterface) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetListType property cannot be an interface; it must be a concrete class that implements the '{0}' interface.", - ObjectType.FullName)); - } - if (value.IsAbstract) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetListType property cannot be abstract (MustInherit in VisualBasic.NET); it must be a concrete class that implements the '{0}' interface.", - ObjectType.FullName)); - } - this._targetListType = value; - } - } - - /// - /// The of objects created by this factory. - /// - /// - /// Always returns the . - /// - public override Type ObjectType - { - get { return typeof (IList); } - } - - #endregion - - /// - /// Constructs a new instance of the target dictionary. - /// - /// The new instance. - protected override object CreateInstance() - { - if (this._sourceList == null) - { - throw new ArgumentException("The 'SourceList' property cannot be null (Nothing in Visual Basic.NET)."); - } - IList result = (IList) ObjectUtils.InstantiateType(this._targetListType); - foreach (object obj in this._sourceList) - { - result.Add(obj); - } - return result; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Simple factory for shared instances. + /// + /// Juergen Hoeller + /// Simon White (.NET) + [Serializable] + public class ListFactoryObject : AbstractFactoryObject + { + private IList _sourceList; + private Type _targetListType = typeof (ArrayList); + + #region Properties + + /// + /// Set the source . + /// + /// + ///

+ /// This value will be used to populate the + /// returned by this factory. + ///

+ ///
+ public IList SourceList + { + set { this._sourceList = value; } + } + + /// + /// Set the of the + /// implementation to use. + /// + /// + ///

+ /// The default is the . + ///

+ ///
+ public Type TargetListType + { + set + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!typeof (IList).IsAssignableFrom(value)) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetListType property must implement the '{0}' interface.", + ObjectType.FullName)); + } + if (value.IsInterface) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetListType property cannot be an interface; it must be a concrete class that implements the '{0}' interface.", + ObjectType.FullName)); + } + if (value.IsAbstract) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetListType property cannot be abstract (MustInherit in VisualBasic.NET); it must be a concrete class that implements the '{0}' interface.", + ObjectType.FullName)); + } + this._targetListType = value; + } + } + + /// + /// The of objects created by this factory. + /// + /// + /// Always returns the . + /// + public override Type ObjectType + { + get { return typeof (IList); } + } + + #endregion + + /// + /// Constructs a new instance of the target dictionary. + /// + /// The new instance. + protected override object CreateInstance() + { + if (this._sourceList == null) + { + throw new ArgumentException("The 'SourceList' property cannot be null (Nothing in Visual Basic.NET)."); + } + IList result = (IList) ObjectUtils.InstantiateType(this._targetListType); + foreach (object obj in this._sourceList) + { + result.Add(obj); + } + return result; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/LogFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/LogFactoryObject.cs index 01901ade..0f379674 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/LogFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/LogFactoryObject.cs @@ -1,171 +1,170 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Common.Logging; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// implementation that - /// creates instances of the class. - /// - /// - ///

- /// Typically used for retrieving shared - /// instances for common topics (such as the 'DAL', 'BLL', etc). The - /// - /// property determines the name of the - /// Common.Logging logger. - ///

- ///
- /// Rick Evans - /// - /// $Id: LogFactoryObject.cs,v 1.3 2007/10/21 18:17:41 markpollack Exp $ - [Serializable] - public class LogFactoryObject : IFactoryObject, IInitializingObject - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - public LogFactoryObject() - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The name of the instance served up by - /// this factory. - /// - /// - /// If the supplied is - /// or contains only whitespace character(s). - /// - public LogFactoryObject(string logName) - { - LogName = logName; - } - - #endregion - - /// - /// The name of the instance served up by - /// this factory. - /// - /// - /// The name of the instance served up by - /// this factory. - /// - /// - /// If the supplied to the setter is - /// or contains only whitespace character(s). - /// - public string LogName - { - get { return this.logName; } - set - { - AssertUtils.ArgumentHasText(value, "The 'LogName' property must have a value."); - this.logName = value.Trim(); - } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// An instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - public object GetObject() - { - if (this.log == null) - { - ValidateProperties(); - this.log = LogManager.GetLogger(LogName); - } - return this.log; - } - - /// - /// Return the type of object that this - /// creates, or - /// if not known in advance. - /// - /// - public Type ObjectType - { - get { return typeof(ILog); } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - /// - public bool IsSingleton - { - get { return true; } - } - - /// - /// Invoked by an - /// after it has set all object properties supplied - /// (and satisfied the - /// - /// and - /// interfaces). - /// - /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - /// - public void AfterPropertiesSet() - { - ValidateProperties(); - } - - private void ValidateProperties() - { - if (StringUtils.IsNullOrEmpty(LogName)) - { - throw new ArgumentException("The 'LogName' property has not been set."); - } - } - - private ILog log; - private string logName; - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Common.Logging; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// implementation that + /// creates instances of the class. + /// + /// + ///

+ /// Typically used for retrieving shared + /// instances for common topics (such as the 'DAL', 'BLL', etc). The + /// + /// property determines the name of the + /// Common.Logging logger. + ///

+ ///
+ /// Rick Evans + /// + [Serializable] + public class LogFactoryObject : IFactoryObject, IInitializingObject + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + public LogFactoryObject() + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The name of the instance served up by + /// this factory. + /// + /// + /// If the supplied is + /// or contains only whitespace character(s). + /// + public LogFactoryObject(string logName) + { + LogName = logName; + } + + #endregion + + /// + /// The name of the instance served up by + /// this factory. + /// + /// + /// The name of the instance served up by + /// this factory. + /// + /// + /// If the supplied to the setter is + /// or contains only whitespace character(s). + /// + public string LogName + { + get { return this.logName; } + set + { + AssertUtils.ArgumentHasText(value, "The 'LogName' property must have a value."); + this.logName = value.Trim(); + } + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// An instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + public object GetObject() + { + if (this.log == null) + { + ValidateProperties(); + this.log = LogManager.GetLogger(LogName); + } + return this.log; + } + + /// + /// Return the type of object that this + /// creates, or + /// if not known in advance. + /// + /// + public Type ObjectType + { + get { return typeof(ILog); } + } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + /// + public bool IsSingleton + { + get { return true; } + } + + /// + /// Invoked by an + /// after it has set all object properties supplied + /// (and satisfied the + /// + /// and + /// interfaces). + /// + /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + /// + public void AfterPropertiesSet() + { + ValidateProperties(); + } + + private void ValidateProperties() + { + if (StringUtils.IsNullOrEmpty(LogName)) + { + throw new ArgumentException("The 'LogName' property has not been set."); + } + } + + private ILog log; + private string logName; + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/MethodInvokingFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/MethodInvokingFactoryObject.cs index fc85033f..34e9b286 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/MethodInvokingFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/MethodInvokingFactoryObject.cs @@ -1,271 +1,270 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Support; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// An that returns a value - /// that is the result of a or instance method invocation. - /// - /// - ///

- /// Note that this class generally is expected to be used for accessing factory methods, - /// and as such defaults to operating in singleton mode. The first request to - /// - /// by the owning object factory will cause a method invocation, the return - /// value of which will be cached for all subsequent requests. The - /// property may be set to - /// , to cause this factory to invoke the target method each - /// time it is asked for an object. - ///

- ///

- /// A target method may be specified by setting the - /// property to a string representing - /// the method name, with specifying - /// the that the method is defined on. - /// Alternatively, a target instance method may be specified, by setting the - /// property as the target object, and - /// the property as the name of the - /// method to call on that target object. Arguments for the method invocation may be - /// specified by setting the property. - ///

- ///

- /// Another (esoteric) use case for this factory object is when one needs to call a method - /// that doesn't return any value (for example, a class method to - /// force some sort of initialization to happen)... this use case is not supported by - /// factory-methods, since a return value is needed to become the object. - ///

- ///

- /// - /// This class depends on the - /// - /// method being called after all properties have been set, as per the - /// contract. If you are - /// using this class outside of a Spring.NET IoC container, you must call one of either - /// or - /// yourself to ready the object's internal - /// state, or you will get a nasty . - /// - ///

- ///
- /// - ///

- /// The following example uses an instance of this class to call a - /// factory method... - ///

- /// - /// - /// - /// - /// - /// - /// - /// 1st - /// 2nd - /// and 3rd arguments - /// - /// - /// - /// - ///

- /// The following example is similar to the preceding example; the only pertinent difference is the fact that - /// a number of different objects are passed as arguments, demonstrating that not only simple value types - /// are valid as elements of the argument list... - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1st - /// - /// - /// - /// - /// - /// - /// http://www.springframework.net/ - /// - /// - /// - /// - /// - ///

- /// Named parameters are also supported... this next example yields the same results as - /// the preceding example (that did not use named arguments). - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// 1st - /// and 3rd arguments - /// 2nd - /// - /// - /// - /// - ///

- /// Similarly, the following example uses an instance of this class to call an instance method... - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// The above example could also have been written using an anonymous inner object definition... if the - /// object on which the method is to be invoked is not going to be used outside of the factory object - /// definition, then this is the preferred idiom because it limits the scope of the object on which the - /// method is to be invoked to the surrounding factory object. - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Colin Sampaleanu - /// Juergen Hoeller - /// Rick Evans (.NET) - /// Simon White (.NET) - /// $Id: MethodInvokingFactoryObject.cs,v 1.15 2007/03/16 04:01:38 aseovic Exp $ - /// - /// - [Serializable] - public class MethodInvokingFactoryObject : ArgumentConvertingMethodInvoker, IFactoryObject, IInitializingObject - { - private bool singleton = true; - private object singletonObject; - - /// - /// If a singleton should be created, or a new object on each request. - /// Defaults to . - /// - public bool IsSingleton - { - get { return singleton; } - set { singleton = value; } - } - - /// - /// Return the return value of the method - /// that this factory invokes, or if not - /// known in advance. - /// - /// - ///

- /// If the return value of the method that this factory is to invoke is - /// , then the - /// will be returned (in accordance with the - /// contract that - /// treats a value as a configuration error). - ///

- ///
- /// - public Type ObjectType - { - get - { - Type objectType = null; - if (GetPreparedMethod() != null) - { - objectType = GetPreparedMethod().ReturnType; - if (objectType.Equals(typeof (void))) - { - objectType = Void.GetType(); - } - } - return objectType; - } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - ///

- /// Returns the return value of the method that is to be invoked. - ///

- ///

- /// Will return the same value each time if the - /// - /// property value is . - ///

- ///
- /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - /// - public object GetObject() - { - if (singleton) - { - if (singletonObject == null) - { - singletonObject = Invoke(); - } - return singletonObject; - } - return Invoke(); - } - - /// - /// Prepares this method invoker. - /// - /// - /// If all required properties are not set. - /// - /// - /// If the specified method could not be found. - /// - /// - public void AfterPropertiesSet() - { - Prepare(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Support; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// An that returns a value + /// that is the result of a or instance method invocation. + /// + /// + ///

+ /// Note that this class generally is expected to be used for accessing factory methods, + /// and as such defaults to operating in singleton mode. The first request to + /// + /// by the owning object factory will cause a method invocation, the return + /// value of which will be cached for all subsequent requests. The + /// property may be set to + /// , to cause this factory to invoke the target method each + /// time it is asked for an object. + ///

+ ///

+ /// A target method may be specified by setting the + /// property to a string representing + /// the method name, with specifying + /// the that the method is defined on. + /// Alternatively, a target instance method may be specified, by setting the + /// property as the target object, and + /// the property as the name of the + /// method to call on that target object. Arguments for the method invocation may be + /// specified by setting the property. + ///

+ ///

+ /// Another (esoteric) use case for this factory object is when one needs to call a method + /// that doesn't return any value (for example, a class method to + /// force some sort of initialization to happen)... this use case is not supported by + /// factory-methods, since a return value is needed to become the object. + ///

+ ///

+ /// + /// This class depends on the + /// + /// method being called after all properties have been set, as per the + /// contract. If you are + /// using this class outside of a Spring.NET IoC container, you must call one of either + /// or + /// yourself to ready the object's internal + /// state, or you will get a nasty . + /// + ///

+ ///
+ /// + ///

+ /// The following example uses an instance of this class to call a + /// factory method... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// 1st + /// 2nd + /// and 3rd arguments + /// + /// + /// + /// + ///

+ /// The following example is similar to the preceding example; the only pertinent difference is the fact that + /// a number of different objects are passed as arguments, demonstrating that not only simple value types + /// are valid as elements of the argument list... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1st + /// + /// + /// + /// + /// + /// + /// http://www.springframework.net/ + /// + /// + /// + /// + /// + ///

+ /// Named parameters are also supported... this next example yields the same results as + /// the preceding example (that did not use named arguments). + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// 1st + /// and 3rd arguments + /// 2nd + /// + /// + /// + /// + ///

+ /// Similarly, the following example uses an instance of this class to call an instance method... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// The above example could also have been written using an anonymous inner object definition... if the + /// object on which the method is to be invoked is not going to be used outside of the factory object + /// definition, then this is the preferred idiom because it limits the scope of the object on which the + /// method is to be invoked to the surrounding factory object. + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Colin Sampaleanu + /// Juergen Hoeller + /// Rick Evans (.NET) + /// Simon White (.NET) + /// + /// + [Serializable] + public class MethodInvokingFactoryObject : ArgumentConvertingMethodInvoker, IFactoryObject, IInitializingObject + { + private bool singleton = true; + private object singletonObject; + + /// + /// If a singleton should be created, or a new object on each request. + /// Defaults to . + /// + public bool IsSingleton + { + get { return singleton; } + set { singleton = value; } + } + + /// + /// Return the return value of the method + /// that this factory invokes, or if not + /// known in advance. + /// + /// + ///

+ /// If the return value of the method that this factory is to invoke is + /// , then the + /// will be returned (in accordance with the + /// contract that + /// treats a value as a configuration error). + ///

+ ///
+ /// + public Type ObjectType + { + get + { + Type objectType = null; + if (GetPreparedMethod() != null) + { + objectType = GetPreparedMethod().ReturnType; + if (objectType.Equals(typeof (void))) + { + objectType = Void.GetType(); + } + } + return objectType; + } + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + ///

+ /// Returns the return value of the method that is to be invoked. + ///

+ ///

+ /// Will return the same value each time if the + /// + /// property value is . + ///

+ ///
+ /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + /// + public object GetObject() + { + if (singleton) + { + if (singletonObject == null) + { + singletonObject = Invoke(); + } + return singletonObject; + } + return Invoke(); + } + + /// + /// Prepares this method invoker. + /// + /// + /// If all required properties are not set. + /// + /// + /// If the specified method could not be found. + /// + /// + public void AfterPropertiesSet() + { + Prepare(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionHolder.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionHolder.cs index d631eeb7..ab687830 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionHolder.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionHolder.cs @@ -1,137 +1,136 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Holder for an with - /// name and aliases. - /// - /// - ///

- /// Recognized by - /// - /// for inner object definitions. Registered by - /// , - /// which also uses it as general holder for a parsed object definition. - ///

- ///

- /// Can also be used for programmatic registration of inner object - /// definitions. If you don't care about the functionality offered by the - /// interface and the like, - /// registering - /// or is good enough. - ///

- ///
- /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: ObjectDefinitionHolder.cs,v 1.2 2007/08/07 22:05:20 markpollack Exp $ - [Serializable] - public class ObjectDefinitionHolder - { - private IObjectDefinition objectDefinition; - private string objectName; - private string[] aliases; - - #region Constructor () / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object definition to be held by this instance. - /// - /// - /// The name of the object definition. - /// - public ObjectDefinitionHolder(IObjectDefinition definition, string name) - : this(definition, name, StringUtils.EmptyStrings) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object definition to be held by this instance. - /// - /// The name of the object. - /// - /// Any aliases for the supplied - /// - public ObjectDefinitionHolder( - IObjectDefinition definition, string name, string[] aliases) - { - this.objectDefinition = definition; - this.objectName = name; - this.aliases = aliases == null ? StringUtils.EmptyStrings : aliases; - } - - #endregion - - #region Properties - - /// - /// The held by this - /// instance. - /// - public IObjectDefinition ObjectDefinition - { - get { return objectDefinition; } - } - - /// - /// The name of the object definition. - /// - public string ObjectName - { - get { return objectName; } - } - - /// - /// Any aliases for the object definition. - /// - /// - ///

- /// Guaranteed to never return ; if the associated - /// - /// does not have any aliases associated with it, then an empty - /// array will be returned. - ///

- ///
- public string[] Aliases - { - get { return aliases; } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Holder for an with + /// name and aliases. + /// + /// + ///

+ /// Recognized by + /// + /// for inner object definitions. Registered by + /// , + /// which also uses it as general holder for a parsed object definition. + ///

+ ///

+ /// Can also be used for programmatic registration of inner object + /// definitions. If you don't care about the functionality offered by the + /// interface and the like, + /// registering + /// or is good enough. + ///

+ ///
+ /// Juergen Hoeller + /// Simon White (.NET) + [Serializable] + public class ObjectDefinitionHolder + { + private IObjectDefinition objectDefinition; + private string objectName; + private string[] aliases; + + #region Constructor () / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object definition to be held by this instance. + /// + /// + /// The name of the object definition. + /// + public ObjectDefinitionHolder(IObjectDefinition definition, string name) + : this(definition, name, StringUtils.EmptyStrings) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object definition to be held by this instance. + /// + /// The name of the object. + /// + /// Any aliases for the supplied + /// + public ObjectDefinitionHolder( + IObjectDefinition definition, string name, string[] aliases) + { + this.objectDefinition = definition; + this.objectName = name; + this.aliases = aliases == null ? StringUtils.EmptyStrings : aliases; + } + + #endregion + + #region Properties + + /// + /// The held by this + /// instance. + /// + public IObjectDefinition ObjectDefinition + { + get { return objectDefinition; } + } + + /// + /// The name of the object definition. + /// + public string ObjectName + { + get { return objectName; } + } + + /// + /// Any aliases for the object definition. + /// + /// + ///

+ /// Guaranteed to never return ; if the associated + /// + /// does not have any aliases associated with it, then an empty + /// array will be returned. + ///

+ ///
+ public string[] Aliases + { + get { return aliases; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionVisitor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionVisitor.cs index 007edef0..53ceb048 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionVisitor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectDefinitionVisitor.cs @@ -1,380 +1,379 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; - -using Spring.Collections; -using Spring.Util; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Visitor class for traversing objects, in particular - /// the property values and constructor arguments contained in them resolving - /// object metadata values. - /// - /// - /// Used by and - /// to parse all string values contained in a ObjectDefinition, resolving any placeholders found. - /// - /// Mark Pollack - /// $Id: ObjectDefinitionVisitor.cs,v 1.9 2008/02/18 00:02:27 bbaia Exp $ - public class ObjectDefinitionVisitor - { - private IVariableSource variableSource; - - - /// - /// Initializes a new instance of the class, - /// applying the specified IVariableSource to all object metadata values. - /// - /// The variable source. - public ObjectDefinitionVisitor(IVariableSource variableSource) - { - this.variableSource = variableSource; - } - - /// - /// Initializes a new instance of the class - /// for subclassing - /// - /// Subclasses should override the ResolveStringValue method - protected ObjectDefinitionVisitor() - { - } - - /// - /// Traverse the given ObjectDefinition object and the MutablePropertyValues - /// and ConstructorArgumentValues contained in them. - /// - /// The object definition to traverse. - public virtual void VisitObjectDefinition(IObjectDefinition definition) - { - VisitObjectTypeName(definition); - VisitPropertyValues(definition); - - ConstructorArgumentValues cas = definition.ConstructorArgumentValues; - if (cas != null) - { - VisitIndexedArgumentValues(cas.IndexedArgumentValues); - VisitNamedArgumentValues(cas.NamedArgumentValues); - VisitGenericArgumentValues(cas.GenericArgumentValues); - } - } - - /// - /// Visits the ObjectDefinition property ObjectTypeName, replacing string values using - /// the specified IVariableSource. - /// - /// The object definition. - protected virtual void VisitObjectTypeName(IObjectDefinition objectDefinition) - { - string objectTypeName = objectDefinition.ObjectTypeName; - if (objectTypeName != null) - { - string resolvedName = ResolveStringValue(objectTypeName).ToString(); - if (!objectTypeName.Equals(resolvedName)) - { - objectDefinition.ObjectTypeName = resolvedName; - } - } - } - - - /// - /// Visits the property values of the ObjectDefinition, replacing string values - /// using the specified IVariableSource. - /// - /// The object definition. - protected virtual void VisitPropertyValues(IObjectDefinition objectDefinition) - { - MutablePropertyValues pvs = objectDefinition.PropertyValues; - if (pvs != null) - { - for (int j = 0; j < pvs.PropertyValues.Length; j++) - { - PropertyValue pv = pvs.PropertyValues[j]; - object newVal = ResolveValue(pv.Value); - if (!ObjectUtils.NullSafeEquals(newVal, pv.Value)) - { - pvs.Add(pv.Name, newVal); - } - } - } - } - - /// - /// Visits the indexed constructor argument values, replacing string values using the - /// specified IVariableSource. - /// - /// The indexed argument values. - protected virtual void VisitIndexedArgumentValues(IDictionary ias) - { - foreach (ConstructorArgumentValues.ValueHolder valueHolder in ias.Values) - { - ConfigureConstructorArgument(valueHolder); - } - } - - /// - /// Visits the named constructor argument values, replacing string values using the - /// specified IVariableSource. - /// - /// The named argument values. - protected virtual void VisitNamedArgumentValues(IDictionary nav) - { - foreach (ConstructorArgumentValues.ValueHolder valueHolder in nav.Values) - { - ConfigureConstructorArgument(valueHolder); - } - } - - /// - /// Visits the generic constructor argument values, replacing string values using - /// the specified IVariableSource. - /// - /// The genreic argument values. - protected virtual void VisitGenericArgumentValues(IList gav) - { - foreach (ConstructorArgumentValues.ValueHolder valueHolder in gav) - { - ConfigureConstructorArgument(valueHolder); - } - } - - /// - /// Configures the constructor argument ValueHolder. - /// - /// The vconstructor alue holder. - protected void ConfigureConstructorArgument(ConstructorArgumentValues.ValueHolder valueHolder) - { - object newVal = ResolveValue(valueHolder.Value); - if (!ObjectUtils.NullSafeEquals(newVal, valueHolder.Value)) - { - valueHolder.Value = newVal; - } - } - - /// - /// Resolves the given value taken from an object definition according to its type - /// - /// the value to resolve - /// the resolved value - protected virtual object ResolveValue(object value) - { - if (value is IObjectDefinition) - { - VisitObjectDefinition((IObjectDefinition)value); - } - else if (value is ObjectDefinitionHolder) - { - VisitObjectDefinition( ((ObjectDefinitionHolder)value).ObjectDefinition); - } - else if (value is RuntimeObjectReference) - { - RuntimeObjectReference ror = (RuntimeObjectReference)value; - //name has to be of string type. - string newObjectName = ResolveStringValue(ror.ObjectName).ToString(); - if (!newObjectName.Equals(ror.ObjectName)) - { - return new RuntimeObjectReference(newObjectName); - } - } - else if (value is ManagedList) - { - VisitManagedList((ManagedList)value); - } - else if (value is ManagedSet) - { - VisitManagedSet((ManagedSet)value); - } - else if (value is ManagedDictionary) - { - VisitManagedDictionary((ManagedDictionary)value); - } - else if (value is NameValueCollection) - { - VisitNameValueCollection((NameValueCollection)value); - } - else if (value is TypedStringValue) - { - TypedStringValue typedStringValue = (TypedStringValue)value; - String stringValue = typedStringValue.Value; - if (stringValue != null) - { - String visitedString = ResolveStringValue(stringValue).ToString(); - typedStringValue.Value = visitedString; - } - } - else if (value is string) - { - return ResolveStringValue((string)value); - } - else if (value is ExpressionHolder) - { - ExpressionHolder holder = (ExpressionHolder)value; - string newExpressionString = ResolveStringValue(holder.ExpressionString).ToString(); - return new ExpressionHolder(newExpressionString); - } - return value; - } - - /// - /// Visits the ManagedList property ElementTypeName and - /// calls for list element. - /// - protected virtual void VisitManagedList(ManagedList listVal) - { - string elementTypeName = listVal.ElementTypeName; - if (elementTypeName != null) - { - string resolvedName = ResolveStringValue(elementTypeName).ToString(); - if (!elementTypeName.Equals(resolvedName)) - { - listVal.ElementTypeName = resolvedName; - } - } - - for (int i = 0; i < listVal.Count; ++i) - { - object oldValue = listVal[i]; - object newValue = ResolveValue(oldValue); - if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) - { - listVal[i] = newValue; - } - } - } - - /// - /// Visits the ManagedSet property ElementTypeName and - /// calls for list element. - /// - protected virtual void VisitManagedSet(ManagedSet setVal) - { - string elementTypeName = setVal.ElementTypeName; - if (elementTypeName != null) - { - string resolvedName = ResolveStringValue(elementTypeName).ToString(); - if (!elementTypeName.Equals(resolvedName)) - { - setVal.ElementTypeName = resolvedName; - } - } - - ISet clone = (ISet)setVal.Clone(); - foreach (object oldValue in clone) - { - object newValue = ResolveValue(oldValue); - if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) - { - setVal.Remove(oldValue); - setVal.Add(newValue); - } - } - } - - /// - /// Visits the ManagedSet properties KeyTypeName and ValueTypeName and - /// calls for dictionary's value element. - /// - protected virtual void VisitManagedDictionary(ManagedDictionary dictVal) - { - string keyTypeName = dictVal.KeyTypeName; - if (keyTypeName != null) - { - string resolvedName = ResolveStringValue(keyTypeName).ToString(); - if (!keyTypeName.Equals(resolvedName)) - { - dictVal.KeyTypeName = resolvedName; - } - } - - string valueTypeName = dictVal.ValueTypeName; - if (valueTypeName != null) - { - string resolvedName = ResolveStringValue(valueTypeName).ToString(); - if (!valueTypeName.Equals(resolvedName)) - { - dictVal.ValueTypeName = resolvedName; - } - } - - Hashtable mods = new Hashtable(); - foreach (DictionaryEntry entry in dictVal) - { - object oldValue = entry.Value; - object newValue = ResolveValue(oldValue); - if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) - { - mods[entry.Key] = newValue; - } - } - foreach (DictionaryEntry entry in mods) - { - dictVal[entry.Key] = entry.Value; - } - } - - /// - /// Visits the elements of a NameValueCollection and calls - /// for value of each element. - /// - protected virtual void VisitNameValueCollection(NameValueCollection collection) - { - foreach (string key in collection.AllKeys) - { - string oldValue = collection[key]; - string newValue = ResolveValue(oldValue) as string; - if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) - { - collection[key] = newValue; - } - } - } - - /// - /// Looks up the value of the given variable name in the configured . - /// - /// The name of the variable to be looked up - /// - /// The value of this variable, as returned from the passed - /// into the constructor - /// - /// If no has been configured. - protected virtual object ResolveStringValue(string variableName) - { - if (variableSource == null) - { - throw new InvalidOperationException("No IVariableSource specified - pass an instance " + - "of this object into the constructor or override the 'ResolveStringValue' method"); - } - return variableSource.ResolveVariable(variableName); - } - - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; + +using Spring.Collections; +using Spring.Util; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Visitor class for traversing objects, in particular + /// the property values and constructor arguments contained in them resolving + /// object metadata values. + /// + /// + /// Used by and + /// to parse all string values contained in a ObjectDefinition, resolving any placeholders found. + /// + /// Mark Pollack + public class ObjectDefinitionVisitor + { + private IVariableSource variableSource; + + + /// + /// Initializes a new instance of the class, + /// applying the specified IVariableSource to all object metadata values. + /// + /// The variable source. + public ObjectDefinitionVisitor(IVariableSource variableSource) + { + this.variableSource = variableSource; + } + + /// + /// Initializes a new instance of the class + /// for subclassing + /// + /// Subclasses should override the ResolveStringValue method + protected ObjectDefinitionVisitor() + { + } + + /// + /// Traverse the given ObjectDefinition object and the MutablePropertyValues + /// and ConstructorArgumentValues contained in them. + /// + /// The object definition to traverse. + public virtual void VisitObjectDefinition(IObjectDefinition definition) + { + VisitObjectTypeName(definition); + VisitPropertyValues(definition); + + ConstructorArgumentValues cas = definition.ConstructorArgumentValues; + if (cas != null) + { + VisitIndexedArgumentValues(cas.IndexedArgumentValues); + VisitNamedArgumentValues(cas.NamedArgumentValues); + VisitGenericArgumentValues(cas.GenericArgumentValues); + } + } + + /// + /// Visits the ObjectDefinition property ObjectTypeName, replacing string values using + /// the specified IVariableSource. + /// + /// The object definition. + protected virtual void VisitObjectTypeName(IObjectDefinition objectDefinition) + { + string objectTypeName = objectDefinition.ObjectTypeName; + if (objectTypeName != null) + { + string resolvedName = ResolveStringValue(objectTypeName).ToString(); + if (!objectTypeName.Equals(resolvedName)) + { + objectDefinition.ObjectTypeName = resolvedName; + } + } + } + + + /// + /// Visits the property values of the ObjectDefinition, replacing string values + /// using the specified IVariableSource. + /// + /// The object definition. + protected virtual void VisitPropertyValues(IObjectDefinition objectDefinition) + { + MutablePropertyValues pvs = objectDefinition.PropertyValues; + if (pvs != null) + { + for (int j = 0; j < pvs.PropertyValues.Length; j++) + { + PropertyValue pv = pvs.PropertyValues[j]; + object newVal = ResolveValue(pv.Value); + if (!ObjectUtils.NullSafeEquals(newVal, pv.Value)) + { + pvs.Add(pv.Name, newVal); + } + } + } + } + + /// + /// Visits the indexed constructor argument values, replacing string values using the + /// specified IVariableSource. + /// + /// The indexed argument values. + protected virtual void VisitIndexedArgumentValues(IDictionary ias) + { + foreach (ConstructorArgumentValues.ValueHolder valueHolder in ias.Values) + { + ConfigureConstructorArgument(valueHolder); + } + } + + /// + /// Visits the named constructor argument values, replacing string values using the + /// specified IVariableSource. + /// + /// The named argument values. + protected virtual void VisitNamedArgumentValues(IDictionary nav) + { + foreach (ConstructorArgumentValues.ValueHolder valueHolder in nav.Values) + { + ConfigureConstructorArgument(valueHolder); + } + } + + /// + /// Visits the generic constructor argument values, replacing string values using + /// the specified IVariableSource. + /// + /// The genreic argument values. + protected virtual void VisitGenericArgumentValues(IList gav) + { + foreach (ConstructorArgumentValues.ValueHolder valueHolder in gav) + { + ConfigureConstructorArgument(valueHolder); + } + } + + /// + /// Configures the constructor argument ValueHolder. + /// + /// The vconstructor alue holder. + protected void ConfigureConstructorArgument(ConstructorArgumentValues.ValueHolder valueHolder) + { + object newVal = ResolveValue(valueHolder.Value); + if (!ObjectUtils.NullSafeEquals(newVal, valueHolder.Value)) + { + valueHolder.Value = newVal; + } + } + + /// + /// Resolves the given value taken from an object definition according to its type + /// + /// the value to resolve + /// the resolved value + protected virtual object ResolveValue(object value) + { + if (value is IObjectDefinition) + { + VisitObjectDefinition((IObjectDefinition)value); + } + else if (value is ObjectDefinitionHolder) + { + VisitObjectDefinition( ((ObjectDefinitionHolder)value).ObjectDefinition); + } + else if (value is RuntimeObjectReference) + { + RuntimeObjectReference ror = (RuntimeObjectReference)value; + //name has to be of string type. + string newObjectName = ResolveStringValue(ror.ObjectName).ToString(); + if (!newObjectName.Equals(ror.ObjectName)) + { + return new RuntimeObjectReference(newObjectName); + } + } + else if (value is ManagedList) + { + VisitManagedList((ManagedList)value); + } + else if (value is ManagedSet) + { + VisitManagedSet((ManagedSet)value); + } + else if (value is ManagedDictionary) + { + VisitManagedDictionary((ManagedDictionary)value); + } + else if (value is NameValueCollection) + { + VisitNameValueCollection((NameValueCollection)value); + } + else if (value is TypedStringValue) + { + TypedStringValue typedStringValue = (TypedStringValue)value; + String stringValue = typedStringValue.Value; + if (stringValue != null) + { + String visitedString = ResolveStringValue(stringValue).ToString(); + typedStringValue.Value = visitedString; + } + } + else if (value is string) + { + return ResolveStringValue((string)value); + } + else if (value is ExpressionHolder) + { + ExpressionHolder holder = (ExpressionHolder)value; + string newExpressionString = ResolveStringValue(holder.ExpressionString).ToString(); + return new ExpressionHolder(newExpressionString); + } + return value; + } + + /// + /// Visits the ManagedList property ElementTypeName and + /// calls for list element. + /// + protected virtual void VisitManagedList(ManagedList listVal) + { + string elementTypeName = listVal.ElementTypeName; + if (elementTypeName != null) + { + string resolvedName = ResolveStringValue(elementTypeName).ToString(); + if (!elementTypeName.Equals(resolvedName)) + { + listVal.ElementTypeName = resolvedName; + } + } + + for (int i = 0; i < listVal.Count; ++i) + { + object oldValue = listVal[i]; + object newValue = ResolveValue(oldValue); + if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) + { + listVal[i] = newValue; + } + } + } + + /// + /// Visits the ManagedSet property ElementTypeName and + /// calls for list element. + /// + protected virtual void VisitManagedSet(ManagedSet setVal) + { + string elementTypeName = setVal.ElementTypeName; + if (elementTypeName != null) + { + string resolvedName = ResolveStringValue(elementTypeName).ToString(); + if (!elementTypeName.Equals(resolvedName)) + { + setVal.ElementTypeName = resolvedName; + } + } + + ISet clone = (ISet)setVal.Clone(); + foreach (object oldValue in clone) + { + object newValue = ResolveValue(oldValue); + if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) + { + setVal.Remove(oldValue); + setVal.Add(newValue); + } + } + } + + /// + /// Visits the ManagedSet properties KeyTypeName and ValueTypeName and + /// calls for dictionary's value element. + /// + protected virtual void VisitManagedDictionary(ManagedDictionary dictVal) + { + string keyTypeName = dictVal.KeyTypeName; + if (keyTypeName != null) + { + string resolvedName = ResolveStringValue(keyTypeName).ToString(); + if (!keyTypeName.Equals(resolvedName)) + { + dictVal.KeyTypeName = resolvedName; + } + } + + string valueTypeName = dictVal.ValueTypeName; + if (valueTypeName != null) + { + string resolvedName = ResolveStringValue(valueTypeName).ToString(); + if (!valueTypeName.Equals(resolvedName)) + { + dictVal.ValueTypeName = resolvedName; + } + } + + Hashtable mods = new Hashtable(); + foreach (DictionaryEntry entry in dictVal) + { + object oldValue = entry.Value; + object newValue = ResolveValue(oldValue); + if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) + { + mods[entry.Key] = newValue; + } + } + foreach (DictionaryEntry entry in mods) + { + dictVal[entry.Key] = entry.Value; + } + } + + /// + /// Visits the elements of a NameValueCollection and calls + /// for value of each element. + /// + protected virtual void VisitNameValueCollection(NameValueCollection collection) + { + foreach (string key in collection.AllKeys) + { + string oldValue = collection[key]; + string newValue = ResolveValue(oldValue) as string; + if (!ObjectUtils.NullSafeEquals(newValue, oldValue)) + { + collection[key] = newValue; + } + } + } + + /// + /// Looks up the value of the given variable name in the configured . + /// + /// The name of the variable to be looked up + /// + /// The value of this variable, as returned from the passed + /// into the constructor + /// + /// If no has been configured. + protected virtual object ResolveStringValue(string variableName) + { + if (variableSource == null) + { + throw new InvalidOperationException("No IVariableSource specified - pass an instance " + + "of this object into the constructor or override the 'ResolveStringValue' method"); + } + return variableSource.ResolveVariable(variableName); + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectFactoryCreatingFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectFactoryCreatingFactoryObject.cs index 3c894ab9..9b4f857d 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectFactoryCreatingFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectFactoryCreatingFactoryObject.cs @@ -1,178 +1,177 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Returns a value that is an - /// that - /// returns an object from an - /// . - /// - /// - ///

- /// The primary motivation of this class is to avoid having a client object - /// directly calling the - /// - /// method to get a prototype object out of an - /// , which would be a - /// violation of the inversion of control principle. With the use of this - /// class, the client object can be fed an - /// as a property - /// that directly returns one target prototype object. - ///

- ///

- /// The object referred to by the value of the - /// - /// property does not have to be a prototype object, but there is little - /// to no point in using this class in conjunction with a singleton object. - ///

- ///
- /// - ///

- /// The following XML configuration snippet illustrates the use of this - /// class... - ///

- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Colin Sampaleanu - /// Simon White (.NET) - /// $Id: ObjectFactoryCreatingFactoryObject.cs,v 1.9 2007/03/16 04:01:38 aseovic Exp $ - [Serializable] - public class ObjectFactoryCreatingFactoryObject - : AbstractFactoryObject, IObjectFactoryAware - { - private string _targetObjectName; - private IObjectFactory _objectFactory; - - #region Properties - - /// - /// Sets the name of the target object. - /// - public string TargetObjectName - { - set { _targetObjectName = value; } - } - - /// - /// The target factory that will be used to perform the lookup - /// of the object referred to by the - /// property. - /// - /// - /// The owning - /// (will never be ). - /// - /// - /// In case of initialization errors. - /// - /// - public IObjectFactory ObjectFactory - { - set { this._objectFactory = value; } - } - - /// - /// The of object created by this factory. - /// - public override Type ObjectType - { - get { return typeof (IGenericObjectFactory); } - } - - #endregion - - /// - /// Returns an instance of the object factory. - /// - /// The object factory. - protected override object CreateInstance() - { - return new GenericObjectFactory(this); - } - - /// - /// Invoked by an - /// after it has set all supplied object properties. - /// - /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - /// - public override void AfterPropertiesSet() - { - if(StringUtils.IsNullOrEmpty(_targetObjectName)) - { - throw new ArgumentException("The 'TargetObjectName' property must have a value."); - } - base.AfterPropertiesSet (); - } - - private sealed class GenericObjectFactory : IGenericObjectFactory - { - private ObjectFactoryCreatingFactoryObject _enclosing; - - /// - /// Creates a new instance of the GenericObjectFactory class. - /// - /// - /// The enclosing - /// . - /// - public GenericObjectFactory( - ObjectFactoryCreatingFactoryObject enclosing) - { - _enclosing = enclosing; - } - - /// - /// Returns the object created by the enclosed object factory. - /// - /// The created object. - public object GetObject() - { - return _enclosing._objectFactory.GetObject(_enclosing._targetObjectName); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Returns a value that is an + /// that + /// returns an object from an + /// . + /// + /// + ///

+ /// The primary motivation of this class is to avoid having a client object + /// directly calling the + /// + /// method to get a prototype object out of an + /// , which would be a + /// violation of the inversion of control principle. With the use of this + /// class, the client object can be fed an + /// as a property + /// that directly returns one target prototype object. + ///

+ ///

+ /// The object referred to by the value of the + /// + /// property does not have to be a prototype object, but there is little + /// to no point in using this class in conjunction with a singleton object. + ///

+ ///
+ /// + ///

+ /// The following XML configuration snippet illustrates the use of this + /// class... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Colin Sampaleanu + /// Simon White (.NET) + [Serializable] + public class ObjectFactoryCreatingFactoryObject + : AbstractFactoryObject, IObjectFactoryAware + { + private string _targetObjectName; + private IObjectFactory _objectFactory; + + #region Properties + + /// + /// Sets the name of the target object. + /// + public string TargetObjectName + { + set { _targetObjectName = value; } + } + + /// + /// The target factory that will be used to perform the lookup + /// of the object referred to by the + /// property. + /// + /// + /// The owning + /// (will never be ). + /// + /// + /// In case of initialization errors. + /// + /// + public IObjectFactory ObjectFactory + { + set { this._objectFactory = value; } + } + + /// + /// The of object created by this factory. + /// + public override Type ObjectType + { + get { return typeof (IGenericObjectFactory); } + } + + #endregion + + /// + /// Returns an instance of the object factory. + /// + /// The object factory. + protected override object CreateInstance() + { + return new GenericObjectFactory(this); + } + + /// + /// Invoked by an + /// after it has set all supplied object properties. + /// + /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + /// + public override void AfterPropertiesSet() + { + if(StringUtils.IsNullOrEmpty(_targetObjectName)) + { + throw new ArgumentException("The 'TargetObjectName' property must have a value."); + } + base.AfterPropertiesSet (); + } + + private sealed class GenericObjectFactory : IGenericObjectFactory + { + private ObjectFactoryCreatingFactoryObject _enclosing; + + /// + /// Creates a new instance of the GenericObjectFactory class. + /// + /// + /// The enclosing + /// . + /// + public GenericObjectFactory( + ObjectFactoryCreatingFactoryObject enclosing) + { + _enclosing = enclosing; + } + + /// + /// Returns the object created by the enclosed object factory. + /// + /// The created object. + public object GetObject() + { + return _enclosing._objectFactory.GetObject(_enclosing._targetObjectName); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectReferenceFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectReferenceFactoryObject.cs index 66ac0df3..34a7e528 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ObjectReferenceFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ObjectReferenceFactoryObject.cs @@ -1,134 +1,133 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Util; - -namespace Spring.Objects.Factory.Config -{ - /// - /// An implementation - /// that exposes an arbitrary target object under a different name. - /// - /// - ///

- /// Usually, the target object will reside in a different object - /// definition file, using this - /// to link it in - /// and expose it under a different name. Effectively, this corresponds - /// to an alias for the target object. - ///

- /// - /// For XML based object definition files, a <alias> - /// tag is available that effectively achieves the same. - /// - ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ObjectReferenceFactoryObject.cs,v 1.3 2007/03/16 04:01:38 aseovic Exp $ - /// - [Serializable] - public sealed class ObjectReferenceFactoryObject - : IFactoryObject, IObjectFactoryAware - { - private string _targetObjectName; - private IObjectFactory _objectFactory; - - /// - /// The name of the target object. - /// - /// - ///

- /// The target object may potentially be defined in a different object - /// definition file. - ///

- ///
- /// The name of the target object. - public string TargetObjectName - { - set { _targetObjectName = value; } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - /// - public object GetObject() - { - return _objectFactory.GetObject(_targetObjectName); - } - - /// - /// Return the type of object that this - /// creates, or - /// if not known in advance. - /// - /// - public Type ObjectType - { - get { return _objectFactory.GetType(_targetObjectName); } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - /// - public bool IsSingleton - { - get { return _objectFactory.IsSingleton(_targetObjectName); } - } - - /// - /// Callback that supplies the owning factory to an object instance. - /// - /// - /// The owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - /// - /// In case of initialization errors. - /// - /// - public IObjectFactory ObjectFactory - { - set - { - // the call to set this property occurs 'after' all properties have been set... - _objectFactory = value; - if (StringUtils.IsNullOrEmpty(_targetObjectName)) - { - throw new ArgumentException( - "The 'TargetObjectName' property is required."); - } - if (!_objectFactory.ContainsObject(_targetObjectName)) - { - throw new NoSuchObjectDefinitionException( - _targetObjectName, _objectFactory.ToString()); - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Util; + +namespace Spring.Objects.Factory.Config +{ + /// + /// An implementation + /// that exposes an arbitrary target object under a different name. + /// + /// + ///

+ /// Usually, the target object will reside in a different object + /// definition file, using this + /// to link it in + /// and expose it under a different name. Effectively, this corresponds + /// to an alias for the target object. + ///

+ /// + /// For XML based object definition files, a <alias> + /// tag is available that effectively achieves the same. + /// + ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// + [Serializable] + public sealed class ObjectReferenceFactoryObject + : IFactoryObject, IObjectFactoryAware + { + private string _targetObjectName; + private IObjectFactory _objectFactory; + + /// + /// The name of the target object. + /// + /// + ///

+ /// The target object may potentially be defined in a different object + /// definition file. + ///

+ ///
+ /// The name of the target object. + public string TargetObjectName + { + set { _targetObjectName = value; } + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + /// + public object GetObject() + { + return _objectFactory.GetObject(_targetObjectName); + } + + /// + /// Return the type of object that this + /// creates, or + /// if not known in advance. + /// + /// + public Type ObjectType + { + get { return _objectFactory.GetType(_targetObjectName); } + } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + /// + public bool IsSingleton + { + get { return _objectFactory.IsSingleton(_targetObjectName); } + } + + /// + /// Callback that supplies the owning factory to an object instance. + /// + /// + /// The owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + /// + /// In case of initialization errors. + /// + /// + public IObjectFactory ObjectFactory + { + set + { + // the call to set this property occurs 'after' all properties have been set... + _objectFactory = value; + if (StringUtils.IsNullOrEmpty(_targetObjectName)) + { + throw new ArgumentException( + "The 'TargetObjectName' property is required."); + } + if (!_objectFactory.ContainsObject(_targetObjectName)) + { + throw new NoSuchObjectDefinitionException( + _targetObjectName, _objectFactory.ToString()); + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyFileVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyFileVariableSource.cs index 9dae39c1..69fdce31 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyFileVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyFileVariableSource.cs @@ -1,102 +1,101 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.IO; -using Spring.Core.IO; -using Spring.Util; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name against Java-style property file. - /// - /// - /// Aleksandar Seovic - /// $Id: PropertyFileVariableSource.cs,v 1.5 2007/08/08 17:47:13 bbaia Exp $ - [Serializable] - public class PropertyFileVariableSource : IVariableSource - { - private IResource[] locations; - private Properties properties; - - /// - /// Gets or sets the locations of the property files - /// to read properties from. - /// - /// - /// The locations of the property files - /// to read properties from. - /// - public IResource[] Locations - { - get { return locations; } - set { locations = value; } - } - - /// - /// Convinience property. Gets or sets a single location - /// to read properties from. - /// - /// - /// A location to read properties from. - /// - public IResource Location - { - set { locations = new IResource[] { value} ;} - } - - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - if (properties == null) - { - InitProperties(); - } - return properties.GetProperty(name); - } - - /// - /// Initializes properties based on the specified - /// property file locations. - /// - private void InitProperties() - { - properties = new Properties(); - foreach (IResource location in locations) - { - using (Stream input = location.InputStream) - { - properties.Load(input); - } - } - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.IO; +using Spring.Core.IO; +using Spring.Util; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name against Java-style property file. + /// + /// + /// Aleksandar Seovic + [Serializable] + public class PropertyFileVariableSource : IVariableSource + { + private IResource[] locations; + private Properties properties; + + /// + /// Gets or sets the locations of the property files + /// to read properties from. + /// + /// + /// The locations of the property files + /// to read properties from. + /// + public IResource[] Locations + { + get { return locations; } + set { locations = value; } + } + + /// + /// Convinience property. Gets or sets a single location + /// to read properties from. + /// + /// + /// A location to read properties from. + /// + public IResource Location + { + set { locations = new IResource[] { value} ;} + } + + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + if (properties == null) + { + InitProperties(); + } + return properties.GetProperty(name); + } + + /// + /// Initializes properties based on the specified + /// property file locations. + /// + private void InitProperties() + { + properties = new Properties(); + foreach (IResource location in locations) + { + using (Stream input = location.InputStream) + { + properties.Load(input); + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyOverrideConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyOverrideConfigurer.cs index 116c4bad..17e978f9 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyOverrideConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyOverrideConfigurer.cs @@ -1,203 +1,202 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections.Specialized; -using System.Globalization; -using Common.Logging; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Overrides default values in one or more object definitions. - /// - /// - ///

- /// Instances of this class override already existing values, and is - /// thus best suited to replacing defaults. If you need to replace - /// placeholder values, consider using the - /// - /// class instead. - ///

- ///

- /// In contrast to the - /// - /// class, the original object definition can have default - /// values or no values at all for such object properties. If an overriding - /// configuration file does not have an entry for a certain object property, - /// the default object value is left as is. Also note that it is not - /// immediately obvious to discern which object definitions will be mutated by - /// one or more - /// s - /// simply by looking at the object configuration. - ///

- ///

- /// Each line in a referenced configuration file is expected to take the - /// following form... - ///

- /// - /// - /// - ///

- /// The name.property key refers to the object name and the - /// property that is to be overridden; and the value is the overridding - /// value that will be inserted into the appropriate object definition's - /// named property. - ///

- ///

- /// Please note that in the case of multiple - /// s - /// that define different values for the same object definition value, the - /// last overridden value will win (due to the fact that the values - /// supplied by previous - /// s - /// will be overridden). - ///

- ///
- /// - ///

- /// The following XML context definition defines an object that has a number - /// of properties, all of which have default values... - ///

- /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// What follows is a .NET config file snippet for the above example (assuming - /// the need to override one of the default values)... - ///

- /// - /// - /// - /// - /// - /// - ///
- /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: PropertyOverrideConfigurer.cs,v 1.11 2007/10/10 16:31:39 bbaia Exp $ - /// - /// - /// - [Serializable] - public class PropertyOverrideConfigurer : PropertyResourceConfigurer - { - private ILog _logger = LogManager.GetLogger(typeof (PropertyOverrideConfigurer)); - - /// - /// Apply the given properties to the supplied - /// . - /// - /// - /// The - /// used by the application context. - /// - /// The properties to apply. - /// - /// If an error occured. - /// - protected override void ProcessProperties( - IConfigurableListableObjectFactory factory, NameValueCollection props) - { - foreach (string key in props.AllKeys) - { - ProcessKey(factory, key, props[key]); - } - } - - /// - /// Process the given key as 'name.property' entry. - /// - /// - /// The object factory containing the object definitions that are to be - /// processed. - /// - /// The key. - /// The value. - /// - /// If an error occurs. - /// - /// - /// If the property was not well formed (i.e. not in the format "name.property"). - /// - protected virtual void ProcessKey( - IConfigurableListableObjectFactory factory, string key, string value) - { - int dotIndex = key.IndexOf('.'); - if (dotIndex == -1) - { - throw new FatalObjectException( - string.Format(CultureInfo.InvariantCulture, - "Invalid key '{0}': expected 'objectName.property' form.", key)); - } - string name = key.Substring(0, dotIndex); - string objectProperty = key.Substring(dotIndex + 1); - IObjectDefinition definition = factory.GetObjectDefinition(name); - if(definition != null) - { - PropertyValue pv = definition.PropertyValues.GetPropertyValue(objectProperty); - if (pv != null && pv.Value is RuntimeObjectReference) - { - definition.PropertyValues.Add(objectProperty, new RuntimeObjectReference(value)); - } - else if (pv != null && pv.Value is ExpressionHolder) - { - definition.PropertyValues.Add(objectProperty, new ExpressionHolder(value)); - } - else - { - definition.PropertyValues.Add(objectProperty, value); - } - } - else - { - #region Instrumentation - - if (_logger.IsWarnEnabled) - { - _logger.Warn(string.Format(CultureInfo.InvariantCulture, - "Cannot find object '{0}' when overriding properties; check configuration.", name)); - } - - #endregion - } - - #region Instrumentation - - if (_logger.IsDebugEnabled) - { - _logger.Debug(string.Format(CultureInfo.InvariantCulture, - "Property '{0}' set to '{1}'.", key, value)); - } - - #endregion - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections.Specialized; +using System.Globalization; +using Common.Logging; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Overrides default values in one or more object definitions. + /// + /// + ///

+ /// Instances of this class override already existing values, and is + /// thus best suited to replacing defaults. If you need to replace + /// placeholder values, consider using the + /// + /// class instead. + ///

+ ///

+ /// In contrast to the + /// + /// class, the original object definition can have default + /// values or no values at all for such object properties. If an overriding + /// configuration file does not have an entry for a certain object property, + /// the default object value is left as is. Also note that it is not + /// immediately obvious to discern which object definitions will be mutated by + /// one or more + /// s + /// simply by looking at the object configuration. + ///

+ ///

+ /// Each line in a referenced configuration file is expected to take the + /// following form... + ///

+ /// + /// + /// + ///

+ /// The name.property key refers to the object name and the + /// property that is to be overridden; and the value is the overridding + /// value that will be inserted into the appropriate object definition's + /// named property. + ///

+ ///

+ /// Please note that in the case of multiple + /// s + /// that define different values for the same object definition value, the + /// last overridden value will win (due to the fact that the values + /// supplied by previous + /// s + /// will be overridden). + ///

+ ///
+ /// + ///

+ /// The following XML context definition defines an object that has a number + /// of properties, all of which have default values... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// What follows is a .NET config file snippet for the above example (assuming + /// the need to override one of the default values)... + ///

+ /// + /// + /// + /// + /// + /// + ///
+ /// Juergen Hoeller + /// Simon White (.NET) + /// + /// + /// + [Serializable] + public class PropertyOverrideConfigurer : PropertyResourceConfigurer + { + private ILog _logger = LogManager.GetLogger(typeof (PropertyOverrideConfigurer)); + + /// + /// Apply the given properties to the supplied + /// . + /// + /// + /// The + /// used by the application context. + /// + /// The properties to apply. + /// + /// If an error occured. + /// + protected override void ProcessProperties( + IConfigurableListableObjectFactory factory, NameValueCollection props) + { + foreach (string key in props.AllKeys) + { + ProcessKey(factory, key, props[key]); + } + } + + /// + /// Process the given key as 'name.property' entry. + /// + /// + /// The object factory containing the object definitions that are to be + /// processed. + /// + /// The key. + /// The value. + /// + /// If an error occurs. + /// + /// + /// If the property was not well formed (i.e. not in the format "name.property"). + /// + protected virtual void ProcessKey( + IConfigurableListableObjectFactory factory, string key, string value) + { + int dotIndex = key.IndexOf('.'); + if (dotIndex == -1) + { + throw new FatalObjectException( + string.Format(CultureInfo.InvariantCulture, + "Invalid key '{0}': expected 'objectName.property' form.", key)); + } + string name = key.Substring(0, dotIndex); + string objectProperty = key.Substring(dotIndex + 1); + IObjectDefinition definition = factory.GetObjectDefinition(name); + if(definition != null) + { + PropertyValue pv = definition.PropertyValues.GetPropertyValue(objectProperty); + if (pv != null && pv.Value is RuntimeObjectReference) + { + definition.PropertyValues.Add(objectProperty, new RuntimeObjectReference(value)); + } + else if (pv != null && pv.Value is ExpressionHolder) + { + definition.PropertyValues.Add(objectProperty, new ExpressionHolder(value)); + } + else + { + definition.PropertyValues.Add(objectProperty, value); + } + } + else + { + #region Instrumentation + + if (_logger.IsWarnEnabled) + { + _logger.Warn(string.Format(CultureInfo.InvariantCulture, + "Cannot find object '{0}' when overriding properties; check configuration.", name)); + } + + #endregion + } + + #region Instrumentation + + if (_logger.IsDebugEnabled) + { + _logger.Debug(string.Format(CultureInfo.InvariantCulture, + "Property '{0}' set to '{1}'.", key, value)); + } + + #endregion + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPathFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPathFactoryObject.cs index e5616d6d..8b76d2fb 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPathFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPathFactoryObject.cs @@ -1,337 +1,336 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Config -{ - /// - /// implementation that - /// evaluates a property path on a given target object. - /// - /// - ///

- /// The target object can be specified directly or via an object name (see - /// example below). - ///

- ///

- /// Please note that the - /// is an implementation, and as such has - /// to comply with the contract of the - /// interface; more specifically, this means that the end result of the property lookup path - /// evaluation cannot be ( - /// implementations are not permitted to return ). If the resut of a - /// property lookup path evaluates to , an exception will be thrown. - ///

- ///
- /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: PropertyPathFactoryObject.cs,v 1.3 2007/03/16 04:01:39 aseovic Exp $ - [Serializable] - public class PropertyPathFactoryObject : IFactoryObject, IObjectNameAware, IObjectFactoryAware - { - private IObjectWrapper targetObjectWrapper; - private string targetObjectName; - private string propertyPath; - private Type resultType; - private string objectName; - private IObjectFactory objectFactory; - - /// - /// The target object that the property path lookup is to be applied to. - /// - /// - ///

- /// This would most likely be an inner object, but can of course be - /// any object reference. - ///

- ///
- /// - /// The target object that the property path lookup is to be applied to. - /// - /// - public object TargetObject - { - set { this.targetObjectWrapper = new ObjectWrapper(value); } - } - - /// - /// The (object) name of the target object that the property path lookup - /// is to be applied to. - /// - /// - ///

- /// Please note that any leading or trailing whitespace will be - /// trimmed from this name prior to resolution. The implication of this is that - /// one cannot use the - /// class in conjunction with object names that start or end with whitespace. - ///

- ///
- /// - /// The (object) name of the target object that the property path lookup - /// is to be applied to. - /// - /// - public string TargetObjectName - { - set - { - if (value != null) - { - value = value.Trim(); - } - this.targetObjectName = value; - } - } - - /// - /// The property (lookup) path to be applied to the target object. - /// - /// - ///

- /// Please note that any leading or trailing whitespace will be - /// trimmed from this path prior to resolution. Whitespace is not a valid - /// identifier for property names (in part or whole) in CLS-based languages, - /// so this is a not unreasonable action. Please also note that whitespace - /// that is embedded within the property path will be left as-is (which may - /// or may not result in an error being thrown, depending on the context of - /// the whitespace). - ///

- ///
- /// - ///

- /// Examples of such property lookup paths can be seen below; note that - /// property lookup paths can be nested to an arbitrary level. - ///

- /// - /// name.length - /// accountManager.account['the key'].name - /// accounts[0].name - /// - ///
- /// - /// The property (lookup) path to be applied to the target object. - /// - public string PropertyPath - { - set - { - if (value != null) - { - value = value.Trim(); - } - this.propertyPath = value; - } - } - - /// - /// The 'expected' of the result from evaluating the - /// property path. - /// - /// - ///

- /// This is not necessary for directly specified target objects, or - /// singleton target objects, where the can - /// be determined via reflection. Just specify this in case of a - /// prototype target, provided that you need matching by type (for - /// example, for autowiring). - ///

- ///

- /// It is permissable to set the value of this property to - /// (which in any case is the default value). - ///

- ///
- /// - /// The 'expected' of the result from evaluating the - /// property path. - /// - public Type ResultType - { - set { this.resultType = value; } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - /// - public object GetObject() - { - IObjectWrapper target = this.targetObjectWrapper; - if (target == null) - { - // fetch the prototype object object... - target = new ObjectWrapper(this.objectFactory[this.targetObjectName]); - } - object value = target.GetPropertyValue(this.propertyPath); - if (value == null) - { - throw new FatalObjectException("PropertyPathFactoryObject is not allowed to return null, " + - "but property value for path '" + this.propertyPath + "' is null."); - } - return value; - } - - /// - /// Return the of object that this - /// creates, or - /// if not known in advance. - /// - /// - public Type ObjectType - { - get { return this.resultType; } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - /// - public bool IsSingleton - { - get { return false; } - } - - /// - /// Set the name of the object in the object factory that created this object. - /// - /// - ///

- /// The object name of this - /// - /// will be interpreted as "objectName.property" pattern, if neither the - /// - /// - /// have been supplied (set). - ///

- ///

- /// This allows for concise object definitions with just an id or name. - ///

- ///
- /// - /// The name of the object in the factory. - /// - public string ObjectName - { - set { this.objectName = value; } - } - - /// - /// Callback that supplies the owning factory to an object instance. - /// - /// - /// Owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - /// - /// In case of initialization errors. - /// - public IObjectFactory ObjectFactory - { - set - { - this.objectFactory = value; - if (this.targetObjectWrapper != null && this.targetObjectName != null) - { - throw new ArgumentException("Only one of the TargetObjectName or TargetObject properties can be set, not both."); - } - if (this.targetObjectWrapper == null && this.targetObjectName == null) - { - if (this.propertyPath != null) - { - throw new ArgumentException( - "Specify TargetObject or TargetObjectName property in combination with PropertyPath."); - } - // no other properties specified: check object name... - string strippedObjectname = this.objectName.Trim(); - int dotIndex = strippedObjectname.IndexOf('.'); - if (dotIndex <= 0) - { - throw new ArgumentException( - "Neither TargetObject nor TargetObjectName specified, and PropertyPathFactoryObject " + - "object name '" + this.objectName + "' does not follow 'objectName.property' syntax."); - } - this.targetObjectName = strippedObjectname.Substring(0, dotIndex); - this.propertyPath = strippedObjectname.Substring(dotIndex + 1); - } - else if (this.propertyPath == null) - { - throw new ArgumentException("The 'PropertyPath' property has not been set."); - } - if (this.targetObjectWrapper == null - && this.objectFactory.IsSingleton(this.targetObjectName)) - { - // eagerly fetch singleton target object, and determine result type... - this.targetObjectWrapper - = new ObjectWrapper(this.objectFactory.GetObject(this.targetObjectName)); - this.resultType = this.targetObjectWrapper.GetPropertyType(this.propertyPath); - } - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Config +{ + /// + /// implementation that + /// evaluates a property path on a given target object. + /// + /// + ///

+ /// The target object can be specified directly or via an object name (see + /// example below). + ///

+ ///

+ /// Please note that the + /// is an implementation, and as such has + /// to comply with the contract of the + /// interface; more specifically, this means that the end result of the property lookup path + /// evaluation cannot be ( + /// implementations are not permitted to return ). If the resut of a + /// property lookup path evaluates to , an exception will be thrown. + ///

+ ///
+ /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class PropertyPathFactoryObject : IFactoryObject, IObjectNameAware, IObjectFactoryAware + { + private IObjectWrapper targetObjectWrapper; + private string targetObjectName; + private string propertyPath; + private Type resultType; + private string objectName; + private IObjectFactory objectFactory; + + /// + /// The target object that the property path lookup is to be applied to. + /// + /// + ///

+ /// This would most likely be an inner object, but can of course be + /// any object reference. + ///

+ ///
+ /// + /// The target object that the property path lookup is to be applied to. + /// + /// + public object TargetObject + { + set { this.targetObjectWrapper = new ObjectWrapper(value); } + } + + /// + /// The (object) name of the target object that the property path lookup + /// is to be applied to. + /// + /// + ///

+ /// Please note that any leading or trailing whitespace will be + /// trimmed from this name prior to resolution. The implication of this is that + /// one cannot use the + /// class in conjunction with object names that start or end with whitespace. + ///

+ ///
+ /// + /// The (object) name of the target object that the property path lookup + /// is to be applied to. + /// + /// + public string TargetObjectName + { + set + { + if (value != null) + { + value = value.Trim(); + } + this.targetObjectName = value; + } + } + + /// + /// The property (lookup) path to be applied to the target object. + /// + /// + ///

+ /// Please note that any leading or trailing whitespace will be + /// trimmed from this path prior to resolution. Whitespace is not a valid + /// identifier for property names (in part or whole) in CLS-based languages, + /// so this is a not unreasonable action. Please also note that whitespace + /// that is embedded within the property path will be left as-is (which may + /// or may not result in an error being thrown, depending on the context of + /// the whitespace). + ///

+ ///
+ /// + ///

+ /// Examples of such property lookup paths can be seen below; note that + /// property lookup paths can be nested to an arbitrary level. + ///

+ /// + /// name.length + /// accountManager.account['the key'].name + /// accounts[0].name + /// + ///
+ /// + /// The property (lookup) path to be applied to the target object. + /// + public string PropertyPath + { + set + { + if (value != null) + { + value = value.Trim(); + } + this.propertyPath = value; + } + } + + /// + /// The 'expected' of the result from evaluating the + /// property path. + /// + /// + ///

+ /// This is not necessary for directly specified target objects, or + /// singleton target objects, where the can + /// be determined via reflection. Just specify this in case of a + /// prototype target, provided that you need matching by type (for + /// example, for autowiring). + ///

+ ///

+ /// It is permissable to set the value of this property to + /// (which in any case is the default value). + ///

+ ///
+ /// + /// The 'expected' of the result from evaluating the + /// property path. + /// + public Type ResultType + { + set { this.resultType = value; } + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + /// + public object GetObject() + { + IObjectWrapper target = this.targetObjectWrapper; + if (target == null) + { + // fetch the prototype object object... + target = new ObjectWrapper(this.objectFactory[this.targetObjectName]); + } + object value = target.GetPropertyValue(this.propertyPath); + if (value == null) + { + throw new FatalObjectException("PropertyPathFactoryObject is not allowed to return null, " + + "but property value for path '" + this.propertyPath + "' is null."); + } + return value; + } + + /// + /// Return the of object that this + /// creates, or + /// if not known in advance. + /// + /// + public Type ObjectType + { + get { return this.resultType; } + } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + /// + public bool IsSingleton + { + get { return false; } + } + + /// + /// Set the name of the object in the object factory that created this object. + /// + /// + ///

+ /// The object name of this + /// + /// will be interpreted as "objectName.property" pattern, if neither the + /// + /// + /// have been supplied (set). + ///

+ ///

+ /// This allows for concise object definitions with just an id or name. + ///

+ ///
+ /// + /// The name of the object in the factory. + /// + public string ObjectName + { + set { this.objectName = value; } + } + + /// + /// Callback that supplies the owning factory to an object instance. + /// + /// + /// Owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + /// + /// In case of initialization errors. + /// + public IObjectFactory ObjectFactory + { + set + { + this.objectFactory = value; + if (this.targetObjectWrapper != null && this.targetObjectName != null) + { + throw new ArgumentException("Only one of the TargetObjectName or TargetObject properties can be set, not both."); + } + if (this.targetObjectWrapper == null && this.targetObjectName == null) + { + if (this.propertyPath != null) + { + throw new ArgumentException( + "Specify TargetObject or TargetObjectName property in combination with PropertyPath."); + } + // no other properties specified: check object name... + string strippedObjectname = this.objectName.Trim(); + int dotIndex = strippedObjectname.IndexOf('.'); + if (dotIndex <= 0) + { + throw new ArgumentException( + "Neither TargetObject nor TargetObjectName specified, and PropertyPathFactoryObject " + + "object name '" + this.objectName + "' does not follow 'objectName.property' syntax."); + } + this.targetObjectName = strippedObjectname.Substring(0, dotIndex); + this.propertyPath = strippedObjectname.Substring(dotIndex + 1); + } + else if (this.propertyPath == null) + { + throw new ArgumentException("The 'PropertyPath' property has not been set."); + } + if (this.targetObjectWrapper == null + && this.objectFactory.IsSingleton(this.targetObjectName)) + { + // eagerly fetch singleton target object, and determine result type... + this.targetObjectWrapper + = new ObjectWrapper(this.objectFactory.GetObject(this.targetObjectName)); + this.resultType = this.targetObjectWrapper.GetPropertyType(this.propertyPath); + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPlaceholderConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPlaceholderConfigurer.cs index 1064dca0..20329884 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPlaceholderConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyPlaceholderConfigurer.cs @@ -1,414 +1,413 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Globalization; -using Common.Logging; -using Spring.Collections; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Resolves placeholder values in one or more object definitions. - /// - /// - ///

- /// The default placeholder syntax follows the NAnt style: ${...}. - /// Instances of this class can be configured in the same way as any other - /// object in a Spring.NET container, and so custom placeholder prefix - /// and suffix values can be set via the - /// and properties. - ///

- /// - ///

- /// The following example XML context definition defines an object that has - /// a number of placeholders. The placeholders can easily be distinguished - /// by the presence of the ${} characters. - ///

- /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// The associated XML configuration file for the above example containing the - /// values for the placeholders would contain a snippet such as .. - ///

- /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// The preceding XML snippet listing the various property keys and their - /// associated values needs to be inserted into the .NET config file of - /// your application (or Web.config file for your ASP.NET web application, - /// as the case may be), like so... - ///

- /// - /// - /// - /// - /// - /// - /// - /// - ///
- ///

- /// - /// checks simple property values, lists, dictionaries, sets, constructor - /// values, object type name, and object names in - /// runtime object references ( - /// ). - /// Furthermore, placeholder values can also cross-reference other - /// placeholders, in the manner of the following example where the - /// rootPath property is cross-referenced by the subPath - /// property. - ///

- /// - /// - /// - /// - /// - /// - /// - /// - ///

- /// In contrast to the - /// - /// class, this configurer only permits the replacement of explicit - /// placeholders in object definitions. Therefore, the original definition - /// cannot specify any default values for its object properties, and the - /// placeholder configuration file is expected to contain an entry for each - /// defined placeholder. That is, if an object definition contains a - /// placeholder ${foo}, there should be an associated - /// <add key="foo" value="..."/> entry in the - /// referenced placeholder configuration file. Default property values - /// can be defined via the inherited - /// - /// collection to overcome any perceived limitation of this feature. - ///

- ///

- /// If a configurer cannot resolve a placeholder, and the value of the - /// - /// property is currently set to , an - /// - /// will be thrown. If you want to resolve properties from multiple configuration - /// resources, simply specify multiple resources via the - /// - /// property. Finally, please note that you can also define multiple - /// - /// instances, each with their own custom placeholder syntax. - ///

- ///
- /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: PropertyPlaceholderConfigurer.cs,v 1.23 2007/08/02 22:18:32 markpollack Exp $ - /// - /// - /// - [Serializable] - public class PropertyPlaceholderConfigurer : PropertyResourceConfigurer - { - /// - /// The default placeholder prefix. - /// - public const string DefaultPlaceholderPrefix = "${"; - - /// - /// The default placeholder suffix. - /// - public const string DefaultPlaceholderSuffix = "}"; - - private ILog logger = LogManager.GetLogger(typeof (PropertyPlaceholderConfigurer)); - private bool ignoreUnresolvablePlaceholders = false; - private string placeholderPrefix = DefaultPlaceholderPrefix; - private string placeholderSuffix = DefaultPlaceholderSuffix; - - private EnvironmentVariableMode environmentVariableMode = EnvironmentVariableMode.Fallback; - - - #region Properties - /// - /// The placeholder prefix (the default is ${). - /// - /// - public string PlaceholderPrefix - { - set { placeholderPrefix = value; } - } - - /// - /// The placeholder suffix (the default is }) - /// - /// - public string PlaceholderSuffix - { - set { placeholderSuffix = value; } - } - - /// - /// Indicates whether unresolved placeholders should be ignored. - /// - public bool IgnoreUnresolvablePlaceholders - { - get { return ignoreUnresolvablePlaceholders; } - set { ignoreUnresolvablePlaceholders = value; } - } - - /// - /// Controls how environment variables will be used to - /// replace property placeholders. - /// - /// - ///

- /// See the overview of the - /// - /// enumeration for the available options. - ///

- ///
- public EnvironmentVariableMode EnvironmentVariableMode - { - set { environmentVariableMode = value; } - } - - #endregion - - /// - /// Apply the given properties to the supplied - /// . - /// - /// - /// The - /// used by the application context. - /// - /// The properties to apply. - /// - /// If an error occured. - /// - protected override void ProcessProperties( - IConfigurableListableObjectFactory factory, NameValueCollection props) - { - IVariableSource variableSource = new PlaceholderResolvingStringVariableSource(this, props); - ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(variableSource); - - string[] objectDefinitionNames = factory.GetObjectDefinitionNames(); - for (int i = 0; i < objectDefinitionNames.Length; ++i) - { - string name = objectDefinitionNames[i]; - IObjectDefinition definition = factory.GetObjectDefinition(name); - try - { - visitor.VisitObjectDefinition(definition); - } - catch (ObjectDefinitionStoreException ex) - { - throw new ObjectDefinitionStoreException( - definition.ResourceDescription, name, ex.Message); - } - } - } - - - - - - - /// - /// Parse values recursively to be able to resolve cross-references between - /// placeholder values. - /// - /// - /// The map of constructor arguments / property values. - /// - /// The string to be resolved. - /// The placeholders that have already been visited - /// during the current resolution attempt (used to detect circular references - /// between placeholders). Only non-null if we're parsing a nested placeholder. - /// - /// If an error occurs. - /// - /// The resolved string. - public virtual string ParseString( - NameValueCollection properties, string strVal, ISet visitedPlaceholders) - { - int startIndex = strVal.IndexOf(placeholderPrefix); - while (startIndex != -1) - { - int endIndex = strVal.IndexOf( - placeholderSuffix, startIndex + placeholderPrefix.Length); - if (endIndex != -1) - { - int pos = startIndex + placeholderPrefix.Length; - string placeholder = strVal.Substring(pos, endIndex - pos); - if (visitedPlaceholders.Contains(placeholder)) - { - throw new ObjectDefinitionStoreException( - string.Format( - CultureInfo.InvariantCulture, - "Circular placeholder reference '{0}' detected " + - "in property definitions [{1}].", - placeholder, properties)); - } - visitedPlaceholders.Add(placeholder); - string resolvedValue = ResolvePlaceholder(placeholder, properties, environmentVariableMode); - if (resolvedValue != null) - { - resolvedValue = ParseString(properties, resolvedValue, visitedPlaceholders); - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format( - CultureInfo.InvariantCulture, - "Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue)); - } - - #endregion - - strVal = strVal.Substring(0, startIndex) + resolvedValue + strVal.Substring(endIndex + 1); - startIndex = strVal.IndexOf(placeholderPrefix, startIndex + resolvedValue.Length); - } - else if (ignoreUnresolvablePlaceholders) - { - // simply return the unprocessed value... - return strVal; - } - else - { - throw new ObjectDefinitionStoreException(string.Format( - CultureInfo.InvariantCulture, - "Could not resolve placeholder '{0}'.", placeholder)); - } - visitedPlaceholders.Remove(placeholder); - } - else - { - startIndex = -1; - } - } - return strVal; - } - - /// - /// Resolve the given placeholder using the given name value collection, - /// performing an environment variables check according to the given mode. - /// - /// - ///

- /// The default implementation delegates to - /// - /// before/afer the environment variable check. Subclasses can override - /// this for custom resolution strategies, including customized points - /// for the environment properties check. - ///

- ///
- /// The placeholder to resolve - /// - /// The merged name value collection of this configurer. - /// - /// The environment variable mode. - /// - /// The resolved value or if none. - /// - /// - protected virtual string ResolvePlaceholder(string placeholder, - NameValueCollection props, - EnvironmentVariableMode mode) - { - string propertyValue = null; - if (mode == Spring.Objects.Factory.Config.EnvironmentVariableMode.Override) - { - propertyValue = Environment.GetEnvironmentVariable(placeholder); - } - if (propertyValue == null) - { - propertyValue = ResolvePlaceholder(placeholder, props); - } - if (propertyValue == null - && mode == Spring.Objects.Factory.Config.EnvironmentVariableMode.Fallback) - { - propertyValue = Environment.GetEnvironmentVariable(placeholder); - } - return propertyValue; - } - - /// - /// Resolve the given placeholder using the given name value collection. - /// - /// - ///

- /// This (the default) implementation simply looks up the value of the - /// supplied key. - ///

- ///

- /// Subclasses can override this for customized placeholder-to-key - /// mappings or custom resolution strategies, possibly just using the - /// given name value collection as fallback. - ///

- ///
- /// The placeholder to resolve. - /// - /// The merged name value collection of this configurer. - /// - /// The resolved value. - protected virtual string ResolvePlaceholder( - string placeholder, NameValueCollection props) - { - return props[placeholder]; - } - } - - #region Helper class - - internal class PlaceholderResolvingStringVariableSource : IVariableSource - { - private PropertyPlaceholderConfigurer ppc; - private NameValueCollection props; - - public PlaceholderResolvingStringVariableSource(PropertyPlaceholderConfigurer outerPPC, NameValueCollection props) - { - ppc = outerPPC; - this.props = props; - } - - public string ResolveVariable(string name) - { - return ppc.ParseString(props, name, new HashedSet()); - } - } - - #endregion +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Globalization; +using Common.Logging; +using Spring.Collections; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Resolves placeholder values in one or more object definitions. + /// + /// + ///

+ /// The default placeholder syntax follows the NAnt style: ${...}. + /// Instances of this class can be configured in the same way as any other + /// object in a Spring.NET container, and so custom placeholder prefix + /// and suffix values can be set via the + /// and properties. + ///

+ /// + ///

+ /// The following example XML context definition defines an object that has + /// a number of placeholders. The placeholders can easily be distinguished + /// by the presence of the ${} characters. + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// The associated XML configuration file for the above example containing the + /// values for the placeholders would contain a snippet such as .. + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// The preceding XML snippet listing the various property keys and their + /// associated values needs to be inserted into the .NET config file of + /// your application (or Web.config file for your ASP.NET web application, + /// as the case may be), like so... + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + ///
+ ///

+ /// + /// checks simple property values, lists, dictionaries, sets, constructor + /// values, object type name, and object names in + /// runtime object references ( + /// ). + /// Furthermore, placeholder values can also cross-reference other + /// placeholders, in the manner of the following example where the + /// rootPath property is cross-referenced by the subPath + /// property. + ///

+ /// + /// + /// + /// + /// + /// + /// + /// + ///

+ /// In contrast to the + /// + /// class, this configurer only permits the replacement of explicit + /// placeholders in object definitions. Therefore, the original definition + /// cannot specify any default values for its object properties, and the + /// placeholder configuration file is expected to contain an entry for each + /// defined placeholder. That is, if an object definition contains a + /// placeholder ${foo}, there should be an associated + /// <add key="foo" value="..."/> entry in the + /// referenced placeholder configuration file. Default property values + /// can be defined via the inherited + /// + /// collection to overcome any perceived limitation of this feature. + ///

+ ///

+ /// If a configurer cannot resolve a placeholder, and the value of the + /// + /// property is currently set to , an + /// + /// will be thrown. If you want to resolve properties from multiple configuration + /// resources, simply specify multiple resources via the + /// + /// property. Finally, please note that you can also define multiple + /// + /// instances, each with their own custom placeholder syntax. + ///

+ ///
+ /// Juergen Hoeller + /// Simon White (.NET) + /// + /// + /// + [Serializable] + public class PropertyPlaceholderConfigurer : PropertyResourceConfigurer + { + /// + /// The default placeholder prefix. + /// + public const string DefaultPlaceholderPrefix = "${"; + + /// + /// The default placeholder suffix. + /// + public const string DefaultPlaceholderSuffix = "}"; + + private ILog logger = LogManager.GetLogger(typeof (PropertyPlaceholderConfigurer)); + private bool ignoreUnresolvablePlaceholders = false; + private string placeholderPrefix = DefaultPlaceholderPrefix; + private string placeholderSuffix = DefaultPlaceholderSuffix; + + private EnvironmentVariableMode environmentVariableMode = EnvironmentVariableMode.Fallback; + + + #region Properties + /// + /// The placeholder prefix (the default is ${). + /// + /// + public string PlaceholderPrefix + { + set { placeholderPrefix = value; } + } + + /// + /// The placeholder suffix (the default is }) + /// + /// + public string PlaceholderSuffix + { + set { placeholderSuffix = value; } + } + + /// + /// Indicates whether unresolved placeholders should be ignored. + /// + public bool IgnoreUnresolvablePlaceholders + { + get { return ignoreUnresolvablePlaceholders; } + set { ignoreUnresolvablePlaceholders = value; } + } + + /// + /// Controls how environment variables will be used to + /// replace property placeholders. + /// + /// + ///

+ /// See the overview of the + /// + /// enumeration for the available options. + ///

+ ///
+ public EnvironmentVariableMode EnvironmentVariableMode + { + set { environmentVariableMode = value; } + } + + #endregion + + /// + /// Apply the given properties to the supplied + /// . + /// + /// + /// The + /// used by the application context. + /// + /// The properties to apply. + /// + /// If an error occured. + /// + protected override void ProcessProperties( + IConfigurableListableObjectFactory factory, NameValueCollection props) + { + IVariableSource variableSource = new PlaceholderResolvingStringVariableSource(this, props); + ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(variableSource); + + string[] objectDefinitionNames = factory.GetObjectDefinitionNames(); + for (int i = 0; i < objectDefinitionNames.Length; ++i) + { + string name = objectDefinitionNames[i]; + IObjectDefinition definition = factory.GetObjectDefinition(name); + try + { + visitor.VisitObjectDefinition(definition); + } + catch (ObjectDefinitionStoreException ex) + { + throw new ObjectDefinitionStoreException( + definition.ResourceDescription, name, ex.Message); + } + } + } + + + + + + + /// + /// Parse values recursively to be able to resolve cross-references between + /// placeholder values. + /// + /// + /// The map of constructor arguments / property values. + /// + /// The string to be resolved. + /// The placeholders that have already been visited + /// during the current resolution attempt (used to detect circular references + /// between placeholders). Only non-null if we're parsing a nested placeholder. + /// + /// If an error occurs. + /// + /// The resolved string. + public virtual string ParseString( + NameValueCollection properties, string strVal, ISet visitedPlaceholders) + { + int startIndex = strVal.IndexOf(placeholderPrefix); + while (startIndex != -1) + { + int endIndex = strVal.IndexOf( + placeholderSuffix, startIndex + placeholderPrefix.Length); + if (endIndex != -1) + { + int pos = startIndex + placeholderPrefix.Length; + string placeholder = strVal.Substring(pos, endIndex - pos); + if (visitedPlaceholders.Contains(placeholder)) + { + throw new ObjectDefinitionStoreException( + string.Format( + CultureInfo.InvariantCulture, + "Circular placeholder reference '{0}' detected " + + "in property definitions [{1}].", + placeholder, properties)); + } + visitedPlaceholders.Add(placeholder); + string resolvedValue = ResolvePlaceholder(placeholder, properties, environmentVariableMode); + if (resolvedValue != null) + { + resolvedValue = ParseString(properties, resolvedValue, visitedPlaceholders); + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format( + CultureInfo.InvariantCulture, + "Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue)); + } + + #endregion + + strVal = strVal.Substring(0, startIndex) + resolvedValue + strVal.Substring(endIndex + 1); + startIndex = strVal.IndexOf(placeholderPrefix, startIndex + resolvedValue.Length); + } + else if (ignoreUnresolvablePlaceholders) + { + // simply return the unprocessed value... + return strVal; + } + else + { + throw new ObjectDefinitionStoreException(string.Format( + CultureInfo.InvariantCulture, + "Could not resolve placeholder '{0}'.", placeholder)); + } + visitedPlaceholders.Remove(placeholder); + } + else + { + startIndex = -1; + } + } + return strVal; + } + + /// + /// Resolve the given placeholder using the given name value collection, + /// performing an environment variables check according to the given mode. + /// + /// + ///

+ /// The default implementation delegates to + /// + /// before/afer the environment variable check. Subclasses can override + /// this for custom resolution strategies, including customized points + /// for the environment properties check. + ///

+ ///
+ /// The placeholder to resolve + /// + /// The merged name value collection of this configurer. + /// + /// The environment variable mode. + /// + /// The resolved value or if none. + /// + /// + protected virtual string ResolvePlaceholder(string placeholder, + NameValueCollection props, + EnvironmentVariableMode mode) + { + string propertyValue = null; + if (mode == Spring.Objects.Factory.Config.EnvironmentVariableMode.Override) + { + propertyValue = Environment.GetEnvironmentVariable(placeholder); + } + if (propertyValue == null) + { + propertyValue = ResolvePlaceholder(placeholder, props); + } + if (propertyValue == null + && mode == Spring.Objects.Factory.Config.EnvironmentVariableMode.Fallback) + { + propertyValue = Environment.GetEnvironmentVariable(placeholder); + } + return propertyValue; + } + + /// + /// Resolve the given placeholder using the given name value collection. + /// + /// + ///

+ /// This (the default) implementation simply looks up the value of the + /// supplied key. + ///

+ ///

+ /// Subclasses can override this for customized placeholder-to-key + /// mappings or custom resolution strategies, possibly just using the + /// given name value collection as fallback. + ///

+ ///
+ /// The placeholder to resolve. + /// + /// The merged name value collection of this configurer. + /// + /// The resolved value. + protected virtual string ResolvePlaceholder( + string placeholder, NameValueCollection props) + { + return props[placeholder]; + } + } + + #region Helper class + + internal class PlaceholderResolvingStringVariableSource : IVariableSource + { + private PropertyPlaceholderConfigurer ppc; + private NameValueCollection props; + + public PlaceholderResolvingStringVariableSource(PropertyPlaceholderConfigurer outerPPC, NameValueCollection props) + { + ppc = outerPPC; + this.props = props; + } + + public string ResolveVariable(string name) + { + return ppc.ParseString(props, name, new HashedSet()); + } + } + + #endregion } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyResourceConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyResourceConfigurer.cs index 2bbcd427..de70f204 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyResourceConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyResourceConfigurer.cs @@ -1,393 +1,392 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections.Specialized; -using System.Globalization; -using Common.Logging; -using Spring.Core; -using Spring.Core.IO; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Allows for the configuration of individual object property values from - /// a .NET .config file. - /// - /// - ///

- /// Useful for custom .NET .config files targetted at system administrators - /// that override object properties configured in the application context. - ///

- ///

- /// Two concrete implementations are provided in the Spring.NET core library: - /// - /// - /// - /// - /// for <add key="placeholderKey" value="..."/> style - /// overriding (pushing values from a .NET .config file into object - /// definitions). - /// - /// - /// - /// - /// - /// for replacing "${...}" placeholders (pulling values from a .NET .config - /// file into object definitions). - /// - /// - /// - ///

- ///

- /// Please refer to the API documentation for the concrete implementations - /// listed above for example usage. - ///

- ///
- /// Juergen Hoeller - /// Simon White (.NET) - /// - /// - /// $Id: PropertyResourceConfigurer.cs,v 1.19 2007/08/27 14:49:42 oakinger Exp $ - [Serializable] - public abstract class PropertyResourceConfigurer - : IObjectFactoryPostProcessor, IOrdered - { - /// - /// The default configuration section name to use if none is explictly supplied. - /// - /// - public const string DefaultConfigSectionName = "spring-config"; - - #region Fields - - private static readonly ILog _log = LogManager.GetLogger(typeof(PropertyResourceConfigurer)); - - private int _order = Int32.MaxValue; // default: same as non-Ordered - private NameValueCollection _defaultProperties; - private IResource[] _locations; - private string[] _configSections; - private bool _ignoreResourceNotFound = false; - private bool _lastLocationOverrides = true; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected PropertyResourceConfigurer() - { - } - - #endregion - - #region Properties - - /// - /// The policy for resolving conflicting property overrides from - /// several resources. - /// - /// - ///

- /// When merging conflicting property overrides from several resources, - /// should append an override with the same key be appended to the - /// current value, or should the property override from the last resource - /// processed override previous values? - ///

- ///

- /// The default value is ; i.e. a property - /// override from the last resource to be processed overrides previous - /// values. - ///

- ///
- /// - /// if the property override from the last resource - /// processed overrides previous values. - /// - public bool LastLocationOverrides - { - set { _lastLocationOverrides = value; } - } - - /// - /// Return the order value of this object, where a higher value means greater in - /// terms of sorting. - /// - /// The order value. - /// - public int Order - { - get { return _order; } - set { _order = value; } - } - - /// - /// The default properties to be applied. - /// - /// - ///

- /// These are to be considered defaults, to be overridden by values - /// loaded from other resources. - ///

- ///
- public NameValueCollection Properties - { - get { return _defaultProperties; } - set { _defaultProperties = value; } - } - - /// - /// The location of the .NET .config file that contains the property - /// overrides that are to be applied. - /// - public IResource Location - { - set { _locations = new IResource[] {value}; } - } - - /// - /// The locations of the .NET .config files containing the property - /// overrides that are to be applied. - /// - public IResource[] Locations - { - set { _locations = value; } - } - - /// - /// The configuration sections to look for within the .config files. - /// - /// - /// - public string[] ConfigSections - { - get - { - if (_configSections == null - || _configSections.Length == 0) - { - _configSections = new string[] {DefaultConfigSectionName}; - } - return _configSections; - } - set { _configSections = value; } - } - - /// - /// Should a failure to find a .config file be ignored? - /// - /// - ///

- /// is only appropriate if the .config file is - /// completely optional. The default is . - ///

- ///
- /// - /// if a failure to find a .config file is to be - /// ignored. - /// - public bool IgnoreResourceNotFound - { - set { _ignoreResourceNotFound = value; } - } - - #endregion - - /// - /// Modify the application context's internal object factory after its - /// standard initialization. - /// - /// - /// The object factory used by the application context. - /// - /// - /// In case of errors. - /// - /// - public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory) - { - try - { - NameValueCollection properties = new NameValueCollection(); - InitializeWithDefaultProperties(properties); - LoadProperties(properties); - ProcessProperties(factory, properties); - } - catch (Exception ex) - { - if (typeof(ObjectsException).IsInstanceOfType(ex)) - { - throw; - } - else - { - throw new ObjectsException( - "Errored while postprocessing an object factory.", ex); - } - } - } - - /// - /// Loads properties from the configuration sections - /// specified in into . - /// - /// The instance to be filled with properties. - protected virtual void LoadProperties(NameValueCollection properties) - { - string[] configSections = ConfigSections; - if (_locations != null) - { - ValidateConfigSections(configSections); - bool usingMultipleConfigSections = configSections.Length > 1; - int sectionNameIndex = 0; - foreach (IResource resource in _locations) - { - #region Instrumentation - - if (_log.IsDebugEnabled) - { - _log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Loading configuration from '{0}'.", resource)); - } - - #endregion - - string sectionName = configSections[sectionNameIndex]; - if (resource is ConfigSectionResource) - { - ConfigurationReader.PopulateFromAppConfig( - properties, sectionName, _lastLocationOverrides); - } - else - { - if (resource.Exists) - { - ConfigurationReader.Read( - resource, sectionName, properties, _lastLocationOverrides); - } - else - { - string errorMessage = "Could not load configuration from " + resource; - if (_ignoreResourceNotFound) - { - #region Instrumentation - - if (_log.IsWarnEnabled) - { - _log.Warn(errorMessage); - } - - #endregion - } - else - { - throw new ObjectInitializationException(errorMessage); - } - } - } - if (usingMultipleConfigSections) - { - ++sectionNameIndex; - } - } - } - else - { - foreach (string sectionName in configSections) - { - ConfigurationReader.PopulateFromAppConfig( - properties, sectionName, _lastLocationOverrides); - } - } - } - - /// - /// Apply the given properties to the supplied - /// . - /// - /// - /// The - /// used by the application context. - /// - /// The properties to apply. - /// - /// If an error occured. - /// - protected abstract void ProcessProperties( - IConfigurableListableObjectFactory factory, - NameValueCollection props); - - /// - /// Validates the supplied . - /// - /// - ///

- /// Basically, if external locations are specified, ensure that either - /// one or a like number of config sections are also specified. - ///

- ///
- /// - /// The to be validated. - /// - private void ValidateConfigSections(string[] configSections) - { - if (_locations.Length != configSections.Length) - { - // if only one config section is specified for all locations that's cool... - if (configSections.Length != 1) - { - throw new ObjectInitializationException( - "Invalid number of config sections specified."); - } - } - } - - /// - /// Simply initializes the supplied - /// collection with this instances default - /// (if any). - /// - /// - /// The collection to be so initialized. - /// - private void InitializeWithDefaultProperties(NameValueCollection properties) - { - if (Properties != null) - { - properties.Add(Properties); - } - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections.Specialized; +using System.Globalization; +using Common.Logging; +using Spring.Core; +using Spring.Core.IO; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Allows for the configuration of individual object property values from + /// a .NET .config file. + /// + /// + ///

+ /// Useful for custom .NET .config files targetted at system administrators + /// that override object properties configured in the application context. + ///

+ ///

+ /// Two concrete implementations are provided in the Spring.NET core library: + /// + /// + /// + /// + /// for <add key="placeholderKey" value="..."/> style + /// overriding (pushing values from a .NET .config file into object + /// definitions). + /// + /// + /// + /// + /// + /// for replacing "${...}" placeholders (pulling values from a .NET .config + /// file into object definitions). + /// + /// + /// + ///

+ ///

+ /// Please refer to the API documentation for the concrete implementations + /// listed above for example usage. + ///

+ ///
+ /// Juergen Hoeller + /// Simon White (.NET) + /// + /// + [Serializable] + public abstract class PropertyResourceConfigurer + : IObjectFactoryPostProcessor, IOrdered + { + /// + /// The default configuration section name to use if none is explictly supplied. + /// + /// + public const string DefaultConfigSectionName = "spring-config"; + + #region Fields + + private static readonly ILog _log = LogManager.GetLogger(typeof(PropertyResourceConfigurer)); + + private int _order = Int32.MaxValue; // default: same as non-Ordered + private NameValueCollection _defaultProperties; + private IResource[] _locations; + private string[] _configSections; + private bool _ignoreResourceNotFound = false; + private bool _lastLocationOverrides = true; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected PropertyResourceConfigurer() + { + } + + #endregion + + #region Properties + + /// + /// The policy for resolving conflicting property overrides from + /// several resources. + /// + /// + ///

+ /// When merging conflicting property overrides from several resources, + /// should append an override with the same key be appended to the + /// current value, or should the property override from the last resource + /// processed override previous values? + ///

+ ///

+ /// The default value is ; i.e. a property + /// override from the last resource to be processed overrides previous + /// values. + ///

+ ///
+ /// + /// if the property override from the last resource + /// processed overrides previous values. + /// + public bool LastLocationOverrides + { + set { _lastLocationOverrides = value; } + } + + /// + /// Return the order value of this object, where a higher value means greater in + /// terms of sorting. + /// + /// The order value. + /// + public int Order + { + get { return _order; } + set { _order = value; } + } + + /// + /// The default properties to be applied. + /// + /// + ///

+ /// These are to be considered defaults, to be overridden by values + /// loaded from other resources. + ///

+ ///
+ public NameValueCollection Properties + { + get { return _defaultProperties; } + set { _defaultProperties = value; } + } + + /// + /// The location of the .NET .config file that contains the property + /// overrides that are to be applied. + /// + public IResource Location + { + set { _locations = new IResource[] {value}; } + } + + /// + /// The locations of the .NET .config files containing the property + /// overrides that are to be applied. + /// + public IResource[] Locations + { + set { _locations = value; } + } + + /// + /// The configuration sections to look for within the .config files. + /// + /// + /// + public string[] ConfigSections + { + get + { + if (_configSections == null + || _configSections.Length == 0) + { + _configSections = new string[] {DefaultConfigSectionName}; + } + return _configSections; + } + set { _configSections = value; } + } + + /// + /// Should a failure to find a .config file be ignored? + /// + /// + ///

+ /// is only appropriate if the .config file is + /// completely optional. The default is . + ///

+ ///
+ /// + /// if a failure to find a .config file is to be + /// ignored. + /// + public bool IgnoreResourceNotFound + { + set { _ignoreResourceNotFound = value; } + } + + #endregion + + /// + /// Modify the application context's internal object factory after its + /// standard initialization. + /// + /// + /// The object factory used by the application context. + /// + /// + /// In case of errors. + /// + /// + public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory) + { + try + { + NameValueCollection properties = new NameValueCollection(); + InitializeWithDefaultProperties(properties); + LoadProperties(properties); + ProcessProperties(factory, properties); + } + catch (Exception ex) + { + if (typeof(ObjectsException).IsInstanceOfType(ex)) + { + throw; + } + else + { + throw new ObjectsException( + "Errored while postprocessing an object factory.", ex); + } + } + } + + /// + /// Loads properties from the configuration sections + /// specified in into . + /// + /// The instance to be filled with properties. + protected virtual void LoadProperties(NameValueCollection properties) + { + string[] configSections = ConfigSections; + if (_locations != null) + { + ValidateConfigSections(configSections); + bool usingMultipleConfigSections = configSections.Length > 1; + int sectionNameIndex = 0; + foreach (IResource resource in _locations) + { + #region Instrumentation + + if (_log.IsDebugEnabled) + { + _log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Loading configuration from '{0}'.", resource)); + } + + #endregion + + string sectionName = configSections[sectionNameIndex]; + if (resource is ConfigSectionResource) + { + ConfigurationReader.PopulateFromAppConfig( + properties, sectionName, _lastLocationOverrides); + } + else + { + if (resource.Exists) + { + ConfigurationReader.Read( + resource, sectionName, properties, _lastLocationOverrides); + } + else + { + string errorMessage = "Could not load configuration from " + resource; + if (_ignoreResourceNotFound) + { + #region Instrumentation + + if (_log.IsWarnEnabled) + { + _log.Warn(errorMessage); + } + + #endregion + } + else + { + throw new ObjectInitializationException(errorMessage); + } + } + } + if (usingMultipleConfigSections) + { + ++sectionNameIndex; + } + } + } + else + { + foreach (string sectionName in configSections) + { + ConfigurationReader.PopulateFromAppConfig( + properties, sectionName, _lastLocationOverrides); + } + } + } + + /// + /// Apply the given properties to the supplied + /// . + /// + /// + /// The + /// used by the application context. + /// + /// The properties to apply. + /// + /// If an error occured. + /// + protected abstract void ProcessProperties( + IConfigurableListableObjectFactory factory, + NameValueCollection props); + + /// + /// Validates the supplied . + /// + /// + ///

+ /// Basically, if external locations are specified, ensure that either + /// one or a like number of config sections are also specified. + ///

+ ///
+ /// + /// The to be validated. + /// + private void ValidateConfigSections(string[] configSections) + { + if (_locations.Length != configSections.Length) + { + // if only one config section is specified for all locations that's cool... + if (configSections.Length != 1) + { + throw new ObjectInitializationException( + "Invalid number of config sections specified."); + } + } + } + + /// + /// Simply initializes the supplied + /// collection with this instances default + /// (if any). + /// + /// + /// The collection to be so initialized. + /// + private void InitializeWithDefaultProperties(NameValueCollection properties) + { + if (Properties != null) + { + properties.Add(Properties); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyRetrievingFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyRetrievingFactoryObject.cs index a598f64b..e6840e48 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/PropertyRetrievingFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/PropertyRetrievingFactoryObject.cs @@ -1,302 +1,301 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Text; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// implementation that - /// retrieves a or non-static public property value. - /// - /// - ///

- /// Typically used for retrieving public property values. - ///

- ///
- /// Rick Evans (.NET) - /// $Id: PropertyRetrievingFactoryObject.cs,v 1.12 2007/07/31 18:16:49 bbaia Exp $ - [Serializable] - public class PropertyRetrievingFactoryObject : AbstractFactoryObject, IInitializingObject - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public PropertyRetrievingFactoryObject() - { - Arguments = new object[] {}; - } - - #endregion - - #region Properties - - /// - /// The of the static property - /// to be retrieved. - /// - public string StaticProperty - { - set - { - AssertUtils.ArgumentNotNull(value, "StaticProperty"); - TypeAssemblyHolder info = new TypeAssemblyHolder(value); - string typeName = info.TypeName; - int indexWherePropertyStarts = 0; - do - { - try - { - indexWherePropertyStarts = typeName.LastIndexOf('.'); - - #region Sanity Check - - if (indexWherePropertyStarts == -1 - || indexWherePropertyStarts == typeName.Length) - { - throw new ArgumentException( - "The value passed to the StaticProperty property must be a fully " + - "qualified Type plus property name: " + - "e.g. 'Example.MyExampleClass.MyProperty, MyAssembly'"); - } - - #endregion - - typeName = typeName.Substring(0, indexWherePropertyStarts); - StringBuilder buffer = new StringBuilder(typeName); - if (info.IsAssemblyQualified) - { - buffer.Append(TypeAssemblyHolder.TypeAssemblySeparator); - buffer.Append(info.AssemblyName); - } - TargetType = TypeResolutionUtils.ResolveType(buffer.ToString()); - } - catch (TypeLoadException) - { - } - } while (TargetType == null); - TargetProperty = info.TypeName.Substring(indexWherePropertyStarts + 1); - } - } - - /// - /// Arguments for the property invocation. - /// - /// - ///

- /// If this property is not set, or the value passed to the setter invocation - /// is a null or zero-length array, a property with no arguments is assumed. - ///

- ///
- public object[] Arguments - { - get { return _arguments; } - set - { - if (value != null) - { - this._arguments = value; - } - } - } - - /// - /// The name of the property the value of which is to be retrieved. - /// - /// - ///

- /// Refers to either a property or a non-static property, - /// depending on a target object being set. - ///

- ///
- public string TargetProperty - { - get { return _targetProperty; } - set { _targetProperty = value; } - } - - /// - /// The object instance on which the property is defined. - /// - public object TargetObject - { - get { return _targetObject; } - set - { - _targetObject = value; - _targetObjectWrapper = new ObjectWrapper(_targetObject); - } - } - - /// - /// The on which the property is defined. - /// - public Type TargetType - { - get { return _targetType; } - set { _targetType = value; } - } - - /// - /// Return the type of object that this - /// creates, or - /// if not known in advance. - /// - public override Type ObjectType - { - get { return (Property == null) ? null : Property.PropertyType; } - } - - private PropertyInfo Property - { - get { return _property; } - set { _property = value; } - } - - #endregion - - #region Methods - - /// - /// Invoked by an - /// after it has set all object properties supplied - /// (and satisfied - /// and ApplicationContextAware). - /// - /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - public override void AfterPropertiesSet() - { - if (TargetType == null - && TargetObject == null) - { - throw new ArgumentException("One of the TargetType or TargetObject properties must be set."); - } - if (TargetProperty == null) - { - throw new ArgumentException("The TargetProperty property is required."); - } - Type targetType = null; - BindingFlags propertyFlags = BindingFlags.Public | BindingFlags.IgnoreCase; - if (TargetObject == null) - { - // a static property... - propertyFlags |= BindingFlags.Static; - targetType = TargetType; - if (TargetProperty.IndexOf(".") == -1) - { - Property = targetType.GetProperty(TargetProperty, propertyFlags); - } - else - { - // $£%#@! a nested static property... recurse to the end property - string property = TargetProperty; - int propertyIndex = property.IndexOf("."); - string startProperty = property.Substring(0, propertyIndex); - Property = targetType.GetProperty(startProperty, propertyFlags); - TargetObject = Property.GetValue(null, new object[] {}); - TargetProperty = property.Substring(propertyIndex + 1); - AfterPropertiesSet(); - } - } - else - { - // an instance property... - propertyFlags |= BindingFlags.Instance; - targetType = TargetObject.GetType(); - - // using the object wrapper does nested property lookup - Property = _targetObjectWrapper.GetPropertyInfo(TargetProperty); - } - if (Property == null) - { - throw new InvalidPropertyException(targetType, TargetProperty); - } - if (!Property.CanRead) - { - throw new NotWritablePropertyException(TargetProperty, targetType); - } - base.AfterPropertiesSet(); - } - - /// - /// Template method that subclasses must override to construct the object - /// returned by this factory. - /// - /// - /// If an exception occured during object creation. - /// - /// The object returned by this factory. - protected override object CreateInstance() - { - object instance = null; - object target = null; - if (TargetObject != null) - { - target = TargetObject; - } - try - { - if (Arguments.Length == 0 && target != null) - { - // using object wrapper supports nested property lookup... - instance = _targetObjectWrapper.GetPropertyValue(_targetProperty); - } - else - { - instance = Property.GetValue(target, Arguments); - } - } - catch (Exception ex) - { - throw new FatalObjectException("Error reading property value.", ex); - } - return instance; - } - - #endregion - - #region Fields - - private string _targetProperty; - private ObjectWrapper _targetObjectWrapper; - private object _targetObject; - private Type _targetType; - private PropertyInfo _property; - private object[] _arguments; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Text; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// implementation that + /// retrieves a or non-static public property value. + /// + /// + ///

+ /// Typically used for retrieving public property values. + ///

+ ///
+ /// Rick Evans (.NET) + [Serializable] + public class PropertyRetrievingFactoryObject : AbstractFactoryObject, IInitializingObject + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public PropertyRetrievingFactoryObject() + { + Arguments = new object[] {}; + } + + #endregion + + #region Properties + + /// + /// The of the static property + /// to be retrieved. + /// + public string StaticProperty + { + set + { + AssertUtils.ArgumentNotNull(value, "StaticProperty"); + TypeAssemblyHolder info = new TypeAssemblyHolder(value); + string typeName = info.TypeName; + int indexWherePropertyStarts = 0; + do + { + try + { + indexWherePropertyStarts = typeName.LastIndexOf('.'); + + #region Sanity Check + + if (indexWherePropertyStarts == -1 + || indexWherePropertyStarts == typeName.Length) + { + throw new ArgumentException( + "The value passed to the StaticProperty property must be a fully " + + "qualified Type plus property name: " + + "e.g. 'Example.MyExampleClass.MyProperty, MyAssembly'"); + } + + #endregion + + typeName = typeName.Substring(0, indexWherePropertyStarts); + StringBuilder buffer = new StringBuilder(typeName); + if (info.IsAssemblyQualified) + { + buffer.Append(TypeAssemblyHolder.TypeAssemblySeparator); + buffer.Append(info.AssemblyName); + } + TargetType = TypeResolutionUtils.ResolveType(buffer.ToString()); + } + catch (TypeLoadException) + { + } + } while (TargetType == null); + TargetProperty = info.TypeName.Substring(indexWherePropertyStarts + 1); + } + } + + /// + /// Arguments for the property invocation. + /// + /// + ///

+ /// If this property is not set, or the value passed to the setter invocation + /// is a null or zero-length array, a property with no arguments is assumed. + ///

+ ///
+ public object[] Arguments + { + get { return _arguments; } + set + { + if (value != null) + { + this._arguments = value; + } + } + } + + /// + /// The name of the property the value of which is to be retrieved. + /// + /// + ///

+ /// Refers to either a property or a non-static property, + /// depending on a target object being set. + ///

+ ///
+ public string TargetProperty + { + get { return _targetProperty; } + set { _targetProperty = value; } + } + + /// + /// The object instance on which the property is defined. + /// + public object TargetObject + { + get { return _targetObject; } + set + { + _targetObject = value; + _targetObjectWrapper = new ObjectWrapper(_targetObject); + } + } + + /// + /// The on which the property is defined. + /// + public Type TargetType + { + get { return _targetType; } + set { _targetType = value; } + } + + /// + /// Return the type of object that this + /// creates, or + /// if not known in advance. + /// + public override Type ObjectType + { + get { return (Property == null) ? null : Property.PropertyType; } + } + + private PropertyInfo Property + { + get { return _property; } + set { _property = value; } + } + + #endregion + + #region Methods + + /// + /// Invoked by an + /// after it has set all object properties supplied + /// (and satisfied + /// and ApplicationContextAware). + /// + /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + public override void AfterPropertiesSet() + { + if (TargetType == null + && TargetObject == null) + { + throw new ArgumentException("One of the TargetType or TargetObject properties must be set."); + } + if (TargetProperty == null) + { + throw new ArgumentException("The TargetProperty property is required."); + } + Type targetType = null; + BindingFlags propertyFlags = BindingFlags.Public | BindingFlags.IgnoreCase; + if (TargetObject == null) + { + // a static property... + propertyFlags |= BindingFlags.Static; + targetType = TargetType; + if (TargetProperty.IndexOf(".") == -1) + { + Property = targetType.GetProperty(TargetProperty, propertyFlags); + } + else + { + // $£%#@! a nested static property... recurse to the end property + string property = TargetProperty; + int propertyIndex = property.IndexOf("."); + string startProperty = property.Substring(0, propertyIndex); + Property = targetType.GetProperty(startProperty, propertyFlags); + TargetObject = Property.GetValue(null, new object[] {}); + TargetProperty = property.Substring(propertyIndex + 1); + AfterPropertiesSet(); + } + } + else + { + // an instance property... + propertyFlags |= BindingFlags.Instance; + targetType = TargetObject.GetType(); + + // using the object wrapper does nested property lookup + Property = _targetObjectWrapper.GetPropertyInfo(TargetProperty); + } + if (Property == null) + { + throw new InvalidPropertyException(targetType, TargetProperty); + } + if (!Property.CanRead) + { + throw new NotWritablePropertyException(TargetProperty, targetType); + } + base.AfterPropertiesSet(); + } + + /// + /// Template method that subclasses must override to construct the object + /// returned by this factory. + /// + /// + /// If an exception occured during object creation. + /// + /// The object returned by this factory. + protected override object CreateInstance() + { + object instance = null; + object target = null; + if (TargetObject != null) + { + target = TargetObject; + } + try + { + if (Arguments.Length == 0 && target != null) + { + // using object wrapper supports nested property lookup... + instance = _targetObjectWrapper.GetPropertyValue(_targetProperty); + } + else + { + instance = Property.GetValue(target, Arguments); + } + } + catch (Exception ex) + { + throw new FatalObjectException("Error reading property value.", ex); + } + return instance; + } + + #endregion + + #region Fields + + private string _targetProperty; + private ObjectWrapper _targetObjectWrapper; + private object _targetObject; + private Type _targetType; + private PropertyInfo _property; + private object[] _arguments; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/RegistryVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/RegistryVariableSource.cs index f35d3238..362f5a51 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/RegistryVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/RegistryVariableSource.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections.Specialized; -using Microsoft.Win32; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name against registry key. - /// - /// Aleksandar Seovic - /// $Id: RegistryVariableSource.cs,v 1.3 2007/08/03 08:31:24 oakinger Exp $ - public class RegistryVariableSource : IVariableSource - { - private RegistryKey key; - - /// - /// Gets or sets the registry key to obtain variable values from. - /// - /// - /// The registry key to obtain variable values from. - /// - public RegistryKey Key - { - get { return key; } - set { key = value; } - } - - /// - /// Resolves variable value for the specified variable name. - /// - /// - /// The name of the variable to resolve. - /// - /// - /// This implementation resolves REG_SZ as well as REG_MULTI_SZ values. In case of a REG_MULTI_SZ value, - /// strings are concatenated to a comma-separated list following - /// - /// - /// The variable value if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - object res = Key.GetValue(name); - if (res is string) - { - return (string) res; - } - else if (res is string[]) - { - NameValueCollection tmp = new NameValueCollection(); - foreach(string val in (string[])res) - { - tmp.Add(name, val); - } - return tmp.Get(name); - } - else if (res is int) - { - return res.ToString(); - } - return null; - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections.Specialized; +using Microsoft.Win32; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name against registry key. + /// + /// Aleksandar Seovic + public class RegistryVariableSource : IVariableSource + { + private RegistryKey key; + + /// + /// Gets or sets the registry key to obtain variable values from. + /// + /// + /// The registry key to obtain variable values from. + /// + public RegistryKey Key + { + get { return key; } + set { key = value; } + } + + /// + /// Resolves variable value for the specified variable name. + /// + /// + /// The name of the variable to resolve. + /// + /// + /// This implementation resolves REG_SZ as well as REG_MULTI_SZ values. In case of a REG_MULTI_SZ value, + /// strings are concatenated to a comma-separated list following + /// + /// + /// The variable value if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + object res = Key.GetValue(name); + if (res is string) + { + return (string) res; + } + else if (res is string[]) + { + NameValueCollection tmp = new NameValueCollection(); + foreach(string val in (string[])res) + { + tmp.Add(name, val); + } + return tmp.Get(name); + } + else if (res is int) + { + return res.ToString(); + } + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ResourceHandlerConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ResourceHandlerConfigurer.cs index 50f1b8cb..cbfff8b3 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ResourceHandlerConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ResourceHandlerConfigurer.cs @@ -1,103 +1,102 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Core.IO; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// - /// implementation that allows for convenient registration of custom - /// IResource implementations. - /// - /// - ///

- /// Because the - /// class implements the - /// - /// interface, instances of this class that have been exposed in the - /// scope of an - /// will - /// automatically be picked up by the application context and made - /// available to the IoC container whenever resolution of IResources is required. - ///

- ///
- /// Mark Pollack - /// $Id: ResourceHandlerConfigurer.cs,v 1.3 2007/08/08 17:47:13 bbaia Exp $ - /// - /// - [Serializable] - public class ResourceHandlerConfigurer : AbstractConfigurer - { - private IDictionary resourceHandlers; - - /// - /// The IResource implementations, i.e. resource handlers, to register. - /// - /// - ///

- /// The has the - /// contains the resource protocol name as the key and type as the value. - /// The key name can either be a string or an object, in which case - /// ToString() will be used to obtain the string name. - /// The value can be the fully qualified name of the IResource - /// implementation, a string, or - /// an actual of the IResource class - /// - ///

- ///
- public IDictionary ResourceHandlers - { - set { resourceHandlers = value; } - } - - /// - /// Registers custom IResource implementations. The supplied - /// is not used since IResourse implementations - /// are registered with a global - /// - /// - /// The object factory. - /// - /// - /// In case of errors. - /// - public override void PostProcessObjectFactory( - IConfigurableListableObjectFactory factory) - { - if (resourceHandlers != null) - { - foreach (DictionaryEntry entry in resourceHandlers) - { - string protocolName = entry.Key.ToString(); - Type type = ResolveRequiredType(entry.Value, "value", "custom IResource implementation"); - ResourceHandlerRegistry.RegisterResourceHandler(protocolName, type); - - } - } - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Core.IO; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// + /// implementation that allows for convenient registration of custom + /// IResource implementations. + /// + /// + ///

+ /// Because the + /// class implements the + /// + /// interface, instances of this class that have been exposed in the + /// scope of an + /// will + /// automatically be picked up by the application context and made + /// available to the IoC container whenever resolution of IResources is required. + ///

+ ///
+ /// Mark Pollack + /// + /// + [Serializable] + public class ResourceHandlerConfigurer : AbstractConfigurer + { + private IDictionary resourceHandlers; + + /// + /// The IResource implementations, i.e. resource handlers, to register. + /// + /// + ///

+ /// The has the + /// contains the resource protocol name as the key and type as the value. + /// The key name can either be a string or an object, in which case + /// ToString() will be used to obtain the string name. + /// The value can be the fully qualified name of the IResource + /// implementation, a string, or + /// an actual of the IResource class + /// + ///

+ ///
+ public IDictionary ResourceHandlers + { + set { resourceHandlers = value; } + } + + /// + /// Registers custom IResource implementations. The supplied + /// is not used since IResourse implementations + /// are registered with a global + /// + /// + /// The object factory. + /// + /// + /// In case of errors. + /// + public override void PostProcessObjectFactory( + IConfigurableListableObjectFactory factory) + { + if (resourceHandlers != null) + { + foreach (DictionaryEntry entry in resourceHandlers) + { + string protocolName = entry.Key.ToString(); + Type type = ResolveRequiredType(entry.Value, "value", "custom IResource implementation"); + ResourceHandlerRegistry.RegisterResourceHandler(protocolName, type); + + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/ResourceManagerFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/ResourceManagerFactoryObject.cs index 03c75d40..c126f91c 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/ResourceManagerFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/ResourceManagerFactoryObject.cs @@ -1,155 +1,154 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using System.Reflection; -using System.Resources; - -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// A convenience class to create a - /// given the resource base - /// name and assembly name. - /// - /// - ///

- /// This is currently the preferred way of injecting resources into view - /// tier components (such as Windows Forms GUIs and ASP.NET ASPX pages). - /// A GUI component (typically a Windows Form) is injected with - /// an instance, and can - /// then proceed to use the various GetXxx() methods on the - /// to retrieve images, - /// strings, custom resources, etc. - ///

- ///
- /// Mark Pollack - /// $Id: ResourceManagerFactoryObject.cs,v 1.11 2007/03/16 04:01:39 aseovic Exp $ - /// - /// - /// - [Serializable] - public class ResourceManagerFactoryObject : AbstractFactoryObject - { - private string _baseName; - private string _assemblyName; - - /// - /// The root name of the resources. - /// - /// - ///

- /// For example, the root name for the resource file named - /// "MyResource.en-US.resources" is "MyResource". - ///

- /// - /// The namespace is also prefixed before the resource file name. - /// - ///
- public string BaseName - { - get { return _baseName; } - set { _baseName = value; } - } - - /// - /// The string representation of the assembly that contains the resource. - /// - public string AssemblyName - { - get { return _assemblyName; } - set { _assemblyName = value; } - } - - /// - /// The . - /// - public override Type ObjectType - { - get { return typeof(ResourceManager); } - } - - /// - /// Creates a . - /// - /// - /// If an exception occured during object creation. - /// - /// The object returned by this factory. - /// - /// - protected override object CreateInstance() - { - Assembly assembly; - try - { -#if NET_2_0 - assembly = Assembly.Load(AssemblyName); -#else - assembly = Assembly.LoadWithPartialName(AssemblyName); -#endif - } - catch (FileLoadException) - { - throw new ArgumentException("Not able to load assembly with a given name [" + _assemblyName + "]"); - } - - if (assembly == null) - { - throw new ArgumentException("Not able to load assembly with a given name [" + _assemblyName + "]"); - } - - return new ResourceManager(_baseName, assembly); - } - - /// - /// Invoked by an - /// after it has set all object properties supplied - /// (and satisfied the - /// - /// and - /// interfaces). - /// - /// - /// In the event of misconfiguration (such as failure to set an essential - /// property) or if initialization fails. - /// - /// - public override void AfterPropertiesSet() - { - if (StringUtils.IsNullOrEmpty(BaseName)) - { - throw new ArgumentException("The 'BaseName' property for the resource is required."); - } - if (StringUtils.IsNullOrEmpty(AssemblyName)) - { - throw new ArgumentException("The 'AssemblyName' property for the resource is required."); - } - base.AfterPropertiesSet(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using System.Reflection; +using System.Resources; + +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// A convenience class to create a + /// given the resource base + /// name and assembly name. + /// + /// + ///

+ /// This is currently the preferred way of injecting resources into view + /// tier components (such as Windows Forms GUIs and ASP.NET ASPX pages). + /// A GUI component (typically a Windows Form) is injected with + /// an instance, and can + /// then proceed to use the various GetXxx() methods on the + /// to retrieve images, + /// strings, custom resources, etc. + ///

+ ///
+ /// Mark Pollack + /// + /// + /// + [Serializable] + public class ResourceManagerFactoryObject : AbstractFactoryObject + { + private string _baseName; + private string _assemblyName; + + /// + /// The root name of the resources. + /// + /// + ///

+ /// For example, the root name for the resource file named + /// "MyResource.en-US.resources" is "MyResource". + ///

+ /// + /// The namespace is also prefixed before the resource file name. + /// + ///
+ public string BaseName + { + get { return _baseName; } + set { _baseName = value; } + } + + /// + /// The string representation of the assembly that contains the resource. + /// + public string AssemblyName + { + get { return _assemblyName; } + set { _assemblyName = value; } + } + + /// + /// The . + /// + public override Type ObjectType + { + get { return typeof(ResourceManager); } + } + + /// + /// Creates a . + /// + /// + /// If an exception occured during object creation. + /// + /// The object returned by this factory. + /// + /// + protected override object CreateInstance() + { + Assembly assembly; + try + { +#if NET_2_0 + assembly = Assembly.Load(AssemblyName); +#else + assembly = Assembly.LoadWithPartialName(AssemblyName); +#endif + } + catch (FileLoadException) + { + throw new ArgumentException("Not able to load assembly with a given name [" + _assemblyName + "]"); + } + + if (assembly == null) + { + throw new ArgumentException("Not able to load assembly with a given name [" + _assemblyName + "]"); + } + + return new ResourceManager(_baseName, assembly); + } + + /// + /// Invoked by an + /// after it has set all object properties supplied + /// (and satisfied the + /// + /// and + /// interfaces). + /// + /// + /// In the event of misconfiguration (such as failure to set an essential + /// property) or if initialization fails. + /// + /// + public override void AfterPropertiesSet() + { + if (StringUtils.IsNullOrEmpty(BaseName)) + { + throw new ArgumentException("The 'BaseName' property for the resource is required."); + } + if (StringUtils.IsNullOrEmpty(AssemblyName)) + { + throw new ArgumentException("The 'AssemblyName' property for the resource is required."); + } + base.AfterPropertiesSet(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/RuntimeObjectReference.cs b/src/Spring/Spring.Core/Objects/Factory/Config/RuntimeObjectReference.cs index d8a74092..c5fcf837 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/RuntimeObjectReference.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/RuntimeObjectReference.cs @@ -1,130 +1,130 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Immutable placeholder class used for the value of a - /// object when it's a reference - /// to another object in this factory to be resolved at runtime. - /// - /// Rod Johnson - /// Rick Evans (.NET) - [Serializable] - public class RuntimeObjectReference - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This does not mark this object as being a reference to - /// another object in any parent factory. - ///

- ///
- /// The name of the target object. - public RuntimeObjectReference(string objectName) - : this(objectName, false) - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This variant constructor allows a client to specifiy whether or not - /// this object is a reference to another object in a parent factory. - ///

- ///
- /// The name of the target object. - /// - /// Whether this object is an explicit reference to an object in a - /// parent factory. - /// - public RuntimeObjectReference(string objectName, bool isToParent) - { - _objectName = objectName; - _isToParent = isToParent; - } - - #endregion - - #region Properties - - /// - /// Return the target object name. - /// - public string ObjectName - { - get { return _objectName; } - } - - /// - /// Is this is an explicit reference to an object in the parent - /// factory? - /// - /// - /// if this is an explicit reference to an - /// object in the parent factory. - /// - public bool IsToParent - { - get { return _isToParent; } - } - - #endregion - - #region Methods - - /// - /// Returns a string representation of this instance. - /// - /// A string representation of this instance. - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, "<{0}>", ObjectName); - } - - #endregion - - #region Fields - - private string _objectName; - - private bool _isToParent; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Immutable placeholder class used for the value of a + /// object when it's a reference + /// to another object in this factory to be resolved at runtime. + /// + /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public class RuntimeObjectReference + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This does not mark this object as being a reference to + /// another object in any parent factory. + ///

+ ///
+ /// The name of the target object. + public RuntimeObjectReference(string objectName) + : this(objectName, false) + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This variant constructor allows a client to specifiy whether or not + /// this object is a reference to another object in a parent factory. + ///

+ ///
+ /// The name of the target object. + /// + /// Whether this object is an explicit reference to an object in a + /// parent factory. + /// + public RuntimeObjectReference(string objectName, bool isToParent) + { + _objectName = objectName; + _isToParent = isToParent; + } + + #endregion + + #region Properties + + /// + /// Return the target object name. + /// + public string ObjectName + { + get { return _objectName; } + } + + /// + /// Is this is an explicit reference to an object in the parent + /// factory? + /// + /// + /// if this is an explicit reference to an + /// object in the parent factory. + /// + public bool IsToParent + { + get { return _isToParent; } + } + + #endregion + + #region Methods + + /// + /// Returns a string representation of this instance. + /// + /// A string representation of this instance. + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, "<{0}>", ObjectName); + } + + #endregion + + #region Fields + + private string _objectName; + + private bool _isToParent; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/SetFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/Config/SetFactoryObject.cs index d77ce6e9..d6ec77fb 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/SetFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/SetFactoryObject.cs @@ -1,124 +1,123 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Spring.Collections; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Simple factory object for shared instances. - /// - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: SetFactoryObject.cs,v 1.10 2007/07/31 03:47:39 markpollack Exp $ - [Serializable] - public class SetFactoryObject : AbstractFactoryObject - { - private ISet _sourceSet; - private Type _targetSetType = typeof (HybridSet); - - /// - /// Set the source . - /// - /// - ///

- /// This value will be used to populate the - /// returned by this factory. - ///

- ///
- public ISet SourceSet - { - set { this._sourceSet = value; } - } - - /// - /// Set the of the - /// implementation to use. - /// - /// - ///

- /// The default is the . - ///

- ///
- public Type TargetSetType - { - set - { - AssertUtils.ArgumentNotNull(value, "value"); - if (!typeof (ISet).IsAssignableFrom(value)) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetSetType property must implement the '{0}' interface.", - typeof (ISet).FullName)); - } - if (value.IsInterface) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetSetType property cannot be an interface; it must be a concrete class that implements the '{0}' interface.", - ObjectType.FullName)); - } - if (value.IsAbstract) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "The Type passed to the TargetSetType property cannot be abstract (MustInherit in VisualBasic.NET); it must be a concrete class that implements the '{0}' interface.", - ObjectType.FullName)); - } - this._targetSetType = value; - } - } - - /// - /// The of objects created by this factory. - /// - /// - /// Always returns the . - /// - public override Type ObjectType - { - get { return typeof (ISet); } - } - - /// - /// Constructs a new instance of the target set. - /// - /// The new instance. - protected override object CreateInstance() - { - if (this._sourceSet == null) - { - throw new ArgumentException("The 'SourceSet' property cannot be null (Nothing in Visual Basic.NET)."); - } - Set result = (Set) ObjectUtils.InstantiateType(this._targetSetType); - result.AddAll(this._sourceSet); - return result; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Spring.Collections; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Simple factory object for shared instances. + /// + /// Juergen Hoeller + /// Simon White (.NET) + [Serializable] + public class SetFactoryObject : AbstractFactoryObject + { + private ISet _sourceSet; + private Type _targetSetType = typeof (HybridSet); + + /// + /// Set the source . + /// + /// + ///

+ /// This value will be used to populate the + /// returned by this factory. + ///

+ ///
+ public ISet SourceSet + { + set { this._sourceSet = value; } + } + + /// + /// Set the of the + /// implementation to use. + /// + /// + ///

+ /// The default is the . + ///

+ ///
+ public Type TargetSetType + { + set + { + AssertUtils.ArgumentNotNull(value, "value"); + if (!typeof (ISet).IsAssignableFrom(value)) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetSetType property must implement the '{0}' interface.", + typeof (ISet).FullName)); + } + if (value.IsInterface) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetSetType property cannot be an interface; it must be a concrete class that implements the '{0}' interface.", + ObjectType.FullName)); + } + if (value.IsAbstract) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "The Type passed to the TargetSetType property cannot be abstract (MustInherit in VisualBasic.NET); it must be a concrete class that implements the '{0}' interface.", + ObjectType.FullName)); + } + this._targetSetType = value; + } + } + + /// + /// The of objects created by this factory. + /// + /// + /// Always returns the . + /// + public override Type ObjectType + { + get { return typeof (ISet); } + } + + /// + /// Constructs a new instance of the target set. + /// + /// The new instance. + protected override object CreateInstance() + { + if (this._sourceSet == null) + { + throw new ArgumentException("The 'SourceSet' property cannot be null (Nothing in Visual Basic.NET)."); + } + Set result = (Set) ObjectUtils.InstantiateType(this._targetSetType); + result.AddAll(this._sourceSet); + return result; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/SmartInstantiationAwareObjectPostProcessor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/SmartInstantiationAwareObjectPostProcessor.cs index b056b0ee..cc068fbd 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/SmartInstantiationAwareObjectPostProcessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/SmartInstantiationAwareObjectPostProcessor.cs @@ -1,63 +1,62 @@ -#region License - -/* - * Copyright © 2002-2008 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Extension of the interface, - /// adding a callback for predicting the eventual type of a processed object. - /// - /// This interface is a special purpose interface, mainly for - /// internal use within the framework. In general, application-provided - /// post-processors should simply implement the plain - /// interface or derive from the - /// class. New methods might be added to this interface even in point releases. - /// - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: SmartInstantiationAwareObjectPostProcessor.cs,v 1.1 2008/04/02 18:02:24 markpollack Exp $ - public interface SmartInstantiationAwareObjectPostProcessor : IInstantiationAwareObjectPostProcessor - { - /// - /// Predicts the type of the object to be eventually returned from this - /// processors callback. - /// - /// The raw Type of the object. - /// Name of the object. - /// The type of the object, or null if not predictable. - /// in case of errors - Type PredictObjectType(Type objectType, string objectName); - - - /// - /// Determines the candidate constructors to use for the given object. - /// - /// The raw Type of the object. - /// Name of the object. - /// The candidate constructors, or null if none specified - /// in case of errors - ConstructorInfo[] DetermineCandidateConstructors(Type objectType, string objectName); - - } +#region License + +/* + * Copyright © 2002-2008 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Extension of the interface, + /// adding a callback for predicting the eventual type of a processed object. + /// + /// This interface is a special purpose interface, mainly for + /// internal use within the framework. In general, application-provided + /// post-processors should simply implement the plain + /// interface or derive from the + /// class. New methods might be added to this interface even in point releases. + /// + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + public interface SmartInstantiationAwareObjectPostProcessor : IInstantiationAwareObjectPostProcessor + { + /// + /// Predicts the type of the object to be eventually returned from this + /// processors callback. + /// + /// The raw Type of the object. + /// Name of the object. + /// The type of the object, or null if not predictable. + /// in case of errors + Type PredictObjectType(Type objectType, string objectName); + + + /// + /// Determines the candidate constructors to use for the given object. + /// + /// The raw Type of the object. + /// Name of the object. + /// The candidate constructors, or null if none specified + /// in case of errors + ConstructorInfo[] DetermineCandidateConstructors(Type objectType, string objectName); + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/SpecialFolderVariableSource.cs b/src/Spring/Spring.Core/Objects/Factory/Config/SpecialFolderVariableSource.cs index 7ee95226..0048f39f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/SpecialFolderVariableSource.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/SpecialFolderVariableSource.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Implementation of that - /// resolves variable name against special folders (as defined by - /// enumeration). - /// - /// Aleksandar Seovic - /// $Id: SpecialFolderVariableSource.cs,v 1.3 2007/08/02 22:18:32 markpollack Exp $ - [Serializable] - public class SpecialFolderVariableSource : IVariableSource - { - /// - /// Resolves specified special folder to its full path. - /// - /// - /// The name of the special folder to resolve. Should be one of the values - /// defined by the enumeration. - /// - /// - /// The folder path if able to resolve, null otherwise. - /// - public string ResolveVariable(string name) - { - try - { - Environment.SpecialFolder folder = - (Environment.SpecialFolder) Enum.Parse(typeof (Environment.SpecialFolder), name, true); - - return Environment.GetFolderPath(folder); - } - catch (Exception) - { - return null; - } - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Implementation of that + /// resolves variable name against special folders (as defined by + /// enumeration). + /// + /// Aleksandar Seovic + [Serializable] + public class SpecialFolderVariableSource : IVariableSource + { + /// + /// Resolves specified special folder to its full path. + /// + /// + /// The name of the special folder to resolve. Should be one of the values + /// defined by the enumeration. + /// + /// + /// The folder path if able to resolve, null otherwise. + /// + public string ResolveVariable(string name) + { + try + { + Environment.SpecialFolder folder = + (Environment.SpecialFolder) Enum.Parse(typeof (Environment.SpecialFolder), name, true); + + return Environment.GetFolderPath(folder); + } + catch (Exception) + { + return null; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/TypeAliasConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/TypeAliasConfigurer.cs index 48fe82ba..171246e7 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/TypeAliasConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/TypeAliasConfigurer.cs @@ -1,106 +1,105 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Core.TypeResolution; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// - /// implementation that allows for convenient registration of custom - /// type aliases. - /// - /// - /// Type aliases can be used instead of fully qualified type names anywhere - /// a type name is expected in a Spring.NET configuration file. - ///

- /// Because the - /// class implements the - /// - /// interface, instances of this class that have been exposed in the - /// scope of an - /// will - /// automatically be picked up by the application context and made - /// available to the IoC container whenever resolution of type aliases is required. - ///

- ///
- /// Mark Pollack - /// $Id: TypeAliasConfigurer.cs,v 1.6 2007/07/31 18:16:49 bbaia Exp $ - /// - /// - [Serializable] - public class TypeAliasConfigurer : AbstractConfigurer - { - private IDictionary types; - - - /// - /// The type aliases to register. - /// - /// - ///

- /// The has the - /// contains the alias name as the key and type as the value. - /// The key name can either be a string or an object, in which case - /// ToString() will be used to obtain the string name. - /// the value can be the fully qualified name of the type as a string or - /// an actual of the class that - /// being aliased. - ///

- ///
- public IDictionary TypeAliases - { - set { types = value; } - } - - /// - /// Registers any type aliases. The supplied - /// is not used since type aliases - /// are registered with a global - /// - /// - /// The object factory. - /// - /// - /// In case of errors. - /// - public override void PostProcessObjectFactory( - IConfigurableListableObjectFactory factory) - { - if (types != null) - { - foreach (DictionaryEntry entry in types) - { - string alias = entry.Key.ToString(); - Type type = ResolveRequiredType(entry.Value, "value", "custom type alias"); - TypeRegistry.RegisterType(alias, type); - } - } - } - - - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Core.TypeResolution; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// + /// implementation that allows for convenient registration of custom + /// type aliases. + /// + /// + /// Type aliases can be used instead of fully qualified type names anywhere + /// a type name is expected in a Spring.NET configuration file. + ///

+ /// Because the + /// class implements the + /// + /// interface, instances of this class that have been exposed in the + /// scope of an + /// will + /// automatically be picked up by the application context and made + /// available to the IoC container whenever resolution of type aliases is required. + ///

+ ///
+ /// Mark Pollack + /// + /// + [Serializable] + public class TypeAliasConfigurer : AbstractConfigurer + { + private IDictionary types; + + + /// + /// The type aliases to register. + /// + /// + ///

+ /// The has the + /// contains the alias name as the key and type as the value. + /// The key name can either be a string or an object, in which case + /// ToString() will be used to obtain the string name. + /// the value can be the fully qualified name of the type as a string or + /// an actual of the class that + /// being aliased. + ///

+ ///
+ public IDictionary TypeAliases + { + set { types = value; } + } + + /// + /// Registers any type aliases. The supplied + /// is not used since type aliases + /// are registered with a global + /// + /// + /// The object factory. + /// + /// + /// In case of errors. + /// + public override void PostProcessObjectFactory( + IConfigurableListableObjectFactory factory) + { + if (types != null) + { + foreach (DictionaryEntry entry in types) + { + string alias = entry.Key.ToString(); + Type type = ResolveRequiredType(entry.Value, "value", "custom type alias"); + TypeRegistry.RegisterType(alias, type); + } + } + } + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs b/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs index 4c4ae743..2668a89f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs @@ -1,143 +1,142 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Holder for a typed value. - /// - /// - ///

- /// Can be added to object definitions to explicitly specify - /// a target type for a value, - /// for example for collection - /// elements. - ///

- ///

- /// This holder just stores the value and the target - /// . The actual conversion will be performed by - /// the surrounding object factory. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: TypedStringValue.cs,v 1.5 2007/05/29 20:00:20 markpollack Exp $ - [Serializable] - public class TypedStringValue - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - public TypedStringValue() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public TypedStringValue(string value) - { - Value = value; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The value that is to be converted. - /// - /// - /// The to convert to. - /// - /// - /// If the supplied is - /// . - /// - public TypedStringValue(string value, Type targetType) - { - Value = value; - TargetType = targetType; - } - - #endregion - - /// - /// The value that is to be converted. - /// - /// - ///

- /// Obviously if the - /// - /// is the , no conversion - /// will actually be performed. - ///

- ///
- public string Value - { - get { return theValue; } - set { this.theValue = value; } - } - - /// - /// The to convert to. - /// - /// - /// If the setter is supplied with a value. - /// - public Type TargetType - { - get { return targetType; } - set - { - AssertUtils.ArgumentNotNull(value, "TargetType"); - targetType = value; - } - } - - /// - /// Gets a value indicating whether this instance has target type. - /// - /// - /// true if this instance has target type; otherwise, false. - /// - public bool HasTargetType - { - get { return targetType != null; } - } - - private string theValue; - private Type targetType; - } - +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Holder for a typed value. + /// + /// + ///

+ /// Can be added to object definitions to explicitly specify + /// a target type for a value, + /// for example for collection + /// elements. + ///

+ ///

+ /// This holder just stores the value and the target + /// . The actual conversion will be performed by + /// the surrounding object factory. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class TypedStringValue + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + public TypedStringValue() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public TypedStringValue(string value) + { + Value = value; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The value that is to be converted. + /// + /// + /// The to convert to. + /// + /// + /// If the supplied is + /// . + /// + public TypedStringValue(string value, Type targetType) + { + Value = value; + TargetType = targetType; + } + + #endregion + + /// + /// The value that is to be converted. + /// + /// + ///

+ /// Obviously if the + /// + /// is the , no conversion + /// will actually be performed. + ///

+ ///
+ public string Value + { + get { return theValue; } + set { this.theValue = value; } + } + + /// + /// The to convert to. + /// + /// + /// If the setter is supplied with a value. + /// + public Type TargetType + { + get { return targetType; } + set + { + AssertUtils.ArgumentNotNull(value, "TargetType"); + targetType = value; + } + } + + /// + /// Gets a value indicating whether this instance has target type. + /// + /// + /// true if this instance has target type; otherwise, false. + /// + public bool HasTargetType + { + get { return targetType != null; } + } + + private string theValue; + private Type targetType; + } + } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/VariableAccessor.cs b/src/Spring/Spring.Core/Objects/Factory/Config/VariableAccessor.cs index f5bef872..2fa7158d 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/VariableAccessor.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/VariableAccessor.cs @@ -1,788 +1,787 @@ -#region Licence - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Provides methods for type-safe accessing s. - /// - /// Erich Eichinger - /// $Id: VariableAccessor.cs,v 1.2 2007/08/27 14:49:42 oakinger Exp $ - public class VariableAccessor - { - private readonly IVariableSource variableSource; - - /// - /// Initialize a new instance of an - /// - /// The underlying to read values from. - public VariableAccessor(IVariableSource variableSource) - { - this.variableSource = variableSource; - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public float GetFloat(string name, float defaultValue) - { - return GetFloat(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public float GetFloat(string name, float defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return float.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public double GetDouble(string name, double defaultValue) - { - return GetDouble(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public double GetDouble(string name, double defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return double.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public decimal GetDecimal(string name, decimal defaultValue) - { - return GetDecimal(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public decimal GetDecimal(string name, decimal defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return decimal.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public long GetInt64(string name, long defaultValue) - { - return GetInt64(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public long GetInt64(string name, long defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return Int64.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public ulong GetUInt64(string name, ulong defaultValue) - { - return GetUInt64(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public ulong GetUInt64(string name, ulong defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return UInt64.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public int GetInt32(string name, int defaultValue) - { - return GetInt32(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public int GetInt32(string name, int defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return Int32.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public uint GetUInt32(string name, uint defaultValue) - { - return GetUInt32(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public uint GetUInt32(string name, uint defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return UInt32.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public short GetInt16(string name, short defaultValue) - { - return GetInt16(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public short GetInt16(string name, short defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return Int16.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public ushort GetUInt16(string name, ushort defaultValue) - { - return GetUInt16(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public ushort GetUInt16(string name, ushort defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return UInt16.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public byte GetByte(string name, byte defaultValue) - { - return GetByte(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public byte GetByte(string name, byte defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return byte.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public Guid GetGuid(string name, Guid defaultValue) - { - return GetGuid(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public Guid GetGuid(string name, Guid defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return new Guid(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The expected format of the variable's value - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public DateTime GetDateTime(string name, string format, DateTime defaultValue) - { - return GetDateTime(name, format, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The expected format of the variable's value - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public DateTime GetDateTime(string name, string format, DateTime defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - if (format == null) - { - return DateTime.Parse(text); - } - else - { - return DateTime.ParseExact(text, format, CultureInfo.InvariantCulture); - } - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public char GetChar(string name, char defaultValue) - { - return GetChar(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public char GetChar(string name, char defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - if (text.Length != 1) - { - throw new ArgumentException("string '{0}' can't be converted to char", text); - } - return text[0]; - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public bool GetBoolean(string name, bool defaultValue) - { - return GetBoolean(name, defaultValue, true); - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// A that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public bool GetBoolean(string name, bool defaultValue, bool throwOnInvalidValue) - { - try - { - string text = GetString(name, defaultValue.ToString()); - return bool.Parse(text); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns an of type that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// An of type that contains the value of the specified variable - /// or , if returns null. - /// - public Enum GetEnum(string name, Enum defaultValue) - { - return GetEnum(name, defaultValue, true); - } - - /// - /// Returns an of type that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns null. - /// - /// If false, suppresses exceptions if the result - /// of cannot be parsed - /// and returns instead. - /// - /// An of type that contains the value of the specified variable - /// or , if cannot be parsed. - /// - public Enum GetEnum(string name, Enum defaultValue, bool throwOnInvalidValue) - { - try - { - return (Enum)Enum.Parse(defaultValue.GetType(), GetString(name, defaultValue.ToString()), true); - } - catch - { - if (throwOnInvalidValue) - { - throw; - } - else - { - return defaultValue; - } - } - } - - /// - /// Returns a that contains the value of the specified variable. - /// - /// The name of the variable to be read. - /// The value to be returned if returns or . - /// - /// A that contains the value of the specified variable - /// or , if returns null. - /// - public string GetString(string name, string defaultValue) - { - string value = (variableSource == null) ? defaultValue : variableSource.ResolveVariable(name); - - if (!StringUtils.HasLength(value)) - { - return defaultValue; - } - - return value; - } - } +#region Licence + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Provides methods for type-safe accessing s. + /// + /// Erich Eichinger + public class VariableAccessor + { + private readonly IVariableSource variableSource; + + /// + /// Initialize a new instance of an + /// + /// The underlying to read values from. + public VariableAccessor(IVariableSource variableSource) + { + this.variableSource = variableSource; + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public float GetFloat(string name, float defaultValue) + { + return GetFloat(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public float GetFloat(string name, float defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return float.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public double GetDouble(string name, double defaultValue) + { + return GetDouble(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public double GetDouble(string name, double defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return double.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public decimal GetDecimal(string name, decimal defaultValue) + { + return GetDecimal(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public decimal GetDecimal(string name, decimal defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return decimal.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public long GetInt64(string name, long defaultValue) + { + return GetInt64(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public long GetInt64(string name, long defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return Int64.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public ulong GetUInt64(string name, ulong defaultValue) + { + return GetUInt64(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public ulong GetUInt64(string name, ulong defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return UInt64.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public int GetInt32(string name, int defaultValue) + { + return GetInt32(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public int GetInt32(string name, int defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return Int32.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public uint GetUInt32(string name, uint defaultValue) + { + return GetUInt32(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public uint GetUInt32(string name, uint defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return UInt32.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public short GetInt16(string name, short defaultValue) + { + return GetInt16(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public short GetInt16(string name, short defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return Int16.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public ushort GetUInt16(string name, ushort defaultValue) + { + return GetUInt16(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public ushort GetUInt16(string name, ushort defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return UInt16.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public byte GetByte(string name, byte defaultValue) + { + return GetByte(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public byte GetByte(string name, byte defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return byte.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public Guid GetGuid(string name, Guid defaultValue) + { + return GetGuid(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public Guid GetGuid(string name, Guid defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return new Guid(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The expected format of the variable's value + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public DateTime GetDateTime(string name, string format, DateTime defaultValue) + { + return GetDateTime(name, format, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The expected format of the variable's value + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public DateTime GetDateTime(string name, string format, DateTime defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + if (format == null) + { + return DateTime.Parse(text); + } + else + { + return DateTime.ParseExact(text, format, CultureInfo.InvariantCulture); + } + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public char GetChar(string name, char defaultValue) + { + return GetChar(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public char GetChar(string name, char defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + if (text.Length != 1) + { + throw new ArgumentException("string '{0}' can't be converted to char", text); + } + return text[0]; + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public bool GetBoolean(string name, bool defaultValue) + { + return GetBoolean(name, defaultValue, true); + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// A that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public bool GetBoolean(string name, bool defaultValue, bool throwOnInvalidValue) + { + try + { + string text = GetString(name, defaultValue.ToString()); + return bool.Parse(text); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns an of type that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// An of type that contains the value of the specified variable + /// or , if returns null. + /// + public Enum GetEnum(string name, Enum defaultValue) + { + return GetEnum(name, defaultValue, true); + } + + /// + /// Returns an of type that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns null. + /// + /// If false, suppresses exceptions if the result + /// of cannot be parsed + /// and returns instead. + /// + /// An of type that contains the value of the specified variable + /// or , if cannot be parsed. + /// + public Enum GetEnum(string name, Enum defaultValue, bool throwOnInvalidValue) + { + try + { + return (Enum)Enum.Parse(defaultValue.GetType(), GetString(name, defaultValue.ToString()), true); + } + catch + { + if (throwOnInvalidValue) + { + throw; + } + else + { + return defaultValue; + } + } + } + + /// + /// Returns a that contains the value of the specified variable. + /// + /// The name of the variable to be read. + /// The value to be returned if returns or . + /// + /// A that contains the value of the specified variable + /// or , if returns null. + /// + public string GetString(string name, string defaultValue) + { + string value = (variableSource == null) ? defaultValue : variableSource.ResolveVariable(name); + + if (!StringUtils.HasLength(value)) + { + return defaultValue; + } + + return value; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/VariablePlaceholderConfigurer.cs b/src/Spring/Spring.Core/Objects/Factory/Config/VariablePlaceholderConfigurer.cs index bf8e83cb..596d10c0 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/VariablePlaceholderConfigurer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/VariablePlaceholderConfigurer.cs @@ -1,316 +1,315 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Globalization; -using Common.Logging; -using Spring.Collections; -using Spring.Core; - -namespace Spring.Objects.Factory.Config -{ - /// - /// Resolves placeholder values in one or more object definitions - /// - /// - /// The placeholder syntax follows the NAnt style: ${...}. - /// Placeholders values are resolved against a list of - /// s. In case of multiple definitions - /// for the same property placeholder name, the first one in the - /// list is used. - /// Variable substitution is performed on simple property values, - /// lists, dictionaries, sets, constructor - /// values, object type name, and object names in - /// runtime object references ( - /// ). - /// Furthermore, placeholder values can also cross-reference other - /// placeholders, in the manner of the following example where the - /// rootPath property is cross-referenced by the subPath - /// property. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// If a configurer cannot resolve a placeholder, and the value of the - /// - /// property is currently set to , an - /// - /// will be thrown. - /// - /// Mark Pollack - /// $Id: VariablePlaceholderConfigurer.cs,v 1.2 2007/08/02 22:18:32 markpollack Exp $ - public class VariablePlaceholderConfigurer : IObjectFactoryPostProcessor, IOrdered - { - #region Fields - private int order = Int32.MaxValue; // default: same as non-Ordered - - private bool ignoreUnresolvablePlaceholders; - - private IList variableSourceList; - #endregion - - #region Properties - - /// - /// Sets the list of s that will be used to resolve placeholder names. - /// - /// A list of s. - public IList VariableSources - { - set { variableSourceList = value; } - } - - /// - /// Sets that will be used to resolve placeholder names. - /// - /// A instance. - public IVariableSource VariableSource - { - set - { - variableSourceList = new ArrayList(); - variableSourceList.Add(value); - } - } - - /// - /// Indicates whether unresolved placeholders should be ignored. - /// - public bool IgnoreUnresolvablePlaceholders - { - set { ignoreUnresolvablePlaceholders = value; } - } - - #endregion - - #region IObjectFactoryPostProcessor Members - - /// - /// Modify the application context's internal object factory after its - /// standard initialization. - /// - /// The object factory used by the application context. - /// - ///

- /// All object definitions will have been loaded, but no objects will have - /// been instantiated yet. This allows for overriding or adding properties - /// even to eager-initializing objects. - ///

- ///
- /// - /// In case of errors. - /// - public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory) - { - try - { - ProcessProperties(factory); - } - catch (Exception ex) - { - if (typeof (ObjectsException).IsInstanceOfType(ex)) - { - throw; - } - else - { - throw new ObjectsException( - "Errored while postprocessing an object factory.", ex); - } - } - } - - #endregion - - #region IOrdered Members - - /// - /// Return the order value of this object, where a higher value means greater in - /// terms of sorting. - /// - /// The order value. - /// - public int Order - { - get { return order; } - set { order = value; } - } - - #endregion - - /// - /// Apply the property replacement using the specified s for all - /// object in the supplied - /// . - /// - /// - /// The - /// used by the application context. - /// - /// - /// If an error occured. - /// - protected virtual void ProcessProperties(IConfigurableListableObjectFactory factory) - { - IVariableSource compositeVariableSource = - new PlaceholderResolvingCompositeVariableSource(variableSourceList, ignoreUnresolvablePlaceholders); - ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(compositeVariableSource); - - string[] objectDefinitionNames = factory.GetObjectDefinitionNames(); - for (int i = 0; i < objectDefinitionNames.Length; ++i) - { - string name = objectDefinitionNames[i]; - IObjectDefinition definition = factory.GetObjectDefinition(name); - try - { - visitor.VisitObjectDefinition(definition); - } - catch (ObjectDefinitionStoreException ex) - { - throw new ObjectDefinitionStoreException( - definition.ResourceDescription, name, ex.Message); - } - } - } - } - - #region Helper class - internal class PlaceholderResolvingCompositeVariableSource : IVariableSource - { - private string placeholderPrefix = "${"; - private string placeholderSuffix = "}"; - private bool ignoreUnresolvablePlaceholders; - - private ILog logger = LogManager.GetLogger(typeof (PlaceholderResolvingCompositeVariableSource)); - - private IList variableSourceList; - - public PlaceholderResolvingCompositeVariableSource(IList variableSourceList, bool ignoreUnresolvablePlaceholders) - { - this.variableSourceList = variableSourceList; - this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; - } - - #region IVariableSource Members - - public string ResolveVariable(string rawStringValue) - { - return ParseAndResolveVariable(rawStringValue, new HashedSet()); - } - - - //TODO handle resolved values at are not string - identify this case as only 1 placeholder present? - - private string ParseAndResolveVariable(string strVal, ISet visitedPlaceholders) - { - int startIndex = strVal.IndexOf(placeholderPrefix); - while (startIndex != -1) - { - int endIndex = strVal.IndexOf( - placeholderSuffix, startIndex + placeholderPrefix.Length); - if (endIndex != -1) - { - int pos = startIndex + placeholderPrefix.Length; - string placeholder = strVal.Substring(pos, endIndex - pos); - if (visitedPlaceholders.Contains(placeholder)) - { - throw new ObjectDefinitionStoreException( - string.Format( - CultureInfo.InvariantCulture, - "Circular placeholder reference '{0}' detected. ", - placeholder)); - } - visitedPlaceholders.Add(placeholder); - string resolvedValue = ResolvePlaceholderVariable(placeholder); - if (resolvedValue != null) - { - resolvedValue = ParseAndResolveVariable(resolvedValue, visitedPlaceholders); - - #region Instrumentation - - if (logger.IsDebugEnabled) - { - logger.Debug(string.Format( - CultureInfo.InvariantCulture, - "Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue)); - } - - #endregion - - strVal = strVal.Substring(0, startIndex) + resolvedValue + strVal.Substring(endIndex + 1); - startIndex = strVal.IndexOf(placeholderPrefix, startIndex + resolvedValue.Length); - } - else if (ignoreUnresolvablePlaceholders) - { - // simply return the unprocessed value... - return strVal; - } - else - { - throw new ObjectDefinitionStoreException(string.Format( - CultureInfo.InvariantCulture, - "Could not resolve placeholder '{0}'.", placeholder)); - } - visitedPlaceholders.Remove(placeholder); - } - else - { - startIndex = -1; - } - } - return strVal; - } - - private string ResolvePlaceholderVariable(string variableName) - { - foreach (IVariableSource variableSource in variableSourceList) - { - //TODO handle resolved values at are not strings? - - object resolvedValue = variableSource.ResolveVariable(variableName); - if (resolvedValue is string) - { - } - if (resolvedValue != null) - { - if (resolvedValue is string) - { - return resolvedValue as string; - } - else - { - logger.Warn("Placeholder " + variableSource + " resolved to object type [" + resolvedValue.GetType() + "]. Only string type currently supported"); - } - } - } - return null; - } - - #endregion - } - - #endregion +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Globalization; +using Common.Logging; +using Spring.Collections; +using Spring.Core; + +namespace Spring.Objects.Factory.Config +{ + /// + /// Resolves placeholder values in one or more object definitions + /// + /// + /// The placeholder syntax follows the NAnt style: ${...}. + /// Placeholders values are resolved against a list of + /// s. In case of multiple definitions + /// for the same property placeholder name, the first one in the + /// list is used. + /// Variable substitution is performed on simple property values, + /// lists, dictionaries, sets, constructor + /// values, object type name, and object names in + /// runtime object references ( + /// ). + /// Furthermore, placeholder values can also cross-reference other + /// placeholders, in the manner of the following example where the + /// rootPath property is cross-referenced by the subPath + /// property. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// If a configurer cannot resolve a placeholder, and the value of the + /// + /// property is currently set to , an + /// + /// will be thrown. + /// + /// Mark Pollack + public class VariablePlaceholderConfigurer : IObjectFactoryPostProcessor, IOrdered + { + #region Fields + private int order = Int32.MaxValue; // default: same as non-Ordered + + private bool ignoreUnresolvablePlaceholders; + + private IList variableSourceList; + #endregion + + #region Properties + + /// + /// Sets the list of s that will be used to resolve placeholder names. + /// + /// A list of s. + public IList VariableSources + { + set { variableSourceList = value; } + } + + /// + /// Sets that will be used to resolve placeholder names. + /// + /// A instance. + public IVariableSource VariableSource + { + set + { + variableSourceList = new ArrayList(); + variableSourceList.Add(value); + } + } + + /// + /// Indicates whether unresolved placeholders should be ignored. + /// + public bool IgnoreUnresolvablePlaceholders + { + set { ignoreUnresolvablePlaceholders = value; } + } + + #endregion + + #region IObjectFactoryPostProcessor Members + + /// + /// Modify the application context's internal object factory after its + /// standard initialization. + /// + /// The object factory used by the application context. + /// + ///

+ /// All object definitions will have been loaded, but no objects will have + /// been instantiated yet. This allows for overriding or adding properties + /// even to eager-initializing objects. + ///

+ ///
+ /// + /// In case of errors. + /// + public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory) + { + try + { + ProcessProperties(factory); + } + catch (Exception ex) + { + if (typeof (ObjectsException).IsInstanceOfType(ex)) + { + throw; + } + else + { + throw new ObjectsException( + "Errored while postprocessing an object factory.", ex); + } + } + } + + #endregion + + #region IOrdered Members + + /// + /// Return the order value of this object, where a higher value means greater in + /// terms of sorting. + /// + /// The order value. + /// + public int Order + { + get { return order; } + set { order = value; } + } + + #endregion + + /// + /// Apply the property replacement using the specified s for all + /// object in the supplied + /// . + /// + /// + /// The + /// used by the application context. + /// + /// + /// If an error occured. + /// + protected virtual void ProcessProperties(IConfigurableListableObjectFactory factory) + { + IVariableSource compositeVariableSource = + new PlaceholderResolvingCompositeVariableSource(variableSourceList, ignoreUnresolvablePlaceholders); + ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(compositeVariableSource); + + string[] objectDefinitionNames = factory.GetObjectDefinitionNames(); + for (int i = 0; i < objectDefinitionNames.Length; ++i) + { + string name = objectDefinitionNames[i]; + IObjectDefinition definition = factory.GetObjectDefinition(name); + try + { + visitor.VisitObjectDefinition(definition); + } + catch (ObjectDefinitionStoreException ex) + { + throw new ObjectDefinitionStoreException( + definition.ResourceDescription, name, ex.Message); + } + } + } + } + + #region Helper class + internal class PlaceholderResolvingCompositeVariableSource : IVariableSource + { + private string placeholderPrefix = "${"; + private string placeholderSuffix = "}"; + private bool ignoreUnresolvablePlaceholders; + + private ILog logger = LogManager.GetLogger(typeof (PlaceholderResolvingCompositeVariableSource)); + + private IList variableSourceList; + + public PlaceholderResolvingCompositeVariableSource(IList variableSourceList, bool ignoreUnresolvablePlaceholders) + { + this.variableSourceList = variableSourceList; + this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; + } + + #region IVariableSource Members + + public string ResolveVariable(string rawStringValue) + { + return ParseAndResolveVariable(rawStringValue, new HashedSet()); + } + + + //TODO handle resolved values at are not string - identify this case as only 1 placeholder present? + + private string ParseAndResolveVariable(string strVal, ISet visitedPlaceholders) + { + int startIndex = strVal.IndexOf(placeholderPrefix); + while (startIndex != -1) + { + int endIndex = strVal.IndexOf( + placeholderSuffix, startIndex + placeholderPrefix.Length); + if (endIndex != -1) + { + int pos = startIndex + placeholderPrefix.Length; + string placeholder = strVal.Substring(pos, endIndex - pos); + if (visitedPlaceholders.Contains(placeholder)) + { + throw new ObjectDefinitionStoreException( + string.Format( + CultureInfo.InvariantCulture, + "Circular placeholder reference '{0}' detected. ", + placeholder)); + } + visitedPlaceholders.Add(placeholder); + string resolvedValue = ResolvePlaceholderVariable(placeholder); + if (resolvedValue != null) + { + resolvedValue = ParseAndResolveVariable(resolvedValue, visitedPlaceholders); + + #region Instrumentation + + if (logger.IsDebugEnabled) + { + logger.Debug(string.Format( + CultureInfo.InvariantCulture, + "Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue)); + } + + #endregion + + strVal = strVal.Substring(0, startIndex) + resolvedValue + strVal.Substring(endIndex + 1); + startIndex = strVal.IndexOf(placeholderPrefix, startIndex + resolvedValue.Length); + } + else if (ignoreUnresolvablePlaceholders) + { + // simply return the unprocessed value... + return strVal; + } + else + { + throw new ObjectDefinitionStoreException(string.Format( + CultureInfo.InvariantCulture, + "Could not resolve placeholder '{0}'.", placeholder)); + } + visitedPlaceholders.Remove(placeholder); + } + else + { + startIndex = -1; + } + } + return strVal; + } + + private string ResolvePlaceholderVariable(string variableName) + { + foreach (IVariableSource variableSource in variableSourceList) + { + //TODO handle resolved values at are not strings? + + object resolvedValue = variableSource.ResolveVariable(variableName); + if (resolvedValue is string) + { + } + if (resolvedValue != null) + { + if (resolvedValue is string) + { + return resolvedValue as string; + } + else + { + logger.Warn("Placeholder " + variableSource + " resolved to object type [" + resolvedValue.GetType() + "]. Only string type currently supported"); + } + } + } + return null; + } + + #endregion + } + + #endregion } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/FactoryObjectNotInitializedException.cs b/src/Spring/Spring.Core/Objects/Factory/FactoryObjectNotInitializedException.cs index 1dd3f524..490b37ce 100644 --- a/src/Spring/Spring.Core/Objects/Factory/FactoryObjectNotInitializedException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/FactoryObjectNotInitializedException.cs @@ -1,124 +1,123 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Exception thrown if an - /// is not fully - /// initialized, for example if it is involved in a circular reference. - /// - /// - ///

- /// This is usually indicated by any of the variants of the - /// - /// method returning . - ///

- ///

- /// A circular reference with an - /// cannot be solved by eagerly caching singleton instances (as is the - /// case with normal objects. The reason is that every - /// needs to be fully - /// initialized before it can return the created object, while only specific - /// normal objects need to be initialized - that is, if a collaborating object - /// actually invokes them on initialization instead of just storing the reference. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: FactoryObjectNotInitializedException.cs,v 1.4 2007/12/05 00:28:04 bbaia Exp $ - [Serializable] - public class FactoryObjectNotInitializedException : ObjectCreationException - { - /// - /// Creates a new instance of the - /// FactoryObjectNotInitializedException class. - /// - public FactoryObjectNotInitializedException() - { - } - - /// - /// Creates a new instance of the FactoryObjectNotInitializedException class. - /// - /// - /// A message about the exception. - /// - public FactoryObjectNotInitializedException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the FactoryObjectNotInitializedException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public FactoryObjectNotInitializedException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// FactoryObjectCircularReferenceException class. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// A message about the exception. - /// - public FactoryObjectNotInitializedException(string objectName, string message) - : base(objectName, StringUtils.HasText(message) ? message : - "Circular dependency chain detected for factory object.") - { - } - - /// - /// Creates a new instance of the FactoryObjectCircularReferenceException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected FactoryObjectNotInitializedException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Exception thrown if an + /// is not fully + /// initialized, for example if it is involved in a circular reference. + /// + /// + ///

+ /// This is usually indicated by any of the variants of the + /// + /// method returning . + ///

+ ///

+ /// A circular reference with an + /// cannot be solved by eagerly caching singleton instances (as is the + /// case with normal objects. The reason is that every + /// needs to be fully + /// initialized before it can return the created object, while only specific + /// normal objects need to be initialized - that is, if a collaborating object + /// actually invokes them on initialization instead of just storing the reference. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class FactoryObjectNotInitializedException : ObjectCreationException + { + /// + /// Creates a new instance of the + /// FactoryObjectNotInitializedException class. + /// + public FactoryObjectNotInitializedException() + { + } + + /// + /// Creates a new instance of the FactoryObjectNotInitializedException class. + /// + /// + /// A message about the exception. + /// + public FactoryObjectNotInitializedException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the FactoryObjectNotInitializedException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public FactoryObjectNotInitializedException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// FactoryObjectCircularReferenceException class. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// A message about the exception. + /// + public FactoryObjectNotInitializedException(string objectName, string message) + : base(objectName, StringUtils.HasText(message) ? message : + "Circular dependency chain detected for factory object.") + { + } + + /// + /// Creates a new instance of the FactoryObjectCircularReferenceException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected FactoryObjectNotInitializedException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/IFactoryObject.cs b/src/Spring/Spring.Core/Objects/Factory/IFactoryObject.cs index 8721cdab..65952e21 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IFactoryObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IFactoryObject.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Interface to be implemented by objects used within an - /// that are themselves - /// factories. - /// - /// - ///

- /// If an object implements this interface, it is used as a factory, - /// not directly as an object. s - /// can support singletons and prototypes - /// ()... - /// please note that an - /// itself can only ever be a singleton. It is a logic error to configure an - /// itself to be a prototype. - ///

- /// - /// An object that implements this interface cannot be used as a normal object. - /// - ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IFactoryObject.cs,v 1.6 2006/04/09 07:18:48 markpollack Exp $ - public interface IFactoryObject - { - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// - /// If this method is being called in the context of an enclosing IoC container and - /// returns , the IoC container will consider this factory - /// object as not being fully initialized and throw a corresponding (and most - /// probably fatal) exception. - /// - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - object GetObject(); - - /// - /// Return the of object that this - /// creates, or - /// if not known in advance. - /// - Type ObjectType { get; } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - bool IsSingleton { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Interface to be implemented by objects used within an + /// that are themselves + /// factories. + /// + /// + ///

+ /// If an object implements this interface, it is used as a factory, + /// not directly as an object. s + /// can support singletons and prototypes + /// ()... + /// please note that an + /// itself can only ever be a singleton. It is a logic error to configure an + /// itself to be a prototype. + ///

+ /// + /// An object that implements this interface cannot be used as a normal object. + /// + ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IFactoryObject + { + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// + /// If this method is being called in the context of an enclosing IoC container and + /// returns , the IoC container will consider this factory + /// object as not being fully initialized and throw a corresponding (and most + /// probably fatal) exception. + /// + /// + /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + object GetObject(); + + /// + /// Return the of object that this + /// creates, or + /// if not known in advance. + /// + Type ObjectType { get; } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + bool IsSingleton { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/IGenericObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IGenericObjectFactory.cs index 88d52e32..2b22a68f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IGenericObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IGenericObjectFactory.cs @@ -1,52 +1,51 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Interface defining a factory which can return an object instance - /// (possibly shared or independent) when invoked. - /// - /// - /// This interface is typically used to encapsulate a generic factory - /// which returns a new instance (prototype) on each invocation. - /// It is similar to the , but - /// implementations of the aforementioned interface are normally meant to be defined - /// as instances by the user in an , - /// while implementations of this class are normally meant to be fed as a property to - /// other objects; as such, the - /// method - /// has different exception handling behavior. - /// - /// Colin Sampaleanu - /// Simon White (.NET) - /// $Id: IGenericObjectFactory.cs,v 1.6 2006/04/09 07:18:48 markpollack Exp $ - public interface IGenericObjectFactory - { - /// - /// Return an instance (possibly shared or independent) - /// of the object managed by this factory. - /// - /// - /// An instance of the object (should never be ). - /// - object GetObject(); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Interface defining a factory which can return an object instance + /// (possibly shared or independent) when invoked. + /// + /// + /// This interface is typically used to encapsulate a generic factory + /// which returns a new instance (prototype) on each invocation. + /// It is similar to the , but + /// implementations of the aforementioned interface are normally meant to be defined + /// as instances by the user in an , + /// while implementations of this class are normally meant to be fed as a property to + /// other objects; as such, the + /// method + /// has different exception handling behavior. + /// + /// Colin Sampaleanu + /// Simon White (.NET) + public interface IGenericObjectFactory + { + /// + /// Return an instance (possibly shared or independent) + /// of the object managed by this factory. + /// + /// + /// An instance of the object (should never be ). + /// + object GetObject(); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs index 2074728b..e7445d24 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Sub-interface implemented by object factories that can be part - /// of a hierarchy. - /// - /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: IHierarchicalObjectFactory.cs,v 1.6 2006/04/09 07:18:48 markpollack Exp $ - public interface IHierarchicalObjectFactory : IObjectFactory - { - /// - /// Return the parent object factory, or - /// if this factory does not have a parent. - /// - /// - /// The parent object factory, or - /// if this factory does not have a parent. - /// - IObjectFactory ParentObjectFactory { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Sub-interface implemented by object factories that can be part + /// of a hierarchy. + /// + /// Rod Johnson + /// Rick Evans (.NET) + public interface IHierarchicalObjectFactory : IObjectFactory + { + /// + /// Return the parent object factory, or + /// if this factory does not have a parent. + /// + /// + /// The parent object factory, or + /// if this factory does not have a parent. + /// + IObjectFactory ParentObjectFactory { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/IInitializingObject.cs b/src/Spring/Spring.Core/Objects/Factory/IInitializingObject.cs index ff0b52bb..02ef1480 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IInitializingObject.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IInitializingObject.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Defines a simple initialization callback for objects that need to to some - /// post-initialization logic after all of their dependencies have been injected. - /// - /// - ///

- /// An implementation of the - /// - /// method might perform some additional custom initialization (over and above that - /// performed by the constructor), or merely check that all mandatory properties - /// have been set (this last example is a very typical use case of this interface). - ///

- /// - /// The use of the - /// interface - /// by non-Spring.NET framework code can be avoided (and is generally - /// discouraged). The Spring.NET container provides support for a generic - /// initialization method given to the object definition in the object - /// configuration store (be it XML, or a database, etc). This requires - /// slightly more configuration (one attribute-value pair in the case of - /// XML configuration), but removes any dependency on Spring.NET from the - /// class definition. - /// - ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: IInitializingObject.cs,v 1.8 2006/04/09 07:18:48 markpollack Exp $ - /// - public interface IInitializingObject - { - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - void AfterPropertiesSet(); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Defines a simple initialization callback for objects that need to to some + /// post-initialization logic after all of their dependencies have been injected. + /// + /// + ///

+ /// An implementation of the + /// + /// method might perform some additional custom initialization (over and above that + /// performed by the constructor), or merely check that all mandatory properties + /// have been set (this last example is a very typical use case of this interface). + ///

+ /// + /// The use of the + /// interface + /// by non-Spring.NET framework code can be avoided (and is generally + /// discouraged). The Spring.NET container provides support for a generic + /// initialization method given to the object definition in the object + /// configuration store (be it XML, or a database, etc). This requires + /// slightly more configuration (one attribute-value pair in the case of + /// XML configuration), but removes any dependency on Spring.NET from the + /// class definition. + /// + ///
+ /// Rod Johnson + /// Rick Evans (.NET) + /// + public interface IInitializingObject + { + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + void AfterPropertiesSet(); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs index f4af15f7..6a4e51be 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs @@ -1,217 +1,216 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Extension of the interface - /// to be implemented by object factories that can enumerate all their object instances, - /// rather than attempting object lookup by name one by one as requested by clients. - /// - /// - ///

- /// implementations that preload - /// all their objects (for example, DOM-based XML factories) may implement this - /// interface. This interface is discussed in - /// "Expert One-on-One J2EE Design and Development", by Rod Johnson. - ///

- ///

- /// If this is an , - /// the return values will not take any - /// hierarchy into account, but - /// will relate only to the objects defined in the current factory. - /// Use the helper class to - /// get all objects. - ///

- ///

- /// With the exception of - /// , - /// the methods and properties in this interface are not designed for frequent - /// invocation. Implementations may be slow. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: IListableObjectFactory.cs,v 1.12 2007/07/29 19:39:27 markpollack Exp $ - public interface IListableObjectFactory : IObjectFactory - { - /// - /// Check if this object factory contains an object definition with the given name. - /// - /// - ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- /// - /// Ignores any singleton objects that have been registered by other means - /// than object definitions. - /// - ///
- /// The name of the object to look for. - /// - /// if this object factory contains an object - /// definition with the given name. - /// - bool ContainsObjectDefinition(string name); - - /// - /// Return the number of objects defined in the factory. - /// - /// - /// The number of objects defined in the factory. - /// - int ObjectDefinitionCount { get; } - - - /// - /// Return the names of all objects defined in this factory. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - string[] GetObjectDefinitionNames(); - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - ///

- /// Does consider objects created by s, - /// or rather it considers the type of objects created by - /// (which means that - /// s will be instantiated). - ///

- ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- ///
- /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - string[] GetObjectNamesForType(Type type); - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - ///

- /// Does consider objects created by s, - /// or rather it considers the type of objects created by - /// (which means that - /// s will be instantiated). - ///

- ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- ///
- /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - string[] GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects); - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - ///

- /// This version of the - /// method matches all kinds of object definitions, be they singletons, prototypes, or - /// s. Typically, the results - /// of this method call will be the same as a call to - /// IListableObjectFactory.GetObjectsOfType(type,true,true) . - ///

- ///
- /// - /// The (class or interface) to match. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - IDictionary GetObjectsOfType(Type type); - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - /// The (class or interface) to match. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - IDictionary GetObjectsOfType( - Type type, bool includePrototypes, bool includeFactoryObjects); - - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Extension of the interface + /// to be implemented by object factories that can enumerate all their object instances, + /// rather than attempting object lookup by name one by one as requested by clients. + /// + /// + ///

+ /// implementations that preload + /// all their objects (for example, DOM-based XML factories) may implement this + /// interface. This interface is discussed in + /// "Expert One-on-One J2EE Design and Development", by Rod Johnson. + ///

+ ///

+ /// If this is an , + /// the return values will not take any + /// hierarchy into account, but + /// will relate only to the objects defined in the current factory. + /// Use the helper class to + /// get all objects. + ///

+ ///

+ /// With the exception of + /// , + /// the methods and properties in this interface are not designed for frequent + /// invocation. Implementations may be slow. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + public interface IListableObjectFactory : IObjectFactory + { + /// + /// Check if this object factory contains an object definition with the given name. + /// + /// + ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ /// + /// Ignores any singleton objects that have been registered by other means + /// than object definitions. + /// + ///
+ /// The name of the object to look for. + /// + /// if this object factory contains an object + /// definition with the given name. + /// + bool ContainsObjectDefinition(string name); + + /// + /// Return the number of objects defined in the factory. + /// + /// + /// The number of objects defined in the factory. + /// + int ObjectDefinitionCount { get; } + + + /// + /// Return the names of all objects defined in this factory. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + string[] GetObjectDefinitionNames(); + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + ///

+ /// Does consider objects created by s, + /// or rather it considers the type of objects created by + /// (which means that + /// s will be instantiated). + ///

+ ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ ///
+ /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + string[] GetObjectNamesForType(Type type); + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + ///

+ /// Does consider objects created by s, + /// or rather it considers the type of objects created by + /// (which means that + /// s will be instantiated). + ///

+ ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ ///
+ /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + string[] GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects); + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + ///

+ /// This version of the + /// method matches all kinds of object definitions, be they singletons, prototypes, or + /// s. Typically, the results + /// of this method call will be the same as a call to + /// IListableObjectFactory.GetObjectsOfType(type,true,true) . + ///

+ ///
+ /// + /// The (class or interface) to match. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + IDictionary GetObjectsOfType(Type type); + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + /// The (class or interface) to match. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + IDictionary GetObjectsOfType( + Type type, bool includePrototypes, bool includeFactoryObjects); + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/IObjectDefinitionFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IObjectDefinitionFactory.cs index 1d06f8cf..5b88c1ae 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IObjectDefinitionFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IObjectDefinitionFactory.cs @@ -1,68 +1,67 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Central interface for factories that can create - /// - /// instances. - /// - /// - ///

- /// Allows for replaceable object definition factories using the Strategy - /// pattern. - ///

- ///
- /// Aleksandar Seovic - /// $Id: IObjectDefinitionFactory.cs,v 1.10 2007/07/30 18:00:01 markpollack Exp $ - public interface IObjectDefinitionFactory - { - - /// - /// Factory style method for getting concrete - /// - /// instances. - /// - /// - /// The FullName of the of the defined object. - /// - /// The name of the parent object definition (if any). - /// - /// The against which any class names - /// will be resolved into instances. It can be null to register the - /// object class just by name. - /// - /// - /// An - /// - /// instance. - /// - AbstractObjectDefinition CreateObjectDefinition(string typeName, string parent, AppDomain domain); - - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Central interface for factories that can create + /// + /// instances. + /// + /// + ///

+ /// Allows for replaceable object definition factories using the Strategy + /// pattern. + ///

+ ///
+ /// Aleksandar Seovic + public interface IObjectDefinitionFactory + { + + /// + /// Factory style method for getting concrete + /// + /// instances. + /// + /// + /// The FullName of the of the defined object. + /// + /// The name of the parent object definition (if any). + /// + /// The against which any class names + /// will be resolved into instances. It can be null to register the + /// object class just by name. + /// + /// + /// An + /// + /// instance. + /// + AbstractObjectDefinition CreateObjectDefinition(string typeName, string parent, AppDomain domain); + + + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs index 11a43768..efaea2a7 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs @@ -1,491 +1,490 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// The root interface for accessing a Spring.NET IoC container. - /// - /// - ///

- /// This is the basic client view of a Spring.NET IoC container; further interfaces - /// such as and - /// - /// are available for specific purposes such as enumeration and configuration. - ///

- ///

- /// This is the root interface to be implemented by objects that can hold a number - /// of object definitions, each uniquely identified by a - /// name. An independent instance of any of these objects can be obtained - /// (the Prototype design pattern), or a single shared instance can be obtained - /// (a superior alternative to the Singleton design pattern, in which the instance is a - /// singleton in the scope of the factory). Which type of instance - /// will be returned depends on the object factory configuration - the API is the same. - /// The Singleton approach is more useful and hence more common in practice. - ///

- ///

- /// The point of this approach is that the IObjectFactory is a central registry of - /// application components, and centralizes the configuring of application components - /// (no more do individual objects need to read properties files, for example). - /// See chapters 4 and 11 of "Expert One-on-One J2EE Design and Development" for a - /// discussion of the benefits of this approach. - ///

- ///

- /// Normally an IObjectFactory will load object definitions stored in a configuration - /// source (such as an XML document), and use the - /// namespace to configure the objects. However, an implementation could simply return - /// .NET objects it creates as necessary directly in .NET code. There are no - /// constraints on how the definitions could be stored: LDAP, RDBMS, XML, properties - /// file etc. Implementations are encouraged to support references amongst objects, - /// to either Singletons or Prototypes. - ///

- ///

- /// In contrast to the methods in - /// , all of the methods - /// in this interface will also check parent factories if this is an - /// . If an object is - /// not found in this factory instance, the immediate parent is asked. Objects in - /// this factory instance are supposed to override objects of the same name in any - /// parent factory. - ///

- ///

- /// Object factories are supposed to support the standard object lifecycle interfaces - /// as far as possible. The maximum set of initialization methods and their standard - /// order is: - ///

- ///

- /// - /// - /// - /// 's - /// property. - /// - /// - /// - /// - /// 's - /// property. - /// - /// - /// - /// - /// - /// (only applicable if running within an ). - /// - /// - /// - /// - /// The - /// - /// method of - /// s. - /// - /// - /// - /// - /// 's - /// method. - /// - /// - /// - /// - /// A custom init-method definition. - /// - /// - /// - /// - /// The - /// - /// method of - /// s. - /// - /// - /// - ///

- ///

- ///

- /// On shutdown of an object factory, the following lifecycle methods apply: - ///

- ///

- /// - /// - /// - /// 's - /// method. - /// - /// - /// - /// - /// A custom destroy-method definition. - /// - /// - /// - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: IObjectFactory.cs,v 1.17 2007/07/30 15:41:32 markpollack Exp $ - public interface IObjectFactory : IDisposable - { - /// - /// Is this object a singleton? - /// - /// - ///

- /// That is, will - /// always return the same object? - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to query. - /// True if the named object is a singleton. - /// - /// If there's no such object definition. - /// - bool IsSingleton(string name); - - - /// - /// Determines whether the specified object name is prototype. That is, will GetObject - /// always return independent instances? - /// - /// This method returning false does not clearly indicate a singleton object. - /// It indicated non-independent instances, which may correspond to a scoped object as - /// well. use the IsSingleton property to explicitly check for a shared - /// singleton instance. - /// Translates aliases back to the corresponding canonical object name. Will ask the - /// parent factory if the object can not be found in this factory instance. - /// - /// - /// - /// The name of the object to query - /// - /// true if the specified object name will always deliver independent instances; otherwise, false. - /// - /// if there is no object with the given name. - bool IsPrototype(string name); - - /// - /// Does this object factory contain an object with the given name? - /// - /// - ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to query. - /// True if an object with the given name is defined. - bool ContainsObject(string name); - - /// - /// Return the aliases for the given object name, if defined. - /// - /// - ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The object name to check for aliases. - /// The aliases, or an empty array if none. - /// - /// If there's no such object definition. - /// - string[] GetAliases(string name); - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///

- /// This is the indexer for the - /// interface. - ///

- ///
- /// The name of the object to return. - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - object this[string name] { get; } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to return. - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - object GetObject(string name); - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to return. - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. If there is no factory method and the - /// arguments are not null, then match the argument values by type and - /// call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the supplied is . - /// - object GetObject(string name, object[] arguments); - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// - /// The the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a factory method. If there is no factory method and the - /// supplied array is not , then - /// match the argument values by type and call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the object is not of the required type. - /// - /// - /// If the supplied is . - /// - /// - object GetObject(string name, Type requiredType, object[] arguments); - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// Provides a measure of type safety by throwing an exception if the object is - /// not of the required . - ///

- ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to return. - /// - /// the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the object is not of the required type. - /// - object GetObject(string name, Type requiredType); - - /// - /// Determine the type of the object with the given name. - /// - /// - ///

- /// More specifically, checks the type of object that - /// would return. - /// For an , returns the type - /// of object that the creates. - ///

- ///
- /// The name of the object to query. - /// - /// The type of the object or if not determinable. - /// - Type GetType(string name); - - - - /// - /// Determines whether the object with the given name matches the specified type. - /// - /// More specifically, check whether a GetObject call for the given name - /// would return an object that is assignable to the specified target type. - /// Translates aliases back to the corresponding canonical bean name. - /// Will ask the parent factory if the bean cannot be found in this factory instance. - /// - /// The name of the object to query. - /// Type of the target to match against. - /// - /// true if the object type matches; otherwise, false - /// if it doesn't match or cannot be determined yet. - /// - /// Ff there is no object with the given name - /// - bool IsTypeMatch(string name, Type targetType); - - /// - /// Injects dependencies into the supplied instance - /// using the named object definition. - /// - /// - ///

- /// In addition to being generally useful, typically this method is used to provide - /// dependency injection functionality for objects that are instantiated outwith the - /// control of a developer. A case in point is the way that the current (1.1) - /// ASP.NET classes instantiate web controls... the instantiation takes place within - /// a private method of a compiled page, and thus cannot be hooked into the - /// typical Spring.NET IOC container lifecycle for dependency injection. - ///

- ///
- /// - /// The following code snippet assumes that the instantiated factory instance - /// has been configured with an object definition named - /// 'ExampleNamespace.BusinessObject' that has been configured to set the - /// Dao property of any ExampleNamespace.BusinessObject instance - /// to an instance of an appropriate implementation... - /// - /// namespace ExampleNamespace - /// { - /// public class BusinessObject - /// { - /// private IDao _dao; - /// - /// public BusinessObject() {} - /// - /// public IDao Dao - /// { - /// get { return _dao; } - /// set { _dao = value; } - /// } - /// } - /// } - /// - /// with the corresponding driver code looking like so... - /// - /// IObjectFactory factory = GetAnIObjectFactoryImplementation(); - /// BusinessObject instance = new BusinessObject(); - /// factory.ConfigureObject(instance, "object_definition_name"); - /// // at this point the dependencies for the 'instance' object will have been resolved... - /// - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// If there is no object definition for the supplied . - /// - /// - /// If any of the target object's dependencies could not be created. - /// - object ConfigureObject(object target, string name); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// The root interface for accessing a Spring.NET IoC container. + /// + /// + ///

+ /// This is the basic client view of a Spring.NET IoC container; further interfaces + /// such as and + /// + /// are available for specific purposes such as enumeration and configuration. + ///

+ ///

+ /// This is the root interface to be implemented by objects that can hold a number + /// of object definitions, each uniquely identified by a + /// name. An independent instance of any of these objects can be obtained + /// (the Prototype design pattern), or a single shared instance can be obtained + /// (a superior alternative to the Singleton design pattern, in which the instance is a + /// singleton in the scope of the factory). Which type of instance + /// will be returned depends on the object factory configuration - the API is the same. + /// The Singleton approach is more useful and hence more common in practice. + ///

+ ///

+ /// The point of this approach is that the IObjectFactory is a central registry of + /// application components, and centralizes the configuring of application components + /// (no more do individual objects need to read properties files, for example). + /// See chapters 4 and 11 of "Expert One-on-One J2EE Design and Development" for a + /// discussion of the benefits of this approach. + ///

+ ///

+ /// Normally an IObjectFactory will load object definitions stored in a configuration + /// source (such as an XML document), and use the + /// namespace to configure the objects. However, an implementation could simply return + /// .NET objects it creates as necessary directly in .NET code. There are no + /// constraints on how the definitions could be stored: LDAP, RDBMS, XML, properties + /// file etc. Implementations are encouraged to support references amongst objects, + /// to either Singletons or Prototypes. + ///

+ ///

+ /// In contrast to the methods in + /// , all of the methods + /// in this interface will also check parent factories if this is an + /// . If an object is + /// not found in this factory instance, the immediate parent is asked. Objects in + /// this factory instance are supposed to override objects of the same name in any + /// parent factory. + ///

+ ///

+ /// Object factories are supposed to support the standard object lifecycle interfaces + /// as far as possible. The maximum set of initialization methods and their standard + /// order is: + ///

+ ///

+ /// + /// + /// + /// 's + /// property. + /// + /// + /// + /// + /// 's + /// property. + /// + /// + /// + /// + /// + /// (only applicable if running within an ). + /// + /// + /// + /// + /// The + /// + /// method of + /// s. + /// + /// + /// + /// + /// 's + /// method. + /// + /// + /// + /// + /// A custom init-method definition. + /// + /// + /// + /// + /// The + /// + /// method of + /// s. + /// + /// + /// + ///

+ ///

+ ///

+ /// On shutdown of an object factory, the following lifecycle methods apply: + ///

+ ///

+ /// + /// + /// + /// 's + /// method. + /// + /// + /// + /// + /// A custom destroy-method definition. + /// + /// + /// + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IObjectFactory : IDisposable + { + /// + /// Is this object a singleton? + /// + /// + ///

+ /// That is, will + /// always return the same object? + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to query. + /// True if the named object is a singleton. + /// + /// If there's no such object definition. + /// + bool IsSingleton(string name); + + + /// + /// Determines whether the specified object name is prototype. That is, will GetObject + /// always return independent instances? + /// + /// This method returning false does not clearly indicate a singleton object. + /// It indicated non-independent instances, which may correspond to a scoped object as + /// well. use the IsSingleton property to explicitly check for a shared + /// singleton instance. + /// Translates aliases back to the corresponding canonical object name. Will ask the + /// parent factory if the object can not be found in this factory instance. + /// + /// + /// + /// The name of the object to query + /// + /// true if the specified object name will always deliver independent instances; otherwise, false. + /// + /// if there is no object with the given name. + bool IsPrototype(string name); + + /// + /// Does this object factory contain an object with the given name? + /// + /// + ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to query. + /// True if an object with the given name is defined. + bool ContainsObject(string name); + + /// + /// Return the aliases for the given object name, if defined. + /// + /// + ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The object name to check for aliases. + /// The aliases, or an empty array if none. + /// + /// If there's no such object definition. + /// + string[] GetAliases(string name); + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///

+ /// This is the indexer for the + /// interface. + ///

+ ///
+ /// The name of the object to return. + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + object this[string name] { get; } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to return. + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + object GetObject(string name); + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to return. + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. If there is no factory method and the + /// arguments are not null, then match the argument values by type and + /// call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the supplied is . + /// + object GetObject(string name, object[] arguments); + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// + /// The the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a factory method. If there is no factory method and the + /// supplied array is not , then + /// match the argument values by type and call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the object is not of the required type. + /// + /// + /// If the supplied is . + /// + /// + object GetObject(string name, Type requiredType, object[] arguments); + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// Provides a measure of type safety by throwing an exception if the object is + /// not of the required . + ///

+ ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to return. + /// + /// the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the object is not of the required type. + /// + object GetObject(string name, Type requiredType); + + /// + /// Determine the type of the object with the given name. + /// + /// + ///

+ /// More specifically, checks the type of object that + /// would return. + /// For an , returns the type + /// of object that the creates. + ///

+ ///
+ /// The name of the object to query. + /// + /// The type of the object or if not determinable. + /// + Type GetType(string name); + + + + /// + /// Determines whether the object with the given name matches the specified type. + /// + /// More specifically, check whether a GetObject call for the given name + /// would return an object that is assignable to the specified target type. + /// Translates aliases back to the corresponding canonical bean name. + /// Will ask the parent factory if the bean cannot be found in this factory instance. + /// + /// The name of the object to query. + /// Type of the target to match against. + /// + /// true if the object type matches; otherwise, false + /// if it doesn't match or cannot be determined yet. + /// + /// Ff there is no object with the given name + /// + bool IsTypeMatch(string name, Type targetType); + + /// + /// Injects dependencies into the supplied instance + /// using the named object definition. + /// + /// + ///

+ /// In addition to being generally useful, typically this method is used to provide + /// dependency injection functionality for objects that are instantiated outwith the + /// control of a developer. A case in point is the way that the current (1.1) + /// ASP.NET classes instantiate web controls... the instantiation takes place within + /// a private method of a compiled page, and thus cannot be hooked into the + /// typical Spring.NET IOC container lifecycle for dependency injection. + ///

+ ///
+ /// + /// The following code snippet assumes that the instantiated factory instance + /// has been configured with an object definition named + /// 'ExampleNamespace.BusinessObject' that has been configured to set the + /// Dao property of any ExampleNamespace.BusinessObject instance + /// to an instance of an appropriate implementation... + /// + /// namespace ExampleNamespace + /// { + /// public class BusinessObject + /// { + /// private IDao _dao; + /// + /// public BusinessObject() {} + /// + /// public IDao Dao + /// { + /// get { return _dao; } + /// set { _dao = value; } + /// } + /// } + /// } + /// + /// with the corresponding driver code looking like so... + /// + /// IObjectFactory factory = GetAnIObjectFactoryImplementation(); + /// BusinessObject instance = new BusinessObject(); + /// factory.ConfigureObject(instance, "object_definition_name"); + /// // at this point the dependencies for the 'instance' object will have been resolved... + /// + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// If there is no object definition for the supplied . + /// + /// + /// If any of the target object's dependencies could not be created. + /// + object ConfigureObject(object target, string name); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/IObjectFactoryAware.cs b/src/Spring/Spring.Core/Objects/Factory/IObjectFactoryAware.cs index f66b7128..1a34ec75 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IObjectFactoryAware.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IObjectFactoryAware.cs @@ -1,72 +1,71 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Interface to be implemented by objects that wish to be aware of their owning - /// . - /// - /// - ///

- /// For example, objects can look up collaborating objects via the factory. - ///

- ///

- /// Note that most objects will choose to receive references to collaborating - /// objects via respective properties and / or an appropriate constructor. - ///

- ///

- /// For a list of all object lifecycle methods, see the - /// API documentation. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: IObjectFactoryAware.cs,v 1.6 2006/04/09 07:18:48 markpollack Exp $ - public interface IObjectFactoryAware - { - /// - /// Callback that supplies the owning factory to an object instance. - /// - /// - /// Owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - /// - ///

- /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - ///

- ///
- /// - /// In case of initialization errors. - /// - IObjectFactory ObjectFactory { set; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Interface to be implemented by objects that wish to be aware of their owning + /// . + /// + /// + ///

+ /// For example, objects can look up collaborating objects via the factory. + ///

+ ///

+ /// Note that most objects will choose to receive references to collaborating + /// objects via respective properties and / or an appropriate constructor. + ///

+ ///

+ /// For a list of all object lifecycle methods, see the + /// API documentation. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + public interface IObjectFactoryAware + { + /// + /// Callback that supplies the owning factory to an object instance. + /// + /// + /// Owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + /// + ///

+ /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + ///

+ ///
+ /// + /// In case of initialization errors. + /// + IObjectFactory ObjectFactory { set; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/IObjectNameAware.cs b/src/Spring/Spring.Core/Objects/Factory/IObjectNameAware.cs index 86077897..a18f566c 100644 --- a/src/Spring/Spring.Core/Objects/Factory/IObjectNameAware.cs +++ b/src/Spring/Spring.Core/Objects/Factory/IObjectNameAware.cs @@ -1,68 +1,68 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Objects.Factory -{ - - /// - /// Interface to be implemented by objects that wish to be aware of their object - /// name in an . - /// - /// - ///

- /// Note that most objects will choose to receive references to collaborating - /// objects via respective properties. - ///

- ///

- /// For a list of all object lifecycle methods, see the - /// API documentation. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - public interface IObjectNameAware - { - - /// - /// Set the name of the object in the object factory that created this object. - /// - /// - /// The name of the object in the factory. - /// - /// - ///

- /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - ///

- ///
- string ObjectName - { - set; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Objects.Factory +{ + + /// + /// Interface to be implemented by objects that wish to be aware of their object + /// name in an . + /// + /// + ///

+ /// Note that most objects will choose to receive references to collaborating + /// objects via respective properties. + ///

+ ///

+ /// For a list of all object lifecycle methods, see the + /// API documentation. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IObjectNameAware + { + + /// + /// Set the name of the object in the object factory that created this object. + /// + /// + /// The name of the object in the factory. + /// + /// + ///

+ /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + ///

+ ///
+ string ObjectName + { + set; + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/NoSuchObjectDefinitionException.cs b/src/Spring/Spring.Core/Objects/Factory/NoSuchObjectDefinitionException.cs index 1c9a1e9e..1d03011a 100644 --- a/src/Spring/Spring.Core/Objects/Factory/NoSuchObjectDefinitionException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/NoSuchObjectDefinitionException.cs @@ -1,195 +1,194 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Exception thrown when an - /// is asked for an object instance name for which it cannot find a definition. - /// - /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: NoSuchObjectDefinitionException.cs,v 1.8 2006/04/09 07:18:48 markpollack Exp $ - [Serializable] - public class NoSuchObjectDefinitionException : ObjectsException - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public NoSuchObjectDefinitionException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public NoSuchObjectDefinitionException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NoSuchObjectDefinitionException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// Name of the missing object. - /// - /// - /// A further, detailed message describing the problem. - /// - public NoSuchObjectDefinitionException(string name, string message) - : base(string.Format( - CultureInfo.CurrentCulture, - "No object named '{0}' is defined : {1}", - name, - StringUtils.HasText(message) ? message : "not found.")) - { - _objectName = name; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The of the missing object. - /// - /// - /// A further, detailed message describing the problem. - /// - public NoSuchObjectDefinitionException(Type type, string message) - : base(string.Format( - CultureInfo.CurrentCulture, - "No unique object of type [{0}] is defined : {1}", - type != null ? type.FullName : "<< no Type specified >>", - StringUtils.HasText(message) ? message : "not found.")) - { - _objectType = type; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NoSuchObjectDefinitionException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - _objectName = info.GetString("ObjectName"); - _objectType = info.GetValue("ObjectType", typeof (Type)) as Type; - } - - #endregion - - #region Methods - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("ObjectName", ObjectName); - info.AddValue("ObjectType", ObjectType); - } - - #endregion - - #region Properties - - /// - /// Return the required of object, if it was a - /// lookup by that failed. - /// - public Type ObjectType - { - get { return _objectType; } - } - - /// - /// Return the name of the missing object, if it was a lookup by name that - /// failed. - /// - public string ObjectName - { - get { return _objectName; } - } - - #endregion - - #region Fields - - private Type _objectType; - private string _objectName; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Exception thrown when an + /// is asked for an object instance name for which it cannot find a definition. + /// + /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public class NoSuchObjectDefinitionException : ObjectsException + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public NoSuchObjectDefinitionException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public NoSuchObjectDefinitionException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NoSuchObjectDefinitionException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// Name of the missing object. + /// + /// + /// A further, detailed message describing the problem. + /// + public NoSuchObjectDefinitionException(string name, string message) + : base(string.Format( + CultureInfo.CurrentCulture, + "No object named '{0}' is defined : {1}", + name, + StringUtils.HasText(message) ? message : "not found.")) + { + _objectName = name; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The of the missing object. + /// + /// + /// A further, detailed message describing the problem. + /// + public NoSuchObjectDefinitionException(Type type, string message) + : base(string.Format( + CultureInfo.CurrentCulture, + "No unique object of type [{0}] is defined : {1}", + type != null ? type.FullName : "<< no Type specified >>", + StringUtils.HasText(message) ? message : "not found.")) + { + _objectType = type; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NoSuchObjectDefinitionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + _objectName = info.GetString("ObjectName"); + _objectType = info.GetValue("ObjectType", typeof (Type)) as Type; + } + + #endregion + + #region Methods + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("ObjectName", ObjectName); + info.AddValue("ObjectType", ObjectType); + } + + #endregion + + #region Properties + + /// + /// Return the required of object, if it was a + /// lookup by that failed. + /// + public Type ObjectType + { + get { return _objectType; } + } + + /// + /// Return the name of the missing object, if it was a lookup by name that + /// failed. + /// + public string ObjectName + { + get { return _objectName; } + } + + #endregion + + #region Fields + + private Type _objectType; + private string _objectName; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectCreationException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectCreationException.cs index bcf70314..54f02177 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectCreationException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectCreationException.cs @@ -1,333 +1,332 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Thrown when an - /// encounters an error when attempting to create an object from an object - /// definition. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ObjectCreationException.cs,v 1.15 2007/12/05 00:28:04 bbaia Exp $ - [Serializable] - public class ObjectCreationException : FatalObjectException - { - /// - /// Creates a new instance of the - /// class. - /// - public ObjectCreationException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public ObjectCreationException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - public ObjectCreationException(string objectName, string message) - : this(null, objectName, message, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectCreationException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectCreationException( - string objectName, string message, Exception rootCause) - : this(null, objectName, message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The description of the resource associated with the object. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - public ObjectCreationException( - string resourceDescription, - string objectName, - string message) - : this(resourceDescription, objectName, message, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The description of the resource associated with the object. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectCreationException( - string resourceDescription, - string objectName, - string message, - Exception rootCause) - : base(message, rootCause) - { - _resourceDescription = resourceDescription; - _objectName = objectName; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectCreationException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - _resourceDescription = (string) info.GetValue("_resourceDescription", typeof (string)); - _objectName = (string) info.GetValue("_objectName", typeof (string)); - _callStack = (string) info.GetValue("_callStack", typeof (string)); - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("_resourceDescription", ResourceDescription); - info.AddValue("_objectName", ObjectName); - info.AddValue("_callStack", _callStack); - } - - /// - /// The name of the object that triggered the exception (if any). - /// - public string ObjectName - { - get { return _objectName; } - } - - /// - /// The description of the resource associated with the object (if any). - /// - public string ResourceDescription - { - get { return _resourceDescription; } - } - - /// - /// Describes the creation failure trace of this exception. - /// - public override string Message - { - get - { - string message = ObjectCreationException.FormatMessage( - _resourceDescription, - _objectName, - base.Message, - _callStack); - return message; - } - } - - private static string FormatMessage( - string resourceDescription, - string objectName, - string message, - string callStack) - { - if (StringUtils.IsNullOrEmpty(callStack)) - { - return StringUtils.IsNullOrEmpty(resourceDescription) ? - string.Format( - "Error creating object with name '{0}' : {1}", - objectName, - message) - : - string.Format( - "Error creating object with name '{0}' defined in '{1}' : {2}", - objectName, - resourceDescription, - message); - } - else - { - return StringUtils.IsNullOrEmpty(resourceDescription) ? - string.Format( - "Error thrown by a dependency of object '{0}' : {1}{2}", - objectName, - message, - callStack) - : - string.Format( - "Error thrown by a dependency of object '{0}' defined in '{1}' : {2}{3}", - objectName, - resourceDescription, - message, - callStack); - } - } - - internal static ObjectCreationException GetObjectCreationException( - Exception ex, string objectName, string propertyName, - string resourceDescription, string referenceName) - { - ObjectCreationException ocex = ex as ObjectCreationException; - if (ocex != null) - { - StringBuilder newCause = new StringBuilder(); - newCause.AppendFormat("{0} while resolving '{1}' to '{2}' ", - Environment.NewLine, propertyName, ocex._objectName); - if (StringUtils.HasText(ocex._resourceDescription)) - { - newCause.Append("defined in '") - .Append(ocex._resourceDescription) - .Append("'"); - } - if (StringUtils.IsNullOrEmpty(ocex._callStack)) - { - ocex._callStack = newCause.ToString(); - } - else - { - ocex._callStack = newCause.Append(ocex._callStack).ToString(); - } - ocex._objectName = objectName; - ocex._resourceDescription = resourceDescription; - return ocex; - } - else if (ex is PropertyAccessExceptionsException - && ex.InnerException is TypeMismatchException) - { - return new ObjectCreationException( - resourceDescription, - objectName, - string.Format( - CultureInfo.InvariantCulture, - "Invalid type for property '{0}' of object '{1}' in '{2}'.", - propertyName, - objectName, - resourceDescription), - ex); - } - return new ObjectCreationException( - resourceDescription, - objectName, - string.Format( - CultureInfo.InvariantCulture, - "Can't resolve reference to object '{0}' while setting '{1}'.", - referenceName, - propertyName), - ex); - } - - private string _callStack; - private string _resourceDescription = string.Empty; - private string _objectName = string.Empty; - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Text; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Thrown when an + /// encounters an error when attempting to create an object from an object + /// definition. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class ObjectCreationException : FatalObjectException + { + /// + /// Creates a new instance of the + /// class. + /// + public ObjectCreationException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public ObjectCreationException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + public ObjectCreationException(string objectName, string message) + : this(null, objectName, message, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectCreationException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectCreationException( + string objectName, string message, Exception rootCause) + : this(null, objectName, message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The description of the resource associated with the object. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + public ObjectCreationException( + string resourceDescription, + string objectName, + string message) + : this(resourceDescription, objectName, message, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The description of the resource associated with the object. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectCreationException( + string resourceDescription, + string objectName, + string message, + Exception rootCause) + : base(message, rootCause) + { + _resourceDescription = resourceDescription; + _objectName = objectName; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectCreationException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + _resourceDescription = (string) info.GetValue("_resourceDescription", typeof (string)); + _objectName = (string) info.GetValue("_objectName", typeof (string)); + _callStack = (string) info.GetValue("_callStack", typeof (string)); + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("_resourceDescription", ResourceDescription); + info.AddValue("_objectName", ObjectName); + info.AddValue("_callStack", _callStack); + } + + /// + /// The name of the object that triggered the exception (if any). + /// + public string ObjectName + { + get { return _objectName; } + } + + /// + /// The description of the resource associated with the object (if any). + /// + public string ResourceDescription + { + get { return _resourceDescription; } + } + + /// + /// Describes the creation failure trace of this exception. + /// + public override string Message + { + get + { + string message = ObjectCreationException.FormatMessage( + _resourceDescription, + _objectName, + base.Message, + _callStack); + return message; + } + } + + private static string FormatMessage( + string resourceDescription, + string objectName, + string message, + string callStack) + { + if (StringUtils.IsNullOrEmpty(callStack)) + { + return StringUtils.IsNullOrEmpty(resourceDescription) ? + string.Format( + "Error creating object with name '{0}' : {1}", + objectName, + message) + : + string.Format( + "Error creating object with name '{0}' defined in '{1}' : {2}", + objectName, + resourceDescription, + message); + } + else + { + return StringUtils.IsNullOrEmpty(resourceDescription) ? + string.Format( + "Error thrown by a dependency of object '{0}' : {1}{2}", + objectName, + message, + callStack) + : + string.Format( + "Error thrown by a dependency of object '{0}' defined in '{1}' : {2}{3}", + objectName, + resourceDescription, + message, + callStack); + } + } + + internal static ObjectCreationException GetObjectCreationException( + Exception ex, string objectName, string propertyName, + string resourceDescription, string referenceName) + { + ObjectCreationException ocex = ex as ObjectCreationException; + if (ocex != null) + { + StringBuilder newCause = new StringBuilder(); + newCause.AppendFormat("{0} while resolving '{1}' to '{2}' ", + Environment.NewLine, propertyName, ocex._objectName); + if (StringUtils.HasText(ocex._resourceDescription)) + { + newCause.Append("defined in '") + .Append(ocex._resourceDescription) + .Append("'"); + } + if (StringUtils.IsNullOrEmpty(ocex._callStack)) + { + ocex._callStack = newCause.ToString(); + } + else + { + ocex._callStack = newCause.Append(ocex._callStack).ToString(); + } + ocex._objectName = objectName; + ocex._resourceDescription = resourceDescription; + return ocex; + } + else if (ex is PropertyAccessExceptionsException + && ex.InnerException is TypeMismatchException) + { + return new ObjectCreationException( + resourceDescription, + objectName, + string.Format( + CultureInfo.InvariantCulture, + "Invalid type for property '{0}' of object '{1}' in '{2}'.", + propertyName, + objectName, + resourceDescription), + ex); + } + return new ObjectCreationException( + resourceDescription, + objectName, + string.Format( + CultureInfo.InvariantCulture, + "Can't resolve reference to object '{0}' while setting '{1}'.", + referenceName, + propertyName), + ex); + } + + private string _callStack; + private string _resourceDescription = string.Empty; + private string _objectName = string.Empty; + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectCurrentlyInCreationException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectCurrentlyInCreationException.cs index 419c2d48..2e94d3dc 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectCurrentlyInCreationException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectCurrentlyInCreationException.cs @@ -1,184 +1,183 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Thrown in case of a reference to an object that is currently in creation. - /// - /// - ///

- /// Typically happens when constructor autowiring matches the currently - /// constructed object. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans - /// $Id: ObjectCurrentlyInCreationException.cs,v 1.7 2008/05/29 12:13:27 oakinger Exp $ - [Serializable] - public class ObjectCurrentlyInCreationException : ObjectCreationException - { - /// - /// The default error message text to be used, if none is specified. - /// - public const string DEFAULTMESSAGE = "Requested object is currently in creation: Is there an unresolvable circular reference?"; - - /// - /// Creates a new instance of the - /// class. - /// - public ObjectCurrentlyInCreationException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the object that triggered the exception. - /// - public ObjectCurrentlyInCreationException(string objectName) - : this(null, objectName, null, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectCurrentlyInCreationException(string objectName, Exception rootCause) - : this(null, objectName, null, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - public ObjectCurrentlyInCreationException(string objectName, string message) - : this(null, objectName, message, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectCurrentlyInCreationException(string objectName, string message, Exception rootCause) - : this(null, objectName, message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The description of the resource associated with the object. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - public ObjectCurrentlyInCreationException( - string resourceDescription, - string objectName, - string message) - : this(resourceDescription, objectName, message, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The description of the resource associated with the object. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectCurrentlyInCreationException( - string resourceDescription, - string objectName, - string message, - Exception rootCause) - : base(resourceDescription, - objectName, - StringUtils.HasText(message) ? message : DEFAULTMESSAGE, - rootCause) - { - } - - /// - /// Creates a new instance of the ObjectCurrentlyInCreationException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectCurrentlyInCreationException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Thrown in case of a reference to an object that is currently in creation. + /// + /// + ///

+ /// Typically happens when constructor autowiring matches the currently + /// constructed object. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans + [Serializable] + public class ObjectCurrentlyInCreationException : ObjectCreationException + { + /// + /// The default error message text to be used, if none is specified. + /// + public const string DEFAULTMESSAGE = "Requested object is currently in creation: Is there an unresolvable circular reference?"; + + /// + /// Creates a new instance of the + /// class. + /// + public ObjectCurrentlyInCreationException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the object that triggered the exception. + /// + public ObjectCurrentlyInCreationException(string objectName) + : this(null, objectName, null, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectCurrentlyInCreationException(string objectName, Exception rootCause) + : this(null, objectName, null, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + public ObjectCurrentlyInCreationException(string objectName, string message) + : this(null, objectName, message, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectCurrentlyInCreationException(string objectName, string message, Exception rootCause) + : this(null, objectName, message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The description of the resource associated with the object. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + public ObjectCurrentlyInCreationException( + string resourceDescription, + string objectName, + string message) + : this(resourceDescription, objectName, message, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The description of the resource associated with the object. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectCurrentlyInCreationException( + string resourceDescription, + string objectName, + string message, + Exception rootCause) + : base(resourceDescription, + objectName, + StringUtils.HasText(message) ? message : DEFAULTMESSAGE, + rootCause) + { + } + + /// + /// Creates a new instance of the ObjectCurrentlyInCreationException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectCurrentlyInCreationException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionException.cs index fcd0fa20..d446effd 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionException.cs @@ -1,134 +1,134 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Objects.Factory.Xml; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Exception thrown when an - /// encounters an error when attempting to parse an object - /// definition. - /// - /// Federico Spinazzi (.NET) - [Serializable] - public class ObjectDefinitionException : Exception - { - #region Fields - private string _className; - #endregion - - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the ObjectDefinitionException class. - /// - public ObjectDefinitionException () - { - } - - /// - /// Creates a new instance of the ObjectDefinitionException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectDefinitionException (string message, Exception rootCause) - : base (message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectDefinitionException class. - /// - /// - /// The value of the xml class attribute thet can be resolved - /// as a type - /// - public ObjectDefinitionException (string name) - { - _className = name; - } - - /// - /// Creates a new instance of the ObjectDefinitionException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectDefinitionException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - _className = info.GetString ("MyClassName"); - } - #endregion - - #region Properties - /// - /// The message about the exception. - /// - public override string Message - { - get - { - return String.Format("The specified name ('{0}') cannot be used to resolve any System.Type instance", _className); - } - } - #endregion - - #region Methods - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] - public override void GetObjectData ( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData (info, context); - info.AddValue ("MyClassName", _className); - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Objects.Factory.Xml; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Exception thrown when an + /// encounters an error when attempting to parse an object + /// definition. + /// + /// Federico Spinazzi (.NET) + [Serializable] + public class ObjectDefinitionException : Exception + { + #region Fields + private string _className; + #endregion + + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the ObjectDefinitionException class. + /// + public ObjectDefinitionException () + { + } + + /// + /// Creates a new instance of the ObjectDefinitionException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectDefinitionException (string message, Exception rootCause) + : base (message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectDefinitionException class. + /// + /// + /// The value of the xml class attribute thet can be resolved + /// as a type + /// + public ObjectDefinitionException (string name) + { + _className = name; + } + + /// + /// Creates a new instance of the ObjectDefinitionException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectDefinitionException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + _className = info.GetString ("MyClassName"); + } + #endregion + + #region Properties + /// + /// The message about the exception. + /// + public override string Message + { + get + { + return String.Format("The specified name ('{0}') cannot be used to resolve any System.Type instance", _className); + } + } + #endregion + + #region Methods + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] + public override void GetObjectData ( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData (info, context); + info.AddValue ("MyClassName", _className); + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionStoreException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionStoreException.cs index e978f42a..4aeb1253 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionStoreException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectDefinitionStoreException.cs @@ -1,260 +1,260 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; -using Spring.Core.IO; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Thrown when an - /// encounters an internal error, and its definitions are invalid. - /// - /// - ///

- /// An example of a situation when this exception would be thrown is - /// in the case of an XML document containing object definitions being - /// malformed. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - [Serializable] - public class ObjectDefinitionStoreException : FatalObjectException - { - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - public ObjectDefinitionStoreException() - { - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// A message about the exception. - /// - public ObjectDefinitionStoreException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// The description of the resource that the object definition came from - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// A message about the exception. - /// - public ObjectDefinitionStoreException( - string resourceDescription, string name, string message) - : this(resourceDescription, name, message, null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The description of the resource that the object definition came from - /// - /// The detail message (used as exception message as-is) - /// The root cause. (may be null - public ObjectDefinitionStoreException(string resourceDescription, string msg, Exception cause) - : this(msg, cause) - { - _resourceDescription = resourceDescription; - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// The resource location (e.g. an XML object definition file) associated - /// with the offending object definition. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - public ObjectDefinitionStoreException( - IResource resourceLocation, - string name, - string message) : this - (resourceLocation == null ? string.Empty : resourceLocation.Description, - name, message) - { - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// The resource location (e.g. an XML object definition file) associated - /// with the offending object definition. - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectDefinitionStoreException( - IResource resourceLocation, - string name, - string message, - Exception rootCause) : this - (resourceLocation == null ? string.Empty : resourceLocation.Description, - name, message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// The description of the resource that the object definition came from - /// - /// - /// A message about the exception. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectDefinitionStoreException( - string resourceDescription, - string name, - string message, - Exception rootCause) - : base( - string.Format( - "Error registering object with name '{0}' defined in '{1}' : {2}", - name, - resourceDescription, - message), - rootCause) - { - _resourceDescription = resourceDescription; - _objectName = name; - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectDefinitionStoreException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectDefinitionStoreException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectDefinitionStoreException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - _resourceDescription = info.GetValue ("_resourceDescription", typeof (object)) as string; - _objectName = info.GetValue ("_objectName", typeof (object)) as string; - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] - public override void GetObjectData ( - SerializationInfo info, StreamingContext context) - { - base.GetObjectData (info, context); - info.AddValue ("_resourceDescription", ResourceDescription); - info.AddValue ("_objectName", ObjectName); - } - - /// - /// The name of the object that triggered the exception (if any). - /// - public string ObjectName - { - get { return _objectName; } - } - - /// - /// The description of the resource associated with the object (if any). - /// - public string ResourceDescription - { - get { return _resourceDescription; } - } - - /// - /// The description of the resource associated with the object - /// - protected string _resourceDescription = string.Empty; - - /// - /// The name of the object that trigger the exception. - /// - protected string _objectName = string.Empty; - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; +using Spring.Core.IO; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Thrown when an + /// encounters an internal error, and its definitions are invalid. + /// + /// + ///

+ /// An example of a situation when this exception would be thrown is + /// in the case of an XML document containing object definitions being + /// malformed. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class ObjectDefinitionStoreException : FatalObjectException + { + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + public ObjectDefinitionStoreException() + { + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// A message about the exception. + /// + public ObjectDefinitionStoreException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// The description of the resource that the object definition came from + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// A message about the exception. + /// + public ObjectDefinitionStoreException( + string resourceDescription, string name, string message) + : this(resourceDescription, name, message, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The description of the resource that the object definition came from + /// + /// The detail message (used as exception message as-is) + /// The root cause. (may be null + public ObjectDefinitionStoreException(string resourceDescription, string msg, Exception cause) + : this(msg, cause) + { + _resourceDescription = resourceDescription; + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// The resource location (e.g. an XML object definition file) associated + /// with the offending object definition. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + public ObjectDefinitionStoreException( + IResource resourceLocation, + string name, + string message) : this + (resourceLocation == null ? string.Empty : resourceLocation.Description, + name, message) + { + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// The resource location (e.g. an XML object definition file) associated + /// with the offending object definition. + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectDefinitionStoreException( + IResource resourceLocation, + string name, + string message, + Exception rootCause) : this + (resourceLocation == null ? string.Empty : resourceLocation.Description, + name, message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// The description of the resource that the object definition came from + /// + /// + /// A message about the exception. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectDefinitionStoreException( + string resourceDescription, + string name, + string message, + Exception rootCause) + : base( + string.Format( + "Error registering object with name '{0}' defined in '{1}' : {2}", + name, + resourceDescription, + message), + rootCause) + { + _resourceDescription = resourceDescription; + _objectName = name; + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectDefinitionStoreException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectDefinitionStoreException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectDefinitionStoreException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + _resourceDescription = info.GetValue ("_resourceDescription", typeof (object)) as string; + _objectName = info.GetValue ("_objectName", typeof (object)) as string; + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] + public override void GetObjectData ( + SerializationInfo info, StreamingContext context) + { + base.GetObjectData (info, context); + info.AddValue ("_resourceDescription", ResourceDescription); + info.AddValue ("_objectName", ObjectName); + } + + /// + /// The name of the object that triggered the exception (if any). + /// + public string ObjectName + { + get { return _objectName; } + } + + /// + /// The description of the resource associated with the object (if any). + /// + public string ResourceDescription + { + get { return _resourceDescription; } + } + + /// + /// The description of the resource associated with the object + /// + protected string _resourceDescription = string.Empty; + + /// + /// The name of the object that trigger the exception. + /// + protected string _objectName = string.Empty; + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs index 71afa378..1897bfb8 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs @@ -1,467 +1,466 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Collections; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Convenience methods operating on object factories, returning object instances, - /// names, or counts. - /// - /// - ///

- /// The nesting hierarchy of an object factory is taken into account by the various methods - /// exposed by this class. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ObjectFactoryUtils.cs,v 1.17 2007/07/31 03:47:39 markpollack Exp $ - public sealed class ObjectFactoryUtils - { - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible - /// constructors. - ///

- ///
- private ObjectFactoryUtils() - { - } - - // CLOVER:ON - - #endregion - - /// - /// Used to dereference an - /// and distinguish it from managed objects created by the factory. - /// - /// - ///

- /// For example, if the managed object identified as foo is a - /// factory, getting &foo will return the factory, not the - /// instance returned by the factory. - ///

- ///
- public const string FactoryObjectPrefix = "&"; - - /// - /// Count all object definitions in any hierarchy in which this - /// factory participates. - /// - /// - ///

- /// Includes counts of ancestor object factories. - ///

- ///

- /// Objects that are "overridden" (specified in a descendant factory - /// with the same name) are counted only once. - ///

- ///
- /// The object factory. - /// - /// The count of objects including those defined in ancestor factories. - /// - public static int CountObjectsIncludingAncestors(IListableObjectFactory factory) - { - return ObjectNamesIncludingAncestors(factory).Length; - } - - /// - /// Return all object names in the factory, including ancestor factories. - /// - /// The object factory. - /// The array of object names, or an empty array if none. - public static string[] ObjectNamesIncludingAncestors(IListableObjectFactory factory) - { - Set result = new HashedSet(); - result.AddAll(factory.GetObjectDefinitionNames()); - IListableObjectFactory pof = GetParentFactoryIfAny(factory); - if (pof != null) - { - string[] parentsResult = ObjectNamesIncludingAncestors(pof); - result.AddAll(parentsResult); - } - return ToArrayOfObjectNames(result); - } - - private static string[] ToArrayOfObjectNames(Set result) - { - Array resultArray = Array.CreateInstance(typeof (string), result.Count); - result.CopyTo(resultArray, 0); - return (string[]) resultArray; - } - - /// - /// Get all object names for the given type, including those defined in ancestor - /// factories. - /// - /// - ///

- /// Will return unique names in case of overridden object definitions. - ///

- ///

- /// Does consider objects created by s - /// if is set to true, - /// which means that s will get initialized. - ///

- ///
- /// - /// If this isn't also an - /// , - /// this method will return the same as it's own - /// - /// method. - /// - /// - /// The that objects must match. - /// - /// - /// Whether to include prototype objects too or just singletons - /// (also applies to instances). - /// - /// - /// Whether to include instances - /// too or just normal objects. - /// - /// - /// The array of object names, or an empty array if none. - /// - public static string[] ObjectNamesForTypeIncludingAncestors( - IListableObjectFactory factory, Type type, - bool includePrototypes, bool includeFactoryObjects) - { - Set result = new HashedSet(); - result.AddAll(factory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects)); - IListableObjectFactory pof = GetParentFactoryIfAny(factory); - if (pof != null) - { - string[] parentsResult = ObjectNamesForTypeIncludingAncestors(pof, type, includePrototypes, includeFactoryObjects); - result.AddAll(parentsResult); - } - return ToArrayOfObjectNames(result); - } - - /// - /// Get all object names for the given type, including those defined in ancestor - /// factories. - /// - /// - ///

- /// Will return unique names in case of overridden object definitions. - ///

- ///

- /// Does consider objects created by s, - /// or rather it considers the type of objects created by - /// (which means that - /// s will be instantiated). - ///

- ///
- /// - /// If this isn't also an - /// , - /// this method will return the same as it's own - /// - /// method. - /// - /// - /// The that objects must match. - /// - /// - /// The array of object names, or an empty array if none. - /// - public static string[] ObjectNamesForTypeIncludingAncestors( - IListableObjectFactory factory, Type type) - { - Set result = new HashedSet(); - result.AddAll(factory.GetObjectNamesForType(type)); - IListableObjectFactory pof = GetParentFactoryIfAny(factory); - if (pof != null) - { - string[] parentsResult = ObjectNamesForTypeIncludingAncestors(pof, type); - result.AddAll(parentsResult); - } - return ToArrayOfObjectNames(result); - } - - private static IListableObjectFactory GetParentFactoryIfAny(IListableObjectFactory factory) - { - IHierarchicalObjectFactory hierFactory = factory as IHierarchicalObjectFactory; - if (hierFactory != null) - { - return - hierFactory.ParentObjectFactory as IListableObjectFactory; - } - return null; - } - - /// - /// Return all objects of the given type or subtypes, also picking up objects - /// defined in ancestor object factories if the current object factory is an - /// . - /// - /// - ///

- /// The return list will only contain objects of this type. - /// Useful convenience method when we don't care about object names. - ///

- ///
- /// The object factory. - /// The of object to match. - /// - /// Whether to include prototype objects too or just singletons - /// (also applies to instances). - /// - /// - /// Whether to include instances - /// too or just normal objects. - /// - /// - /// If the objects could not be created. - /// - /// - /// The of object instances, or an - /// empty if none. - /// - public static IDictionary ObjectsOfTypeIncludingAncestors( - IListableObjectFactory factory, Type type, - bool includePrototypes, bool includeFactoryObjects) - { - Hashtable result = new Hashtable(); - foreach (DictionaryEntry entry in - factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects)) - { - result.Add(entry.Key, entry.Value); - } - IListableObjectFactory pof = GetParentFactoryIfAny(factory); - if (pof != null) - { - IDictionary parentResult - = ObjectsOfTypeIncludingAncestors( - pof, type, includePrototypes, includeFactoryObjects); - foreach (object instance in parentResult.Keys) - { - if (!result.ContainsKey(instance)) - { - result.Add(instance, parentResult[instance]); - } - } - } - return result; - } - - /// - /// Return a single object of the given type or subtypes, also picking up objects defined - /// in ancestor object factories if the current object factory is an - /// . - /// - /// - ///

- /// Useful convenience method when we expect a single object and don't care - /// about the object name. - ///

- ///
- /// The object factory. - /// The of object to match. - /// - /// Whether to include prototype objects too or just singletons - /// (also applies to instances). - /// - /// - /// Whether to include instances - /// too or just normal objects. - /// - /// - /// If the object could not be created. - /// - /// - /// If more than one instance of an object was found. - /// - /// - /// A single object of the given type or subtypes. - /// - public static object ObjectOfTypeIncludingAncestors( - IListableObjectFactory factory, Type type, - bool includePrototypes, bool includeFactoryObjects) - { - IDictionary objectsOfType - = ObjectsOfTypeIncludingAncestors( - factory, type, includePrototypes, includeFactoryObjects); - return GrabTheOnlyObject(objectsOfType, type); - } - - private static object GrabTheOnlyObject(IDictionary objectsOfType, Type type) - { - if (objectsOfType.Count == 1) - { - return ObjectUtils.EnumerateFirstElement(objectsOfType.Values); - } - else - { - throw new NoSuchObjectDefinitionException(type, "Expected single object but found " + objectsOfType.Count); - } - } - - /// - /// Return a single object of the given type or subtypes, not looking in - /// ancestor factories. - /// - /// - ///

- /// Useful convenience method when we expect a single object and don't care - /// about the object name. - ///

- ///
- /// The object factory. - /// The of object to match. - /// - /// Whether to include prototype objects too or just singletons - /// (also applies to instances). - /// - /// - /// Whether to include instances - /// too or just normal objects. - /// - /// - /// If the object could not be created. - /// - /// - /// If not exactly one instance of an object was found. - /// - /// - /// A single object of the given type or subtypes. - /// - public static object ObjectOfType(IListableObjectFactory factory, Type type, - bool includePrototypes, bool includeFactoryObjects) - { - IDictionary objectsOfType - = factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects); - return GrabTheOnlyObject(objectsOfType, type); - } - - /// - /// Return a single object of the given type or subtypes, not looking in - /// ancestor factories. - /// - /// - ///

- /// Useful convenience method when we expect a single object and don't care - /// about the object name. - /// This version of ObjectOfType automatically includes prototypes and - /// instances. - ///

- ///
- /// The object factory. - /// The of object to match. - /// - /// If the object could not be created. - /// - /// - /// If not exactly one instance of an object was found. - /// - /// - /// A single object of the given type or subtypes. - /// - public static object ObjectOfType(IListableObjectFactory factory, Type type) - { - return ObjectOfType(factory, type, true, true); - } - - /// - /// Return the object name, stripping out the factory dereference prefix if necessary. - /// - /// The name of the object. - /// The object name sans any factory dereference prefix. - public static string TransformedObjectName(string name) - { - AssertUtils.ArgumentNotNull(name, "name", "Object name must not be null."); - string objectName = name; - if (ObjectFactoryUtils.IsFactoryDereference(objectName)) - { - objectName = objectName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length); - } - return objectName; - } - - /// - /// Given an (object) name, builds a corresponding factory object name such that - /// the return value can be used as a lookup name for a factory object. - /// - /// - /// The name to be used to build the resulting factory object name. - /// - /// - /// The transformed into its factory object name - /// equivalent. - /// - /// - /// - public static string BuildFactoryObjectName(string objectName) - { - return ObjectFactoryUtils.FactoryObjectPrefix + objectName; - } - - /// - /// Is the supplied a factory dereference? - /// - /// - ///

- /// That is, does the supplied begin with - /// the - /// ? - ///

- ///
- /// The name to check. - /// - /// if the supplied is a - /// factory dereference; if not, or the - /// aupplied is or - /// consists solely of the - /// - /// value. - /// - /// - public static bool IsFactoryDereference(string name) - { - return name != null - && name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix) - && name.Length > ObjectFactoryUtils.FactoryObjectPrefix.Length; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Collections; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Convenience methods operating on object factories, returning object instances, + /// names, or counts. + /// + /// + ///

+ /// The nesting hierarchy of an object factory is taken into account by the various methods + /// exposed by this class. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public sealed class ObjectFactoryUtils + { + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible + /// constructors. + ///

+ ///
+ private ObjectFactoryUtils() + { + } + + // CLOVER:ON + + #endregion + + /// + /// Used to dereference an + /// and distinguish it from managed objects created by the factory. + /// + /// + ///

+ /// For example, if the managed object identified as foo is a + /// factory, getting &foo will return the factory, not the + /// instance returned by the factory. + ///

+ ///
+ public const string FactoryObjectPrefix = "&"; + + /// + /// Count all object definitions in any hierarchy in which this + /// factory participates. + /// + /// + ///

+ /// Includes counts of ancestor object factories. + ///

+ ///

+ /// Objects that are "overridden" (specified in a descendant factory + /// with the same name) are counted only once. + ///

+ ///
+ /// The object factory. + /// + /// The count of objects including those defined in ancestor factories. + /// + public static int CountObjectsIncludingAncestors(IListableObjectFactory factory) + { + return ObjectNamesIncludingAncestors(factory).Length; + } + + /// + /// Return all object names in the factory, including ancestor factories. + /// + /// The object factory. + /// The array of object names, or an empty array if none. + public static string[] ObjectNamesIncludingAncestors(IListableObjectFactory factory) + { + Set result = new HashedSet(); + result.AddAll(factory.GetObjectDefinitionNames()); + IListableObjectFactory pof = GetParentFactoryIfAny(factory); + if (pof != null) + { + string[] parentsResult = ObjectNamesIncludingAncestors(pof); + result.AddAll(parentsResult); + } + return ToArrayOfObjectNames(result); + } + + private static string[] ToArrayOfObjectNames(Set result) + { + Array resultArray = Array.CreateInstance(typeof (string), result.Count); + result.CopyTo(resultArray, 0); + return (string[]) resultArray; + } + + /// + /// Get all object names for the given type, including those defined in ancestor + /// factories. + /// + /// + ///

+ /// Will return unique names in case of overridden object definitions. + ///

+ ///

+ /// Does consider objects created by s + /// if is set to true, + /// which means that s will get initialized. + ///

+ ///
+ /// + /// If this isn't also an + /// , + /// this method will return the same as it's own + /// + /// method. + /// + /// + /// The that objects must match. + /// + /// + /// Whether to include prototype objects too or just singletons + /// (also applies to instances). + /// + /// + /// Whether to include instances + /// too or just normal objects. + /// + /// + /// The array of object names, or an empty array if none. + /// + public static string[] ObjectNamesForTypeIncludingAncestors( + IListableObjectFactory factory, Type type, + bool includePrototypes, bool includeFactoryObjects) + { + Set result = new HashedSet(); + result.AddAll(factory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects)); + IListableObjectFactory pof = GetParentFactoryIfAny(factory); + if (pof != null) + { + string[] parentsResult = ObjectNamesForTypeIncludingAncestors(pof, type, includePrototypes, includeFactoryObjects); + result.AddAll(parentsResult); + } + return ToArrayOfObjectNames(result); + } + + /// + /// Get all object names for the given type, including those defined in ancestor + /// factories. + /// + /// + ///

+ /// Will return unique names in case of overridden object definitions. + ///

+ ///

+ /// Does consider objects created by s, + /// or rather it considers the type of objects created by + /// (which means that + /// s will be instantiated). + ///

+ ///
+ /// + /// If this isn't also an + /// , + /// this method will return the same as it's own + /// + /// method. + /// + /// + /// The that objects must match. + /// + /// + /// The array of object names, or an empty array if none. + /// + public static string[] ObjectNamesForTypeIncludingAncestors( + IListableObjectFactory factory, Type type) + { + Set result = new HashedSet(); + result.AddAll(factory.GetObjectNamesForType(type)); + IListableObjectFactory pof = GetParentFactoryIfAny(factory); + if (pof != null) + { + string[] parentsResult = ObjectNamesForTypeIncludingAncestors(pof, type); + result.AddAll(parentsResult); + } + return ToArrayOfObjectNames(result); + } + + private static IListableObjectFactory GetParentFactoryIfAny(IListableObjectFactory factory) + { + IHierarchicalObjectFactory hierFactory = factory as IHierarchicalObjectFactory; + if (hierFactory != null) + { + return + hierFactory.ParentObjectFactory as IListableObjectFactory; + } + return null; + } + + /// + /// Return all objects of the given type or subtypes, also picking up objects + /// defined in ancestor object factories if the current object factory is an + /// . + /// + /// + ///

+ /// The return list will only contain objects of this type. + /// Useful convenience method when we don't care about object names. + ///

+ ///
+ /// The object factory. + /// The of object to match. + /// + /// Whether to include prototype objects too or just singletons + /// (also applies to instances). + /// + /// + /// Whether to include instances + /// too or just normal objects. + /// + /// + /// If the objects could not be created. + /// + /// + /// The of object instances, or an + /// empty if none. + /// + public static IDictionary ObjectsOfTypeIncludingAncestors( + IListableObjectFactory factory, Type type, + bool includePrototypes, bool includeFactoryObjects) + { + Hashtable result = new Hashtable(); + foreach (DictionaryEntry entry in + factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects)) + { + result.Add(entry.Key, entry.Value); + } + IListableObjectFactory pof = GetParentFactoryIfAny(factory); + if (pof != null) + { + IDictionary parentResult + = ObjectsOfTypeIncludingAncestors( + pof, type, includePrototypes, includeFactoryObjects); + foreach (object instance in parentResult.Keys) + { + if (!result.ContainsKey(instance)) + { + result.Add(instance, parentResult[instance]); + } + } + } + return result; + } + + /// + /// Return a single object of the given type or subtypes, also picking up objects defined + /// in ancestor object factories if the current object factory is an + /// . + /// + /// + ///

+ /// Useful convenience method when we expect a single object and don't care + /// about the object name. + ///

+ ///
+ /// The object factory. + /// The of object to match. + /// + /// Whether to include prototype objects too or just singletons + /// (also applies to instances). + /// + /// + /// Whether to include instances + /// too or just normal objects. + /// + /// + /// If the object could not be created. + /// + /// + /// If more than one instance of an object was found. + /// + /// + /// A single object of the given type or subtypes. + /// + public static object ObjectOfTypeIncludingAncestors( + IListableObjectFactory factory, Type type, + bool includePrototypes, bool includeFactoryObjects) + { + IDictionary objectsOfType + = ObjectsOfTypeIncludingAncestors( + factory, type, includePrototypes, includeFactoryObjects); + return GrabTheOnlyObject(objectsOfType, type); + } + + private static object GrabTheOnlyObject(IDictionary objectsOfType, Type type) + { + if (objectsOfType.Count == 1) + { + return ObjectUtils.EnumerateFirstElement(objectsOfType.Values); + } + else + { + throw new NoSuchObjectDefinitionException(type, "Expected single object but found " + objectsOfType.Count); + } + } + + /// + /// Return a single object of the given type or subtypes, not looking in + /// ancestor factories. + /// + /// + ///

+ /// Useful convenience method when we expect a single object and don't care + /// about the object name. + ///

+ ///
+ /// The object factory. + /// The of object to match. + /// + /// Whether to include prototype objects too or just singletons + /// (also applies to instances). + /// + /// + /// Whether to include instances + /// too or just normal objects. + /// + /// + /// If the object could not be created. + /// + /// + /// If not exactly one instance of an object was found. + /// + /// + /// A single object of the given type or subtypes. + /// + public static object ObjectOfType(IListableObjectFactory factory, Type type, + bool includePrototypes, bool includeFactoryObjects) + { + IDictionary objectsOfType + = factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects); + return GrabTheOnlyObject(objectsOfType, type); + } + + /// + /// Return a single object of the given type or subtypes, not looking in + /// ancestor factories. + /// + /// + ///

+ /// Useful convenience method when we expect a single object and don't care + /// about the object name. + /// This version of ObjectOfType automatically includes prototypes and + /// instances. + ///

+ ///
+ /// The object factory. + /// The of object to match. + /// + /// If the object could not be created. + /// + /// + /// If not exactly one instance of an object was found. + /// + /// + /// A single object of the given type or subtypes. + /// + public static object ObjectOfType(IListableObjectFactory factory, Type type) + { + return ObjectOfType(factory, type, true, true); + } + + /// + /// Return the object name, stripping out the factory dereference prefix if necessary. + /// + /// The name of the object. + /// The object name sans any factory dereference prefix. + public static string TransformedObjectName(string name) + { + AssertUtils.ArgumentNotNull(name, "name", "Object name must not be null."); + string objectName = name; + if (ObjectFactoryUtils.IsFactoryDereference(objectName)) + { + objectName = objectName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length); + } + return objectName; + } + + /// + /// Given an (object) name, builds a corresponding factory object name such that + /// the return value can be used as a lookup name for a factory object. + /// + /// + /// The name to be used to build the resulting factory object name. + /// + /// + /// The transformed into its factory object name + /// equivalent. + /// + /// + /// + public static string BuildFactoryObjectName(string objectName) + { + return ObjectFactoryUtils.FactoryObjectPrefix + objectName; + } + + /// + /// Is the supplied a factory dereference? + /// + /// + ///

+ /// That is, does the supplied begin with + /// the + /// ? + ///

+ ///
+ /// The name to check. + /// + /// if the supplied is a + /// factory dereference; if not, or the + /// aupplied is or + /// consists solely of the + /// + /// value. + /// + /// + public static bool IsFactoryDereference(string name) + { + return name != null + && name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix) + && name.Length > ObjectFactoryUtils.FactoryObjectPrefix.Length; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectInitializationException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectInitializationException.cs index d6ea606d..d78a69b3 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectInitializationException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectInitializationException.cs @@ -1,98 +1,98 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Exception that an object implementation is suggested to throw if its own - /// factory-aware initialization code fails. - /// thrown by object factory methods - /// themselves should simply be propagated as-is. - /// - /// - ///

- /// Note that non-factory-aware initialization methods like AfterPropertiesSet () - /// or a custom "init-method" can throw any exception. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - [Serializable] - public class ObjectInitializationException : FatalObjectException - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the ObjectInitializationException class. - /// - public ObjectInitializationException () - { - } - - /// - /// Creates a new instance of the ObjectInitializationException class. - /// - /// - /// A message about the exception. - /// - public ObjectInitializationException (string message) - : base (message) - { - } - - /// - /// Creates a new instance of the ObjectInitializationException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectInitializationException (string message, Exception rootCause) - : base (message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectInitializationException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectInitializationException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Exception that an object implementation is suggested to throw if its own + /// factory-aware initialization code fails. + /// thrown by object factory methods + /// themselves should simply be propagated as-is. + /// + /// + ///

+ /// Note that non-factory-aware initialization methods like AfterPropertiesSet () + /// or a custom "init-method" can throw any exception. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class ObjectInitializationException : FatalObjectException + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the ObjectInitializationException class. + /// + public ObjectInitializationException () + { + } + + /// + /// Creates a new instance of the ObjectInitializationException class. + /// + /// + /// A message about the exception. + /// + public ObjectInitializationException (string message) + : base (message) + { + } + + /// + /// Creates a new instance of the ObjectInitializationException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectInitializationException (string message, Exception rootCause) + : base (message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectInitializationException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectInitializationException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectIsNotAFactoryException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectIsNotAFactoryException.cs index 8acd1f33..1497d80c 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectIsNotAFactoryException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectIsNotAFactoryException.cs @@ -1,115 +1,114 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Thrown in response to an attempt to lookup a factory object, and - /// the object identified by the lookup key is not a factory. - /// - /// - ///

- /// An object is a factory if it implements (either directly or indirectly - /// via inheritance) the - /// interface. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: ObjectIsNotAFactoryException.cs,v 1.5 2006/04/09 07:18:49 markpollack Exp $ - [Serializable] - public class ObjectIsNotAFactoryException : ObjectNotOfRequiredTypeException - { - /// - /// Creates a new instance of the - /// class. - /// - public ObjectIsNotAFactoryException() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public ObjectIsNotAFactoryException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectIsNotAFactoryException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the object that was being retrieved from the factory. - /// - /// - /// The object instance that was retrieved. - /// - public ObjectIsNotAFactoryException(string name, object actualInstance) - : base(name, typeof (IFactoryObject), actualInstance) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectIsNotAFactoryException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Thrown in response to an attempt to lookup a factory object, and + /// the object identified by the lookup key is not a factory. + /// + /// + ///

+ /// An object is a factory if it implements (either directly or indirectly + /// via inheritance) the + /// interface. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public class ObjectIsNotAFactoryException : ObjectNotOfRequiredTypeException + { + /// + /// Creates a new instance of the + /// class. + /// + public ObjectIsNotAFactoryException() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public ObjectIsNotAFactoryException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectIsNotAFactoryException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the object that was being retrieved from the factory. + /// + /// + /// The object instance that was retrieved. + /// + public ObjectIsNotAFactoryException(string name, object actualInstance) + : base(name, typeof (IFactoryObject), actualInstance) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectIsNotAFactoryException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectNotOfRequiredTypeException.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectNotOfRequiredTypeException.cs index 16ecfd47..b38602b6 100644 --- a/src/Spring/Spring.Core/Objects/Factory/ObjectNotOfRequiredTypeException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/ObjectNotOfRequiredTypeException.cs @@ -1,185 +1,185 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; -using System.Security.Permissions; - -#endregion - -namespace Spring.Objects.Factory { - /// - /// Thrown when an object doesn't match the required . - /// - /// Rod Johnson - /// Rick Evans (.NET) - [Serializable] - public class ObjectNotOfRequiredTypeException : ObjectsException { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the ObjectNotOfRequiredTypeException class. - /// - public ObjectNotOfRequiredTypeException () { - } - - /// - /// Creates a new instance of the ObjectNotOfRequiredTypeException class. - /// - /// - /// A message about the exception. - /// - public ObjectNotOfRequiredTypeException (string message) - : base (message) { - } - - /// - /// Creates a new instance of the ObjectNotOfRequiredTypeException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectNotOfRequiredTypeException (string message, Exception rootCause) - : base (message, rootCause) { - } - - /// - /// Creates a new instance of the ObjectNotOfRequiredTypeException class. - /// - /// - /// Name of the object requested. - /// - /// - /// The required of the actual object - /// instance that was retrieved. - /// - /// - /// The instance actually returned, whose class did not match the - /// expected . - /// - public ObjectNotOfRequiredTypeException ( - string name, Type requiredType, object actualInstance) - : base ( - string.Format ( - "Object named '{0}' must be of type [{1}], but was actually of type [{2}]", - name, - requiredType.Name, - actualInstance.GetType ().Name)) { - this.name = name; - this.actualInstance = actualInstance; - this.requiredType = requiredType; - } - - /// - /// Creates a new instance of the ObjectNotOfRequiredTypeException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectNotOfRequiredTypeException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - requiredType = info.GetValue ("RequiredType", typeof (Type)) as Type; - actualInstance = info.GetValue ("ActualInstance", typeof (object)); - name = info.GetString ("Name"); - } - #endregion - - #region Properties - /// - /// The actual of the actual object - /// instance that was retrieved. - /// - public Type ActualType { - get { - return ActualInstance.GetType (); - } - } - /// - /// The required of the actual object - /// instance that was retrieved. - /// - public Type RequiredType { - get { - return requiredType; - } - } - - /// - /// The instance actually returned, whose class did not match the - /// expected . - /// - public object ActualInstance { - get { - return actualInstance; - } - } - - /// - /// The name of the object requested. - /// - public string ObjectName { - get { - return name; - } - } - #endregion - - #region Methods - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] - public override void GetObjectData ( - SerializationInfo info, StreamingContext context) { - base.GetObjectData (info, context); - info.AddValue ("RequiredType", requiredType); - info.AddValue ("ActualInstance", actualInstance); - info.AddValue ("Name", name); - } - #endregion - - #region Fields - private Type requiredType; - private object actualInstance; - private string name; - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Security.Permissions; + +#endregion + +namespace Spring.Objects.Factory { + /// + /// Thrown when an object doesn't match the required . + /// + /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public class ObjectNotOfRequiredTypeException : ObjectsException { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the ObjectNotOfRequiredTypeException class. + /// + public ObjectNotOfRequiredTypeException () { + } + + /// + /// Creates a new instance of the ObjectNotOfRequiredTypeException class. + /// + /// + /// A message about the exception. + /// + public ObjectNotOfRequiredTypeException (string message) + : base (message) { + } + + /// + /// Creates a new instance of the ObjectNotOfRequiredTypeException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectNotOfRequiredTypeException (string message, Exception rootCause) + : base (message, rootCause) { + } + + /// + /// Creates a new instance of the ObjectNotOfRequiredTypeException class. + /// + /// + /// Name of the object requested. + /// + /// + /// The required of the actual object + /// instance that was retrieved. + /// + /// + /// The instance actually returned, whose class did not match the + /// expected . + /// + public ObjectNotOfRequiredTypeException ( + string name, Type requiredType, object actualInstance) + : base ( + string.Format ( + "Object named '{0}' must be of type [{1}], but was actually of type [{2}]", + name, + requiredType.Name, + actualInstance.GetType ().Name)) { + this.name = name; + this.actualInstance = actualInstance; + this.requiredType = requiredType; + } + + /// + /// Creates a new instance of the ObjectNotOfRequiredTypeException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectNotOfRequiredTypeException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + requiredType = info.GetValue ("RequiredType", typeof (Type)) as Type; + actualInstance = info.GetValue ("ActualInstance", typeof (object)); + name = info.GetString ("Name"); + } + #endregion + + #region Properties + /// + /// The actual of the actual object + /// instance that was retrieved. + /// + public Type ActualType { + get { + return ActualInstance.GetType (); + } + } + /// + /// The required of the actual object + /// instance that was retrieved. + /// + public Type RequiredType { + get { + return requiredType; + } + } + + /// + /// The instance actually returned, whose class did not match the + /// expected . + /// + public object ActualInstance { + get { + return actualInstance; + } + } + + /// + /// The name of the object requested. + /// + public string ObjectName { + get { + return name; + } + } + #endregion + + #region Methods + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission (SecurityAction.Demand,SerializationFormatter=true)] + public override void GetObjectData ( + SerializationInfo info, StreamingContext context) { + base.GetObjectData (info, context); + info.AddValue ("RequiredType", requiredType); + info.AddValue ("ActualInstance", actualInstance); + info.AddValue ("Name", name); + } + #endregion + + #region Fields + private Type requiredType; + private object actualInstance; + private string name; + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Parsing/ReaderContext.cs b/src/Spring/Spring.Core/Objects/Factory/Parsing/ReaderContext.cs index f14ad51f..00a185ae 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Parsing/ReaderContext.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Parsing/ReaderContext.cs @@ -1,56 +1,55 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using Spring.Core.IO; - -namespace Spring.Objects.Factory.Parsing -{ - /// - /// Context that gets passed along an object definition reading process, - /// encapsulating all relevant configuraiton as well as state. - /// - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: ReaderContext.cs,v 1.3 2007/08/08 17:47:13 bbaia Exp $ - public class ReaderContext - { - private IResource resource; - - /// - /// Initializes a new instance of the class. - /// - /// The resource. - public ReaderContext(IResource resource) - { - this.resource = resource; - } - - - /// - /// Gets the resource. - /// - /// The resource. - public IResource Resource - { - get { return resource; } - } - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using Spring.Core.IO; + +namespace Spring.Objects.Factory.Parsing +{ + /// + /// Context that gets passed along an object definition reading process, + /// encapsulating all relevant configuraiton as well as state. + /// + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class ReaderContext + { + private IResource resource; + + /// + /// Initializes a new instance of the class. + /// + /// The resource. + public ReaderContext(IResource resource) + { + this.resource = resource; + } + + + /// + /// Gets the resource. + /// + /// The resource. + public IResource Resource + { + get { return resource; } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs index cfc35767..f4dfda8f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs @@ -1,2435 +1,2434 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Globalization; -using System.Reflection; - -using Common.Logging; -using Spring.Collections; -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Core.TypeResolution; -using Spring.Expressions; -using Spring.Objects; -using Spring.Objects.Factory.Config; -using Spring.Objects.Support; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Abstract superclass - /// that implements default object creation. - /// - /// - ///

- /// Provides object creation, initialization and wiring, supporting - /// autowiring and constructor resolution. Handles runtime object - /// references, managed collections, and object destruction. - ///

- ///

- /// The main template method to be implemented by subclasses is - /// , - /// used for autowiring by type. Note that this class does not implement object - /// definition registry capabilities - /// ( - /// does). - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: AbstractAutowireCapableObjectFactory.cs,v 1.90 2008/05/29 12:13:27 oakinger Exp $ - [Serializable] - public abstract class AbstractAutowireCapableObjectFactory : AbstractObjectFactory, IAutowireCapableObjectFactory - { - #region Constants - - /// - /// The used during the invocation and - /// searching for of methods. - /// - protected const BindingFlags MethodResolutionFlags = - BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreCase; - - #endregion - - /// - /// The instance for this class. - /// - private readonly ILog log = LogManager.GetLogger(typeof(AbstractAutowireCapableObjectFactory)); - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- /// Flag specifying whether to make this object factory case sensitive or not. - protected AbstractAutowireCapableObjectFactory(bool caseSensitive) - : this(caseSensitive, null) - { } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- /// Flag specifying whether to make this object factory case sensitive or not. - /// The parent object factory, or if none. - protected AbstractAutowireCapableObjectFactory(bool caseSensitive, IObjectFactory parentFactory) - : base(caseSensitive, parentFactory) - { - this.IgnoreDependencyInterface(typeof(IObjectFactoryAware)); - this.IgnoreDependencyInterface(typeof(IObjectNameAware)); - } - - #endregion - - #region Properties - - /// - /// The - /// implementation to be used to instantiate managed objects. - /// - protected IInstantiationStrategy InstantiationStrategy - { - get { return instantiationStrategy; } - set { instantiationStrategy = value; } - } - - #endregion - - #region Methods - - /// - /// Predict the eventual object type (of the processed object instance) for the - /// specified object. - /// - /// Name of the object. - /// The merged object definition to determine the type for. - /// - /// The type of the object, or null if not predictable - /// - protected override Type PredictObjectType(string objectName, RootObjectDefinition mod) - { - Type objectType; - if (StringUtils.HasText(mod.FactoryMethodName)) - { - objectType = GetTypeForFactoryMethod(objectName, mod); - } - else - { - objectType = ResolveObjectType(mod, objectName); - } - return objectType; - } - - /// - /// Determines the of the object defined - /// by the supplied object . - /// - /// - /// The name associated with the supplied object . - /// - /// - /// The - /// that the is to be determined for. - /// - /// - /// The of the object defined by the supplied - /// object ; or if the - /// cannot be determined. - /// - protected override Type GetTypeForFactoryMethod(string objectName, RootObjectDefinition definition) - { - if (StringUtils.HasText(definition.FactoryObjectName) && definition.IsSingleton && !definition.IsLazyInit) - { - return GetObject(objectName).GetType(); - } - - Type factoryType = null; - bool isStatic = true; - - if (StringUtils.HasText(definition.FactoryObjectName)) - { - // check declared factory method return type on factory type... - factoryType = GetType(definition.FactoryObjectName); - isStatic = false; - } - else - { - factoryType = ResolveObjectType(definition, objectName); - } - if (factoryType == null) - { - return null; - } - - // If all factory methods have the same return type, return that type. - // Can't clearly figure out exact method due to type converting / autowiring! - int minNrOfArgs = definition.ConstructorArgumentValues.GenericArgumentValues.Count; - MethodInfo[] candidates = factoryType.GetMethods(); - ISet returnTypes = new HybridSet(); - foreach (MethodInfo factoryMethod in candidates) - { -#if NET_2_0 - GenericArgumentsHolder genericArgsInfo = new GenericArgumentsHolder(definition.FactoryMethodName); - if (factoryMethod.IsStatic == isStatic && factoryMethod.Name.Equals(genericArgsInfo.GenericMethodName) - && ReflectionUtils.GetParameterTypes(factoryMethod).Length >= minNrOfArgs - && factoryMethod.GetGenericArguments().Length == genericArgsInfo.GetGenericArguments().Length) - { - if (genericArgsInfo.ContainsGenericArguments) - { - string[] unresolvedGenericArgs = genericArgsInfo.GetGenericArguments(); - Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; - for (int j = 0; j < unresolvedGenericArgs.Length; j++) - { - genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); - } - returnTypes.Add(factoryMethod.MakeGenericMethod(genericArgs).ReturnType); - } - else - { - returnTypes.Add(factoryMethod.ReturnType); - } - } -#else - if (factoryMethod.IsStatic == isStatic && factoryMethod.Name.Equals(definition.FactoryMethodName) - && ReflectionUtils.GetParameterTypes(factoryMethod).Length >= minNrOfArgs) - { - returnTypes.Add(factoryMethod.ReturnType); - } -#endif - } - if (returnTypes.Count == 1) - { - // clear return type found: all factory methods return same type... - return (Type)ObjectUtils.EnumerateFirstElement(returnTypes); - } - else - { - // ambiguous return types found: return null to indicate "not determinable"... - return null; - } - } - - /// - /// Apply the property values of the object definition with the supplied - /// to the supplied . - /// - /// - /// The existing object that the property values for the named object will - /// be applied to. - /// - /// - /// The name of the object definition associated with the property values that are - /// to be applied. - /// - public override void ApplyObjectPropertyValues(object instance, string name) - { - RootObjectDefinition definition = GetMergedObjectDefinition(name, true); - if (definition != null) - { - log.Debug(string.Format("configuring object '{0}' using definition '{1}'", instance, name)); - ApplyPropertyValues(name, definition, new ObjectWrapper(instance), definition.PropertyValues); - } - } - - /// - /// Apply any - /// s. - /// - /// - ///

- /// The returned instance may be a wrapper around the original. - ///

- ///
- /// - /// The of the object that is to be - /// instantiated. - /// - /// - /// The name of the object that is to be instantiated. - /// - /// - /// An instance to use in place of the original instance. - /// - /// - /// In case of errors. - /// - protected object ApplyObjectPostProcessorsBeforeInstantiation(Type objectType, string objectName) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format("Invoking IInstantiationAwareObjectPostProcessors before " + "the instantiation of '{0}'.", objectName)); - } - - #endregion - - foreach (IObjectPostProcessor processor in ObjectPostProcessors) - { - IInstantiationAwareObjectPostProcessor inProc = processor as IInstantiationAwareObjectPostProcessor; - if (inProc != null) - { - object theObject = inProc.PostProcessBeforeInstantiation(objectType, objectName); - if (theObject != null) - { - return theObject; - } - } - } - return null; - } - - /// - /// Apply the given property values, resolving any runtime references - /// to other objects in this object factory. - /// - /// - /// The object name passed for better exception information. - /// - /// - /// The definition of the named object. - /// - /// - /// The wrapping the target object. - /// - /// - /// The new property values. - /// - /// - ///

- /// Must use deep copy, so that we don't permanently modify this property. - ///

- ///
- protected void ApplyPropertyValues(string name, RootObjectDefinition definition, IObjectWrapper wrapper, IPropertyValues properties) - { - if (properties == null || properties.PropertyValues.Length == 0) - { - return; - } - MutablePropertyValues deepCopy = new MutablePropertyValues(properties); - PropertyValue[] copiedProperties = deepCopy.PropertyValues; - for (int i = 0; i < copiedProperties.Length; ++i) - { - PropertyValue copiedProperty = copiedProperties[i]; - object value = ResolveValueIfNecessary(name, definition, copiedProperty.Name, copiedProperty.Value); - PropertyValue propertyValue = new PropertyValue(copiedProperty.Name, value, copiedProperty.Expression); - // update mutable copy... - deepCopy.SetPropertyValueAt(propertyValue, i); - } - // set the (possibly resolved) deep copy properties... - try - { - wrapper.SetPropertyValues(deepCopy); - } - catch (ObjectsException ex) - { - // improve the message by showing the context... - throw new ObjectCreationException(definition.ResourceDescription, name, "Error setting property values: " + ex.Message, ex); - } - } - - /// - /// Return an array of object-type property names that are unsatisfied. - /// - /// - ///

- /// These are probably unsatisfied references to other objects in the - /// factory. Does not include simple properties like primitives or - /// s. - ///

- ///
- /// - /// An array of object-type property names that are unsatisfied. - /// - /// - /// The definition of the named object. - /// - /// - /// The wrapping the target object. - /// - protected string[] UnsatisfiedObjectProperties(RootObjectDefinition definition, IObjectWrapper wrapper) - { - ArrayList result = new ArrayList(); - ISet ignoredTypes = IgnoredDependencyTypes; - PropertyInfo[] properties = wrapper.GetPropertyInfos(); - foreach (PropertyInfo property in properties) - { - string name = property.Name; - if (property.CanWrite && !ignoredTypes.Contains(property.PropertyType) && !result.Contains(name) - && !ObjectUtils.IsSimpleProperty(property.PropertyType)) - { - result.Add(name); - } - } - return (string[])result.ToArray(typeof(string)); - } - - /// - /// Destroy all cached singletons in this factory. - /// - /// - ///

- /// To be called on shutdown of a factory. - ///

- ///
- public override void Dispose() - { - base.Dispose(); - foreach (object o in _disposableInnerObjects) - { - DestroyObject(string.Format(CultureInfo.InvariantCulture, "(Inner object of Type '{0}')", o.GetType().FullName), o); - } - _disposableInnerObjects.Clear(); - } - - /// - /// Populate the object instance in the given - /// with the property values from the - /// object definition. - /// - /// - /// The name of the object. - /// - /// - /// The definition of the named object. - /// - /// - /// The wrapping the target object. - /// - protected void PopulateObject(string name, RootObjectDefinition definition, IObjectWrapper wrapper) - { - // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the - // state of the bean before properties are set. This can be used, for example, - // to support styles of field injection. - bool continueWithPropertyPopulation = true; - - if (HasInstantiationAwareBeanPostProcessors) - { - foreach (IObjectPostProcessor processor in ObjectPostProcessors) - { - IInstantiationAwareObjectPostProcessor inProc = processor as IInstantiationAwareObjectPostProcessor; - if (inProc != null) - { - if (!inProc.PostProcessAfterInstantiation(wrapper.WrappedInstance, name)) - { - continueWithPropertyPopulation = false; - break; - } - } - } - } - if (!continueWithPropertyPopulation) - { - return; - } - - IPropertyValues properties = definition.PropertyValues; - - if (wrapper == null) - { - if (properties.PropertyValues.Length > 0) - { - throw new ObjectCreationException(definition.ResourceDescription, - name, "Cannot apply property values to null instance."); - } - else - { - // skip property population phase for null instance - return; - } - } - - if (definition.ResolvedAutowireMode == AutoWiringMode.ByName || definition.ResolvedAutowireMode == AutoWiringMode.ByType) - { - MutablePropertyValues mpvs = new MutablePropertyValues(properties); - // add property values based on autowire by name if it's applied - if (definition.ResolvedAutowireMode == AutoWiringMode.ByName) - { - AutowireByName(name, definition, wrapper, mpvs); - } - // add property values based on autowire by type if it's applied - if (definition.ResolvedAutowireMode == AutoWiringMode.ByType) - { - AutowireByType(name, definition, wrapper, mpvs); - } - properties = mpvs; - } - //DependencyCheck(name, definition, wrapper, properties); - - - bool hasInstAwareOpps = HasInstantiationAwareBeanPostProcessors; - bool needsDepCheck = (definition.DependencyCheck != DependencyCheckingMode.None); - - - if (hasInstAwareOpps || needsDepCheck) - { - PropertyInfo[] filteredPropInfo = FilterPropertyInfoForDependencyCheck(wrapper); - if (hasInstAwareOpps) - { - foreach (IObjectPostProcessor processor in ObjectPostProcessors) - { - IInstantiationAwareObjectPostProcessor instantiationAwareObjectPostProcessor = - processor as IInstantiationAwareObjectPostProcessor; - if (instantiationAwareObjectPostProcessor != null) - { - properties = - instantiationAwareObjectPostProcessor.PostProcessPropertyValues(properties, filteredPropInfo, wrapper.WrappedInstance, - name); - if (properties == null) - { - return; - } - } - } - } - - if (needsDepCheck) - { - CheckDependencies(name, definition, filteredPropInfo, properties); - } - - } - - ApplyPropertyValues(name, definition, wrapper, properties); - } - - /// - /// Wires up any exposed events in the object instance in the given - /// with any event handler - /// values from the . - /// - /// - /// The name of the object. - /// - /// - /// The definition of the named object. - /// - /// - /// The wrapping the target object. - /// - protected void WireEvents(string name, IConfigurableObjectDefinition definition, IObjectWrapper wrapper) - { - foreach (string eventName in definition.EventHandlerValues.Events) - { - foreach (IEventHandlerValue handlerValue - in definition.EventHandlerValues[eventName]) - { - object handler = null; - if (handlerValue.Source is RuntimeObjectReference) - { - RuntimeObjectReference roref = (RuntimeObjectReference)handlerValue.Source; - handler = ResolveReference(definition, name, eventName, roref); - } - else if (handlerValue.Source is Type) - { - // a static Type event is being wired up; simply pass on the Type - handler = handlerValue.Source; - } - else if (handlerValue.Source is string) - { - // a static Type event is being wired up; we need to resolve the Type - handler = TypeResolutionUtils.ResolveType(handlerValue.Source as string); - } - else - { - throw new FatalObjectException("Currently, only references to other objects and Types are " + "supported as event sources."); - } - handlerValue.Wire(handler, wrapper.WrappedInstance); - } - } - } - - /// - /// Fills in any missing property values with references to - /// other objects in this factory if autowire is set to - /// . - /// - /// - /// The object name to be autowired by . - /// - /// - /// The definition of the named object to update through autowiring. - /// - /// - /// The wrapping the target object (and - /// from which we can rip out information concerning the object). - /// - /// - /// The property values to register wired objects with. - /// - protected void AutowireByName(string name, RootObjectDefinition definition, IObjectWrapper wrapper, MutablePropertyValues properties) - { - string[] propertyNames = UnsatisfiedObjectProperties(definition, wrapper); - foreach (string propertyName in propertyNames) - { - // look for a matching type - if (ContainsObject(propertyName)) - { - object o = GetObject(propertyName); - properties.Add(propertyName, o); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, - "Added autowiring by name from object name '{0}' via " + "property '{1}' to object named '{1}'.", name, - propertyName)); - } - - #endregion - } - else - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, - "Not autowiring property '{0}' of object '{1}' by name: " + "no matching object found.", propertyName, name)); - } - - #endregion - } - } - } - - /// - /// Defines "autowire by type" (object properties by type) behavior. - /// - /// - ///

- /// This is like PicoContainer default, in which there must be exactly one object - /// of the property type in the object factory. This makes object factories simple - /// to configure for small namespaces, but doesn't work as well as standard Spring - /// behavior for bigger applications. - ///

- ///
- /// - /// The object name to be autowired by . - /// - /// - /// The definition of the named object to update through autowiring. - /// - /// - /// The wrapping the target object (and - /// from which we can rip out information concerning the object). - /// - /// - /// The property values to register wired objects with. - /// - protected void AutowireByType(string name, RootObjectDefinition definition, IObjectWrapper wrapper, MutablePropertyValues properties) - { - string[] propertyNames = UnsatisfiedObjectProperties(definition, wrapper); - foreach (string propertyName in propertyNames) - { - // look for a matching type - Type requiredType = wrapper.GetPropertyType(propertyName); - IDictionary matchingObjects = FindMatchingObjects(requiredType); - if (matchingObjects != null && matchingObjects.Count == 1) - { - properties.Add(propertyName, ObjectUtils.EnumerateFirstElement(matchingObjects.Values)); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, - "Autowiring by type from object name '{0}' via property " + "'{1}' to object named '{2}'.", name, - propertyName, ObjectUtils.EnumerateFirstElement(matchingObjects.Keys))); - } - - #endregion - } - else if (matchingObjects != null && matchingObjects.Count > 1) - { - throw new UnsatisfiedDependencyException(string.Empty, name, propertyName, - string.Format(CultureInfo.InvariantCulture, - "There are {0} objects of Type [{1}] for autowire by " - + "type, when there should have been just 1 to be able to " - + "autowire property '{2}' of object '{3}'.", matchingObjects.Count, - requiredType, propertyName, name)); - } - else - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, "Not autowiring property '{0}' of object '{1}': no matching object found.", - propertyName, name)); - } - - #endregion - } - } - } - - /// - /// Ignore the given dependency type for autowiring - /// - /// - /// This will typically be used by application contexts to register - /// dependencies that are resolved in other ways, like IOjbectFactory through - /// IObjectFactoryAware or IApplicationContext through IApplicationContextAware. - /// By default, IObjectFactoryAware and IObjectName interfaces are ignored. - /// For further types to ignore, invoke this method for each type. - /// - /// . - public void IgnoreDependencyInterface(Type type) - { - ignoredDependencyInterfaces.Add(type); - } - - /// - /// Create an object instance for the given object definition. - /// - /// The name of the object. - /// - /// The object definition for the object that is to be instantiated. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. It is invalid to use a non- arguments value - /// in any other case. - /// - /// - /// A new instance of the object. - /// - /// - /// In case of errors. - /// - /// - ///

- /// Delegates to the - /// - /// method version with the allowEagerCaching parameter set to true. - ///

- ///

- /// The object definition will already have been merged with the parent - /// definition in case of a child definition. - ///

- ///

- /// All the other methods in this class invoke this method, although objects - /// may be cached after being instantiated by this method. All object - /// instantiation within this class is performed by this method. - ///

- ///
- protected override object CreateObject(string name, RootObjectDefinition definition, object[] arguments) - { - return CreateObject(name, definition, arguments, true); - } - - /// - /// Create an object instance for the given object definition. - /// - /// The name of the object. - /// - /// The object definition for the object that is to be instantiated. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. It is invalid to use a non- arguments value - /// in any other case. - /// - /// - /// Whether eager caching of singletons is allowed... typically true for - /// singlton objects, but never true for inner object definitions. - /// - /// - /// A new instance of the object. - /// - /// - /// In case of errors. - /// - /// - ///

- /// The object definition will already have been merged with the parent - /// definition in case of a child definition. - ///

- ///

- /// All the other methods in this class invoke this method, although objects - /// may be cached after being instantiated by this method. All object - /// instantiation within this class is performed by this method. - ///

- ///
- protected virtual object CreateObject(string name, RootObjectDefinition definition, object[] arguments, bool allowEagerCaching) - { - // guarantee the initialization of objects that the current one depends on.. - if (definition.DependsOn != null && definition.DependsOn.Length > 0) - { - foreach (string dependant in definition.DependsOn) - { - GetObject(dependant); - } - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Creating instance of Object '{0}' with merged definition [{1}].", name, definition)); - } - - #endregion - - // Make sure object type is actually resolved at this point. - ResolveObjectType(definition, name); - - try - { - definition.PrepareMethodOverrides(); - } - catch (ObjectDefinitionValidationException ex) - { - throw new ObjectDefinitionStoreException(definition.ResourceDescription, name, - "Validation of method overrides failed. " + ex.Message, ex); - } - - // return IObjectDefinition instance itself for an abstract object-definition - if (definition.IsTemplate) - { - return definition; - } - - - - object instance = null; - - - IObjectWrapper instanceWrapper = null; - bool eagerlyCached = false; - try - { - // Give IInstantiationAwareObjectPostProcessors a chance to return a proxy instead of the target instance.... - if (definition.HasObjectType) - { - instance = ApplyObjectPostProcessorsBeforeInstantiation(definition.ObjectType, name); - if (instance != null) - { - return instance; - } - } - - - instanceWrapper = CreateObjectInstance(name, definition, arguments); - instance = instanceWrapper.WrappedInstance; - - // eagerly cache singletons to be able to resolve circular references - // even when triggered by lifecycle interfaces like IObjectFactoryAware. - if (allowEagerCaching && definition.IsSingleton) - { - if (log.IsDebugEnabled) - { - log.Debug("Eagerly caching object '" + name + "' to allow for resolving potential circular references"); - } - AddEagerlyCachedSingleton(name, definition, instance); - eagerlyCached = true; - } - - instance = ConfigureObject(name, definition, instanceWrapper); - } - catch (ObjectCreationException) - { - if (eagerlyCached) - { - RemoveEagerlyCachedSingleton(name, definition); - } - throw; - } - catch (Exception ex) - { - if (eagerlyCached) - { - RemoveEagerlyCachedSingleton(name, definition); - } - throw new ObjectCreationException(definition.ResourceDescription, name, "Initialization of object failed : " + ex.Message, ex); - } - return instance; - } - - /// - /// Add the created, but yet unpopulated singleton to the singleton cache - /// to be able to resolve circular references - /// - /// the name of the object to add to the cache. - /// the definition used to create and populated the object. - /// the raw object instance. - /// - /// Derived classes may override this method to select the right cache based on the object definition. - /// - protected virtual void AddEagerlyCachedSingleton(string objectName, IObjectDefinition objectDefinition, object rawSingletonInstance) - { - base.AddSingleton(objectName, rawSingletonInstance); - } - - /// - /// Remove the specified singleton from the singleton cache that has - /// been added before by a call to - /// - /// the name of the object to remove from the cache. - /// the definition used to create and populated the object. - /// - /// Derived classes may override this method to select the right cache based on the object definition. - /// - protected virtual void RemoveEagerlyCachedSingleton(string objectName, IObjectDefinition objectDefinition) - { - base.RemoveSingleton(objectName); - } - - /// - /// Creates an instance from the passed in - /// using constructor - /// - /// The name of the object to create - used for error messages. - /// The describing the object to be created. - /// optional arguments to pass to the constructor - /// An wrapping the already instantiated object - protected IObjectWrapper CreateObjectInstance(string name, RootObjectDefinition definition, object[] arguments) - { - IObjectWrapper instanceWrapper; - if (StringUtils.HasText(definition.FactoryMethodName)) - { - instanceWrapper = InstantiateUsingFactoryMethod(name, definition, arguments); - } - //Handle case when arguments are passed in explicitly. - else if (arguments != null && arguments.Length > 0) - { - instanceWrapper = AutowireConstructor(name, definition, arguments); - } - else if (definition.ResolvedAutowireMode == AutoWiringMode.Constructor || - definition.HasConstructorArgumentValues) - { - instanceWrapper = AutowireConstructor(name, definition); - } - else - { - instanceWrapper = new ObjectWrapper(InstantiationStrategy.Instantiate(definition, name, this)); - InitObjectWrapper(instanceWrapper); - } - return instanceWrapper; - } - - /// - /// Instantiate an object instance using a named factory method. - /// - /// - ///

- /// The method may be static, if the - /// parameter specifies a class, rather than a - /// instance, or an - /// instance variable on a factory object itself configured using Dependency - /// Injection. - ///

- ///

- /// Implementation requires iterating over the static or instance methods - /// with the name specified in the supplied - /// (the method may be overloaded) and trying to match with the parameters. - /// We don't have the types attached to constructor args, so trial and error - /// is the only way to go here. - ///

- ///
- /// - /// The name associated with the supplied . - /// - /// - /// The definition describing the instance that is to be instantiated. - /// - /// - /// Any arguments to the factory method that is to be invoked. - /// - /// - /// The result of the factory method invocation (the instance). - /// - protected virtual IObjectWrapper InstantiateUsingFactoryMethod(string name, RootObjectDefinition definition, object[] arguments) - { - ConstructorArgumentValues cargs = definition.ConstructorArgumentValues; - ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); - int expectedArgCount = 0; - - // we don't have arguments passed in programmatically, so we need to resolve the - // arguments specified in the constructor arguments held in the object definition... - if (arguments == null || arguments.Length == 0) - { - expectedArgCount = cargs.ArgumentCount; - ResolveConstructorArguments(name, definition, resolvedValues); - } - else - { - // if we have constructor args, don't need to resolve them... - expectedArgCount = arguments.Length; - } - ObjectWrapper wrapper = new ObjectWrapper(); - InitObjectWrapper(wrapper); - bool isStatic = true; - Type factoryClass = null; - if (StringUtils.HasText(definition.FactoryObjectName)) - { - // it's an instance method on the factory object's class... - factoryClass = GetObject(definition.FactoryObjectName).GetType(); - isStatic = false; - } - else - { - // it's a static factory method on the object class... - factoryClass = definition.ObjectType; - } - -#if NET_2_0 - GenericArgumentsHolder genericArgsInfo = new GenericArgumentsHolder(definition.FactoryMethodName); - - MethodInfo[] factoryMethods = FindMethods(genericArgsInfo.GenericMethodName, expectedArgCount, isStatic, factoryClass); - UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; - // try all matching methods to see if they match the constructor arguments... - for (int i = 0; i < factoryMethods.Length; i++) - { - unsatisfiedDependencyExceptionData = null; - MethodInfo factoryMethod = factoryMethods[i]; - - if (genericArgsInfo.ContainsGenericArguments) - { - string[] unresolvedGenericArgs = genericArgsInfo.GetGenericArguments(); - if (factoryMethod.GetGenericArguments().Length != unresolvedGenericArgs.Length) - continue; - - Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; - for (int j = 0; j < unresolvedGenericArgs.Length; j++) - { - genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); - } - factoryMethod = factoryMethod.MakeGenericMethod(genericArgs); - } -#else - MethodInfo[] factoryMethods = FindMethods(definition.FactoryMethodName, expectedArgCount, isStatic, factoryClass); - UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; - // try all matching methods to see if they match the constructor arguments... - foreach(MethodInfo factoryMethod in factoryMethods) - { -#endif - if (arguments == null || arguments.Length == 0) - { - // try to create the required arguments... - arguments = CreateArgumentArray(name, definition, resolvedValues, factoryMethod, out unsatisfiedDependencyExceptionData); - if (arguments == null) - { - // if we failed to match this method, keep - // trying new overloaded factory methods... - continue; - } - } - // if we get here, we found a factory method... - - if (ReflectionUtils.GetMethodByArgumentValues(new MethodInfo[] { factoryMethod }, arguments) == null) - { - continue; - } - - - object objectInstance = InstantiationStrategy.Instantiate(definition, name, this, factoryMethod, arguments); - wrapper.WrappedInstance = objectInstance; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Object '{0}' instantiated via factory method [{1}].", name, factoryMethod)); - } - - #endregion - - return wrapper; - } - - - - // if we get here, we didn't match any method... - throw new ObjectDefinitionStoreException( - string.Format(CultureInfo.InvariantCulture, "Cannot find matching factory method '{0} on Type [{1}].", definition.FactoryMethodName, - factoryClass)); - } - - /// - /// Returns an array of all of those - /// methods exposed on the - /// that match the supplied criteria. - /// - /// - /// Methods that have this name (can be in the form of a regular expression). - /// - /// - /// Methods that have exactly this many arguments. - /// - /// - /// Methods that are static / instance. - /// - /// - /// The on which the methods (if any) are to be found. - /// - /// - /// An array of all of those - /// methods exposed on the - /// that match the supplied criteria. - /// - private static MethodInfo[] FindMethods(string methodName, int expectedArgumentCount, bool isStatic, Type searchType) - { - ComposedCriteria methodCriteria = new ComposedCriteria(); - methodCriteria.Add(new MethodNameMatchCriteria(methodName)); - methodCriteria.Add(new MethodParametersCountCriteria(expectedArgumentCount)); - BindingFlags methodFlags = BindingFlags.Public | BindingFlags.IgnoreCase | (isStatic ? BindingFlags.Static : BindingFlags.Instance); - MemberInfo[] methods = - searchType.FindMembers(MemberTypes.Method, methodFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - methodCriteria); - return (MethodInfo[])ArrayList.Adapter(methods).ToArray(typeof(MethodInfo)); - } - - /// - /// Create an array of arguments to invoke a constructor or static factory method, - /// given the resolved constructor arguments values. - /// - /// When return value is null the out parameter UnsatisfiedDependencyExceptionData will contain - /// information for use in throwing a UnsatisfiedDependencyException by the caller. This avoids using - /// exceptions for flow control as in the original implementation. - private object[] CreateArgumentArray(string name, RootObjectDefinition definition, - ConstructorArgumentValues resolvedValues, MethodBase methodOrCtor, out UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData) - { - string methodType = (methodOrCtor is ConstructorInfo) ? "constructor" : "factory method"; - unsatisfiedDependencyExceptionData = null; - ParameterInfo[] argTypes = methodOrCtor.GetParameters(); - object[] args = new object[argTypes.Length]; - ISet alreadyUsedValues = new HybridSet(); - for (int j = 0; j < argTypes.Length; ++j) - { - Type parameterType = argTypes[j].ParameterType; - string parameterName = argTypes[j].Name; - ConstructorArgumentValues.ValueHolder valueHolder = null; - if (resolvedValues.GetNamedArgumentValue(parameterName) != null) - { - valueHolder = resolvedValues.GetArgumentValue(parameterName, parameterType, alreadyUsedValues); - } - else - { - valueHolder = resolvedValues.GetArgumentValue(j, parameterType, alreadyUsedValues); - } - if (valueHolder != null) - { - try - { - args[j] = TypeConversionUtils.ConvertValueIfNecessary(parameterType, valueHolder.Value, null); - alreadyUsedValues.Add(valueHolder); - } - catch (TypeMismatchException ex) - { - string errorMessage = String.Format(CultureInfo.InvariantCulture, - "Could not convert {0} argument value [{1}] to required type [{2}] : {3}", - methodType, valueHolder.Value, - parameterType, ex.Message); - unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage); - - - return null; - } - } - else - { - if (definition.ResolvedAutowireMode != AutoWiringMode.Constructor) - { - string errorMessage = String.Format(CultureInfo.InvariantCulture, - "Ambiguous {0} argument types - " + - "Did you specify the correct object references as {0} arguments?", - methodType); - unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage); - - return null; - } - IDictionary matchingObjects = FindMatchingObjects(parameterType); - if (matchingObjects == null || matchingObjects.Count != 1) - { - string errorMessage = String.Format(CultureInfo.InvariantCulture, - "There are '{0}' objects of type [{1}] for autowiring " - + - "{2}. There should have been exactly 1 to be able to " - + - "autowire the '{3}' argument on the {2} of object '{4}'.", - (matchingObjects == null - ? 0 - : matchingObjects.Count), - parameterType, methodType, - parameterName, name); - unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage); - - return null; - } - DictionaryEntry entry = (DictionaryEntry)ObjectUtils.EnumerateFirstElement(matchingObjects); - args[j] = entry.Value; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, - "Autowiring '{0}' argument by type from object name '{1}' via {2} to " - + "object named '{3}'.", parameterName, name, methodType, entry.Key)); - } - - #endregion - } - } - - return args; - } - - /// - /// Explicitly construct the object using the supplied constructor arguments. - /// Constructor arguments are matched by type. - /// - /// - /// The name of the object to autowire by type. - /// - /// - /// The object definition to update through autowiring. - /// - /// Array of constructor argument values. - /// - /// An for the new instance. - /// - protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition, object[] args) - { - ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); - for (int i = 0; i < args.Length; i++) - { - //This is assigning ctor arguments by type. - resolvedValues.AddGenericArgumentValue(args[i]); - } - return AutowireConstructor(name, definition, resolvedValues); - } - - /// - /// "autowire constructor" (with constructor arguments by type) behaviour. - /// - /// Passes an empty collection of constructor argument values - /// to overloaded method. - /// - /// - /// The name of the object to autowire by type. - /// - /// - /// The object definition to update through autowiring. - /// - /// - /// An for the new instance. - /// - protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition) - { - return AutowireConstructor(name, definition, new ConstructorArgumentValues()); - } - - /// - /// "autowire constructor" (with constructor arguments by type) behaviour. - /// - /// - ///

- /// Also applied if explicit constructor argument values are specified, - /// matching all remaining arguments with objects from the object factory. - ///

- ///

- /// This corresponds to constructor injection: in this mode, a Spring.NET - /// object factory is able to host components that expect constructor-based - /// dependency resolution. - ///

- ///
- /// - /// The name of the object to autowire by type. - /// - /// - /// The object definition to update through autowiring. - /// - /// - /// The collection on constructor argument values. - /// - /// - /// An for the new instance. - /// - protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition, ConstructorArgumentValues argumentValues) - { - int minNrOfArgs = ResolveConstructorArguments(name, definition, argumentValues); - ConstructorInfo[] constructors = AutowireUtils.GetConstructors(definition, minNrOfArgs); - if (constructors == null || constructors.Length == 0) - { - throw new ObjectCreationException(definition.ResourceDescription, name, - string.Format(CultureInfo.InvariantCulture, - "'{0}' constructor arguments specified but no matching constructor found " - + "in object '{1}' (hint: specify argument indexes, names, or " - + "types to avoid ambiguities).", minNrOfArgs, name)); - } - ObjectWrapper wrapper = new ObjectWrapper(); - InitObjectWrapper(wrapper); - ConstructorInfo constructorToUse = null; - object[] argsToUse = null; - int weighting = Int32.MaxValue; - UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; - for (int i = 0; i < constructors.Length; ++i) - { - unsatisfiedDependencyExceptionData = null; - ConstructorInfo constructor = constructors[i]; - if (constructorToUse != null && - constructorToUse.GetParameters().Length > constructor.GetParameters().Length) - { - // already found greedy constructor that can be satisfied, so - // don't look any further, there are only less greedy constructors left... - break; - } - - object[] args = CreateArgumentArray(name, definition, argumentValues, constructor, out unsatisfiedDependencyExceptionData); - if (args == null) - { - if (i == constructors.Length - 1 && constructorToUse == null) - { - throw new UnsatisfiedDependencyException(definition.ResourceDescription, - name, - unsatisfiedDependencyExceptionData.ParameterIndex, - unsatisfiedDependencyExceptionData.ParameterType, - unsatisfiedDependencyExceptionData.ErrorMessage); - } - // try next constructor... - continue; - } - - int typeDiffWeight = AutowireUtils.GetTypeDifferenceWeight(constructor.GetParameters(), args); - if (typeDiffWeight < weighting) - { - constructorToUse = constructor; - argsToUse = args; - weighting = typeDiffWeight; - } - } - - if (constructorToUse == null) - { - throw new ObjectCreationException(definition.ResourceDescription, name, "Could not resolve matching constructor."); - } - wrapper.WrappedInstance = InstantiationStrategy.Instantiate(definition, name, this, constructorToUse, argsToUse); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Object '{0}' instantiated via constructor [{1}].", name, constructorToUse)); - } - - #endregion - - return wrapper; - } - - /// - /// Resolves the - /// of the supplied . - /// - /// - ///

- /// 'Resolve' can be taken to mean that all of the s - /// constructor arguments is resolved into a concrete object that can be plugged - /// into one of the s constructors. Runtime object - /// references to other objects in this (or a parent) factory are resolved, - /// type conversion is performed, etc. - ///

- ///

- /// These resolved values are plugged into the supplied - /// object, because we wouldn't want to touch - /// the s constructor arguments in case it (or any of - /// its constructor arguments) is a prototype object definition. - ///

- ///

- /// This method is also used for handling invocations of static factory methods. - ///

- ///
- /// - /// The name of the object that is being resolved by this factory. - /// - /// - /// The definition associated with the above . - /// - /// - /// Where the resolved constructor arguments will be placed. - /// - /// - /// The minimum number of arguments that any constructor for the supplied - /// must have. - /// - private int ResolveConstructorArguments(string name, RootObjectDefinition definition, ConstructorArgumentValues resolvedValues) - { - int minNrOfArgs = 0; - if (definition.ConstructorArgumentValues != null) - { - minNrOfArgs = definition.ConstructorArgumentValues.ArgumentCount; - foreach (DictionaryEntry de in definition.ConstructorArgumentValues.IndexedArgumentValues) - { - int index = (int)de.Key; - if (index < 0) - { - throw new ObjectCreationException(definition.ResourceDescription, name, "Invalid constructor argument index: " + index); - } - if (index > minNrOfArgs) - { - minNrOfArgs = index + 1; - } - string argName = "constructor argument with index " + index; - ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder)de.Value; - object resolvedValue = ResolveValueIfNecessary(name, definition, argName, valueHolder.Value); - resolvedValues.AddIndexedArgumentValue(index, resolvedValue, - StringUtils.HasText(valueHolder.Type) - ? TypeResolutionUtils.ResolveType(valueHolder.Type).AssemblyQualifiedName - : null); - } - foreach (ConstructorArgumentValues.ValueHolder valueHolder in definition.ConstructorArgumentValues.GenericArgumentValues) - { - string argName = "constructor argument"; - object resolvedValue = ResolveValueIfNecessary(name, definition, argName, valueHolder.Value); - resolvedValues.AddGenericArgumentValue(resolvedValue, - StringUtils.HasText(valueHolder.Type) - ? TypeResolutionUtils.ResolveType(valueHolder.Type).AssemblyQualifiedName - : null); - } - foreach (DictionaryEntry namedArgumentEntry in definition.ConstructorArgumentValues.NamedArgumentValues) - { - string argumentName = (string)namedArgumentEntry.Key; - string syntheticArgumentName = "constructor argument with name " + argumentName; - ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder)namedArgumentEntry.Value; - object resolvedValue = ResolveValueIfNecessary(name, definition, syntheticArgumentName, valueHolder.Value); - resolvedValues.AddNamedArgumentValue(argumentName, resolvedValue); - } - } - return minNrOfArgs; - } - - /// - /// Perform a dependency check that all properties exposed have been set, if desired. - /// - /// - ///

- /// Dependency checks can be objects (collaborating objects), simple (primitives - /// and ), or all (both). - ///

- ///
- /// - /// The name of the object. - /// - /// - /// The definition of the named object. - /// - /// - /// The wrapping the target object. - /// - /// - /// The property values to be checked. - /// - /// - /// If all of the checked dependencies were not satisfied. - /// - protected void DependencyCheck(string name, IConfigurableObjectDefinition definition, IObjectWrapper wrapper, IPropertyValues properties) - { - DependencyCheckingMode dependencyCheck = definition.DependencyCheck; - if (dependencyCheck == DependencyCheckingMode.None) - { - return; - } - - PropertyInfo[] filteredPropInfo = FilterPropertyInfoForDependencyCheck(wrapper); - if (HasInstantiationAwareBeanPostProcessors) - { - foreach (IObjectPostProcessor processor in ObjectPostProcessors) - { - IInstantiationAwareObjectPostProcessor inProc = processor as IInstantiationAwareObjectPostProcessor; - if (inProc != null) - { - properties = - inProc.PostProcessPropertyValues(properties, filteredPropInfo, wrapper.WrappedInstance, name); - if (properties == null) - { - return; - } - } - } - } - - - CheckDependencies(name, definition, filteredPropInfo, properties); - } - - private static void CheckDependencies(string name, IConfigurableObjectDefinition definition, PropertyInfo[] filteredPropInfo, IPropertyValues properties) - { - DependencyCheckingMode dependencyCheck = definition.DependencyCheck; - foreach (PropertyInfo property in filteredPropInfo) - { - if (property.CanWrite && properties.GetPropertyValue(property.Name) == null) - { - bool isSimple = ObjectUtils.IsSimpleProperty(property.PropertyType); - bool unsatisfied = (dependencyCheck == DependencyCheckingMode.All) || (isSimple && dependencyCheck == DependencyCheckingMode.Simple) - || (!isSimple && dependencyCheck == DependencyCheckingMode.Objects); - if (unsatisfied) - { - throw new UnsatisfiedDependencyException(definition.ResourceDescription, name, property.Name, - "Set this property value or disable dependency checking for this object."); - } - } - } - } - - /// - /// Extract a filtered set of PropertyInfos from the given IObjectWrapper, excluding - /// ignored dependency types. - /// - /// The object wrapper the object was created with. - /// The filtered PropertyInfos - private PropertyInfo[] FilterPropertyInfoForDependencyCheck(IObjectWrapper wrapper) - { - lock (filteredPropertyDescriptorsCache) - { - PropertyInfo[] filtered = (PropertyInfo[])filteredPropertyDescriptorsCache[wrapper.WrappedType]; - if (filtered == null) - { - - ArrayList list = new ArrayList(wrapper.GetPropertyInfos()); - for (int i = list.Count - 1; i >= 0; i--) - { - PropertyInfo pi = (PropertyInfo)list[i]; - if (IsExcludedFromDependencyCheck(pi)) - { - list.RemoveAt(i); - } - } - - filtered = (PropertyInfo[])list.ToArray(typeof(PropertyInfo)); - filteredPropertyDescriptorsCache.Add(wrapper.WrappedType, filtered); - } - return filtered; - } - - } - - private bool IsExcludedFromDependencyCheck(PropertyInfo pi) - { - bool b1 = !pi.CanWrite; //AutowireUtils.IsExcludedFromDependencyCheck(pi); - bool b2 = IgnoredDependencyTypes.Contains(pi.PropertyType); - bool b3 = AutowireUtils.IsSetterDefinedInInterface(pi, ignoredDependencyInterfaces); - return b1 || b2 || b3; - /* - return AutowireUtils.IsExcludedFromDependencyCheck(pi) || - IgnoredDependencyTypes.Contains(pi.PropertyType) || - AutowireUtils.IsSetterDefinedInInterface(pi, ignoredDependencyInterfaces); - */ - } - - /// - /// Give an object a chance to react now all its properties are set, - /// and a chance to know about its owning object factory (this object). - /// - /// - ///

- /// This means checking whether the object implements - /// and / or - /// , and invoking the - /// necessary callback(s) if it does. - ///

- ///

- /// Custom init methods are resolved in a case-insensitive manner. - ///

- ///
- /// - /// The new object instance we may need to initialise. - /// - /// - /// The name the object has in the factory. Used for logging output. - /// - /// - /// The definition of the target object instance. - /// - protected virtual void InvokeInitMethods(object target, string name, IConfigurableObjectDefinition definition) - { - if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IInitializingObject), target)) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Calling AfterPropertiesSet() on object with name '{0}'.", name)); - } - - #endregion - - ((IInitializingObject)target).AfterPropertiesSet(); - } - if (StringUtils.HasText(definition.InitMethodName)) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, "Calling custom init method '{0} on object with name '{1}'.", - definition.InitMethodName, name)); - } - - #endregion - - try - { - MethodInfo targetMethod = target.GetType().GetMethod(definition.InitMethodName, MethodResolutionFlags, null, Type.EmptyTypes, null); - if (targetMethod == null) - { - throw new ObjectCreationException(definition.ResourceDescription, name, - "Could not find the named initialization method '" + definition.InitMethodName + "'."); - } - targetMethod.Invoke(target, ObjectUtils.EmptyObjects); - } - catch (TargetInvocationException ex) - { - throw new ObjectCreationException(definition.ResourceDescription, name, - "Initialization method '" + definition.InitMethodName + "' threw exception", ex.GetBaseException()); - } - catch (Exception ex) - { - throw new ObjectCreationException(definition.ResourceDescription, name, - "Invocation of initialization method '" + definition.InitMethodName + "' failed", ex); - } - } - } - - /// - /// Invoke the specified custom destroy method on the given object. - /// - /// - ///

- /// This implementation invokes a no-arg method if found, else checking - /// for a method with a single boolean argument (passing in "true", - /// assuming a "force" parameter), else logging an error. - ///

- ///

- /// Can be overridden in subclasses for custom resolution of destroy - /// methods with arguments. - ///

- ///

- /// Custom destroy methods are resolved in a case-insensitive manner. - ///

- ///
- protected virtual void InvokeCustomDestroyMethod(string name, object target, string destroyMethodName) - { - bool usingForcingVersion = false; - MethodInfo targetMethod = target.GetType().GetMethod(destroyMethodName, MethodResolutionFlags, null, Type.EmptyTypes, null); - if (targetMethod == null) - { - // #%&^! try to find the method with a boolean "force" parameter - targetMethod = target.GetType().GetMethod(destroyMethodName, MethodResolutionFlags, null, new Type[] { typeof(bool) }, null); - if (targetMethod != null) - { - usingForcingVersion = true; - } - } - if (targetMethod == null) - { - #region Instrumentation - - log.Error("Couldn't find a method named '" + destroyMethodName + "' on object with name '" + name + "'"); - - #endregion - } - else - { - object[] args = usingForcingVersion ? new object[] { true } : ObjectUtils.EmptyObjects; - try - { - targetMethod.Invoke(target, args); - } - catch (TargetInvocationException ex) - { - #region Instrumentation - - log.Error("Couldn't invoke destroy method '" + destroyMethodName + "' of object with name '" + name + "'", ex.GetBaseException()); - - #endregion - } - catch (Exception ex) - { - LogExceptionRaisedByCustomDestroyMethodInvocation(destroyMethodName, name, ex); - } - } - } - - private void LogExceptionRaisedByCustomDestroyMethodInvocation(string destroyMethodName, string name, Exception ex) - { - log.Error( - string.Format(CultureInfo.InvariantCulture, "Couldn't invoke destroy method '{0}' of object with name '{1}'.", destroyMethodName, name), - ex); - } - - /// - /// Destroy the target object. - /// - /// - ///

- /// Must destroy objects that depend on the given object before the object itself. - /// Should not throw any exceptions. - ///

- ///
- /// - /// The name of the object. - /// - /// - /// The target object instance to destroyed. - /// - protected override void DestroyObject(string name, object target) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Destroying dependant objects for object '" + name + "'"); - } - - #endregion - - DestroyDependantObjects(name); - if (target is IDisposable) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Calling Dispose () on object with name '{0}'.", name)); - } - - #endregion - - try - { - ((IDisposable)target).Dispose(); - } - catch (Exception ex) - { - #region Instrumentation - - log.Error("Destroy() on object with name '" + name + "' threw an exception.", ex); - - #endregion - } - } - RootObjectDefinition rootDefinition = GetMergedObjectDefinition(name, false); - if (rootDefinition != null && StringUtils.HasText(rootDefinition.DestroyMethodName)) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Calling custom destroy method '" + rootDefinition.DestroyMethodName + "' on object with name '" + name + "'."); - } - - #endregion - - InvokeCustomDestroyMethod(name, target, rootDefinition.DestroyMethodName); - } - } - - /// - /// Destroys all of the objects registered as dependant on the - /// object (definition) identified by the supplied . - /// - /// - /// The name of the root object (definition) that is itself being destroyed. - /// - private void DestroyDependantObjects(string name) - { - string[] dependingObjects = GetDependingObjectNames(name); - foreach (string doName in dependingObjects) - { - DestroySingleton(doName); - } - } - - /// - /// Given a property value, return a value, resolving any references to other - /// objects in the factory if necessary. - /// - /// - ///

- /// The value could be : - /// - /// - ///

- /// An , - /// which leads to the creation of a corresponding new object instance. - /// Singleton flags and names of such "inner objects" are always ignored: inner objects - /// are anonymous prototypes. - ///

- /// - /// - ///

- /// A , which must - /// be resolved. - ///

- ///
- /// - ///

- /// An . This is a - /// special placeholder collection that may contain - /// s or - /// collections that will need to be resolved. - ///

- ///
- /// - ///

- /// An ordinary object or , in which case it's left alone. - ///

- ///
- /// - ///

- ///
- /// - /// The name of the object that is having the value of one of its properties resolved. - /// - /// - /// The definition of the named object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The value of the property that is being resolved. - /// - protected object ResolveValueIfNecessary(string name, RootObjectDefinition definition, string argumentName, object argumentValue) - { - object resolvedValue = null; - // we must check the argument value to see whether it requires a runtime - // reference to another object to be resolved. - // if it does, we'll attempt to instantiate the object and set the reference. - if (argumentValue is ObjectDefinitionHolder) - { - // contains an IObjectDefinition with name and aliases... - ObjectDefinitionHolder holder = (ObjectDefinitionHolder)argumentValue; - resolvedValue = ResolveInnerObjectDefinition(name, holder.ObjectName, argumentName, holder.ObjectDefinition, definition.IsSingleton); - } - else if (argumentValue is IObjectDefinition) - { - // resolve plain IObjectDefinition, without contained name: use dummy name... - IObjectDefinition def = (IObjectDefinition)argumentValue; - resolvedValue = ResolveInnerObjectDefinition(name, "(inner object)", argumentName, def, definition.IsSingleton); - - } - else if (argumentValue is RuntimeObjectReference) - { - RuntimeObjectReference roref = (RuntimeObjectReference)argumentValue; - resolvedValue = ResolveReference(definition, name, argumentName, roref); - } - else if (argumentValue is ExpressionHolder) - { - ExpressionHolder expHolder = (ExpressionHolder)argumentValue; - object context = null; - IDictionary variables = null; - - if (expHolder.Properties != null) - { - PropertyValue contextProperty = expHolder.Properties.GetPropertyValue("Context"); - context = contextProperty == null - ? null - : ResolveValueIfNecessary(name, definition, "Context", - contextProperty.Value); - PropertyValue variablesProperty = expHolder.Properties.GetPropertyValue("Variables"); - object vars = (variablesProperty == null - ? null - : ResolveValueIfNecessary(name, definition, "Variables", - variablesProperty.Value)); - if (vars is IDictionary) - { - variables = (IDictionary)vars; - } - else - { - if (vars != null) throw new ArgumentException("'Variables' must resolve to an IDictionary"); - } - } - - if (variables == null) variables = CollectionsUtil.CreateCaseInsensitiveHashtable(); - // add 'this' objectfactory reference to variables - variables.Add(Expression.ReservedVariableNames.CurrentObjectFactory, this); - - resolvedValue = expHolder.Expression.GetValue(context, variables); - } - else if (argumentValue is IManagedCollection) - { - resolvedValue = - ((IManagedCollection)argumentValue).Resolve(name, definition, argumentName, - new ManagedCollectionElementResolver(ResolveValueIfNecessary)); - } - else if (argumentValue is TypedStringValue) - { - TypedStringValue tsv = (TypedStringValue)argumentValue; - try - { - Type resolvedTargetType = ResolveTargetType(tsv); - if (resolvedTargetType != null) - { - resolvedValue = TypeConversionUtils.ConvertValueIfNecessary(tsv.TargetType, tsv.Value, null); - } - else - { - resolvedValue = tsv.Value; - } - } - catch (Exception ex) - { - throw new ObjectCreationException(definition.ResourceDescription, name, - "Error converted typed String value for " + argumentName, ex); - } - - } - else - { - // no need to resolve value... - resolvedValue = argumentValue; - } - return resolvedValue; - } - - /// - /// Resolve the target type of the passed . - /// - /// The who's target type is to be resolved - /// The resolved target type, if any. otherwise. - protected virtual Type ResolveTargetType(TypedStringValue value) - { - if (value.HasTargetType) - { - return value.TargetType; - } - else - { - return null; - } - } - /// - /// Resolves an inner object definition. - /// - /// - /// The name of the object that surrounds this inner object definition. - /// - /// - /// The name of the inner object definition... note: this is a synthetic - /// name assigned by the factory (since it makes no sense for inner object - /// definitions to have names). - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The definition of the inner object that is to be resolved. - /// - /// - /// if the owner of the property is a singleton. - /// - /// - /// The resolved object as defined by the inner object definition. - /// - protected object ResolveInnerObjectDefinition(string name, string innerObjectName, string argumentName, IObjectDefinition definition, - bool singletonOwner) - { - RootObjectDefinition mod = GetMergedObjectDefinition(innerObjectName, definition); - mod.IsSingleton = singletonOwner; - object instance; - object result; - try - { - instance = CreateObject(innerObjectName, mod, ObjectUtils.EmptyObjects, false); - result = GetObjectForInstance(innerObjectName, instance); - } - catch (ObjectsException ex) - { - throw ObjectCreationException.GetObjectCreationException(ex, name, argumentName, definition.ResourceDescription, innerObjectName); - } - if (singletonOwner && instance is IDisposable) - { - // keep a reference to the inner object instance, to be able to destroy - // it on factory shutdown... - _disposableInnerObjects.Add(instance); - } - return result; - } - - /// - /// Resolve a reference to another object in the factory. - /// - /// - /// The name of the object that is having the value of one of its properties resolved. - /// - /// - /// The definition of the named object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The runtime reference containing the value of the property. - /// - /// A reference to another object in the factory. - protected object ResolveReference(IConfigurableObjectDefinition definition, string name, string argumentName, RuntimeObjectReference reference) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, "Resolving reference from property '{0}' in object '{1}' to object '{2}'.", - argumentName, name, reference.ObjectName)); - } - - #endregion - - try - { - if (reference.IsToParent) - { - if (null == ParentObjectFactory) - { - throw new ObjectCreationException(definition.ResourceDescription, name, - string.Format( - "Can't resolve reference to '{0}' in parent factory: " + "no parent factory available.", - reference.ObjectName)); - } - return ParentObjectFactory.GetObject(reference.ObjectName); - } - return GetObject(reference.ObjectName); - } - catch (ObjectsException ex) - { - throw ObjectCreationException.GetObjectCreationException(ex, name, argumentName, definition.ResourceDescription, reference.ObjectName); - } - } - - /// - /// Find object instances that match the required . - /// - /// - ///

- /// Called by autowiring. If a subclass cannot obtain information about object - /// names by , a corresponding exception should be thrown. - ///

- ///
- /// - /// The of the objects to look up. - /// - /// - /// An of object names and object - /// instances that match the required , or - /// if none are found. - /// - /// - /// In case of errors. - /// - protected abstract IDictionary FindMatchingObjects(Type requiredType); - - /// - /// Return the names of the objects that depend on the given object. - /// Called by DestroyObject, to be able to destroy depending objects first. - /// - /// - /// The name of the object to find depending objects for. - /// - /// - /// The array of names of depending objects, or the empty string array if none. - /// - /// - /// In case of errors. - /// - protected abstract string[] GetDependingObjectNames(string name); - - /// - /// Injects dependencies into the supplied instance - /// using the named object definition. - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - public override object ConfigureObject(object target, string name) - { - RootObjectDefinition definition = GetMergedObjectDefinition(name, true); - if (definition != null) - { - return ConfigureObject(name, definition, new ObjectWrapper(target)); - } - - return null; - } - - /// - /// Injects dependencies into the supplied instance - /// using the supplied . - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// An object definition that should be used to configure object. - /// - /// - public override object ConfigureObject(object target, string name, IObjectDefinition definition) - { - return ConfigureObject(name, new RootObjectDefinition(definition), new ObjectWrapper(target)); - } - - /// - /// Configures object instance by injecting dependencies, satisfying Spring lifecycle - /// interfaces and applying object post-processors. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// An object definition that should be used to configure object. - /// - /// - /// A wrapped object instance that is to be so configured. - /// - /// - protected virtual object ConfigureObject(string name, RootObjectDefinition definition, IObjectWrapper wrapper) - { - object instance = wrapper.WrappedInstance; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format("configuring object '{0}' using definition '{1}'", instance, name)); - } - - #endregion - - PopulateObject(name, definition, wrapper); - WireEvents(name, definition, wrapper); - - if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IObjectNameAware), instance)) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Setting the name property on the IObjectNameAware object '{0}'.", name)); - } - - #endregion - - ((IObjectNameAware)instance).ObjectName = name; - } - - if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IObjectFactoryAware), instance)) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format(CultureInfo.InvariantCulture, "Setting the ObjectFactory property on the IObjectFactoryAware object '{0}'.", - name)); - } - - #endregion - - ((IObjectFactoryAware)instance).ObjectFactory = this; - } - - instance = ApplyObjectPostProcessorsBeforeInitialization(instance, name); - InvokeInitMethods(instance, name, definition); - instance = ApplyObjectPostProcessorsAfterInitialization(instance, name); - - return instance; - } - - - /// - /// Applies the PostProcessAfterInitialization callback of all - /// registered IObjectPostProcessors, giving them a chance to post-process - /// the object obtained from IFactoryObjects (for example, to auto-proxy them) - /// - /// The instance obtained from the IFactoryObject. - /// Name of the object. - /// The object instance to expose - /// if any post-processing failed. - protected override object PostProcessObjectFromFactoryObject(object instance, string objectName) - { - return ApplyObjectPostProcessorsAfterInitialization(instance, objectName); - } - - #endregion - - #region IAutowireCapableObjectFactory Members - - /// - /// Create a new object instance of the given class with the specified - /// autowire strategy. - /// - /// - /// The of the object to instantiate. - /// - /// - /// The desired autowiring mode. - /// - /// - /// Whether to perform a dependency check for objects (not applicable to - /// autowiring a constructor, thus ignored there). - /// - /// The new object instance. - /// - /// If the wiring fails. - /// - /// - public virtual object Autowire(Type type, AutoWiringMode autowireMode, bool dependencyCheck) - { - RootObjectDefinition rod = new RootObjectDefinition(type, autowireMode, dependencyCheck); - if (rod.ResolvedAutowireMode == AutoWiringMode.Constructor) - { - return AutowireConstructor(type.Name, rod).WrappedInstance; - } - else - { - object obj = InstantiationStrategy.Instantiate(rod, string.Empty, this); - PopulateObject(obj.GetType().Name, rod, new ObjectWrapper(obj)); - return obj; - } - } - - /// - /// Autowire the object properties of the given object instance by name or - /// . - /// - /// - /// The existing object instance. - /// - /// - /// The desired autowiring mode. - /// - /// - /// Whether to perform a dependency check for the object. - /// - /// - /// If the wiring fails. - /// - /// - /// If the supplied is not one of the - /// or - /// - /// values. - /// - /// - public virtual void AutowireObjectProperties(object instance, AutoWiringMode autowireMode, bool dependencyCheck) - { - if (autowireMode != AutoWiringMode.ByName && autowireMode != AutoWiringMode.ByType) - { - throw new ArgumentException("Just AutoWiringMode.ByName and AutoWiringMode.ByType allowed."); - } - RootObjectDefinition rod = new RootObjectDefinition(instance.GetType(), autowireMode, dependencyCheck); - PopulateObject(instance.GetType().Name, rod, new ObjectWrapper(instance)); - } - - /// - /// Apply s - /// to the given existing object instance, invoking their - /// - /// methods. - /// - /// - /// The existing object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// If any post-processing failed. - /// - /// - public virtual object ApplyObjectPostProcessorsBeforeInitialization(object instance, string name) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Invoking IObjectPostProcessors before initialization of object '" + name + "'"); - } - - #endregion - - object result = instance; - foreach (IObjectPostProcessor objectProcessor in ObjectPostProcessors) - { - result = objectProcessor.PostProcessBeforeInitialization(result, name); - if (result == null) - { - throw new ObjectCreationException(name, - string.Format(CultureInfo.InvariantCulture, - "PostProcessBeforeInitialization method of IObjectPostProcessor [{0}] " - + " returned null for object [{1}] with name '{2}'.", objectProcessor, instance, name)); - } - } - return result; - } - - /// - /// Apply s - /// to the given existing object instance, invoking their - /// - /// methods. - /// - /// - /// The existing object instance. - /// - /// - /// The name of the object. - /// - /// - /// The object instance to use, either the original or a wrapped one. - /// - /// - /// If any post-processing failed. - /// - /// - public virtual object ApplyObjectPostProcessorsAfterInitialization(object instance, string name) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Invoking IObjectPostProcessors after initialization of object '" + name + "'"); - } - - #endregion - - object result = instance; - foreach (IObjectPostProcessor objectProcessor in ObjectPostProcessors) - { - result = objectProcessor.PostProcessAfterInitialization(result, name); - if (result == null) - { - throw new ObjectCreationException(name, - string.Format(CultureInfo.InvariantCulture, - "PostProcessAfterInitialization method of IObjectPostProcessor [{0}] " - + " returned null for object [{1}] with name [{2}].", objectProcessor, instance, name)); - } - } - return result; - } - - #endregion - - #region Fields - - /// - /// Set that holds all inner objects created by this factory that implement the IDisposable - /// interface, to be destroyed on call to Dispose. - /// - private ISet _disposableInnerObjects = new SynchronizedSet(new HybridSet()); - - private IInstantiationStrategy instantiationStrategy = new MethodInjectingInstantiationStrategy(); - - /// - /// Cache of unfinished IFactoryObject instances: IFactoryObject name --> IObjectWrapper */ - /// - private IDictionary factoryObjectInstanceCache = new Hashtable(); - - /// - /// Cache of filtered PropertyInfos: object Type -> PropertyInfo array - /// - private IDictionary filteredPropertyDescriptorsCache = new Hashtable(); - - /// - /// Dependency interfaces to ignore on dependency check and autowire, as Set of - /// Class objects. By default, only the IObjectFactoryAware and IObjectNameAware - /// interfaces are ignored. - /// - private ISet ignoredDependencyInterfaces = new HybridSet(); - - #endregion - } - - internal class UnsatisfiedDependencyExceptionData - { - private int parameterIndex; - private Type parameterType; - private string errorMessage; - - public UnsatisfiedDependencyExceptionData(int parameterIndex, Type parameterType, string errorMessage) - { - this.parameterIndex = parameterIndex; - this.parameterType = parameterType; - this.errorMessage = errorMessage; - } - - public int ParameterIndex - { - get { return parameterIndex; } - } - - public Type ParameterType - { - get { return parameterType; } - } - - public string ErrorMessage - { - get { return errorMessage; } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Globalization; +using System.Reflection; + +using Common.Logging; +using Spring.Collections; +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Core.TypeResolution; +using Spring.Expressions; +using Spring.Objects; +using Spring.Objects.Factory.Config; +using Spring.Objects.Support; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Abstract superclass + /// that implements default object creation. + /// + /// + ///

+ /// Provides object creation, initialization and wiring, supporting + /// autowiring and constructor resolution. Handles runtime object + /// references, managed collections, and object destruction. + ///

+ ///

+ /// The main template method to be implemented by subclasses is + /// , + /// used for autowiring by type. Note that this class does not implement object + /// definition registry capabilities + /// ( + /// does). + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public abstract class AbstractAutowireCapableObjectFactory : AbstractObjectFactory, IAutowireCapableObjectFactory + { + #region Constants + + /// + /// The used during the invocation and + /// searching for of methods. + /// + protected const BindingFlags MethodResolutionFlags = + BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreCase; + + #endregion + + /// + /// The instance for this class. + /// + private readonly ILog log = LogManager.GetLogger(typeof(AbstractAutowireCapableObjectFactory)); + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ /// Flag specifying whether to make this object factory case sensitive or not. + protected AbstractAutowireCapableObjectFactory(bool caseSensitive) + : this(caseSensitive, null) + { } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ /// Flag specifying whether to make this object factory case sensitive or not. + /// The parent object factory, or if none. + protected AbstractAutowireCapableObjectFactory(bool caseSensitive, IObjectFactory parentFactory) + : base(caseSensitive, parentFactory) + { + this.IgnoreDependencyInterface(typeof(IObjectFactoryAware)); + this.IgnoreDependencyInterface(typeof(IObjectNameAware)); + } + + #endregion + + #region Properties + + /// + /// The + /// implementation to be used to instantiate managed objects. + /// + protected IInstantiationStrategy InstantiationStrategy + { + get { return instantiationStrategy; } + set { instantiationStrategy = value; } + } + + #endregion + + #region Methods + + /// + /// Predict the eventual object type (of the processed object instance) for the + /// specified object. + /// + /// Name of the object. + /// The merged object definition to determine the type for. + /// + /// The type of the object, or null if not predictable + /// + protected override Type PredictObjectType(string objectName, RootObjectDefinition mod) + { + Type objectType; + if (StringUtils.HasText(mod.FactoryMethodName)) + { + objectType = GetTypeForFactoryMethod(objectName, mod); + } + else + { + objectType = ResolveObjectType(mod, objectName); + } + return objectType; + } + + /// + /// Determines the of the object defined + /// by the supplied object . + /// + /// + /// The name associated with the supplied object . + /// + /// + /// The + /// that the is to be determined for. + /// + /// + /// The of the object defined by the supplied + /// object ; or if the + /// cannot be determined. + /// + protected override Type GetTypeForFactoryMethod(string objectName, RootObjectDefinition definition) + { + if (StringUtils.HasText(definition.FactoryObjectName) && definition.IsSingleton && !definition.IsLazyInit) + { + return GetObject(objectName).GetType(); + } + + Type factoryType = null; + bool isStatic = true; + + if (StringUtils.HasText(definition.FactoryObjectName)) + { + // check declared factory method return type on factory type... + factoryType = GetType(definition.FactoryObjectName); + isStatic = false; + } + else + { + factoryType = ResolveObjectType(definition, objectName); + } + if (factoryType == null) + { + return null; + } + + // If all factory methods have the same return type, return that type. + // Can't clearly figure out exact method due to type converting / autowiring! + int minNrOfArgs = definition.ConstructorArgumentValues.GenericArgumentValues.Count; + MethodInfo[] candidates = factoryType.GetMethods(); + ISet returnTypes = new HybridSet(); + foreach (MethodInfo factoryMethod in candidates) + { +#if NET_2_0 + GenericArgumentsHolder genericArgsInfo = new GenericArgumentsHolder(definition.FactoryMethodName); + if (factoryMethod.IsStatic == isStatic && factoryMethod.Name.Equals(genericArgsInfo.GenericMethodName) + && ReflectionUtils.GetParameterTypes(factoryMethod).Length >= minNrOfArgs + && factoryMethod.GetGenericArguments().Length == genericArgsInfo.GetGenericArguments().Length) + { + if (genericArgsInfo.ContainsGenericArguments) + { + string[] unresolvedGenericArgs = genericArgsInfo.GetGenericArguments(); + Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; + for (int j = 0; j < unresolvedGenericArgs.Length; j++) + { + genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); + } + returnTypes.Add(factoryMethod.MakeGenericMethod(genericArgs).ReturnType); + } + else + { + returnTypes.Add(factoryMethod.ReturnType); + } + } +#else + if (factoryMethod.IsStatic == isStatic && factoryMethod.Name.Equals(definition.FactoryMethodName) + && ReflectionUtils.GetParameterTypes(factoryMethod).Length >= minNrOfArgs) + { + returnTypes.Add(factoryMethod.ReturnType); + } +#endif + } + if (returnTypes.Count == 1) + { + // clear return type found: all factory methods return same type... + return (Type)ObjectUtils.EnumerateFirstElement(returnTypes); + } + else + { + // ambiguous return types found: return null to indicate "not determinable"... + return null; + } + } + + /// + /// Apply the property values of the object definition with the supplied + /// to the supplied . + /// + /// + /// The existing object that the property values for the named object will + /// be applied to. + /// + /// + /// The name of the object definition associated with the property values that are + /// to be applied. + /// + public override void ApplyObjectPropertyValues(object instance, string name) + { + RootObjectDefinition definition = GetMergedObjectDefinition(name, true); + if (definition != null) + { + log.Debug(string.Format("configuring object '{0}' using definition '{1}'", instance, name)); + ApplyPropertyValues(name, definition, new ObjectWrapper(instance), definition.PropertyValues); + } + } + + /// + /// Apply any + /// s. + /// + /// + ///

+ /// The returned instance may be a wrapper around the original. + ///

+ ///
+ /// + /// The of the object that is to be + /// instantiated. + /// + /// + /// The name of the object that is to be instantiated. + /// + /// + /// An instance to use in place of the original instance. + /// + /// + /// In case of errors. + /// + protected object ApplyObjectPostProcessorsBeforeInstantiation(Type objectType, string objectName) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format("Invoking IInstantiationAwareObjectPostProcessors before " + "the instantiation of '{0}'.", objectName)); + } + + #endregion + + foreach (IObjectPostProcessor processor in ObjectPostProcessors) + { + IInstantiationAwareObjectPostProcessor inProc = processor as IInstantiationAwareObjectPostProcessor; + if (inProc != null) + { + object theObject = inProc.PostProcessBeforeInstantiation(objectType, objectName); + if (theObject != null) + { + return theObject; + } + } + } + return null; + } + + /// + /// Apply the given property values, resolving any runtime references + /// to other objects in this object factory. + /// + /// + /// The object name passed for better exception information. + /// + /// + /// The definition of the named object. + /// + /// + /// The wrapping the target object. + /// + /// + /// The new property values. + /// + /// + ///

+ /// Must use deep copy, so that we don't permanently modify this property. + ///

+ ///
+ protected void ApplyPropertyValues(string name, RootObjectDefinition definition, IObjectWrapper wrapper, IPropertyValues properties) + { + if (properties == null || properties.PropertyValues.Length == 0) + { + return; + } + MutablePropertyValues deepCopy = new MutablePropertyValues(properties); + PropertyValue[] copiedProperties = deepCopy.PropertyValues; + for (int i = 0; i < copiedProperties.Length; ++i) + { + PropertyValue copiedProperty = copiedProperties[i]; + object value = ResolveValueIfNecessary(name, definition, copiedProperty.Name, copiedProperty.Value); + PropertyValue propertyValue = new PropertyValue(copiedProperty.Name, value, copiedProperty.Expression); + // update mutable copy... + deepCopy.SetPropertyValueAt(propertyValue, i); + } + // set the (possibly resolved) deep copy properties... + try + { + wrapper.SetPropertyValues(deepCopy); + } + catch (ObjectsException ex) + { + // improve the message by showing the context... + throw new ObjectCreationException(definition.ResourceDescription, name, "Error setting property values: " + ex.Message, ex); + } + } + + /// + /// Return an array of object-type property names that are unsatisfied. + /// + /// + ///

+ /// These are probably unsatisfied references to other objects in the + /// factory. Does not include simple properties like primitives or + /// s. + ///

+ ///
+ /// + /// An array of object-type property names that are unsatisfied. + /// + /// + /// The definition of the named object. + /// + /// + /// The wrapping the target object. + /// + protected string[] UnsatisfiedObjectProperties(RootObjectDefinition definition, IObjectWrapper wrapper) + { + ArrayList result = new ArrayList(); + ISet ignoredTypes = IgnoredDependencyTypes; + PropertyInfo[] properties = wrapper.GetPropertyInfos(); + foreach (PropertyInfo property in properties) + { + string name = property.Name; + if (property.CanWrite && !ignoredTypes.Contains(property.PropertyType) && !result.Contains(name) + && !ObjectUtils.IsSimpleProperty(property.PropertyType)) + { + result.Add(name); + } + } + return (string[])result.ToArray(typeof(string)); + } + + /// + /// Destroy all cached singletons in this factory. + /// + /// + ///

+ /// To be called on shutdown of a factory. + ///

+ ///
+ public override void Dispose() + { + base.Dispose(); + foreach (object o in _disposableInnerObjects) + { + DestroyObject(string.Format(CultureInfo.InvariantCulture, "(Inner object of Type '{0}')", o.GetType().FullName), o); + } + _disposableInnerObjects.Clear(); + } + + /// + /// Populate the object instance in the given + /// with the property values from the + /// object definition. + /// + /// + /// The name of the object. + /// + /// + /// The definition of the named object. + /// + /// + /// The wrapping the target object. + /// + protected void PopulateObject(string name, RootObjectDefinition definition, IObjectWrapper wrapper) + { + // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the + // state of the bean before properties are set. This can be used, for example, + // to support styles of field injection. + bool continueWithPropertyPopulation = true; + + if (HasInstantiationAwareBeanPostProcessors) + { + foreach (IObjectPostProcessor processor in ObjectPostProcessors) + { + IInstantiationAwareObjectPostProcessor inProc = processor as IInstantiationAwareObjectPostProcessor; + if (inProc != null) + { + if (!inProc.PostProcessAfterInstantiation(wrapper.WrappedInstance, name)) + { + continueWithPropertyPopulation = false; + break; + } + } + } + } + if (!continueWithPropertyPopulation) + { + return; + } + + IPropertyValues properties = definition.PropertyValues; + + if (wrapper == null) + { + if (properties.PropertyValues.Length > 0) + { + throw new ObjectCreationException(definition.ResourceDescription, + name, "Cannot apply property values to null instance."); + } + else + { + // skip property population phase for null instance + return; + } + } + + if (definition.ResolvedAutowireMode == AutoWiringMode.ByName || definition.ResolvedAutowireMode == AutoWiringMode.ByType) + { + MutablePropertyValues mpvs = new MutablePropertyValues(properties); + // add property values based on autowire by name if it's applied + if (definition.ResolvedAutowireMode == AutoWiringMode.ByName) + { + AutowireByName(name, definition, wrapper, mpvs); + } + // add property values based on autowire by type if it's applied + if (definition.ResolvedAutowireMode == AutoWiringMode.ByType) + { + AutowireByType(name, definition, wrapper, mpvs); + } + properties = mpvs; + } + //DependencyCheck(name, definition, wrapper, properties); + + + bool hasInstAwareOpps = HasInstantiationAwareBeanPostProcessors; + bool needsDepCheck = (definition.DependencyCheck != DependencyCheckingMode.None); + + + if (hasInstAwareOpps || needsDepCheck) + { + PropertyInfo[] filteredPropInfo = FilterPropertyInfoForDependencyCheck(wrapper); + if (hasInstAwareOpps) + { + foreach (IObjectPostProcessor processor in ObjectPostProcessors) + { + IInstantiationAwareObjectPostProcessor instantiationAwareObjectPostProcessor = + processor as IInstantiationAwareObjectPostProcessor; + if (instantiationAwareObjectPostProcessor != null) + { + properties = + instantiationAwareObjectPostProcessor.PostProcessPropertyValues(properties, filteredPropInfo, wrapper.WrappedInstance, + name); + if (properties == null) + { + return; + } + } + } + } + + if (needsDepCheck) + { + CheckDependencies(name, definition, filteredPropInfo, properties); + } + + } + + ApplyPropertyValues(name, definition, wrapper, properties); + } + + /// + /// Wires up any exposed events in the object instance in the given + /// with any event handler + /// values from the . + /// + /// + /// The name of the object. + /// + /// + /// The definition of the named object. + /// + /// + /// The wrapping the target object. + /// + protected void WireEvents(string name, IConfigurableObjectDefinition definition, IObjectWrapper wrapper) + { + foreach (string eventName in definition.EventHandlerValues.Events) + { + foreach (IEventHandlerValue handlerValue + in definition.EventHandlerValues[eventName]) + { + object handler = null; + if (handlerValue.Source is RuntimeObjectReference) + { + RuntimeObjectReference roref = (RuntimeObjectReference)handlerValue.Source; + handler = ResolveReference(definition, name, eventName, roref); + } + else if (handlerValue.Source is Type) + { + // a static Type event is being wired up; simply pass on the Type + handler = handlerValue.Source; + } + else if (handlerValue.Source is string) + { + // a static Type event is being wired up; we need to resolve the Type + handler = TypeResolutionUtils.ResolveType(handlerValue.Source as string); + } + else + { + throw new FatalObjectException("Currently, only references to other objects and Types are " + "supported as event sources."); + } + handlerValue.Wire(handler, wrapper.WrappedInstance); + } + } + } + + /// + /// Fills in any missing property values with references to + /// other objects in this factory if autowire is set to + /// . + /// + /// + /// The object name to be autowired by . + /// + /// + /// The definition of the named object to update through autowiring. + /// + /// + /// The wrapping the target object (and + /// from which we can rip out information concerning the object). + /// + /// + /// The property values to register wired objects with. + /// + protected void AutowireByName(string name, RootObjectDefinition definition, IObjectWrapper wrapper, MutablePropertyValues properties) + { + string[] propertyNames = UnsatisfiedObjectProperties(definition, wrapper); + foreach (string propertyName in propertyNames) + { + // look for a matching type + if (ContainsObject(propertyName)) + { + object o = GetObject(propertyName); + properties.Add(propertyName, o); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, + "Added autowiring by name from object name '{0}' via " + "property '{1}' to object named '{1}'.", name, + propertyName)); + } + + #endregion + } + else + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, + "Not autowiring property '{0}' of object '{1}' by name: " + "no matching object found.", propertyName, name)); + } + + #endregion + } + } + } + + /// + /// Defines "autowire by type" (object properties by type) behavior. + /// + /// + ///

+ /// This is like PicoContainer default, in which there must be exactly one object + /// of the property type in the object factory. This makes object factories simple + /// to configure for small namespaces, but doesn't work as well as standard Spring + /// behavior for bigger applications. + ///

+ ///
+ /// + /// The object name to be autowired by . + /// + /// + /// The definition of the named object to update through autowiring. + /// + /// + /// The wrapping the target object (and + /// from which we can rip out information concerning the object). + /// + /// + /// The property values to register wired objects with. + /// + protected void AutowireByType(string name, RootObjectDefinition definition, IObjectWrapper wrapper, MutablePropertyValues properties) + { + string[] propertyNames = UnsatisfiedObjectProperties(definition, wrapper); + foreach (string propertyName in propertyNames) + { + // look for a matching type + Type requiredType = wrapper.GetPropertyType(propertyName); + IDictionary matchingObjects = FindMatchingObjects(requiredType); + if (matchingObjects != null && matchingObjects.Count == 1) + { + properties.Add(propertyName, ObjectUtils.EnumerateFirstElement(matchingObjects.Values)); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, + "Autowiring by type from object name '{0}' via property " + "'{1}' to object named '{2}'.", name, + propertyName, ObjectUtils.EnumerateFirstElement(matchingObjects.Keys))); + } + + #endregion + } + else if (matchingObjects != null && matchingObjects.Count > 1) + { + throw new UnsatisfiedDependencyException(string.Empty, name, propertyName, + string.Format(CultureInfo.InvariantCulture, + "There are {0} objects of Type [{1}] for autowire by " + + "type, when there should have been just 1 to be able to " + + "autowire property '{2}' of object '{3}'.", matchingObjects.Count, + requiredType, propertyName, name)); + } + else + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, "Not autowiring property '{0}' of object '{1}': no matching object found.", + propertyName, name)); + } + + #endregion + } + } + } + + /// + /// Ignore the given dependency type for autowiring + /// + /// + /// This will typically be used by application contexts to register + /// dependencies that are resolved in other ways, like IOjbectFactory through + /// IObjectFactoryAware or IApplicationContext through IApplicationContextAware. + /// By default, IObjectFactoryAware and IObjectName interfaces are ignored. + /// For further types to ignore, invoke this method for each type. + /// + /// . + public void IgnoreDependencyInterface(Type type) + { + ignoredDependencyInterfaces.Add(type); + } + + /// + /// Create an object instance for the given object definition. + /// + /// The name of the object. + /// + /// The object definition for the object that is to be instantiated. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. It is invalid to use a non- arguments value + /// in any other case. + /// + /// + /// A new instance of the object. + /// + /// + /// In case of errors. + /// + /// + ///

+ /// Delegates to the + /// + /// method version with the allowEagerCaching parameter set to true. + ///

+ ///

+ /// The object definition will already have been merged with the parent + /// definition in case of a child definition. + ///

+ ///

+ /// All the other methods in this class invoke this method, although objects + /// may be cached after being instantiated by this method. All object + /// instantiation within this class is performed by this method. + ///

+ ///
+ protected override object CreateObject(string name, RootObjectDefinition definition, object[] arguments) + { + return CreateObject(name, definition, arguments, true); + } + + /// + /// Create an object instance for the given object definition. + /// + /// The name of the object. + /// + /// The object definition for the object that is to be instantiated. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. It is invalid to use a non- arguments value + /// in any other case. + /// + /// + /// Whether eager caching of singletons is allowed... typically true for + /// singlton objects, but never true for inner object definitions. + /// + /// + /// A new instance of the object. + /// + /// + /// In case of errors. + /// + /// + ///

+ /// The object definition will already have been merged with the parent + /// definition in case of a child definition. + ///

+ ///

+ /// All the other methods in this class invoke this method, although objects + /// may be cached after being instantiated by this method. All object + /// instantiation within this class is performed by this method. + ///

+ ///
+ protected virtual object CreateObject(string name, RootObjectDefinition definition, object[] arguments, bool allowEagerCaching) + { + // guarantee the initialization of objects that the current one depends on.. + if (definition.DependsOn != null && definition.DependsOn.Length > 0) + { + foreach (string dependant in definition.DependsOn) + { + GetObject(dependant); + } + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, "Creating instance of Object '{0}' with merged definition [{1}].", name, definition)); + } + + #endregion + + // Make sure object type is actually resolved at this point. + ResolveObjectType(definition, name); + + try + { + definition.PrepareMethodOverrides(); + } + catch (ObjectDefinitionValidationException ex) + { + throw new ObjectDefinitionStoreException(definition.ResourceDescription, name, + "Validation of method overrides failed. " + ex.Message, ex); + } + + // return IObjectDefinition instance itself for an abstract object-definition + if (definition.IsTemplate) + { + return definition; + } + + + + object instance = null; + + + IObjectWrapper instanceWrapper = null; + bool eagerlyCached = false; + try + { + // Give IInstantiationAwareObjectPostProcessors a chance to return a proxy instead of the target instance.... + if (definition.HasObjectType) + { + instance = ApplyObjectPostProcessorsBeforeInstantiation(definition.ObjectType, name); + if (instance != null) + { + return instance; + } + } + + + instanceWrapper = CreateObjectInstance(name, definition, arguments); + instance = instanceWrapper.WrappedInstance; + + // eagerly cache singletons to be able to resolve circular references + // even when triggered by lifecycle interfaces like IObjectFactoryAware. + if (allowEagerCaching && definition.IsSingleton) + { + if (log.IsDebugEnabled) + { + log.Debug("Eagerly caching object '" + name + "' to allow for resolving potential circular references"); + } + AddEagerlyCachedSingleton(name, definition, instance); + eagerlyCached = true; + } + + instance = ConfigureObject(name, definition, instanceWrapper); + } + catch (ObjectCreationException) + { + if (eagerlyCached) + { + RemoveEagerlyCachedSingleton(name, definition); + } + throw; + } + catch (Exception ex) + { + if (eagerlyCached) + { + RemoveEagerlyCachedSingleton(name, definition); + } + throw new ObjectCreationException(definition.ResourceDescription, name, "Initialization of object failed : " + ex.Message, ex); + } + return instance; + } + + /// + /// Add the created, but yet unpopulated singleton to the singleton cache + /// to be able to resolve circular references + /// + /// the name of the object to add to the cache. + /// the definition used to create and populated the object. + /// the raw object instance. + /// + /// Derived classes may override this method to select the right cache based on the object definition. + /// + protected virtual void AddEagerlyCachedSingleton(string objectName, IObjectDefinition objectDefinition, object rawSingletonInstance) + { + base.AddSingleton(objectName, rawSingletonInstance); + } + + /// + /// Remove the specified singleton from the singleton cache that has + /// been added before by a call to + /// + /// the name of the object to remove from the cache. + /// the definition used to create and populated the object. + /// + /// Derived classes may override this method to select the right cache based on the object definition. + /// + protected virtual void RemoveEagerlyCachedSingleton(string objectName, IObjectDefinition objectDefinition) + { + base.RemoveSingleton(objectName); + } + + /// + /// Creates an instance from the passed in + /// using constructor + /// + /// The name of the object to create - used for error messages. + /// The describing the object to be created. + /// optional arguments to pass to the constructor + /// An wrapping the already instantiated object + protected IObjectWrapper CreateObjectInstance(string name, RootObjectDefinition definition, object[] arguments) + { + IObjectWrapper instanceWrapper; + if (StringUtils.HasText(definition.FactoryMethodName)) + { + instanceWrapper = InstantiateUsingFactoryMethod(name, definition, arguments); + } + //Handle case when arguments are passed in explicitly. + else if (arguments != null && arguments.Length > 0) + { + instanceWrapper = AutowireConstructor(name, definition, arguments); + } + else if (definition.ResolvedAutowireMode == AutoWiringMode.Constructor || + definition.HasConstructorArgumentValues) + { + instanceWrapper = AutowireConstructor(name, definition); + } + else + { + instanceWrapper = new ObjectWrapper(InstantiationStrategy.Instantiate(definition, name, this)); + InitObjectWrapper(instanceWrapper); + } + return instanceWrapper; + } + + /// + /// Instantiate an object instance using a named factory method. + /// + /// + ///

+ /// The method may be static, if the + /// parameter specifies a class, rather than a + /// instance, or an + /// instance variable on a factory object itself configured using Dependency + /// Injection. + ///

+ ///

+ /// Implementation requires iterating over the static or instance methods + /// with the name specified in the supplied + /// (the method may be overloaded) and trying to match with the parameters. + /// We don't have the types attached to constructor args, so trial and error + /// is the only way to go here. + ///

+ ///
+ /// + /// The name associated with the supplied . + /// + /// + /// The definition describing the instance that is to be instantiated. + /// + /// + /// Any arguments to the factory method that is to be invoked. + /// + /// + /// The result of the factory method invocation (the instance). + /// + protected virtual IObjectWrapper InstantiateUsingFactoryMethod(string name, RootObjectDefinition definition, object[] arguments) + { + ConstructorArgumentValues cargs = definition.ConstructorArgumentValues; + ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); + int expectedArgCount = 0; + + // we don't have arguments passed in programmatically, so we need to resolve the + // arguments specified in the constructor arguments held in the object definition... + if (arguments == null || arguments.Length == 0) + { + expectedArgCount = cargs.ArgumentCount; + ResolveConstructorArguments(name, definition, resolvedValues); + } + else + { + // if we have constructor args, don't need to resolve them... + expectedArgCount = arguments.Length; + } + ObjectWrapper wrapper = new ObjectWrapper(); + InitObjectWrapper(wrapper); + bool isStatic = true; + Type factoryClass = null; + if (StringUtils.HasText(definition.FactoryObjectName)) + { + // it's an instance method on the factory object's class... + factoryClass = GetObject(definition.FactoryObjectName).GetType(); + isStatic = false; + } + else + { + // it's a static factory method on the object class... + factoryClass = definition.ObjectType; + } + +#if NET_2_0 + GenericArgumentsHolder genericArgsInfo = new GenericArgumentsHolder(definition.FactoryMethodName); + + MethodInfo[] factoryMethods = FindMethods(genericArgsInfo.GenericMethodName, expectedArgCount, isStatic, factoryClass); + UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; + // try all matching methods to see if they match the constructor arguments... + for (int i = 0; i < factoryMethods.Length; i++) + { + unsatisfiedDependencyExceptionData = null; + MethodInfo factoryMethod = factoryMethods[i]; + + if (genericArgsInfo.ContainsGenericArguments) + { + string[] unresolvedGenericArgs = genericArgsInfo.GetGenericArguments(); + if (factoryMethod.GetGenericArguments().Length != unresolvedGenericArgs.Length) + continue; + + Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; + for (int j = 0; j < unresolvedGenericArgs.Length; j++) + { + genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); + } + factoryMethod = factoryMethod.MakeGenericMethod(genericArgs); + } +#else + MethodInfo[] factoryMethods = FindMethods(definition.FactoryMethodName, expectedArgCount, isStatic, factoryClass); + UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; + // try all matching methods to see if they match the constructor arguments... + foreach(MethodInfo factoryMethod in factoryMethods) + { +#endif + if (arguments == null || arguments.Length == 0) + { + // try to create the required arguments... + arguments = CreateArgumentArray(name, definition, resolvedValues, factoryMethod, out unsatisfiedDependencyExceptionData); + if (arguments == null) + { + // if we failed to match this method, keep + // trying new overloaded factory methods... + continue; + } + } + // if we get here, we found a factory method... + + if (ReflectionUtils.GetMethodByArgumentValues(new MethodInfo[] { factoryMethod }, arguments) == null) + { + continue; + } + + + object objectInstance = InstantiationStrategy.Instantiate(definition, name, this, factoryMethod, arguments); + wrapper.WrappedInstance = objectInstance; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, "Object '{0}' instantiated via factory method [{1}].", name, factoryMethod)); + } + + #endregion + + return wrapper; + } + + + + // if we get here, we didn't match any method... + throw new ObjectDefinitionStoreException( + string.Format(CultureInfo.InvariantCulture, "Cannot find matching factory method '{0} on Type [{1}].", definition.FactoryMethodName, + factoryClass)); + } + + /// + /// Returns an array of all of those + /// methods exposed on the + /// that match the supplied criteria. + /// + /// + /// Methods that have this name (can be in the form of a regular expression). + /// + /// + /// Methods that have exactly this many arguments. + /// + /// + /// Methods that are static / instance. + /// + /// + /// The on which the methods (if any) are to be found. + /// + /// + /// An array of all of those + /// methods exposed on the + /// that match the supplied criteria. + /// + private static MethodInfo[] FindMethods(string methodName, int expectedArgumentCount, bool isStatic, Type searchType) + { + ComposedCriteria methodCriteria = new ComposedCriteria(); + methodCriteria.Add(new MethodNameMatchCriteria(methodName)); + methodCriteria.Add(new MethodParametersCountCriteria(expectedArgumentCount)); + BindingFlags methodFlags = BindingFlags.Public | BindingFlags.IgnoreCase | (isStatic ? BindingFlags.Static : BindingFlags.Instance); + MemberInfo[] methods = + searchType.FindMembers(MemberTypes.Method, methodFlags, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + methodCriteria); + return (MethodInfo[])ArrayList.Adapter(methods).ToArray(typeof(MethodInfo)); + } + + /// + /// Create an array of arguments to invoke a constructor or static factory method, + /// given the resolved constructor arguments values. + /// + /// When return value is null the out parameter UnsatisfiedDependencyExceptionData will contain + /// information for use in throwing a UnsatisfiedDependencyException by the caller. This avoids using + /// exceptions for flow control as in the original implementation. + private object[] CreateArgumentArray(string name, RootObjectDefinition definition, + ConstructorArgumentValues resolvedValues, MethodBase methodOrCtor, out UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData) + { + string methodType = (methodOrCtor is ConstructorInfo) ? "constructor" : "factory method"; + unsatisfiedDependencyExceptionData = null; + ParameterInfo[] argTypes = methodOrCtor.GetParameters(); + object[] args = new object[argTypes.Length]; + ISet alreadyUsedValues = new HybridSet(); + for (int j = 0; j < argTypes.Length; ++j) + { + Type parameterType = argTypes[j].ParameterType; + string parameterName = argTypes[j].Name; + ConstructorArgumentValues.ValueHolder valueHolder = null; + if (resolvedValues.GetNamedArgumentValue(parameterName) != null) + { + valueHolder = resolvedValues.GetArgumentValue(parameterName, parameterType, alreadyUsedValues); + } + else + { + valueHolder = resolvedValues.GetArgumentValue(j, parameterType, alreadyUsedValues); + } + if (valueHolder != null) + { + try + { + args[j] = TypeConversionUtils.ConvertValueIfNecessary(parameterType, valueHolder.Value, null); + alreadyUsedValues.Add(valueHolder); + } + catch (TypeMismatchException ex) + { + string errorMessage = String.Format(CultureInfo.InvariantCulture, + "Could not convert {0} argument value [{1}] to required type [{2}] : {3}", + methodType, valueHolder.Value, + parameterType, ex.Message); + unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage); + + + return null; + } + } + else + { + if (definition.ResolvedAutowireMode != AutoWiringMode.Constructor) + { + string errorMessage = String.Format(CultureInfo.InvariantCulture, + "Ambiguous {0} argument types - " + + "Did you specify the correct object references as {0} arguments?", + methodType); + unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage); + + return null; + } + IDictionary matchingObjects = FindMatchingObjects(parameterType); + if (matchingObjects == null || matchingObjects.Count != 1) + { + string errorMessage = String.Format(CultureInfo.InvariantCulture, + "There are '{0}' objects of type [{1}] for autowiring " + + + "{2}. There should have been exactly 1 to be able to " + + + "autowire the '{3}' argument on the {2} of object '{4}'.", + (matchingObjects == null + ? 0 + : matchingObjects.Count), + parameterType, methodType, + parameterName, name); + unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage); + + return null; + } + DictionaryEntry entry = (DictionaryEntry)ObjectUtils.EnumerateFirstElement(matchingObjects); + args[j] = entry.Value; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, + "Autowiring '{0}' argument by type from object name '{1}' via {2} to " + + "object named '{3}'.", parameterName, name, methodType, entry.Key)); + } + + #endregion + } + } + + return args; + } + + /// + /// Explicitly construct the object using the supplied constructor arguments. + /// Constructor arguments are matched by type. + /// + /// + /// The name of the object to autowire by type. + /// + /// + /// The object definition to update through autowiring. + /// + /// Array of constructor argument values. + /// + /// An for the new instance. + /// + protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition, object[] args) + { + ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); + for (int i = 0; i < args.Length; i++) + { + //This is assigning ctor arguments by type. + resolvedValues.AddGenericArgumentValue(args[i]); + } + return AutowireConstructor(name, definition, resolvedValues); + } + + /// + /// "autowire constructor" (with constructor arguments by type) behaviour. + /// + /// Passes an empty collection of constructor argument values + /// to overloaded method. + /// + /// + /// The name of the object to autowire by type. + /// + /// + /// The object definition to update through autowiring. + /// + /// + /// An for the new instance. + /// + protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition) + { + return AutowireConstructor(name, definition, new ConstructorArgumentValues()); + } + + /// + /// "autowire constructor" (with constructor arguments by type) behaviour. + /// + /// + ///

+ /// Also applied if explicit constructor argument values are specified, + /// matching all remaining arguments with objects from the object factory. + ///

+ ///

+ /// This corresponds to constructor injection: in this mode, a Spring.NET + /// object factory is able to host components that expect constructor-based + /// dependency resolution. + ///

+ ///
+ /// + /// The name of the object to autowire by type. + /// + /// + /// The object definition to update through autowiring. + /// + /// + /// The collection on constructor argument values. + /// + /// + /// An for the new instance. + /// + protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition, ConstructorArgumentValues argumentValues) + { + int minNrOfArgs = ResolveConstructorArguments(name, definition, argumentValues); + ConstructorInfo[] constructors = AutowireUtils.GetConstructors(definition, minNrOfArgs); + if (constructors == null || constructors.Length == 0) + { + throw new ObjectCreationException(definition.ResourceDescription, name, + string.Format(CultureInfo.InvariantCulture, + "'{0}' constructor arguments specified but no matching constructor found " + + "in object '{1}' (hint: specify argument indexes, names, or " + + "types to avoid ambiguities).", minNrOfArgs, name)); + } + ObjectWrapper wrapper = new ObjectWrapper(); + InitObjectWrapper(wrapper); + ConstructorInfo constructorToUse = null; + object[] argsToUse = null; + int weighting = Int32.MaxValue; + UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; + for (int i = 0; i < constructors.Length; ++i) + { + unsatisfiedDependencyExceptionData = null; + ConstructorInfo constructor = constructors[i]; + if (constructorToUse != null && + constructorToUse.GetParameters().Length > constructor.GetParameters().Length) + { + // already found greedy constructor that can be satisfied, so + // don't look any further, there are only less greedy constructors left... + break; + } + + object[] args = CreateArgumentArray(name, definition, argumentValues, constructor, out unsatisfiedDependencyExceptionData); + if (args == null) + { + if (i == constructors.Length - 1 && constructorToUse == null) + { + throw new UnsatisfiedDependencyException(definition.ResourceDescription, + name, + unsatisfiedDependencyExceptionData.ParameterIndex, + unsatisfiedDependencyExceptionData.ParameterType, + unsatisfiedDependencyExceptionData.ErrorMessage); + } + // try next constructor... + continue; + } + + int typeDiffWeight = AutowireUtils.GetTypeDifferenceWeight(constructor.GetParameters(), args); + if (typeDiffWeight < weighting) + { + constructorToUse = constructor; + argsToUse = args; + weighting = typeDiffWeight; + } + } + + if (constructorToUse == null) + { + throw new ObjectCreationException(definition.ResourceDescription, name, "Could not resolve matching constructor."); + } + wrapper.WrappedInstance = InstantiationStrategy.Instantiate(definition, name, this, constructorToUse, argsToUse); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, "Object '{0}' instantiated via constructor [{1}].", name, constructorToUse)); + } + + #endregion + + return wrapper; + } + + /// + /// Resolves the + /// of the supplied . + /// + /// + ///

+ /// 'Resolve' can be taken to mean that all of the s + /// constructor arguments is resolved into a concrete object that can be plugged + /// into one of the s constructors. Runtime object + /// references to other objects in this (or a parent) factory are resolved, + /// type conversion is performed, etc. + ///

+ ///

+ /// These resolved values are plugged into the supplied + /// object, because we wouldn't want to touch + /// the s constructor arguments in case it (or any of + /// its constructor arguments) is a prototype object definition. + ///

+ ///

+ /// This method is also used for handling invocations of static factory methods. + ///

+ ///
+ /// + /// The name of the object that is being resolved by this factory. + /// + /// + /// The definition associated with the above . + /// + /// + /// Where the resolved constructor arguments will be placed. + /// + /// + /// The minimum number of arguments that any constructor for the supplied + /// must have. + /// + private int ResolveConstructorArguments(string name, RootObjectDefinition definition, ConstructorArgumentValues resolvedValues) + { + int minNrOfArgs = 0; + if (definition.ConstructorArgumentValues != null) + { + minNrOfArgs = definition.ConstructorArgumentValues.ArgumentCount; + foreach (DictionaryEntry de in definition.ConstructorArgumentValues.IndexedArgumentValues) + { + int index = (int)de.Key; + if (index < 0) + { + throw new ObjectCreationException(definition.ResourceDescription, name, "Invalid constructor argument index: " + index); + } + if (index > minNrOfArgs) + { + minNrOfArgs = index + 1; + } + string argName = "constructor argument with index " + index; + ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder)de.Value; + object resolvedValue = ResolveValueIfNecessary(name, definition, argName, valueHolder.Value); + resolvedValues.AddIndexedArgumentValue(index, resolvedValue, + StringUtils.HasText(valueHolder.Type) + ? TypeResolutionUtils.ResolveType(valueHolder.Type).AssemblyQualifiedName + : null); + } + foreach (ConstructorArgumentValues.ValueHolder valueHolder in definition.ConstructorArgumentValues.GenericArgumentValues) + { + string argName = "constructor argument"; + object resolvedValue = ResolveValueIfNecessary(name, definition, argName, valueHolder.Value); + resolvedValues.AddGenericArgumentValue(resolvedValue, + StringUtils.HasText(valueHolder.Type) + ? TypeResolutionUtils.ResolveType(valueHolder.Type).AssemblyQualifiedName + : null); + } + foreach (DictionaryEntry namedArgumentEntry in definition.ConstructorArgumentValues.NamedArgumentValues) + { + string argumentName = (string)namedArgumentEntry.Key; + string syntheticArgumentName = "constructor argument with name " + argumentName; + ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder)namedArgumentEntry.Value; + object resolvedValue = ResolveValueIfNecessary(name, definition, syntheticArgumentName, valueHolder.Value); + resolvedValues.AddNamedArgumentValue(argumentName, resolvedValue); + } + } + return minNrOfArgs; + } + + /// + /// Perform a dependency check that all properties exposed have been set, if desired. + /// + /// + ///

+ /// Dependency checks can be objects (collaborating objects), simple (primitives + /// and ), or all (both). + ///

+ ///
+ /// + /// The name of the object. + /// + /// + /// The definition of the named object. + /// + /// + /// The wrapping the target object. + /// + /// + /// The property values to be checked. + /// + /// + /// If all of the checked dependencies were not satisfied. + /// + protected void DependencyCheck(string name, IConfigurableObjectDefinition definition, IObjectWrapper wrapper, IPropertyValues properties) + { + DependencyCheckingMode dependencyCheck = definition.DependencyCheck; + if (dependencyCheck == DependencyCheckingMode.None) + { + return; + } + + PropertyInfo[] filteredPropInfo = FilterPropertyInfoForDependencyCheck(wrapper); + if (HasInstantiationAwareBeanPostProcessors) + { + foreach (IObjectPostProcessor processor in ObjectPostProcessors) + { + IInstantiationAwareObjectPostProcessor inProc = processor as IInstantiationAwareObjectPostProcessor; + if (inProc != null) + { + properties = + inProc.PostProcessPropertyValues(properties, filteredPropInfo, wrapper.WrappedInstance, name); + if (properties == null) + { + return; + } + } + } + } + + + CheckDependencies(name, definition, filteredPropInfo, properties); + } + + private static void CheckDependencies(string name, IConfigurableObjectDefinition definition, PropertyInfo[] filteredPropInfo, IPropertyValues properties) + { + DependencyCheckingMode dependencyCheck = definition.DependencyCheck; + foreach (PropertyInfo property in filteredPropInfo) + { + if (property.CanWrite && properties.GetPropertyValue(property.Name) == null) + { + bool isSimple = ObjectUtils.IsSimpleProperty(property.PropertyType); + bool unsatisfied = (dependencyCheck == DependencyCheckingMode.All) || (isSimple && dependencyCheck == DependencyCheckingMode.Simple) + || (!isSimple && dependencyCheck == DependencyCheckingMode.Objects); + if (unsatisfied) + { + throw new UnsatisfiedDependencyException(definition.ResourceDescription, name, property.Name, + "Set this property value or disable dependency checking for this object."); + } + } + } + } + + /// + /// Extract a filtered set of PropertyInfos from the given IObjectWrapper, excluding + /// ignored dependency types. + /// + /// The object wrapper the object was created with. + /// The filtered PropertyInfos + private PropertyInfo[] FilterPropertyInfoForDependencyCheck(IObjectWrapper wrapper) + { + lock (filteredPropertyDescriptorsCache) + { + PropertyInfo[] filtered = (PropertyInfo[])filteredPropertyDescriptorsCache[wrapper.WrappedType]; + if (filtered == null) + { + + ArrayList list = new ArrayList(wrapper.GetPropertyInfos()); + for (int i = list.Count - 1; i >= 0; i--) + { + PropertyInfo pi = (PropertyInfo)list[i]; + if (IsExcludedFromDependencyCheck(pi)) + { + list.RemoveAt(i); + } + } + + filtered = (PropertyInfo[])list.ToArray(typeof(PropertyInfo)); + filteredPropertyDescriptorsCache.Add(wrapper.WrappedType, filtered); + } + return filtered; + } + + } + + private bool IsExcludedFromDependencyCheck(PropertyInfo pi) + { + bool b1 = !pi.CanWrite; //AutowireUtils.IsExcludedFromDependencyCheck(pi); + bool b2 = IgnoredDependencyTypes.Contains(pi.PropertyType); + bool b3 = AutowireUtils.IsSetterDefinedInInterface(pi, ignoredDependencyInterfaces); + return b1 || b2 || b3; + /* + return AutowireUtils.IsExcludedFromDependencyCheck(pi) || + IgnoredDependencyTypes.Contains(pi.PropertyType) || + AutowireUtils.IsSetterDefinedInInterface(pi, ignoredDependencyInterfaces); + */ + } + + /// + /// Give an object a chance to react now all its properties are set, + /// and a chance to know about its owning object factory (this object). + /// + /// + ///

+ /// This means checking whether the object implements + /// and / or + /// , and invoking the + /// necessary callback(s) if it does. + ///

+ ///

+ /// Custom init methods are resolved in a case-insensitive manner. + ///

+ ///
+ /// + /// The new object instance we may need to initialise. + /// + /// + /// The name the object has in the factory. Used for logging output. + /// + /// + /// The definition of the target object instance. + /// + protected virtual void InvokeInitMethods(object target, string name, IConfigurableObjectDefinition definition) + { + if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IInitializingObject), target)) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, "Calling AfterPropertiesSet() on object with name '{0}'.", name)); + } + + #endregion + + ((IInitializingObject)target).AfterPropertiesSet(); + } + if (StringUtils.HasText(definition.InitMethodName)) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, "Calling custom init method '{0} on object with name '{1}'.", + definition.InitMethodName, name)); + } + + #endregion + + try + { + MethodInfo targetMethod = target.GetType().GetMethod(definition.InitMethodName, MethodResolutionFlags, null, Type.EmptyTypes, null); + if (targetMethod == null) + { + throw new ObjectCreationException(definition.ResourceDescription, name, + "Could not find the named initialization method '" + definition.InitMethodName + "'."); + } + targetMethod.Invoke(target, ObjectUtils.EmptyObjects); + } + catch (TargetInvocationException ex) + { + throw new ObjectCreationException(definition.ResourceDescription, name, + "Initialization method '" + definition.InitMethodName + "' threw exception", ex.GetBaseException()); + } + catch (Exception ex) + { + throw new ObjectCreationException(definition.ResourceDescription, name, + "Invocation of initialization method '" + definition.InitMethodName + "' failed", ex); + } + } + } + + /// + /// Invoke the specified custom destroy method on the given object. + /// + /// + ///

+ /// This implementation invokes a no-arg method if found, else checking + /// for a method with a single boolean argument (passing in "true", + /// assuming a "force" parameter), else logging an error. + ///

+ ///

+ /// Can be overridden in subclasses for custom resolution of destroy + /// methods with arguments. + ///

+ ///

+ /// Custom destroy methods are resolved in a case-insensitive manner. + ///

+ ///
+ protected virtual void InvokeCustomDestroyMethod(string name, object target, string destroyMethodName) + { + bool usingForcingVersion = false; + MethodInfo targetMethod = target.GetType().GetMethod(destroyMethodName, MethodResolutionFlags, null, Type.EmptyTypes, null); + if (targetMethod == null) + { + // #%&^! try to find the method with a boolean "force" parameter + targetMethod = target.GetType().GetMethod(destroyMethodName, MethodResolutionFlags, null, new Type[] { typeof(bool) }, null); + if (targetMethod != null) + { + usingForcingVersion = true; + } + } + if (targetMethod == null) + { + #region Instrumentation + + log.Error("Couldn't find a method named '" + destroyMethodName + "' on object with name '" + name + "'"); + + #endregion + } + else + { + object[] args = usingForcingVersion ? new object[] { true } : ObjectUtils.EmptyObjects; + try + { + targetMethod.Invoke(target, args); + } + catch (TargetInvocationException ex) + { + #region Instrumentation + + log.Error("Couldn't invoke destroy method '" + destroyMethodName + "' of object with name '" + name + "'", ex.GetBaseException()); + + #endregion + } + catch (Exception ex) + { + LogExceptionRaisedByCustomDestroyMethodInvocation(destroyMethodName, name, ex); + } + } + } + + private void LogExceptionRaisedByCustomDestroyMethodInvocation(string destroyMethodName, string name, Exception ex) + { + log.Error( + string.Format(CultureInfo.InvariantCulture, "Couldn't invoke destroy method '{0}' of object with name '{1}'.", destroyMethodName, name), + ex); + } + + /// + /// Destroy the target object. + /// + /// + ///

+ /// Must destroy objects that depend on the given object before the object itself. + /// Should not throw any exceptions. + ///

+ ///
+ /// + /// The name of the object. + /// + /// + /// The target object instance to destroyed. + /// + protected override void DestroyObject(string name, object target) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Destroying dependant objects for object '" + name + "'"); + } + + #endregion + + DestroyDependantObjects(name); + if (target is IDisposable) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, "Calling Dispose () on object with name '{0}'.", name)); + } + + #endregion + + try + { + ((IDisposable)target).Dispose(); + } + catch (Exception ex) + { + #region Instrumentation + + log.Error("Destroy() on object with name '" + name + "' threw an exception.", ex); + + #endregion + } + } + RootObjectDefinition rootDefinition = GetMergedObjectDefinition(name, false); + if (rootDefinition != null && StringUtils.HasText(rootDefinition.DestroyMethodName)) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Calling custom destroy method '" + rootDefinition.DestroyMethodName + "' on object with name '" + name + "'."); + } + + #endregion + + InvokeCustomDestroyMethod(name, target, rootDefinition.DestroyMethodName); + } + } + + /// + /// Destroys all of the objects registered as dependant on the + /// object (definition) identified by the supplied . + /// + /// + /// The name of the root object (definition) that is itself being destroyed. + /// + private void DestroyDependantObjects(string name) + { + string[] dependingObjects = GetDependingObjectNames(name); + foreach (string doName in dependingObjects) + { + DestroySingleton(doName); + } + } + + /// + /// Given a property value, return a value, resolving any references to other + /// objects in the factory if necessary. + /// + /// + ///

+ /// The value could be : + /// + /// + ///

+ /// An , + /// which leads to the creation of a corresponding new object instance. + /// Singleton flags and names of such "inner objects" are always ignored: inner objects + /// are anonymous prototypes. + ///

+ /// + /// + ///

+ /// A , which must + /// be resolved. + ///

+ ///
+ /// + ///

+ /// An . This is a + /// special placeholder collection that may contain + /// s or + /// collections that will need to be resolved. + ///

+ ///
+ /// + ///

+ /// An ordinary object or , in which case it's left alone. + ///

+ ///
+ /// + ///

+ ///
+ /// + /// The name of the object that is having the value of one of its properties resolved. + /// + /// + /// The definition of the named object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The value of the property that is being resolved. + /// + protected object ResolveValueIfNecessary(string name, RootObjectDefinition definition, string argumentName, object argumentValue) + { + object resolvedValue = null; + // we must check the argument value to see whether it requires a runtime + // reference to another object to be resolved. + // if it does, we'll attempt to instantiate the object and set the reference. + if (argumentValue is ObjectDefinitionHolder) + { + // contains an IObjectDefinition with name and aliases... + ObjectDefinitionHolder holder = (ObjectDefinitionHolder)argumentValue; + resolvedValue = ResolveInnerObjectDefinition(name, holder.ObjectName, argumentName, holder.ObjectDefinition, definition.IsSingleton); + } + else if (argumentValue is IObjectDefinition) + { + // resolve plain IObjectDefinition, without contained name: use dummy name... + IObjectDefinition def = (IObjectDefinition)argumentValue; + resolvedValue = ResolveInnerObjectDefinition(name, "(inner object)", argumentName, def, definition.IsSingleton); + + } + else if (argumentValue is RuntimeObjectReference) + { + RuntimeObjectReference roref = (RuntimeObjectReference)argumentValue; + resolvedValue = ResolveReference(definition, name, argumentName, roref); + } + else if (argumentValue is ExpressionHolder) + { + ExpressionHolder expHolder = (ExpressionHolder)argumentValue; + object context = null; + IDictionary variables = null; + + if (expHolder.Properties != null) + { + PropertyValue contextProperty = expHolder.Properties.GetPropertyValue("Context"); + context = contextProperty == null + ? null + : ResolveValueIfNecessary(name, definition, "Context", + contextProperty.Value); + PropertyValue variablesProperty = expHolder.Properties.GetPropertyValue("Variables"); + object vars = (variablesProperty == null + ? null + : ResolveValueIfNecessary(name, definition, "Variables", + variablesProperty.Value)); + if (vars is IDictionary) + { + variables = (IDictionary)vars; + } + else + { + if (vars != null) throw new ArgumentException("'Variables' must resolve to an IDictionary"); + } + } + + if (variables == null) variables = CollectionsUtil.CreateCaseInsensitiveHashtable(); + // add 'this' objectfactory reference to variables + variables.Add(Expression.ReservedVariableNames.CurrentObjectFactory, this); + + resolvedValue = expHolder.Expression.GetValue(context, variables); + } + else if (argumentValue is IManagedCollection) + { + resolvedValue = + ((IManagedCollection)argumentValue).Resolve(name, definition, argumentName, + new ManagedCollectionElementResolver(ResolveValueIfNecessary)); + } + else if (argumentValue is TypedStringValue) + { + TypedStringValue tsv = (TypedStringValue)argumentValue; + try + { + Type resolvedTargetType = ResolveTargetType(tsv); + if (resolvedTargetType != null) + { + resolvedValue = TypeConversionUtils.ConvertValueIfNecessary(tsv.TargetType, tsv.Value, null); + } + else + { + resolvedValue = tsv.Value; + } + } + catch (Exception ex) + { + throw new ObjectCreationException(definition.ResourceDescription, name, + "Error converted typed String value for " + argumentName, ex); + } + + } + else + { + // no need to resolve value... + resolvedValue = argumentValue; + } + return resolvedValue; + } + + /// + /// Resolve the target type of the passed . + /// + /// The who's target type is to be resolved + /// The resolved target type, if any. otherwise. + protected virtual Type ResolveTargetType(TypedStringValue value) + { + if (value.HasTargetType) + { + return value.TargetType; + } + else + { + return null; + } + } + /// + /// Resolves an inner object definition. + /// + /// + /// The name of the object that surrounds this inner object definition. + /// + /// + /// The name of the inner object definition... note: this is a synthetic + /// name assigned by the factory (since it makes no sense for inner object + /// definitions to have names). + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The definition of the inner object that is to be resolved. + /// + /// + /// if the owner of the property is a singleton. + /// + /// + /// The resolved object as defined by the inner object definition. + /// + protected object ResolveInnerObjectDefinition(string name, string innerObjectName, string argumentName, IObjectDefinition definition, + bool singletonOwner) + { + RootObjectDefinition mod = GetMergedObjectDefinition(innerObjectName, definition); + mod.IsSingleton = singletonOwner; + object instance; + object result; + try + { + instance = CreateObject(innerObjectName, mod, ObjectUtils.EmptyObjects, false); + result = GetObjectForInstance(innerObjectName, instance); + } + catch (ObjectsException ex) + { + throw ObjectCreationException.GetObjectCreationException(ex, name, argumentName, definition.ResourceDescription, innerObjectName); + } + if (singletonOwner && instance is IDisposable) + { + // keep a reference to the inner object instance, to be able to destroy + // it on factory shutdown... + _disposableInnerObjects.Add(instance); + } + return result; + } + + /// + /// Resolve a reference to another object in the factory. + /// + /// + /// The name of the object that is having the value of one of its properties resolved. + /// + /// + /// The definition of the named object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The runtime reference containing the value of the property. + /// + /// A reference to another object in the factory. + protected object ResolveReference(IConfigurableObjectDefinition definition, string name, string argumentName, RuntimeObjectReference reference) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, "Resolving reference from property '{0}' in object '{1}' to object '{2}'.", + argumentName, name, reference.ObjectName)); + } + + #endregion + + try + { + if (reference.IsToParent) + { + if (null == ParentObjectFactory) + { + throw new ObjectCreationException(definition.ResourceDescription, name, + string.Format( + "Can't resolve reference to '{0}' in parent factory: " + "no parent factory available.", + reference.ObjectName)); + } + return ParentObjectFactory.GetObject(reference.ObjectName); + } + return GetObject(reference.ObjectName); + } + catch (ObjectsException ex) + { + throw ObjectCreationException.GetObjectCreationException(ex, name, argumentName, definition.ResourceDescription, reference.ObjectName); + } + } + + /// + /// Find object instances that match the required . + /// + /// + ///

+ /// Called by autowiring. If a subclass cannot obtain information about object + /// names by , a corresponding exception should be thrown. + ///

+ ///
+ /// + /// The of the objects to look up. + /// + /// + /// An of object names and object + /// instances that match the required , or + /// if none are found. + /// + /// + /// In case of errors. + /// + protected abstract IDictionary FindMatchingObjects(Type requiredType); + + /// + /// Return the names of the objects that depend on the given object. + /// Called by DestroyObject, to be able to destroy depending objects first. + /// + /// + /// The name of the object to find depending objects for. + /// + /// + /// The array of names of depending objects, or the empty string array if none. + /// + /// + /// In case of errors. + /// + protected abstract string[] GetDependingObjectNames(string name); + + /// + /// Injects dependencies into the supplied instance + /// using the named object definition. + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + public override object ConfigureObject(object target, string name) + { + RootObjectDefinition definition = GetMergedObjectDefinition(name, true); + if (definition != null) + { + return ConfigureObject(name, definition, new ObjectWrapper(target)); + } + + return null; + } + + /// + /// Injects dependencies into the supplied instance + /// using the supplied . + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// An object definition that should be used to configure object. + /// + /// + public override object ConfigureObject(object target, string name, IObjectDefinition definition) + { + return ConfigureObject(name, new RootObjectDefinition(definition), new ObjectWrapper(target)); + } + + /// + /// Configures object instance by injecting dependencies, satisfying Spring lifecycle + /// interfaces and applying object post-processors. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// An object definition that should be used to configure object. + /// + /// + /// A wrapped object instance that is to be so configured. + /// + /// + protected virtual object ConfigureObject(string name, RootObjectDefinition definition, IObjectWrapper wrapper) + { + object instance = wrapper.WrappedInstance; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format("configuring object '{0}' using definition '{1}'", instance, name)); + } + + #endregion + + PopulateObject(name, definition, wrapper); + WireEvents(name, definition, wrapper); + + if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IObjectNameAware), instance)) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, "Setting the name property on the IObjectNameAware object '{0}'.", name)); + } + + #endregion + + ((IObjectNameAware)instance).ObjectName = name; + } + + if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IObjectFactoryAware), instance)) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format(CultureInfo.InvariantCulture, "Setting the ObjectFactory property on the IObjectFactoryAware object '{0}'.", + name)); + } + + #endregion + + ((IObjectFactoryAware)instance).ObjectFactory = this; + } + + instance = ApplyObjectPostProcessorsBeforeInitialization(instance, name); + InvokeInitMethods(instance, name, definition); + instance = ApplyObjectPostProcessorsAfterInitialization(instance, name); + + return instance; + } + + + /// + /// Applies the PostProcessAfterInitialization callback of all + /// registered IObjectPostProcessors, giving them a chance to post-process + /// the object obtained from IFactoryObjects (for example, to auto-proxy them) + /// + /// The instance obtained from the IFactoryObject. + /// Name of the object. + /// The object instance to expose + /// if any post-processing failed. + protected override object PostProcessObjectFromFactoryObject(object instance, string objectName) + { + return ApplyObjectPostProcessorsAfterInitialization(instance, objectName); + } + + #endregion + + #region IAutowireCapableObjectFactory Members + + /// + /// Create a new object instance of the given class with the specified + /// autowire strategy. + /// + /// + /// The of the object to instantiate. + /// + /// + /// The desired autowiring mode. + /// + /// + /// Whether to perform a dependency check for objects (not applicable to + /// autowiring a constructor, thus ignored there). + /// + /// The new object instance. + /// + /// If the wiring fails. + /// + /// + public virtual object Autowire(Type type, AutoWiringMode autowireMode, bool dependencyCheck) + { + RootObjectDefinition rod = new RootObjectDefinition(type, autowireMode, dependencyCheck); + if (rod.ResolvedAutowireMode == AutoWiringMode.Constructor) + { + return AutowireConstructor(type.Name, rod).WrappedInstance; + } + else + { + object obj = InstantiationStrategy.Instantiate(rod, string.Empty, this); + PopulateObject(obj.GetType().Name, rod, new ObjectWrapper(obj)); + return obj; + } + } + + /// + /// Autowire the object properties of the given object instance by name or + /// . + /// + /// + /// The existing object instance. + /// + /// + /// The desired autowiring mode. + /// + /// + /// Whether to perform a dependency check for the object. + /// + /// + /// If the wiring fails. + /// + /// + /// If the supplied is not one of the + /// or + /// + /// values. + /// + /// + public virtual void AutowireObjectProperties(object instance, AutoWiringMode autowireMode, bool dependencyCheck) + { + if (autowireMode != AutoWiringMode.ByName && autowireMode != AutoWiringMode.ByType) + { + throw new ArgumentException("Just AutoWiringMode.ByName and AutoWiringMode.ByType allowed."); + } + RootObjectDefinition rod = new RootObjectDefinition(instance.GetType(), autowireMode, dependencyCheck); + PopulateObject(instance.GetType().Name, rod, new ObjectWrapper(instance)); + } + + /// + /// Apply s + /// to the given existing object instance, invoking their + /// + /// methods. + /// + /// + /// The existing object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// If any post-processing failed. + /// + /// + public virtual object ApplyObjectPostProcessorsBeforeInitialization(object instance, string name) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Invoking IObjectPostProcessors before initialization of object '" + name + "'"); + } + + #endregion + + object result = instance; + foreach (IObjectPostProcessor objectProcessor in ObjectPostProcessors) + { + result = objectProcessor.PostProcessBeforeInitialization(result, name); + if (result == null) + { + throw new ObjectCreationException(name, + string.Format(CultureInfo.InvariantCulture, + "PostProcessBeforeInitialization method of IObjectPostProcessor [{0}] " + + " returned null for object [{1}] with name '{2}'.", objectProcessor, instance, name)); + } + } + return result; + } + + /// + /// Apply s + /// to the given existing object instance, invoking their + /// + /// methods. + /// + /// + /// The existing object instance. + /// + /// + /// The name of the object. + /// + /// + /// The object instance to use, either the original or a wrapped one. + /// + /// + /// If any post-processing failed. + /// + /// + public virtual object ApplyObjectPostProcessorsAfterInitialization(object instance, string name) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Invoking IObjectPostProcessors after initialization of object '" + name + "'"); + } + + #endregion + + object result = instance; + foreach (IObjectPostProcessor objectProcessor in ObjectPostProcessors) + { + result = objectProcessor.PostProcessAfterInitialization(result, name); + if (result == null) + { + throw new ObjectCreationException(name, + string.Format(CultureInfo.InvariantCulture, + "PostProcessAfterInitialization method of IObjectPostProcessor [{0}] " + + " returned null for object [{1}] with name [{2}].", objectProcessor, instance, name)); + } + } + return result; + } + + #endregion + + #region Fields + + /// + /// Set that holds all inner objects created by this factory that implement the IDisposable + /// interface, to be destroyed on call to Dispose. + /// + private ISet _disposableInnerObjects = new SynchronizedSet(new HybridSet()); + + private IInstantiationStrategy instantiationStrategy = new MethodInjectingInstantiationStrategy(); + + /// + /// Cache of unfinished IFactoryObject instances: IFactoryObject name --> IObjectWrapper */ + /// + private IDictionary factoryObjectInstanceCache = new Hashtable(); + + /// + /// Cache of filtered PropertyInfos: object Type -> PropertyInfo array + /// + private IDictionary filteredPropertyDescriptorsCache = new Hashtable(); + + /// + /// Dependency interfaces to ignore on dependency check and autowire, as Set of + /// Class objects. By default, only the IObjectFactoryAware and IObjectNameAware + /// interfaces are ignored. + /// + private ISet ignoredDependencyInterfaces = new HybridSet(); + + #endregion + } + + internal class UnsatisfiedDependencyExceptionData + { + private int parameterIndex; + private Type parameterType; + private string errorMessage; + + public UnsatisfiedDependencyExceptionData(int parameterIndex, Type parameterType, string errorMessage) + { + this.parameterIndex = parameterIndex; + this.parameterType = parameterType; + this.errorMessage = errorMessage; + } + + public int ParameterIndex + { + get { return parameterIndex; } + } + + public Type ParameterType + { + get { return parameterType; } + } + + public string ErrorMessage + { + get { return errorMessage; } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractMethodReplacer.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractMethodReplacer.cs index f1815983..6a2240d4 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractMethodReplacer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractMethodReplacer.cs @@ -1,128 +1,127 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// An - /// implementation that provides some convenience support for - /// derived classes. - /// - /// - ///

- /// This class is reserved for internal use within the framework; it is - /// not intended to be used by application developers using Spring.NET. - ///

- ///
- /// Rick Evans - /// $Id: AbstractMethodReplacer.cs,v 1.3 2007/07/30 17:52:22 markpollack Exp $ - public abstract class AbstractMethodReplacer : IMethodReplacer - { - private IConfigurableObjectDefinition objectDefinition; - private IObjectFactory objectFactory; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such has no - /// publicly visible constructors. - ///

- ///
- /// - /// The object definition that is the target of the method replacement. - /// - /// - /// The enclosing IoC container with which the above - /// is associated. - /// - /// - /// If either of the supplied arguments is . - /// - protected AbstractMethodReplacer( - IConfigurableObjectDefinition objectDefinition, IObjectFactory objectFactory) - { - AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); - AssertUtils.ArgumentNotNull(objectFactory, "objectFactory"); - this.objectDefinition = objectDefinition; - this.objectFactory = objectFactory; - } - - /// - /// Is ; derived classes must supply an implementation. - /// - /// - /// The instance whose is to be - /// (re)implemented. - /// - /// - /// The method that is to be (re)implemented. - /// - /// The target method's arguments. - /// The result of the object lookup. - public abstract object Implement(object target, MethodInfo method, object[] arguments); - - /// - /// Helper method for subclasses to retrieve the appropriate - /// for the - /// supplied . - /// - /// - /// The to use to retrieve - /// the appropriate - /// . - /// - /// - /// The appropriate - /// . - /// - protected MethodOverride GetOverride(MethodInfo method) - { - return this.objectDefinition.MethodOverrides.GetOverride(method); - } - - /// - /// Helper method for subclasses to lookup an object from an enclosing - /// IoC container. - /// - /// - /// The name of the object that is to be looked up. - /// - /// - /// The named object. - /// - protected object GetObject(string objectName) - { - return this.objectFactory.GetObject(objectName); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// An + /// implementation that provides some convenience support for + /// derived classes. + /// + /// + ///

+ /// This class is reserved for internal use within the framework; it is + /// not intended to be used by application developers using Spring.NET. + ///

+ ///
+ /// Rick Evans + public abstract class AbstractMethodReplacer : IMethodReplacer + { + private IConfigurableObjectDefinition objectDefinition; + private IObjectFactory objectFactory; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such has no + /// publicly visible constructors. + ///

+ ///
+ /// + /// The object definition that is the target of the method replacement. + /// + /// + /// The enclosing IoC container with which the above + /// is associated. + /// + /// + /// If either of the supplied arguments is . + /// + protected AbstractMethodReplacer( + IConfigurableObjectDefinition objectDefinition, IObjectFactory objectFactory) + { + AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); + AssertUtils.ArgumentNotNull(objectFactory, "objectFactory"); + this.objectDefinition = objectDefinition; + this.objectFactory = objectFactory; + } + + /// + /// Is ; derived classes must supply an implementation. + /// + /// + /// The instance whose is to be + /// (re)implemented. + /// + /// + /// The method that is to be (re)implemented. + /// + /// The target method's arguments. + /// The result of the object lookup. + public abstract object Implement(object target, MethodInfo method, object[] arguments); + + /// + /// Helper method for subclasses to retrieve the appropriate + /// for the + /// supplied . + /// + /// + /// The to use to retrieve + /// the appropriate + /// . + /// + /// + /// The appropriate + /// . + /// + protected MethodOverride GetOverride(MethodInfo method) + { + return this.objectDefinition.MethodOverrides.GetOverride(method); + } + + /// + /// Helper method for subclasses to lookup an object from an enclosing + /// IoC container. + /// + /// + /// The name of the object that is to be looked up. + /// + /// + /// The named object. + /// + protected object GetObject(string objectName) + { + return this.objectFactory.GetObject(objectName); + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinition.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinition.cs index 54728959..47c2de31 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinition.cs @@ -1,747 +1,746 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; -using System.Text; -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Common base class for object definitions, factoring out common - /// functionality from - /// and - /// . - /// - /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: AbstractObjectDefinition.cs,v 1.31 2007/08/27 13:57:43 oakinger Exp $ - [Serializable] - public abstract class AbstractObjectDefinition : IConfigurableObjectDefinition - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected AbstractObjectDefinition() : this(null, null) - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected AbstractObjectDefinition(ConstructorArgumentValues arguments, MutablePropertyValues properties) - { - constructorArgumentValues = - (arguments != null) ? arguments : new ConstructorArgumentValues(); - propertyValues = - (properties != null) ? properties : new MutablePropertyValues(); - eventHandlerValues = new EventValues(); - DependsOn = StringUtils.EmptyStrings; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The object definition used to initialise the member fields of this - /// instance. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- protected AbstractObjectDefinition(IObjectDefinition other) - { - AssertUtils.ArgumentNotNull(other, "other"); - AbstractObjectDefinition aod = other as AbstractObjectDefinition; - if (aod != null) - { - if (aod.HasObjectType) - { - ObjectType = other.ObjectType; - } - else - { - ObjectTypeName = other.ObjectTypeName; - } - MethodOverrides = new MethodOverrides(aod.MethodOverrides); - DependencyCheck = aod.DependencyCheck; - } - IsAbstract = other.IsAbstract; - IsSingleton = other.IsSingleton; - IsLazyInit = other.IsLazyInit; - ConstructorArgumentValues - = new ConstructorArgumentValues(other.ConstructorArgumentValues); - PropertyValues = new MutablePropertyValues(other.PropertyValues); - EventHandlerValues = new EventValues(other.EventHandlerValues); - - InitMethodName = other.InitMethodName; - DestroyMethodName = other.DestroyMethodName; - DependsOn = new string[other.DependsOn.Length]; - Array.Copy(other.DependsOn, DependsOn, other.DependsOn.Length); - FactoryMethodName = other.FactoryMethodName; - FactoryObjectName = other.FactoryObjectName; - AutowireMode = other.AutowireMode; - ResourceDescription = other.ResourceDescription; - } - - #endregion - - #region Properties - - /// - /// The property values that are to be applied to the object - /// upon creation. - /// - /// - ///

- /// Setting the value of this property to - /// will merely result in a new (and empty) - /// - /// collection being assigned to the property value. - ///

- ///
- /// - /// The property values (if any) for this object; may be an - /// empty collection but is guaranteed not to be - /// . - /// - public MutablePropertyValues PropertyValues - { - get { return propertyValues; } - set { propertyValues = value == null ? new MutablePropertyValues() : value; } - } - - /// - /// Does this definition have any - /// ? - /// - /// - /// if this definition has at least one - /// . - /// - public bool HasMethodOverrides - { - get { return !MethodOverrides.IsEmpty; } - } - - /// - /// The constructor argument values for this object. - /// - /// - ///

- /// Setting the value of this property to - /// will merely result in a new (and empty) - /// - /// collection being assigned. - ///

- ///
- /// - /// The constructor argument values (if any) for this object; may be an - /// empty collection but is guaranteed not to be - /// . - /// - public ConstructorArgumentValues ConstructorArgumentValues - { - get { return constructorArgumentValues; } - set { constructorArgumentValues = value == null ? new ConstructorArgumentValues() : value; } - } - - /// - /// The event handler values for this object. - /// - /// - ///

- /// Setting the value of this property to - /// will merely result in a new (and empty) - /// - /// collection being assigned. - ///

- ///
- /// - /// The event handler values (if any) for this object; may be an - /// empty collection but is guaranteed not to be - /// . - /// - public EventValues EventHandlerValues - { - get { return eventHandlerValues; } - set { eventHandlerValues = value == null ? new EventValues() : value; } - } - - /// - /// The method overrides (if any) for this object. - /// - /// - ///

- /// Setting the value of this property to - /// will merely result in a new (and empty) - /// - /// collection being assigned to the property value. - ///

- ///
- /// - /// The method overrides (if any) for this object; may be an - /// empty collection but is guaranteed not to be - /// . - /// - public MethodOverrides MethodOverrides - { - get { return methodOverrides; } - set { methodOverrides = value == null ? new MethodOverrides() : value; } - } - - /// - /// Is this definition a singleton, with - /// a single, shared instance returned on all calls to an enclosing - /// container (typically an - /// or - /// ). - /// - /// - ///

- /// If , an object factory will apply the - /// prototype design pattern, with each caller requesting an - /// instance getting an independent instance. How this is defined - /// will depend on the object factory implementation. singletons - /// are the commoner type. - ///

- ///
- /// - public virtual bool IsSingleton - { - get { return isSingleton; } - set - { - isSingleton = value; - isPrototype = !value; - } - } - - /// - /// Gets a value indicating whether this instance is prototype, with an independent instance - /// returned for each call. - /// - /// - /// true if this instance is prototype; otherwise, false. - /// - public virtual bool IsPrototype - { - get { return isPrototype; } - } - - /// - /// Is this object lazily initialized? - /// - ///

- /// Only applicable to a singleton object. - ///

- ///

- /// If , it will get instantiated on startup - /// by object factories that perform eager initialization of - /// singletons. - ///

- ///
- public bool IsLazyInit - { - get { return isLazyInit; } - set { isLazyInit = value; } - } - - /// - /// Is this object definition a "template", i.e. not meant to be instantiated - /// itself but rather just serving as an object definition for configuration - /// templates used by . - /// - /// - /// if this object definition is a "template". - /// - public bool IsTemplate - { - get - { - return ( - isAbstract || - (objectType == null && StringUtils.IsNullOrEmpty(factoryObjectName)) - ); - } - } - - /// - /// Is this object definition "abstract", i.e. not meant to be - /// instantiated itself but rather just serving as a parent for concrete - /// child object definitions. - /// - /// - /// if this object definition is "abstract". - /// - public bool IsAbstract - { - get { return isAbstract; } - set { isAbstract = value; } - } - - /// - /// The of the object definition (if any). - /// - /// - /// A resolved object . - /// - /// - /// If the of the object definition is not a - /// resolved or . - /// - /// - public Type ObjectType - { - get - { - if (!HasObjectType) - { - throw new ApplicationException( - "Object definition does not carry a resolved System.Type"); - } - return (Type) objectType; - } - set { objectType = value; } - } - - /// - /// Is the of the object definition a resolved - /// ? - /// - public bool HasObjectType - { - get { return objectType is Type; } - } - - /// - /// Returns the of the - /// of the object definition (if any). - /// - public string ObjectTypeName - { - get - { - if (objectType is Type) - { - return ((Type) objectType).FullName; - } - else - { - return objectType as string; - } - } - set { objectType = value; } - } - - /// - /// A description of the resource that this object definition - /// came from (for the purpose of showing context in case of errors). - /// - public string ResourceDescription - { - get { return resourceDescription; } - set { resourceDescription = value; } - } - - /// - /// The autowire mode as specified in the object definition. - /// - /// - ///

- /// This determines whether any automagical detection and setting of - /// object references will happen. The default is - /// , - /// which means that no autowiring will be performed. - ///

- ///
- public AutoWiringMode AutowireMode - { - get { return autowireMode; } - set { autowireMode = value; } - } - - /// - /// Gets the resolved autowire mode. - /// - /// - ///

- /// This resolves - /// - /// to one of - /// - /// or - /// . - ///

- ///
- public AutoWiringMode ResolvedAutowireMode - { - get - { - if (AutowireMode == AutoWiringMode.AutoDetect) - { - // Work out whether to apply setter autowiring or constructor autowiring. - // If it has a no-arg constructor it's deemed to be setter autowiring, - // otherwise we'll try constructor autowiring. - ConstructorInfo[] constructors = - ObjectType.GetConstructors(); - foreach (ConstructorInfo ctor in constructors) - { - if (ctor.GetParameters().Length == 0) - { - return AutoWiringMode.ByType; - } - } - return AutoWiringMode.Constructor; - } - else - { - return AutowireMode; - } - } - } - - /// - /// The dependency checking mode. - /// - /// - ///

- /// The default is - /// . - ///

- ///
- public DependencyCheckingMode DependencyCheck - { - get { return dependencyCheck; } - set { dependencyCheck = value; } - } - - /// - /// The object names that this object depends on. - /// - /// - ///

- /// The object factory will guarantee that these objects get initialized - /// before this object definition. - ///

- /// - /// Dependencies are normally expressed through object properties - /// or constructor arguments. This property should just be necessary for - /// other kinds of dependencies such as statics (*ugh*) or database - /// preparation on startup. - /// - ///
- public string[] DependsOn - { - get { return dependsOn; } - set { dependsOn = value == null ? StringUtils.EmptyStrings : value; } - } - - /// - /// The name of the initializer method. - /// - /// - ///

- /// The default value is the constant, - /// in which case there is no initializer method. - ///

- ///
- public string InitMethodName - { - get { return initMethodName; } - set { initMethodName = value; } - } - - /// - /// Return the name of the destroy method. - /// - /// - ///

- /// The default value is the constant, - /// in which case there is no destroy method. - ///

- ///
- public string DestroyMethodName - { - get { return destroyMethodName; } - set { destroyMethodName = value; } - } - - /// - /// The name of the factory method to use (if any). - /// - /// - ///

- /// This method will be invoked with constructor arguments, or with no - /// arguments if none are specified. The - /// method will be invoked on the specified - /// . - ///

- ///
- public string FactoryMethodName - { - get { return factoryMethodName; } - set { factoryMethodName = value; } - } - - /// - /// The name of the factory object to use (if any). - /// - public string FactoryObjectName - { - get { return factoryObjectName; } - set { factoryObjectName = value; } - } - - /// - /// Does this object definition have any constructor argument values? - /// - /// - /// if his object definition has at least one - /// element in it's - /// - /// property. - /// - public virtual bool HasConstructorArgumentValues - { - get - { - return ConstructorArgumentValues != null - && !ConstructorArgumentValues.Empty; - } - } - - #endregion - - #region Methods - - /// - /// Resolves the type of the object, resolving it from a specified - /// object type name if necessary. - /// - /// - /// A resolved instance. - /// - /// - /// If the type cannot be resolved. - /// - public Type ResolveObjectType() - { - string typeName = ObjectTypeName; - if (typeName == null) - { - return null; - } - Type resolvedType = TypeResolutionUtils.ResolveType(typeName); - this.ObjectType = resolvedType; - return resolvedType; - } - - /// - /// Validate this object definition. - /// - /// - /// In the case of a validation failure. - /// - public virtual void Validate() - { - if (IsLazyInit && !IsSingleton) - { - throw new ObjectDefinitionValidationException( - "Lazy initialization is only applicable to singleton objects."); - } - if (HasMethodOverrides && StringUtils.HasText(FactoryMethodName)) - { - throw new ObjectDefinitionValidationException( - "Cannot combine static factory method with method overrides: " + - "the static factory method must create the instance."); - } - if (HasObjectType) - { - PrepareMethodOverrides(); - } - } - - /// - /// Validates all - /// - public virtual void PrepareMethodOverrides() - { - // ascertain that the various lookup methods exist... - foreach (MethodOverride mo in MethodOverrides.Overrides) - { - PrepareMethodOverride(mo); - } - } - - /// - /// Validate the supplied . - /// - /// - /// The - /// to be validated. - /// - protected void PrepareMethodOverride(MethodOverride methodOverride) - { - if (!ReflectionUtils.HasAtLeastOneMethodWithName(ObjectType, methodOverride.MethodName)) - { - throw new ObjectDefinitionValidationException( - string.Format( - CultureInfo.InvariantCulture, - "Invalid method override: no method with name '{0}' on class [{1}].", - methodOverride.MethodName, ObjectTypeName)); - } - //TODO investigate setting overloaded at this point using MethodCountForName... - //Test SunnyDayReplaceMethod_WithArgumentAcceptingReplacerWithNoTypeFragmentsSpecified - // will fail if doing this optimization. - } - - /// - /// Override settings in this object definition from the supplied - /// object definition. - /// - /// - /// The object definition used to override the member fields of this instance. - /// - public virtual void OverrideFrom(IObjectDefinition other) - { - AbstractObjectDefinition aod = other as AbstractObjectDefinition; - if (aod != null) - { - if (aod.HasObjectType) - { - ObjectType = other.ObjectType; - } - MethodOverrides.AddAll(aod.MethodOverrides); - DependencyCheck = aod.DependencyCheck; - } - IsAbstract = other.IsAbstract; - IsSingleton = other.IsSingleton; - IsLazyInit = other.IsLazyInit; - ConstructorArgumentValues.AddAll(other.ConstructorArgumentValues); - PropertyValues.AddAll(other.PropertyValues.PropertyValues); - EventHandlerValues.AddAll(other.EventHandlerValues); - if (StringUtils.HasText(other.InitMethodName)) - { - InitMethodName = other.InitMethodName; - } - if (StringUtils.HasText(other.DestroyMethodName)) - { - DestroyMethodName = other.DestroyMethodName; - } - if (StringUtils.HasText(other.FactoryObjectName)) - { - FactoryObjectName = other.FactoryObjectName; - } - if (StringUtils.HasText(other.FactoryMethodName)) - { - FactoryMethodName = other.FactoryMethodName; - } - DependsOn = new string[other.DependsOn.Length]; - Array.Copy(other.DependsOn, DependsOn, other.DependsOn.Length); - AutowireMode = other.AutowireMode; - ResourceDescription = other.ResourceDescription; - } - - /// - /// Returns a that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - StringBuilder buffer = new StringBuilder(); - buffer.Append("Abstract = ").Append(IsAbstract); - buffer.Append("; Singleton = ").Append(IsSingleton); - buffer.Append("; LazyInit = ").Append(IsLazyInit); - buffer.Append("; Autowire = ").Append(AutowireMode); - buffer.Append("; DependencyCheck = ").Append(DependencyCheck); - buffer.Append("; InitMethodName = ").Append(InitMethodName); - buffer.Append("; DestroyMethodName = ").Append(DestroyMethodName); - buffer.Append("; FactoryMethodName = ").Append(FactoryMethodName); - buffer.Append("; FactoryObjectName = ").Append(FactoryObjectName); - if (StringUtils.HasText(ResourceDescription)) - { - buffer.Append("; defined in = ").Append(ResourceDescription); - } - return buffer.ToString(); - } - - #endregion - - #region Fields - - private ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); - private MutablePropertyValues propertyValues = new MutablePropertyValues(); - private EventValues eventHandlerValues = new EventValues(); - private MethodOverrides methodOverrides = new MethodOverrides(); - private string resourceDescription = string.Empty; - private bool isSingleton = true; - private bool isPrototype = false; - private bool isLazyInit = false; - private bool isAbstract = false; - private object objectType; - private AutoWiringMode autowireMode = AutoWiringMode.No; - private DependencyCheckingMode dependencyCheck = DependencyCheckingMode.None; - private string[] dependsOn; - private string initMethodName = string.Empty; - private string destroyMethodName = string.Empty; - private string factoryMethodName = string.Empty; - private string factoryObjectName = string.Empty; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; +using System.Text; +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Common base class for object definitions, factoring out common + /// functionality from + /// and + /// . + /// + /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public abstract class AbstractObjectDefinition : IConfigurableObjectDefinition + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected AbstractObjectDefinition() : this(null, null) + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected AbstractObjectDefinition(ConstructorArgumentValues arguments, MutablePropertyValues properties) + { + constructorArgumentValues = + (arguments != null) ? arguments : new ConstructorArgumentValues(); + propertyValues = + (properties != null) ? properties : new MutablePropertyValues(); + eventHandlerValues = new EventValues(); + DependsOn = StringUtils.EmptyStrings; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The object definition used to initialise the member fields of this + /// instance. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ protected AbstractObjectDefinition(IObjectDefinition other) + { + AssertUtils.ArgumentNotNull(other, "other"); + AbstractObjectDefinition aod = other as AbstractObjectDefinition; + if (aod != null) + { + if (aod.HasObjectType) + { + ObjectType = other.ObjectType; + } + else + { + ObjectTypeName = other.ObjectTypeName; + } + MethodOverrides = new MethodOverrides(aod.MethodOverrides); + DependencyCheck = aod.DependencyCheck; + } + IsAbstract = other.IsAbstract; + IsSingleton = other.IsSingleton; + IsLazyInit = other.IsLazyInit; + ConstructorArgumentValues + = new ConstructorArgumentValues(other.ConstructorArgumentValues); + PropertyValues = new MutablePropertyValues(other.PropertyValues); + EventHandlerValues = new EventValues(other.EventHandlerValues); + + InitMethodName = other.InitMethodName; + DestroyMethodName = other.DestroyMethodName; + DependsOn = new string[other.DependsOn.Length]; + Array.Copy(other.DependsOn, DependsOn, other.DependsOn.Length); + FactoryMethodName = other.FactoryMethodName; + FactoryObjectName = other.FactoryObjectName; + AutowireMode = other.AutowireMode; + ResourceDescription = other.ResourceDescription; + } + + #endregion + + #region Properties + + /// + /// The property values that are to be applied to the object + /// upon creation. + /// + /// + ///

+ /// Setting the value of this property to + /// will merely result in a new (and empty) + /// + /// collection being assigned to the property value. + ///

+ ///
+ /// + /// The property values (if any) for this object; may be an + /// empty collection but is guaranteed not to be + /// . + /// + public MutablePropertyValues PropertyValues + { + get { return propertyValues; } + set { propertyValues = value == null ? new MutablePropertyValues() : value; } + } + + /// + /// Does this definition have any + /// ? + /// + /// + /// if this definition has at least one + /// . + /// + public bool HasMethodOverrides + { + get { return !MethodOverrides.IsEmpty; } + } + + /// + /// The constructor argument values for this object. + /// + /// + ///

+ /// Setting the value of this property to + /// will merely result in a new (and empty) + /// + /// collection being assigned. + ///

+ ///
+ /// + /// The constructor argument values (if any) for this object; may be an + /// empty collection but is guaranteed not to be + /// . + /// + public ConstructorArgumentValues ConstructorArgumentValues + { + get { return constructorArgumentValues; } + set { constructorArgumentValues = value == null ? new ConstructorArgumentValues() : value; } + } + + /// + /// The event handler values for this object. + /// + /// + ///

+ /// Setting the value of this property to + /// will merely result in a new (and empty) + /// + /// collection being assigned. + ///

+ ///
+ /// + /// The event handler values (if any) for this object; may be an + /// empty collection but is guaranteed not to be + /// . + /// + public EventValues EventHandlerValues + { + get { return eventHandlerValues; } + set { eventHandlerValues = value == null ? new EventValues() : value; } + } + + /// + /// The method overrides (if any) for this object. + /// + /// + ///

+ /// Setting the value of this property to + /// will merely result in a new (and empty) + /// + /// collection being assigned to the property value. + ///

+ ///
+ /// + /// The method overrides (if any) for this object; may be an + /// empty collection but is guaranteed not to be + /// . + /// + public MethodOverrides MethodOverrides + { + get { return methodOverrides; } + set { methodOverrides = value == null ? new MethodOverrides() : value; } + } + + /// + /// Is this definition a singleton, with + /// a single, shared instance returned on all calls to an enclosing + /// container (typically an + /// or + /// ). + /// + /// + ///

+ /// If , an object factory will apply the + /// prototype design pattern, with each caller requesting an + /// instance getting an independent instance. How this is defined + /// will depend on the object factory implementation. singletons + /// are the commoner type. + ///

+ ///
+ /// + public virtual bool IsSingleton + { + get { return isSingleton; } + set + { + isSingleton = value; + isPrototype = !value; + } + } + + /// + /// Gets a value indicating whether this instance is prototype, with an independent instance + /// returned for each call. + /// + /// + /// true if this instance is prototype; otherwise, false. + /// + public virtual bool IsPrototype + { + get { return isPrototype; } + } + + /// + /// Is this object lazily initialized? + /// + ///

+ /// Only applicable to a singleton object. + ///

+ ///

+ /// If , it will get instantiated on startup + /// by object factories that perform eager initialization of + /// singletons. + ///

+ ///
+ public bool IsLazyInit + { + get { return isLazyInit; } + set { isLazyInit = value; } + } + + /// + /// Is this object definition a "template", i.e. not meant to be instantiated + /// itself but rather just serving as an object definition for configuration + /// templates used by . + /// + /// + /// if this object definition is a "template". + /// + public bool IsTemplate + { + get + { + return ( + isAbstract || + (objectType == null && StringUtils.IsNullOrEmpty(factoryObjectName)) + ); + } + } + + /// + /// Is this object definition "abstract", i.e. not meant to be + /// instantiated itself but rather just serving as a parent for concrete + /// child object definitions. + /// + /// + /// if this object definition is "abstract". + /// + public bool IsAbstract + { + get { return isAbstract; } + set { isAbstract = value; } + } + + /// + /// The of the object definition (if any). + /// + /// + /// A resolved object . + /// + /// + /// If the of the object definition is not a + /// resolved or . + /// + /// + public Type ObjectType + { + get + { + if (!HasObjectType) + { + throw new ApplicationException( + "Object definition does not carry a resolved System.Type"); + } + return (Type) objectType; + } + set { objectType = value; } + } + + /// + /// Is the of the object definition a resolved + /// ? + /// + public bool HasObjectType + { + get { return objectType is Type; } + } + + /// + /// Returns the of the + /// of the object definition (if any). + /// + public string ObjectTypeName + { + get + { + if (objectType is Type) + { + return ((Type) objectType).FullName; + } + else + { + return objectType as string; + } + } + set { objectType = value; } + } + + /// + /// A description of the resource that this object definition + /// came from (for the purpose of showing context in case of errors). + /// + public string ResourceDescription + { + get { return resourceDescription; } + set { resourceDescription = value; } + } + + /// + /// The autowire mode as specified in the object definition. + /// + /// + ///

+ /// This determines whether any automagical detection and setting of + /// object references will happen. The default is + /// , + /// which means that no autowiring will be performed. + ///

+ ///
+ public AutoWiringMode AutowireMode + { + get { return autowireMode; } + set { autowireMode = value; } + } + + /// + /// Gets the resolved autowire mode. + /// + /// + ///

+ /// This resolves + /// + /// to one of + /// + /// or + /// . + ///

+ ///
+ public AutoWiringMode ResolvedAutowireMode + { + get + { + if (AutowireMode == AutoWiringMode.AutoDetect) + { + // Work out whether to apply setter autowiring or constructor autowiring. + // If it has a no-arg constructor it's deemed to be setter autowiring, + // otherwise we'll try constructor autowiring. + ConstructorInfo[] constructors = + ObjectType.GetConstructors(); + foreach (ConstructorInfo ctor in constructors) + { + if (ctor.GetParameters().Length == 0) + { + return AutoWiringMode.ByType; + } + } + return AutoWiringMode.Constructor; + } + else + { + return AutowireMode; + } + } + } + + /// + /// The dependency checking mode. + /// + /// + ///

+ /// The default is + /// . + ///

+ ///
+ public DependencyCheckingMode DependencyCheck + { + get { return dependencyCheck; } + set { dependencyCheck = value; } + } + + /// + /// The object names that this object depends on. + /// + /// + ///

+ /// The object factory will guarantee that these objects get initialized + /// before this object definition. + ///

+ /// + /// Dependencies are normally expressed through object properties + /// or constructor arguments. This property should just be necessary for + /// other kinds of dependencies such as statics (*ugh*) or database + /// preparation on startup. + /// + ///
+ public string[] DependsOn + { + get { return dependsOn; } + set { dependsOn = value == null ? StringUtils.EmptyStrings : value; } + } + + /// + /// The name of the initializer method. + /// + /// + ///

+ /// The default value is the constant, + /// in which case there is no initializer method. + ///

+ ///
+ public string InitMethodName + { + get { return initMethodName; } + set { initMethodName = value; } + } + + /// + /// Return the name of the destroy method. + /// + /// + ///

+ /// The default value is the constant, + /// in which case there is no destroy method. + ///

+ ///
+ public string DestroyMethodName + { + get { return destroyMethodName; } + set { destroyMethodName = value; } + } + + /// + /// The name of the factory method to use (if any). + /// + /// + ///

+ /// This method will be invoked with constructor arguments, or with no + /// arguments if none are specified. The + /// method will be invoked on the specified + /// . + ///

+ ///
+ public string FactoryMethodName + { + get { return factoryMethodName; } + set { factoryMethodName = value; } + } + + /// + /// The name of the factory object to use (if any). + /// + public string FactoryObjectName + { + get { return factoryObjectName; } + set { factoryObjectName = value; } + } + + /// + /// Does this object definition have any constructor argument values? + /// + /// + /// if his object definition has at least one + /// element in it's + /// + /// property. + /// + public virtual bool HasConstructorArgumentValues + { + get + { + return ConstructorArgumentValues != null + && !ConstructorArgumentValues.Empty; + } + } + + #endregion + + #region Methods + + /// + /// Resolves the type of the object, resolving it from a specified + /// object type name if necessary. + /// + /// + /// A resolved instance. + /// + /// + /// If the type cannot be resolved. + /// + public Type ResolveObjectType() + { + string typeName = ObjectTypeName; + if (typeName == null) + { + return null; + } + Type resolvedType = TypeResolutionUtils.ResolveType(typeName); + this.ObjectType = resolvedType; + return resolvedType; + } + + /// + /// Validate this object definition. + /// + /// + /// In the case of a validation failure. + /// + public virtual void Validate() + { + if (IsLazyInit && !IsSingleton) + { + throw new ObjectDefinitionValidationException( + "Lazy initialization is only applicable to singleton objects."); + } + if (HasMethodOverrides && StringUtils.HasText(FactoryMethodName)) + { + throw new ObjectDefinitionValidationException( + "Cannot combine static factory method with method overrides: " + + "the static factory method must create the instance."); + } + if (HasObjectType) + { + PrepareMethodOverrides(); + } + } + + /// + /// Validates all + /// + public virtual void PrepareMethodOverrides() + { + // ascertain that the various lookup methods exist... + foreach (MethodOverride mo in MethodOverrides.Overrides) + { + PrepareMethodOverride(mo); + } + } + + /// + /// Validate the supplied . + /// + /// + /// The + /// to be validated. + /// + protected void PrepareMethodOverride(MethodOverride methodOverride) + { + if (!ReflectionUtils.HasAtLeastOneMethodWithName(ObjectType, methodOverride.MethodName)) + { + throw new ObjectDefinitionValidationException( + string.Format( + CultureInfo.InvariantCulture, + "Invalid method override: no method with name '{0}' on class [{1}].", + methodOverride.MethodName, ObjectTypeName)); + } + //TODO investigate setting overloaded at this point using MethodCountForName... + //Test SunnyDayReplaceMethod_WithArgumentAcceptingReplacerWithNoTypeFragmentsSpecified + // will fail if doing this optimization. + } + + /// + /// Override settings in this object definition from the supplied + /// object definition. + /// + /// + /// The object definition used to override the member fields of this instance. + /// + public virtual void OverrideFrom(IObjectDefinition other) + { + AbstractObjectDefinition aod = other as AbstractObjectDefinition; + if (aod != null) + { + if (aod.HasObjectType) + { + ObjectType = other.ObjectType; + } + MethodOverrides.AddAll(aod.MethodOverrides); + DependencyCheck = aod.DependencyCheck; + } + IsAbstract = other.IsAbstract; + IsSingleton = other.IsSingleton; + IsLazyInit = other.IsLazyInit; + ConstructorArgumentValues.AddAll(other.ConstructorArgumentValues); + PropertyValues.AddAll(other.PropertyValues.PropertyValues); + EventHandlerValues.AddAll(other.EventHandlerValues); + if (StringUtils.HasText(other.InitMethodName)) + { + InitMethodName = other.InitMethodName; + } + if (StringUtils.HasText(other.DestroyMethodName)) + { + DestroyMethodName = other.DestroyMethodName; + } + if (StringUtils.HasText(other.FactoryObjectName)) + { + FactoryObjectName = other.FactoryObjectName; + } + if (StringUtils.HasText(other.FactoryMethodName)) + { + FactoryMethodName = other.FactoryMethodName; + } + DependsOn = new string[other.DependsOn.Length]; + Array.Copy(other.DependsOn, DependsOn, other.DependsOn.Length); + AutowireMode = other.AutowireMode; + ResourceDescription = other.ResourceDescription; + } + + /// + /// Returns a that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + StringBuilder buffer = new StringBuilder(); + buffer.Append("Abstract = ").Append(IsAbstract); + buffer.Append("; Singleton = ").Append(IsSingleton); + buffer.Append("; LazyInit = ").Append(IsLazyInit); + buffer.Append("; Autowire = ").Append(AutowireMode); + buffer.Append("; DependencyCheck = ").Append(DependencyCheck); + buffer.Append("; InitMethodName = ").Append(InitMethodName); + buffer.Append("; DestroyMethodName = ").Append(DestroyMethodName); + buffer.Append("; FactoryMethodName = ").Append(FactoryMethodName); + buffer.Append("; FactoryObjectName = ").Append(FactoryObjectName); + if (StringUtils.HasText(ResourceDescription)) + { + buffer.Append("; defined in = ").Append(ResourceDescription); + } + return buffer.ToString(); + } + + #endregion + + #region Fields + + private ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); + private MutablePropertyValues propertyValues = new MutablePropertyValues(); + private EventValues eventHandlerValues = new EventValues(); + private MethodOverrides methodOverrides = new MethodOverrides(); + private string resourceDescription = string.Empty; + private bool isSingleton = true; + private bool isPrototype = false; + private bool isLazyInit = false; + private bool isAbstract = false; + private object objectType; + private AutoWiringMode autowireMode = AutoWiringMode.No; + private DependencyCheckingMode dependencyCheck = DependencyCheckingMode.None; + private string[] dependsOn; + private string initMethodName = string.Empty; + private string destroyMethodName = string.Empty; + private string factoryMethodName = string.Empty; + private string factoryObjectName = string.Empty; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs index 0f9e7222..1ce7974e 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs @@ -1,272 +1,271 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Common.Logging; -using Spring.Core.IO; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Abstract base class for object definition readers. - /// - /// - ///

- /// Provides common properties like the object registry to work on. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: AbstractObjectDefinitionReader.cs,v 1.14 2008/01/10 14:32:24 bbaia Exp $ - public abstract class AbstractObjectDefinitionReader : IObjectDefinitionReader - { - #region Constants - - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (AbstractObjectDefinitionReader)); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The - /// instance that this reader works on. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractObjectDefinitionReader(IObjectDefinitionRegistry registry) - : this(registry, AppDomain.CurrentDomain) - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The - /// instance that this reader works on. - /// - /// - /// The against which any class names - /// will be resolved into instances. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractObjectDefinitionReader( - IObjectDefinitionRegistry registry, - AppDomain domain) - { - AssertUtils.ArgumentNotNull(registry, "registry", "IObjectDefinitionRegistry must not be null"); - _registry = registry; - _domain = domain; - if (registry is IResourceLoader) - { - _resourceLoader = registry as IResourceLoader; - } - else - { - _resourceLoader = new ConfigurableResourceLoader(); - } - } - - #endregion - - #region Properties - - /// - /// Gets the - /// - /// instance that this reader works on. - /// - public IObjectDefinitionRegistry Registry - { - get { return _registry; } - } - - - /// - /// The to use for anonymous - /// objects (wihtout explicit object name specified). - /// - /// - public IObjectNameGenerator ObjectNameGenerator - { - get { return _objectNameGenerator; } - set - { - if (value != null) - { - _objectNameGenerator = value; - } - else - { - _objectNameGenerator = new DefaultObjectNameGenerator(); - } - } - } - - /// - /// The against which any class names - /// will be resolved into instances. - /// - public AppDomain Domain - { - get { return _domain; } - } - - - /// - /// Gets or sets the resource loader to use for resource locations. - /// - /// The resource loader. - public IResourceLoader ResourceLoader - { - get { return _resourceLoader; } - set { _resourceLoader = value; } - } - - #endregion - - #region Methods - - /// - /// Load object definitions from the supplied . - /// - /// - /// The resource for the object definitions that are to be loaded. - /// - /// - /// The number of object definitions that were loaded. - /// - /// - /// In the case of loading or parsing errors. - /// - public abstract int LoadObjectDefinitions(IResource resource); - - /// - /// Load object definitions from the supplied . - /// - /// - /// The resources for the object definitions that are to be loaded. - /// - /// - /// The number of object definitions found - /// - /// - /// In the case of loading or parsing errors. - /// - public int LoadObjectDefinitions(IResource[] resources) - { - AssertUtils.ArgumentNotNull(resources, "resources"); - int counter = 0; - foreach (IResource resource in resources) - { - counter += LoadObjectDefinitions(resource); - } - return counter; - } - - /// - /// Loads the object definitions from the specified resource location. - /// - /// The resource location, to be loaded with the - /// IResourceLoader location . - /// - /// The number of object definitions found - /// - public int LoadObjectDefinitions(string location) - { - if (ResourceLoader == null) - { - throw new ObjectDefinitionStoreException("Cannot import object definitions from location [" + location + - "]:" + - " no ResourceLoader available"); - } - IResource resource; - try - { - resource = ResourceLoader.GetResource(location); - } catch (Exception e) - { - throw new ObjectDefinitionStoreException("Could not resolve resource location [" + location + "]",e); - } - int loadCount = LoadObjectDefinitions(resource); - - if (log.IsDebugEnabled) - { - log.Debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); - } - return loadCount; - } - - - /// - /// Loads the object definitions from the specified resource locations. - /// - /// The the resource locations to be loaded with the - /// IResourceLoader of this object definition reader. - /// - /// The number of object definitions found - /// - public int LoadObjectDefinitions(string[] locations) - { - AssertUtils.ArgumentNotNull(locations, "location"); - int counter = 0; - foreach (string location in locations) - { - counter += LoadObjectDefinitions(location); - } - return counter; - } - - #endregion - - #region Fields - - private IObjectDefinitionRegistry _registry; - private AppDomain _domain; - private IResourceLoader _resourceLoader; - private IObjectNameGenerator _objectNameGenerator = new DefaultObjectNameGenerator(); - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Common.Logging; +using Spring.Core.IO; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Abstract base class for object definition readers. + /// + /// + ///

+ /// Provides common properties like the object registry to work on. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public abstract class AbstractObjectDefinitionReader : IObjectDefinitionReader + { + #region Constants + + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (AbstractObjectDefinitionReader)); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The + /// instance that this reader works on. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractObjectDefinitionReader(IObjectDefinitionRegistry registry) + : this(registry, AppDomain.CurrentDomain) + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The + /// instance that this reader works on. + /// + /// + /// The against which any class names + /// will be resolved into instances. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractObjectDefinitionReader( + IObjectDefinitionRegistry registry, + AppDomain domain) + { + AssertUtils.ArgumentNotNull(registry, "registry", "IObjectDefinitionRegistry must not be null"); + _registry = registry; + _domain = domain; + if (registry is IResourceLoader) + { + _resourceLoader = registry as IResourceLoader; + } + else + { + _resourceLoader = new ConfigurableResourceLoader(); + } + } + + #endregion + + #region Properties + + /// + /// Gets the + /// + /// instance that this reader works on. + /// + public IObjectDefinitionRegistry Registry + { + get { return _registry; } + } + + + /// + /// The to use for anonymous + /// objects (wihtout explicit object name specified). + /// + /// + public IObjectNameGenerator ObjectNameGenerator + { + get { return _objectNameGenerator; } + set + { + if (value != null) + { + _objectNameGenerator = value; + } + else + { + _objectNameGenerator = new DefaultObjectNameGenerator(); + } + } + } + + /// + /// The against which any class names + /// will be resolved into instances. + /// + public AppDomain Domain + { + get { return _domain; } + } + + + /// + /// Gets or sets the resource loader to use for resource locations. + /// + /// The resource loader. + public IResourceLoader ResourceLoader + { + get { return _resourceLoader; } + set { _resourceLoader = value; } + } + + #endregion + + #region Methods + + /// + /// Load object definitions from the supplied . + /// + /// + /// The resource for the object definitions that are to be loaded. + /// + /// + /// The number of object definitions that were loaded. + /// + /// + /// In the case of loading or parsing errors. + /// + public abstract int LoadObjectDefinitions(IResource resource); + + /// + /// Load object definitions from the supplied . + /// + /// + /// The resources for the object definitions that are to be loaded. + /// + /// + /// The number of object definitions found + /// + /// + /// In the case of loading or parsing errors. + /// + public int LoadObjectDefinitions(IResource[] resources) + { + AssertUtils.ArgumentNotNull(resources, "resources"); + int counter = 0; + foreach (IResource resource in resources) + { + counter += LoadObjectDefinitions(resource); + } + return counter; + } + + /// + /// Loads the object definitions from the specified resource location. + /// + /// The resource location, to be loaded with the + /// IResourceLoader location . + /// + /// The number of object definitions found + /// + public int LoadObjectDefinitions(string location) + { + if (ResourceLoader == null) + { + throw new ObjectDefinitionStoreException("Cannot import object definitions from location [" + location + + "]:" + + " no ResourceLoader available"); + } + IResource resource; + try + { + resource = ResourceLoader.GetResource(location); + } catch (Exception e) + { + throw new ObjectDefinitionStoreException("Could not resolve resource location [" + location + "]",e); + } + int loadCount = LoadObjectDefinitions(resource); + + if (log.IsDebugEnabled) + { + log.Debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); + } + return loadCount; + } + + + /// + /// Loads the object definitions from the specified resource locations. + /// + /// The the resource locations to be loaded with the + /// IResourceLoader of this object definition reader. + /// + /// The number of object definitions found + /// + public int LoadObjectDefinitions(string[] locations) + { + AssertUtils.ArgumentNotNull(locations, "location"); + int counter = 0; + foreach (string location in locations) + { + counter += LoadObjectDefinitions(location); + } + return counter; + } + + #endregion + + #region Fields + + private IObjectDefinitionRegistry _registry; + private AppDomain _domain; + private IResourceLoader _resourceLoader; + private IObjectNameGenerator _objectNameGenerator = new DefaultObjectNameGenerator(); + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs index 8fd9db1a..c8dcce93 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs @@ -1,1978 +1,1977 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.ComponentModel; - -using Common.Logging; - -using Spring.Collections; -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Abstract superclass for - /// implementations. - /// - /// - ///

- /// This class provides singleton / prototype determination, singleton caching, - /// object definition aliasing, - /// handling, and object definition merging for child object definitions. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: AbstractObjectFactory.cs,v 1.77 2008/05/29 12:13:27 oakinger Exp $ - [Serializable] - public abstract class AbstractObjectFactory : IConfigurableObjectFactory - { - /// - /// Marker object to be temporarily registered in the singleton cache, - /// while instantiating an object (in order to be able to detect circular references). - /// - private static readonly object CURRENTLY_IN_CREATION = new Object(); - - /// - /// The instance for this class. - /// - private readonly ILog log = LogManager.GetLogger(typeof(AbstractObjectFactory)); - - /// - /// Used as value in hashtable that keeps track of singleton names currently in the - /// process of being created. Would not be necessary if we created a case insensitive implementation of - /// ISet. - /// - private static object emptyObject = new object(); - - - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This constructor implicitly creates an - /// - /// that treats the names of objects in this factory in a case-sensitive fashion. - ///

- ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractObjectFactory() : this(true) - {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- /// - /// if the names of objects in this factory are to be treated in a - /// case-sensitive fashion. - /// - protected AbstractObjectFactory(bool caseSensitive) - { - this.log = LogManager.GetLogger(this.GetType()); - if (caseSensitive) - { - this.aliasMap = new SynchronizedHashtable(); - this.singletonCache = new Hashtable(); - this.singletonsInCreation = new Hashtable(); - } - else - { - this.aliasMap = new SynchronizedHashtable(CollectionsUtil.CreateCaseInsensitiveHashtable()); - this.singletonCache = CollectionsUtil.CreateCaseInsensitiveHashtable(); - this.singletonsInCreation = CollectionsUtil.CreateCaseInsensitiveHashtable(); - } - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- /// - /// if the names of objects in this factory are to be treated in a - /// case-sensitive fashion. - /// - /// - /// Any parent object factory; may be . - /// - protected AbstractObjectFactory(bool caseSensitive, IObjectFactory parentFactory) : this(caseSensitive) - { - ParentObjectFactory = parentFactory; - } - - #endregion - - #region Properties - - /// - /// Gets the of - /// s - /// that will be applied to objects created by this factory. - /// - public IList ObjectPostProcessors - { - get { return objectPostProcessors; } - } - - /// - /// Gets the set of classes that will be ignored for autowiring. - /// - /// - ///

- /// The elements of this are - /// s. - ///

- ///
- public ISet IgnoredDependencyTypes - { - get { return ignoreDependencyTypes; } - } - - /// - /// Returns, whether this object factory instance contains objects. - /// - protected bool HasInstantiationAwareBeanPostProcessors - { - get { return hasInstantiationAwareBeanPostProcessors; } - } - - /// - /// Returns, whether this object factory instance contains objects. - /// - protected bool HasDestructionAwareBeanPostProcessors - { - get { return hasDestructionAwareBeanPostProcessors; } - } - - #endregion - - #region Methods - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// - /// The the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a factory method. If there is no factory method and the - /// supplied array is not , then - /// match the argument values by type and call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the object is not of the required type. - /// - /// - /// If the supplied is . - /// - /// - public object GetObject(string name, Type requiredType, object[] arguments) - { - string objectName = TransformedObjectName(name); - object instance = null; - // eagerly check singleton cache for manually registered singletons... - object sharedInstance = GetSingleton(objectName); - - if (sharedInstance != null) - { - #region Instrumentation - - if (IsSingletonCurrentlyInCreation(objectName)) - { - if (log.IsDebugEnabled) - { - log.Debug("Returning eagerly cached instance of singleton object '" + objectName + - "' that is not fully initialized yet - a consequence of a circular reference"); - } - } - else - { - if (log.IsDebugEnabled) - { - log.Debug(string.Format("Returning cached instance of singleton object '{0}'.", objectName)); - } - } - - #endregion - - instance = GetObjectForInstance(name, sharedInstance); - } - else - { - // check if object definition exists - RootObjectDefinition mergedObjectDefinition = null; - mergedObjectDefinition = GetMergedObjectDefinition(objectName, false); - if (mergedObjectDefinition == null) - { - if (ParentObjectFactory != null) - { - return ParentObjectFactory.GetObject(name, requiredType, arguments); - } - throw new NoSuchObjectDefinitionException(name, "Cannot find definition for object [" + name + "]"); - } - - CheckMergedObjectDefinition(mergedObjectDefinition, objectName, requiredType, arguments); - - // return IObjectDefinition instance itself for an abstract object-definition - if (mergedObjectDefinition.IsAbstract) - { - instance = mergedObjectDefinition; - } - else if (mergedObjectDefinition.IsSingleton) - { - // create object instance... - sharedInstance = CreateAndCacheSingletonInstance(objectName, mergedObjectDefinition, arguments); - instance = GetObjectForInstance(name, sharedInstance); - } - else - { - // it's a prototype, so create a new instance... - instance = CreateObject(name, mergedObjectDefinition, arguments); - } - } - // check that any required type matches the type of the actual object instance... - if (requiredType != null && !requiredType.IsAssignableFrom(instance.GetType())) - { - throw new ObjectNotOfRequiredTypeException(name, requiredType, instance); - } - return instance; - } - - - - /// - /// Apply the property values of the object definition with the supplied - /// to the supplied . - /// - /// - ///

- /// The object definition can either define a fully self-contained object, - /// reusing it's property values, or just property values meant to be used - /// for existing object instances. - ///

- ///
- /// - /// The existing object that the property values for the named object will - /// be applied to. - /// - /// - /// The name of the object definition associated with the property values that are - /// to be applied. - /// - /// - /// In case of errors. - /// - public virtual void ApplyObjectPropertyValues(object instance, string name) - { - // explicit no-op... - } - - /// - /// Initializes the given with the - /// custom s registered with - /// this factory. - /// - /// - /// The to initialise. - /// - protected void InitObjectWrapper(IObjectWrapper wrapper) - { - } - - /// - /// Create an object instance for the given object definition. - /// - /// - ///

- /// The object definition will already have been merged with the parent - /// definition in case of a child definition. - ///

- ///

- /// All the other methods in this class invoke this method, although objects - /// may be cached after being instantiated by this method. All object - /// instantiation within this class is performed by this method. - ///

- ///
- /// The name of the object. - /// - /// The object definition for the object that is to be instantiated. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a factory method. If there is no factory method and the - /// supplied array is not , - /// then match the argument values by type and call the object's constructor. - /// - /// - /// A new instance of the object. - /// - /// - /// In case of errors. - /// - protected abstract object CreateObject(string name, RootObjectDefinition definition, object[] arguments); - - /// - /// Destroy the target object. - /// - /// - ///

- /// Must destroy objects that depend on the given object before the object itself, - /// nor throw an exception. - ///

- ///
- /// - /// The name of the object. - /// - /// - /// The target object instance to destroyed. - /// - protected abstract void DestroyObject(string name, object target); - - /// - /// Does this object factory contain an object definition with the - /// supplied ? - /// - /// - ///

- /// Does not consider any hierarchy this factory may participate in. - /// Invoked by - /// - /// when no cached singleton instance is found. - ///

- ///
- /// - /// The name of the object to look for. - /// - /// - /// if this object factory contains an object - /// definition with the supplied . - /// - public abstract bool ContainsObjectDefinition(string name); - - /// - /// Adds the supplied (object) to this factory's - /// singleton cache. - /// - /// - ///

- /// To be called for eager registration of singletons, e.g. to be able to - /// resolve circular references. - ///

- /// - /// If a singleton has already been registered under the same name as - /// the supplied , then the old singleton will - /// be replaced. - /// - ///
- /// The name of the object. - /// The singleton object. - /// - /// If the argument is - /// or consists wholly of whitespace characters; or if the - /// is . - /// - protected virtual void AddSingleton(string name, object singleton) - { - AssertUtils.ArgumentHasText(name, "The object name must not be empty."); - AssertUtils.ArgumentNotNull(singleton, "singleton"); - lock (singletonCache) - { - singletonCache[name] = singleton; - } - } - - /// - /// Return the object name, stripping out the factory dereference prefix if - /// necessary, and resolving aliases to canonical names. - /// - /// - /// The transformed name of the object. - /// - protected string TransformedObjectName(string name) - { - string objectName = ObjectFactoryUtils.TransformedObjectName(name); - // handle aliasing... - lock (aliasMap) - { - string canonicalName = (string) aliasMap[objectName]; - return canonicalName != null ? canonicalName : objectName; - } - } - - /// - /// Ensures, that the given name is prefixed with - /// if it incidentially already starts with this prefix. This avoids troubles when dereferencing - /// the object name during - /// - protected string OriginalObjectName(string name) - { - string objectName = TransformedObjectName(name); - if (name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix)) - { - objectName = ObjectFactoryUtils.FactoryObjectPrefix + objectName; - } - return objectName; - } - - /// - /// Determines whether the specified name is defined as an alias as opposed - /// to the name of an actual object definition. - /// - /// The object name to check. - /// - /// true if the specified name is alias; otherwise, false. - /// - protected bool IsAlias(string name) - { - lock (aliasMap) - { - return aliasMap.Contains(name); - } - } - - /// - /// Return a , - /// even by traversing parent if the parameter is a child definition. - /// - /// - /// The name of the object. - /// - /// - /// Are ancestors to be included in the merge? - /// - /// - ///

- /// Will ask the parent object factory if not found in this instance. - ///

- ///
- /// - /// A merged - /// with overridden properties. - /// - public virtual RootObjectDefinition GetMergedObjectDefinition(string name, bool includingAncestors) - { - return GetMergedObjectDefinition(name, GetObjectDefinition(name, includingAncestors)); - } - - /// - /// Return a , - /// even by traversing parent if the parameter is a child definition. - /// - /// - /// A merged - /// with overridden properties. - /// - protected virtual RootObjectDefinition GetMergedObjectDefinition(string name, IObjectDefinition definition) - { - if (definition == null) - { - return null; - } - else if (definition is RootObjectDefinition) - { - return (RootObjectDefinition) definition; - } - else if (definition is ChildObjectDefinition) - { - ChildObjectDefinition childDefinition = (ChildObjectDefinition) definition; - RootObjectDefinition parentDefinition = null; - if (!name.Equals(childDefinition.ParentName)) - { - parentDefinition = - GetMergedObjectDefinition(TransformedObjectName(childDefinition.ParentName), true); - } - else - { - if (ParentObjectFactory is AbstractObjectFactory) - { - parentDefinition = - ((AbstractObjectFactory) ParentObjectFactory).GetMergedObjectDefinition( - childDefinition.ParentName, true); - } - } - if (parentDefinition == null) - { - throw new NoSuchObjectDefinitionException(childDefinition.ParentName, - string.Format( - "Parent name '{0}' is equal to object name '{1}' - " - + - "cannot be resolved without an AbstractObjectFactory parent.", - childDefinition.ParentName, name)); - } - - RootObjectDefinition rootDefinition = CreateRootObjectDefinition(parentDefinition); - rootDefinition.OverrideFrom(childDefinition); - return rootDefinition; - } - else - { - throw new ObjectDefinitionStoreException(definition.ResourceDescription, name, - "Definition is neither a RootObjectDefinition nor a ChildObjectDefinition."); - } - } -/* - /// - /// Merges the object definitions. - /// - /// Object definition name. - /// The parent definition. - /// The child definition. - /// Merged object definition. - protected virtual RootObjectDefinition MergeObjectDefinitions(string name, IObjectDefinition parentDefinition, - IObjectDefinition childDefinition) - { - RootObjectDefinition rootDefinition = CreateRootObjectDefinition(parentDefinition); - rootDefinition.OverrideFrom(childDefinition); - return rootDefinition; - } -*/ - /// - /// Creates the root object definition. - /// - /// The template definition to base root definition on. - /// Root object definition. - protected virtual RootObjectDefinition CreateRootObjectDefinition(IObjectDefinition templateDefinition) - { - return new RootObjectDefinition(templateDefinition); - } - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - public abstract IObjectDefinition GetObjectDefinition(string name); - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// Whether to search parent object factories. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - public abstract IObjectDefinition GetObjectDefinition(string name, bool includeAncestors); - - /// - /// Gets the type for the given FactoryObject. - /// - /// The factory object instance to check. - /// the FactoryObject's object type - protected virtual Type GetTypeForFactoryObject(IFactoryObject factoryObject) - { - try - { - return factoryObject.ObjectType; - } - catch (Exception ex) - { - log.Warn("FactoryObject threw exception from ObjectType, despite the contract saying " + - "that it should return null if the type of its object cannot be determined yet", ex); - return null; - } - } - - /// - /// Gets the object type for the given FactoryObject definition, as far as possible. - /// Only called if there is no singleton instance registered for the target object already. - /// - /// - /// The default implementation creates the FactoryObject via GetObject - /// to call its ObjectType property. Subclasses are encouraged to optimize - /// this, typically by just instantiating the FactoryObject but not populating it yet, - /// trying whether its ObjectType property already returns a type. - /// If no type found, a full FactoryObject creation as performed by this implementation - /// should be used as fallback. - /// - /// Name of the object. - /// The merged object definition for the object. - /// The type for the object if determinable, or null otherwise - protected virtual Type GetTypeForFactoryObject(string objectName, RootObjectDefinition mod) - { - if (!mod.IsSingleton) - { - return null; - } - try - { - IFactoryObject factoryObject = GetFactoryObject(objectName); - return GetTypeForFactoryObject(factoryObject); - } catch (ObjectCreationException ex) - { - // Can only happen when getting a FactoryObject. - log.Debug("Ignoring object creation exception on FactoryObject type check", ex); - return null; - } - } - - /// - /// Predict the eventual object type (of the processed object instance) for the - /// specified object. - /// - /// - /// Does not need to handle FactoryObjects specifically, since it is only - /// supposed to operate on the raw object type. - /// This implementation is simplistic in that it is not able to - /// handle factory methods and InstantiationAwareBeanPostProcessors. - /// It only predicts the object type correctly for a standard object. - /// To be overridden in subclasses, applying more sophisticated type detection. - /// - /// Name of the object. - /// The merged object definition to determine the type for. - /// The type of the object, or null if not predictable - protected virtual Type PredictObjectType(string objectName, RootObjectDefinition mod) - { - if (StringUtils.HasText(mod.FactoryObjectName)) - { - return null; - } - return ResolveObjectType(mod, objectName); - } - - /// - /// Get the object for the given object instance, either the object - /// instance itself or its created object in case of an - /// . - /// - /// - /// The name that may include the factory dereference prefix. - /// - /// The object instance. - /// - /// The singleton instance of the object. - /// - protected virtual object GetObjectForInstance(string name, object instance) - { - //string objectName = TransformedObjectName(name); - - // don't let calling code try to dereference the - // object factory if the object isn't a factory - if (IsFactoryDereference(name) && !(instance is IFactoryObject)) - { - throw new ObjectIsNotAFactoryException(TransformedObjectName(name), instance); - } - - // now we have the object instance, which may be a normal object - // or an IFactoryObject. If it's an IFactoryObject, we use it to - // create an object instance, unless the caller actually wants - // a reference to the factory. - if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IFactoryObject), instance)) - { - if (!IsFactoryDereference(name)) - { - - // return object instance from factory... - IFactoryObject factory = (IFactoryObject) instance; - string objectName = TransformedObjectName(name); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format("Object with name '{0}' is a factory object.", objectName)); - } - - #endregion - - RootObjectDefinition rod = - (ContainsObjectDefinition(objectName) ? GetMergedObjectDefinition(objectName,true) : null); - instance = GetObjectFromFactoryObject(factory, objectName, rod); - - if (instance == null) - { - throw new FactoryObjectNotInitializedException(TransformedObjectName(name), - "Factory object returned null object - " - + "possible cause: not fully initialized due to " - + "circular object reference."); - } - } - else - { - // the user wants the factory itself... - if (log.IsDebugEnabled) - { - log.Debug( - string.Format("Calling code asked for IFactoryObject instance for name '{0}'.", - TransformedObjectName(name))); - } - } - } - return instance; - } - - /// - /// Obtain an object to expose from the given IFactoryObject. - /// - /// The IFactoryObject instance. - /// Name of the object. - /// The merged object definition. - /// The object obtained from the IFactoryObject - /// If IFactoryObject object creation failed. - private object GetObjectFromFactoryObject(IFactoryObject factory, string objectName, RootObjectDefinition rod) - { - object instance; - - try - { - instance = factory.GetObject(); - } - catch (FactoryObjectNotInitializedException ex) - { - throw new ObjectCurrentlyInCreationException( - rod.ResourceDescription, objectName, ex); - } - catch (Exception ex) - { - throw new ObjectCreationException(rod.ResourceDescription, objectName, - "FactoryObject threw exception on object creation.", ex); - } - - // Do not accept a null value for a FactoryBean that's not fully - // initialized yet: Many FactoryBeans just return null then. - if (instance == null && IsSingletonCurrentlyInCreation(objectName)) { - throw new ObjectCurrentlyInCreationException(rod.ResourceDescription, objectName, - "FactoryObject which is currently in creation returned null from GetObject."); - } - - if (factory is IConfigurableFactoryObject) - { - IConfigurableFactoryObject configurableFactory = (IConfigurableFactoryObject)factory; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format("Factory object with name '{0}' is configurable.", TransformedObjectName(objectName))); - } - - #endregion - - if (configurableFactory.ProductTemplate != null) - { - instance = ConfigureObject(instance, - String.Format("{0}.ProductTemplate", objectName), - configurableFactory.ProductTemplate); - } - } - - if (instance != null) - { - try - { - instance = PostProcessObjectFromFactoryObject(instance, objectName); - } - catch (Exception ex) { - throw new ObjectCreationException(rod.ResourceDescription, objectName, - "Post-processing of the FactoryObject's object failed.", ex); - } - } - - return instance; - } - - /// - /// Post-process the given object that has been obtained from the FactoryObject. - /// The resulting object will be exposed for object references. - /// - /// The default implementation simply returns the given object - /// as-is. Subclasses may override this, for example, to apply - /// post-processors. - /// The instance obtained from the IFactoryObject. - /// Name of the object. - /// The object instance to expose - /// if any post-processing failed. - protected virtual object PostProcessObjectFromFactoryObject(object instance, string objectName) - { - return instance; - } - - /// - /// Convenience method to pull an - /// from this factory. - /// - /// - /// The name of the factory object to be retrieved. If this name is not a valid - /// name, it will be converted - /// into one. - /// - /// - /// The associated with the - /// supplied . - /// - protected IFactoryObject GetFactoryObject(string objectName) - { - if (!ObjectFactoryUtils.IsFactoryDereference(objectName)) - { - objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); - } - return (IFactoryObject) GetObject(objectName); - } - - /// - /// Is the supplied a factory object dereference? - /// - protected bool IsFactoryDereference(string name) - { - return ObjectFactoryUtils.IsFactoryDereference(name); - } - - /// - /// Determines whether the type of the given object definition matches the - /// specified target type. - /// - /// Allows for lazy load of the actual object type, provided that the - /// type match can be determined otherwise. - /// The default implementation simply delegates to the standard - /// ResolveObjectType method. Subclasses may override this to use - /// a differnt strategy. - /// - /// Name of the object (for error handling purposes). - /// The merged object definition to determine the type for. - /// Type to match against (never null). - /// - /// true if object definition matches tye specified target type; otherwise, false. - /// - /// if we failed to load the type." - protected bool IsObjectTypeMatch(string objectName, RootObjectDefinition rod, Type targetType) - { - Type objectType = ResolveObjectType(rod, objectName); - return (objectType != null && targetType.IsAssignableFrom(objectType)); - } - - /// - /// Resolves the type of the object for the specified object definition resolving - /// an object type name to a Type (if necessary) and storing the resolved Type - /// in the object definition for further use. - /// - /// The merged object definition to dertermine the type for. - /// Name of the object (for error handling purposes). - /// - protected Type ResolveObjectType(RootObjectDefinition rod, string objectName) - { - try - { - if (rod.HasObjectType) - { - return rod.ObjectType; - } - return rod.ResolveObjectType(); - } catch (TypeLoadException e) - { - throw new CannotLoadObjectTypeException(rod.ResourceDescription, objectName, rod.ObjectTypeName, e); - } - } - - /// - /// Is the object (definition) with the supplied an - /// ? - /// - /// The name of the object to be checked. - /// - /// the object (definition) with the supplied - /// an ? - /// - protected bool IsFactoryObject(string name) - { - string objectName = TransformedObjectName(name); - object objectInstance = GetSingleton(objectName); - //TODO investigate - if (IsSingletonCurrentlyInCreation(name)) - { - throw new ObjectCurrentlyInCreationException(objectName); - } - - if (objectInstance != null) - { - return (objectInstance is IFactoryObject); - } - else - { - RootObjectDefinition definition = GetMergedObjectDefinition(objectName, false); - if (definition != null) - { - return (definition.HasObjectType && typeof(IFactoryObject).IsAssignableFrom(definition.ObjectType)); - } - else - { - if (parentObjectFactory != null) - { - return ((AbstractObjectFactory) parentObjectFactory).IsFactoryObject(name); - } - else - { - throw new NoSuchObjectDefinitionException(objectName, - "Cannot find definition for object [" + objectName - + "]"); - } - } - } - } - - /// - /// Remove the object identified by the supplied - /// from this factory's singleton cache. - /// - /// - /// The name of the object that is to be removed from the singleton - /// cache. - /// - /// - /// If the argument is or - /// consists wholly of whitespace characters. - /// - protected void RemoveSingleton(string name) - { - AssertUtils.ArgumentHasText(name, "name"); - lock (singletonCache) - { - this.singletonCache.Remove(name); - } - } - - /// - /// Return the names of objects in the singleton cache that match the given - /// object type (including subclasses). - /// - /// - /// The class or interface to match, or for all object names. - /// - /// - ///

- /// Will not consider s - /// as the type of their created objects is not known before instantiation. - ///

- ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- ///
- /// - /// The names of objects in the singleton cache that match the given - /// object type (including subclasses), or an empty array if none. - /// - public virtual string[] GetSingletonNames(Type type) - { - lock (singletonCache) - { - ArrayList matches = new ArrayList(); - foreach (string name in singletonCache.Keys) - { - object singletonObject = singletonCache[name]; - if (singletonObject != null && type.IsAssignableFrom(singletonObject.GetType()) - && !matches.Contains(name)) - { - matches.Add(name); - } - } - return (string[]) matches.ToArray(typeof(string)); - } - } - - /// - /// Determines whether the object with the given name matches the specified type. - /// - /// More specifically, check whether a GetObject call for the given name - /// would return an object that is assignable to the specified target type. - /// Translates aliases back to the corresponding canonical bean name. - /// Will ask the parent factory if the bean cannot be found in this factory instance. - /// - /// The name of the object to query. - /// Type of the target to match against. - /// - /// true if the object type matches; otherwise, false - /// if it doesn't match or cannot be determined yet. - /// - /// Ff there is no object with the given name - /// - public bool IsTypeMatch(string name, Type targetType) - { - string objectName = TransformedObjectName(name); - Type typeToMatch = (targetType != null ? targetType : typeof (object)); - - //Check manually registered singletons. - object objectInstance = GetSingleton(objectName); - if (objectInstance != null) - { - if (objectInstance is IFactoryObject) - { - if (!IsFactoryDereference(name)) - { - Type type = GetTypeForFactoryObject((IFactoryObject)objectInstance); - return (type != null && typeToMatch.IsAssignableFrom(type)); - } - else - { - return typeToMatch.IsAssignableFrom(objectInstance.GetType()); - } - } - else - { - return !IsFactoryDereference(name) && typeToMatch.IsAssignableFrom(objectInstance.GetType()); - } - } - else - { - // No singleton instance found -> check object definition - IObjectFactory parentFactory = ParentObjectFactory; - if (parentFactory != null && !ContainsObjectDefinition(name)) - { - // No object definition found in this factory -> delegate to parent - return parentFactory.IsTypeMatch(OriginalObjectName(name), targetType); - } - - RootObjectDefinition mod = GetMergedObjectDefinition(objectName, false); - Type objectType = PredictObjectType(objectName, mod); - - if (objectType == null) - { - return false; - } - - // Check object class whether we're dealing with a FactoryObject - if (typeof(IFactoryObject).IsAssignableFrom(objectType)) - { - if (!IsFactoryDereference(name)) - { - // If it's a FactoryObject, we want to look at what it creates, not the factory class. - Type type = GetTypeForFactoryObject(objectName, mod); - return (type != null && typeToMatch.IsAssignableFrom(type)); - } - else - { - return typeToMatch.IsAssignableFrom(objectType); - } - } - else - { - return !IsFactoryDereference(name) && typeToMatch.IsAssignableFrom(objectType); - } - } - } - - /// - /// Determines the of the object with the - /// supplied . - /// - /// - ///

- /// More specifically, checks the of object that - /// would return. - /// For an , returns the - /// of object that the - /// creates. - ///

- ///

- /// Please note that (prototype) objects created via a factory method or - /// objects are handled - /// slightly differently, in that we don't want to needlessly create - /// instances of such objects just to determine the - /// of object that they create. - ///

- ///
- /// The name of the object to query. - /// - /// The of the object or - /// if not determinable. - /// - public virtual Type GetType(string name) - { - string objectName = TransformedObjectName(name); - - // check manually registered singletons... - object objectInstance = GetSingleton(objectName); - - if (objectInstance != null) - { - IFactoryObject factoryObject = objectInstance as IFactoryObject; - if (factoryObject != null & !IsFactoryDereference(objectName)) - { - return GetTypeForFactoryObject(factoryObject); - } - else - { - return objectInstance.GetType(); - } - } - else - { - // No singleton instance found -> check bean definition. - IObjectFactory parentFactory = ParentObjectFactory; - if (parentFactory != null && !ContainsObjectDefinition(objectName)) - { - // No bean definition found in this factory -> delegate to parent. - return parentFactory.GetType(this.OriginalObjectName(name)); - } - - RootObjectDefinition mod = this.GetMergedObjectDefinition(objectName, false); - Type objectType = PredictObjectType(objectName, mod); - - if (objectType != null && typeof (IFactoryObject).IsAssignableFrom(objectType)) - { - if (!IsFactoryDereference(name)) - { - // If it's a FactoryBean, we want to look at what it creates, not the factory class. - return GetTypeForFactoryObject(objectName, mod); - } - else - { - return objectType; - } - } - else - { - return (!IsFactoryDereference(name) ? objectType : null); - } - } - } - - /// - /// Determines the of the object defined - /// by the supplied object . - /// - /// - ///

- /// This, the default, implementation returns - /// to indicate that the type cannot be determined. Subclasses are - /// encouraged to try to determine the actual return - /// here, matching their strategy of resolving - /// factory methods in the - /// - /// implementation. - ///

- ///
- /// - /// The name associated with the supplied object . - /// - /// - /// The - /// that the is to be determined for. - /// - /// - /// The of the object defined by the supplied - /// object ; or if the - /// cannot be determined. - /// - protected virtual Type GetTypeForFactoryMethod(string objectName, RootObjectDefinition definition) - { - return null; - } - - /// - /// Returns the names of the objects in the singleton cache. - /// - /// - ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- ///
- /// The names of the objects in the singleton cache. - public virtual string[] GetSingletonNames() - { - lock (singletonCache) - { - return (string[]) new ArrayList(singletonCache.Keys).ToArray(typeof(string)); - } - } - - /// - /// Returns the number of objects in the singleton cache. - /// - /// - ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- ///
- /// The number of objects in the singleton cache. - public virtual int GetSingletonCount() - { - lock (singletonCache) - { - return singletonCache.Count; - } - } - - /// - /// Destroys the named singleton object. - /// - /// - ///

- /// Delegates to - /// - /// if a corresponding singleton instance is found. - ///

- ///
- /// - /// The name of the singleton object that is to be destroyed. - /// - /// - protected virtual void DestroySingleton(string name) - { - lock (singletonCache) - { - object tempObject = singletonCache[name]; - singletonCache.Remove(name); - - object singletonInstance = tempObject; - if (singletonInstance != null) - { - DestroyObject(name, singletonInstance); - } - } - } - - /// - /// Check the supplied merged object definition for any possible - /// validation errors. - /// - /// - /// The object definition to be checked for validation errors. - /// - /// - /// The name of the object associated with the supplied object definition. - /// - /// - /// The the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a factory method. If there is no factory method and the - /// supplied array is not , then - /// match the argument values by type and call the object's constructor. - /// - /// - /// In the case of object validation errors. - /// - protected void CheckMergedObjectDefinition(RootObjectDefinition mergedObjectDefinition, String objectName, - Type requiredType, params object[] arguments) - { - // check if required type can match according to the object definition; - // this is only possible at this early stage for conventional objects! - if (mergedObjectDefinition.HasObjectType) - { - Type objectType = mergedObjectDefinition.ObjectType; - if (requiredType != null && StringUtils.IsNullOrEmpty(mergedObjectDefinition.FactoryMethodName) - && !typeof(IFactoryObject).IsAssignableFrom(objectType) - && !requiredType.IsAssignableFrom(objectType)) - { - throw new ObjectNotOfRequiredTypeException(objectName, requiredType, objectType); - } - } - // check validity of the usage of the args parameter; this can - // only be used for prototypes constructed via a factory method... - if (arguments != null && arguments.Length > 0) - { - if (mergedObjectDefinition.IsSingleton) - { - throw new ObjectDefinitionStoreException("Cannot specify arguments in the GetObject () method when " - + "referring to a singleton object definition."); - } - //MLP lets skip this check for now. - /* - else if (StringUtils.IsNullOrEmpty(mergedObjectDefinition.FactoryMethodName)) - { - throw new ObjectDefinitionStoreException( - "Can only specify arguments in the GetObject () method in " + - "conjunction with a factory method."); - } - */ - } - } - - /// - /// Gets the temporary object that is placed - /// into the singleton cache during object resolution. - /// - protected object TemporarySingletonPlaceHolder - { - get { return CURRENTLY_IN_CREATION; } - } - - #endregion - - #region Fields - - /// - /// Parent object factory, for object inheritance support - /// - private IObjectFactory parentObjectFactory; - - /// - /// Dependency types to ignore on dependency check and autowire, as Set of - /// Type objects: for example, string. Default is none. - /// - private ISet ignoreDependencyTypes = new HybridSet(); - - - /// - /// ObjectPostProcessors to apply in CreateObject - /// - private IList objectPostProcessors = new ArrayList(); - - /// - /// Indicates whether any IInstantiationAwareBeanPostProcessors have been registered - /// - private bool hasInstantiationAwareBeanPostProcessors; - - /// - /// Indicates whether any IDestructionAwareBeanPostProcessors have been registered - /// - private bool hasDestructionAwareBeanPostProcessors; - - private IDictionary aliasMap; - private IDictionary singletonCache; - private IDictionary singletonsInCreation; - - #endregion - - #region IHierarchicalObjectFactory Members - - /// - /// The parent object factory, or if there is none. - /// - /// - /// The parent object factory, or if there is none. - /// - public IObjectFactory ParentObjectFactory - { - get { return parentObjectFactory; } - set { parentObjectFactory = value; } - } - - #endregion - - #region IObjectFactory Members - - /// - /// Is this object a singleton? - /// - /// - public bool IsSingleton(string name) - { - string objectName = TransformedObjectName(name); - object objectInstance = this.GetSingleton(objectName); - if (objectInstance != null) - { - IFactoryObject factoryObject = objectInstance as IFactoryObject; - if (factoryObject != null) - { - return IsFactoryDereference(name) || factoryObject.IsSingleton; - } - else - { - return !IsFactoryDereference(name); - } - } - else - { - // No singleton instance found -> check object definition - IObjectFactory pof = ParentObjectFactory; - if (pof != null && !ContainsObjectDefinition(objectName)) - { - // No object definition found in this factory -> delegate to parent - return pof.IsSingleton(OriginalObjectName(name)); - } - RootObjectDefinition od = GetMergedObjectDefinition(objectName, false); - - // In case of IFactoryObject, return singleton status of created object if not a dereference - if (od.IsSingleton) - { - if (IsObjectTypeMatch(objectName, od, typeof(IFactoryObject))) - { - if (IsFactoryDereference(name)) - { - return true; - } - IFactoryObject factoryObject = - (IFactoryObject) GetObject(ObjectFactoryUtils.BuildFactoryObjectName(objectName)); - return factoryObject.IsSingleton; - } - else - { - return !IsFactoryDereference(name); - } - } - else - { - return false; - } - } - } - - /// - /// Determines whether the specified object name is prototype. That is, will GetObject - /// always return independent instances? - /// - /// The name of the object to query - /// - /// true if the specified object name will always deliver independent instances; otherwise, false. - /// - /// This method returning false does not clearly indicate a singleton object. - /// It indicated non-independent instances, which may correspond to a scoped object as - /// well. use the IsSingleton property to explicitly check for a shared - /// singleton instance. - /// Translates aliases back to the corresponding canonical object name. Will ask the - /// parent factory if the object can not be found in this factory instance. - /// - /// - /// if there is no object with the given name. - public bool IsPrototype(string name) - { - string objectName = TransformedObjectName(name); - IObjectFactory parentFactory = ParentObjectFactory; - if (parentFactory != null && !this.ContainsObjectDefinition(objectName)) - { - // No object definition found in this factory -> delegate to parent - return parentFactory.IsPrototype(OriginalObjectName(name)); - } - - RootObjectDefinition od = GetMergedObjectDefinition(objectName, false); - - // In case of FactoryObject, return singleton status of created object if not a dereference - if (od.IsPrototype) - { - return (!IsFactoryDereference(name) || IsObjectTypeMatch(objectName, od, typeof(IFactoryObject))); - } - else - { - // not a prototype, however factory object may still produce a prototype object - if (IsFactoryDereference(name) && IsObjectTypeMatch(objectName, od, typeof (IFactoryObject))) - { - IFactoryObject factoryObject = GetFactoryObject(objectName); - return (!factoryObject.IsSingleton); - } - else - { - return false; - } - } - } - - /// - /// Does this object factory contain an object with the given name? - /// - /// - /// This method does not (and it should not) check if the specified - /// object exists in one of the parent object factories. If it did, - /// message sources and event registries within application context - /// hierarchy would have circular references, which would cause stack - /// overflows during message lookup, for example. (A. Seovic) - /// - /// . - public bool ContainsObject(string name) - { - string objectName = TransformedObjectName(name); - lock (singletonCache) - { - if (singletonCache.Contains(objectName)) - { - return true; - } - } - if (ContainsObjectDefinition(objectName)) - { - return true; - } - else - { - return false; - } - } - - /// - /// Return the aliases for the given object name, if defined. - /// - /// . - public string[] GetAliases(string name) - { - string objectName = TransformedObjectName(name); - // check if object actually exists in this object factory... - bool isInSingletonCache = false; - lock(singletonCache) - { - isInSingletonCache = singletonCache.Contains(objectName); - } - if (isInSingletonCache || ContainsObjectDefinition(objectName)) - { - // if found, gather aliases... - ArrayList matches = new ArrayList(); - lock (aliasMap) - { - foreach (DictionaryEntry aliasEntry in aliasMap) - { - if (aliasEntry.Value.Equals(objectName)) - { - matches.Add(aliasEntry.Key); - } - } - } - return (string[]) matches.ToArray(typeof(string)); - } - else - { - // not found, so check parent... - if (ParentObjectFactory != null) - { - return ParentObjectFactory.GetAliases(objectName); - } - throw new NoSuchObjectDefinitionException(objectName, ToString()); - } - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// . - public object this[string name] - { - get { return GetObject(name); } - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// . - public object GetObject(string name) - { - return GetObject(name, typeof(object), ObjectUtils.EmptyObjects); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to return. - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. If there is no factory method and the - /// arguments are not null, then match the argument values by type and - /// call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the supplied is . - /// - public object GetObject(string name, object[] arguments) - { - object instance = null; - string objectName = TransformedObjectName(name); - - // check if object definition exists - RootObjectDefinition mergedObjectDefinition = null; - mergedObjectDefinition = GetMergedObjectDefinition(objectName, false); - if (mergedObjectDefinition == null) - { - if (ParentObjectFactory != null) - { - return ParentObjectFactory.GetObject(name, arguments); - } - throw new NoSuchObjectDefinitionException(name, "Cannot find definition for object [" + name + "]"); - } - - // Override constructor values and configure as a prototype - RootObjectDefinition tmpObjectDefinition = new RootObjectDefinition(mergedObjectDefinition); - tmpObjectDefinition.ConstructorArgumentValues = null; - tmpObjectDefinition.IsSingleton = false; - - // create a new instance... - instance = CreateObject(name, tmpObjectDefinition, arguments); - - return GetObjectForInstance(name, instance); - } - - /// - /// Tries to find a cached object for the specified name. - /// - /// Teh object name to look for. - /// The cached object if found, otherwise. - protected virtual object GetSingleton(string objectName) - { - lock (singletonCache) - { - return singletonCache[objectName]; - } - } - - /// - /// Creates a singleton instance for the specified object name and definition. - /// - /// - /// The object name (will be used as the key in the singleton cache key). - /// - /// The object definition. - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. If there is no factory method and the - /// arguments are not null, then match the argument values by type and - /// call the object's constructor. - /// - /// The created object instance. - protected virtual object CreateAndCacheSingletonInstance(string objectName, - RootObjectDefinition objectDefinition, - object[] arguments) - { - lock (singletonCache) - { - object sharedInstance = singletonCache[objectName]; - if (sharedInstance == null) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Creating shared instance of singleton object '" + objectName + "'"); - } - - #endregion - - BeforeSingletonCreation(objectName); - try - { - sharedInstance = CreateObject(objectName, objectDefinition, arguments); - } - finally - { - AfterSingletonCreation(objectName); - } - AddSingleton(objectName, sharedInstance); - } - return sharedInstance; - } - } - - private void AfterSingletonCreation(string name) - { - if (!singletonsInCreation.Contains(name)) - { - throw new InvalidOperationException("Singleton " + name + " isn't currently in creation."); - } - singletonsInCreation.Remove(name); - } - - private void BeforeSingletonCreation(string name) - { - if (this.singletonsInCreation.Contains(name)) - { - throw new ObjectCurrentlyInCreationException(name); - } - singletonsInCreation.Add(name, emptyObject); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - public object GetObject(string name, Type requiredType) - { - return GetObject(name, requiredType, ObjectUtils.EmptyObjects); - } - - /// - /// Injects dependencies into the supplied instance - /// using the named object definition. - /// - /// - public abstract object ConfigureObject(object target, string name); - - /// - /// Injects dependencies into the supplied instance - /// using the supplied . - /// - /// - public abstract object ConfigureObject(object target, string name, IObjectDefinition definition); - - #endregion - - #region IConfigurableObjectFactory Members - - /// - /// Destroy all cached singletons in this factory. - /// - public virtual void Dispose() - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format("Destroying singletons in factory [{0}].", this)); - } - - #endregion - - lock (singletonCache) - { - // copy the keys into a new set, 'cos we are going to modifying the - // original collection (_singletonCache) as we destroy each singleton. - ISet keys = new HashedSet(singletonCache.Keys); - foreach (string name in keys) - { - DestroySingleton(name); - } - } - } - - /// - /// Ignore the given dependency type for autowiring - /// - /// . - public void IgnoreDependencyType(Type type) - { - IgnoredDependencyTypes.Add(type); - } - - /// - /// Determines whether the specified object name is currently in creation.. - /// - /// Name of the object. - /// - /// true if the specified object name is currently in creation; otherwise, false. - /// - public bool IsCurrentlyInCreation(string objectName) - { - return IsSingletonCurrentlyInCreation(objectName) || IsPrototypeCurrentlyInCreation(objectName); - } - - private bool IsPrototypeCurrentlyInCreation(string name) - { - //TODO - return false; - } - - private bool IsSingletonCurrentlyInCreation(string name) - { - if (this.singletonsInCreation.Contains(name)) - { - return true; - } - else - { - return false; - } - } - - /// - /// Add a new - /// that will get applied to objects created by this factory. - /// - /// - /// The - /// to register. - /// - /// . - public void AddObjectPostProcessor(IObjectPostProcessor objectPostProcessor) - { - // ensure the same instance doesn't get registered twice - if (!ObjectPostProcessors.Contains(objectPostProcessor)) - { - ObjectPostProcessors.Add(objectPostProcessor); - } - if (typeof (IInstantiationAwareObjectPostProcessor).IsInstanceOfType(objectPostProcessor)) - { - hasInstantiationAwareBeanPostProcessors = true; - } - if (typeof (IDestructionAwareObjectPostProcessor).IsInstanceOfType(objectPostProcessor)) - { - hasDestructionAwareBeanPostProcessors = true; - } - } - - /// - /// Returns the current number of registered - /// s. - /// - /// - /// The current number of registered - /// s. - /// - /// . - public int ObjectPostProcessorCount - { - get { return ObjectPostProcessors.Count; } - } - - /// - /// Given an object name, create an alias. - /// - /// . - public void RegisterAlias(string name, string alias) - { - #region Sanity Checks - - AssertUtils.ArgumentHasText(name, "The object name must not be empty."); - AssertUtils.ArgumentHasText(alias, "The alias must not be empty."); - - #endregion - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format("Registering alias '{0}' for object with name '{1}'.", alias, name)); - } - - #endregion - - lock (aliasMap) - { - object registeredName = aliasMap[alias]; - if (registeredName != null) - { - throw new ObjectDefinitionStoreException( - string.Format( - "Cannot register alias '{0}' for object with name '{1}': it's already registered for object name '{2}'.", - alias, name, registeredName)); - } - aliasMap[alias] = name; - } - } - - /// - /// Register the given existing object as singleton in the object factory, - /// under the given object name. - /// - /// . - public void RegisterSingleton(string name, object singletonObject) - { - AssertUtils.ArgumentHasText(name, "name", "The singleton object cannot be registered under an empty name."); - lock (singletonCache) - { - object oldObject = singletonCache[name]; - if (oldObject != null) - { - throw new ObjectDefinitionStoreException( - string.Format( - "Could not register object [{0}] under object name '{1}': there's already object [{2}] bound.", - singletonObject, name, oldObject)); - } - AddSingleton(name, singletonObject); - } - } - - /// - /// Register the given custom - /// for all properties of the given . - /// - /// . - public void RegisterCustomConverter(Type requiredType, TypeConverter converter) - { - AssertUtils.ArgumentNotNull(requiredType, "requiredType"); - TypeConverterRegistry.RegisterConverter(requiredType, converter); - } - - /// - /// Does this object factory contains a singleton instance with the - /// supplied ? - /// - /// - public bool ContainsSingleton(string name) - { - AssertUtils.ArgumentHasText(name, "name"); - lock (singletonCache) - { - return singletonCache.Contains(name); - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; + +using Common.Logging; + +using Spring.Collections; +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Abstract superclass for + /// implementations. + /// + /// + ///

+ /// This class provides singleton / prototype determination, singleton caching, + /// object definition aliasing, + /// handling, and object definition merging for child object definitions. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public abstract class AbstractObjectFactory : IConfigurableObjectFactory + { + /// + /// Marker object to be temporarily registered in the singleton cache, + /// while instantiating an object (in order to be able to detect circular references). + /// + private static readonly object CURRENTLY_IN_CREATION = new Object(); + + /// + /// The instance for this class. + /// + private readonly ILog log = LogManager.GetLogger(typeof(AbstractObjectFactory)); + + /// + /// Used as value in hashtable that keeps track of singleton names currently in the + /// process of being created. Would not be necessary if we created a case insensitive implementation of + /// ISet. + /// + private static object emptyObject = new object(); + + + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This constructor implicitly creates an + /// + /// that treats the names of objects in this factory in a case-sensitive fashion. + ///

+ ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractObjectFactory() : this(true) + {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ /// + /// if the names of objects in this factory are to be treated in a + /// case-sensitive fashion. + /// + protected AbstractObjectFactory(bool caseSensitive) + { + this.log = LogManager.GetLogger(this.GetType()); + if (caseSensitive) + { + this.aliasMap = new SynchronizedHashtable(); + this.singletonCache = new Hashtable(); + this.singletonsInCreation = new Hashtable(); + } + else + { + this.aliasMap = new SynchronizedHashtable(CollectionsUtil.CreateCaseInsensitiveHashtable()); + this.singletonCache = CollectionsUtil.CreateCaseInsensitiveHashtable(); + this.singletonsInCreation = CollectionsUtil.CreateCaseInsensitiveHashtable(); + } + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ /// + /// if the names of objects in this factory are to be treated in a + /// case-sensitive fashion. + /// + /// + /// Any parent object factory; may be . + /// + protected AbstractObjectFactory(bool caseSensitive, IObjectFactory parentFactory) : this(caseSensitive) + { + ParentObjectFactory = parentFactory; + } + + #endregion + + #region Properties + + /// + /// Gets the of + /// s + /// that will be applied to objects created by this factory. + /// + public IList ObjectPostProcessors + { + get { return objectPostProcessors; } + } + + /// + /// Gets the set of classes that will be ignored for autowiring. + /// + /// + ///

+ /// The elements of this are + /// s. + ///

+ ///
+ public ISet IgnoredDependencyTypes + { + get { return ignoreDependencyTypes; } + } + + /// + /// Returns, whether this object factory instance contains objects. + /// + protected bool HasInstantiationAwareBeanPostProcessors + { + get { return hasInstantiationAwareBeanPostProcessors; } + } + + /// + /// Returns, whether this object factory instance contains objects. + /// + protected bool HasDestructionAwareBeanPostProcessors + { + get { return hasDestructionAwareBeanPostProcessors; } + } + + #endregion + + #region Methods + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// + /// The the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a factory method. If there is no factory method and the + /// supplied array is not , then + /// match the argument values by type and call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the object is not of the required type. + /// + /// + /// If the supplied is . + /// + /// + public object GetObject(string name, Type requiredType, object[] arguments) + { + string objectName = TransformedObjectName(name); + object instance = null; + // eagerly check singleton cache for manually registered singletons... + object sharedInstance = GetSingleton(objectName); + + if (sharedInstance != null) + { + #region Instrumentation + + if (IsSingletonCurrentlyInCreation(objectName)) + { + if (log.IsDebugEnabled) + { + log.Debug("Returning eagerly cached instance of singleton object '" + objectName + + "' that is not fully initialized yet - a consequence of a circular reference"); + } + } + else + { + if (log.IsDebugEnabled) + { + log.Debug(string.Format("Returning cached instance of singleton object '{0}'.", objectName)); + } + } + + #endregion + + instance = GetObjectForInstance(name, sharedInstance); + } + else + { + // check if object definition exists + RootObjectDefinition mergedObjectDefinition = null; + mergedObjectDefinition = GetMergedObjectDefinition(objectName, false); + if (mergedObjectDefinition == null) + { + if (ParentObjectFactory != null) + { + return ParentObjectFactory.GetObject(name, requiredType, arguments); + } + throw new NoSuchObjectDefinitionException(name, "Cannot find definition for object [" + name + "]"); + } + + CheckMergedObjectDefinition(mergedObjectDefinition, objectName, requiredType, arguments); + + // return IObjectDefinition instance itself for an abstract object-definition + if (mergedObjectDefinition.IsAbstract) + { + instance = mergedObjectDefinition; + } + else if (mergedObjectDefinition.IsSingleton) + { + // create object instance... + sharedInstance = CreateAndCacheSingletonInstance(objectName, mergedObjectDefinition, arguments); + instance = GetObjectForInstance(name, sharedInstance); + } + else + { + // it's a prototype, so create a new instance... + instance = CreateObject(name, mergedObjectDefinition, arguments); + } + } + // check that any required type matches the type of the actual object instance... + if (requiredType != null && !requiredType.IsAssignableFrom(instance.GetType())) + { + throw new ObjectNotOfRequiredTypeException(name, requiredType, instance); + } + return instance; + } + + + + /// + /// Apply the property values of the object definition with the supplied + /// to the supplied . + /// + /// + ///

+ /// The object definition can either define a fully self-contained object, + /// reusing it's property values, or just property values meant to be used + /// for existing object instances. + ///

+ ///
+ /// + /// The existing object that the property values for the named object will + /// be applied to. + /// + /// + /// The name of the object definition associated with the property values that are + /// to be applied. + /// + /// + /// In case of errors. + /// + public virtual void ApplyObjectPropertyValues(object instance, string name) + { + // explicit no-op... + } + + /// + /// Initializes the given with the + /// custom s registered with + /// this factory. + /// + /// + /// The to initialise. + /// + protected void InitObjectWrapper(IObjectWrapper wrapper) + { + } + + /// + /// Create an object instance for the given object definition. + /// + /// + ///

+ /// The object definition will already have been merged with the parent + /// definition in case of a child definition. + ///

+ ///

+ /// All the other methods in this class invoke this method, although objects + /// may be cached after being instantiated by this method. All object + /// instantiation within this class is performed by this method. + ///

+ ///
+ /// The name of the object. + /// + /// The object definition for the object that is to be instantiated. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a factory method. If there is no factory method and the + /// supplied array is not , + /// then match the argument values by type and call the object's constructor. + /// + /// + /// A new instance of the object. + /// + /// + /// In case of errors. + /// + protected abstract object CreateObject(string name, RootObjectDefinition definition, object[] arguments); + + /// + /// Destroy the target object. + /// + /// + ///

+ /// Must destroy objects that depend on the given object before the object itself, + /// nor throw an exception. + ///

+ ///
+ /// + /// The name of the object. + /// + /// + /// The target object instance to destroyed. + /// + protected abstract void DestroyObject(string name, object target); + + /// + /// Does this object factory contain an object definition with the + /// supplied ? + /// + /// + ///

+ /// Does not consider any hierarchy this factory may participate in. + /// Invoked by + /// + /// when no cached singleton instance is found. + ///

+ ///
+ /// + /// The name of the object to look for. + /// + /// + /// if this object factory contains an object + /// definition with the supplied . + /// + public abstract bool ContainsObjectDefinition(string name); + + /// + /// Adds the supplied (object) to this factory's + /// singleton cache. + /// + /// + ///

+ /// To be called for eager registration of singletons, e.g. to be able to + /// resolve circular references. + ///

+ /// + /// If a singleton has already been registered under the same name as + /// the supplied , then the old singleton will + /// be replaced. + /// + ///
+ /// The name of the object. + /// The singleton object. + /// + /// If the argument is + /// or consists wholly of whitespace characters; or if the + /// is . + /// + protected virtual void AddSingleton(string name, object singleton) + { + AssertUtils.ArgumentHasText(name, "The object name must not be empty."); + AssertUtils.ArgumentNotNull(singleton, "singleton"); + lock (singletonCache) + { + singletonCache[name] = singleton; + } + } + + /// + /// Return the object name, stripping out the factory dereference prefix if + /// necessary, and resolving aliases to canonical names. + /// + /// + /// The transformed name of the object. + /// + protected string TransformedObjectName(string name) + { + string objectName = ObjectFactoryUtils.TransformedObjectName(name); + // handle aliasing... + lock (aliasMap) + { + string canonicalName = (string) aliasMap[objectName]; + return canonicalName != null ? canonicalName : objectName; + } + } + + /// + /// Ensures, that the given name is prefixed with + /// if it incidentially already starts with this prefix. This avoids troubles when dereferencing + /// the object name during + /// + protected string OriginalObjectName(string name) + { + string objectName = TransformedObjectName(name); + if (name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix)) + { + objectName = ObjectFactoryUtils.FactoryObjectPrefix + objectName; + } + return objectName; + } + + /// + /// Determines whether the specified name is defined as an alias as opposed + /// to the name of an actual object definition. + /// + /// The object name to check. + /// + /// true if the specified name is alias; otherwise, false. + /// + protected bool IsAlias(string name) + { + lock (aliasMap) + { + return aliasMap.Contains(name); + } + } + + /// + /// Return a , + /// even by traversing parent if the parameter is a child definition. + /// + /// + /// The name of the object. + /// + /// + /// Are ancestors to be included in the merge? + /// + /// + ///

+ /// Will ask the parent object factory if not found in this instance. + ///

+ ///
+ /// + /// A merged + /// with overridden properties. + /// + public virtual RootObjectDefinition GetMergedObjectDefinition(string name, bool includingAncestors) + { + return GetMergedObjectDefinition(name, GetObjectDefinition(name, includingAncestors)); + } + + /// + /// Return a , + /// even by traversing parent if the parameter is a child definition. + /// + /// + /// A merged + /// with overridden properties. + /// + protected virtual RootObjectDefinition GetMergedObjectDefinition(string name, IObjectDefinition definition) + { + if (definition == null) + { + return null; + } + else if (definition is RootObjectDefinition) + { + return (RootObjectDefinition) definition; + } + else if (definition is ChildObjectDefinition) + { + ChildObjectDefinition childDefinition = (ChildObjectDefinition) definition; + RootObjectDefinition parentDefinition = null; + if (!name.Equals(childDefinition.ParentName)) + { + parentDefinition = + GetMergedObjectDefinition(TransformedObjectName(childDefinition.ParentName), true); + } + else + { + if (ParentObjectFactory is AbstractObjectFactory) + { + parentDefinition = + ((AbstractObjectFactory) ParentObjectFactory).GetMergedObjectDefinition( + childDefinition.ParentName, true); + } + } + if (parentDefinition == null) + { + throw new NoSuchObjectDefinitionException(childDefinition.ParentName, + string.Format( + "Parent name '{0}' is equal to object name '{1}' - " + + + "cannot be resolved without an AbstractObjectFactory parent.", + childDefinition.ParentName, name)); + } + + RootObjectDefinition rootDefinition = CreateRootObjectDefinition(parentDefinition); + rootDefinition.OverrideFrom(childDefinition); + return rootDefinition; + } + else + { + throw new ObjectDefinitionStoreException(definition.ResourceDescription, name, + "Definition is neither a RootObjectDefinition nor a ChildObjectDefinition."); + } + } +/* + /// + /// Merges the object definitions. + /// + /// Object definition name. + /// The parent definition. + /// The child definition. + /// Merged object definition. + protected virtual RootObjectDefinition MergeObjectDefinitions(string name, IObjectDefinition parentDefinition, + IObjectDefinition childDefinition) + { + RootObjectDefinition rootDefinition = CreateRootObjectDefinition(parentDefinition); + rootDefinition.OverrideFrom(childDefinition); + return rootDefinition; + } +*/ + /// + /// Creates the root object definition. + /// + /// The template definition to base root definition on. + /// Root object definition. + protected virtual RootObjectDefinition CreateRootObjectDefinition(IObjectDefinition templateDefinition) + { + return new RootObjectDefinition(templateDefinition); + } + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + public abstract IObjectDefinition GetObjectDefinition(string name); + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// Whether to search parent object factories. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + public abstract IObjectDefinition GetObjectDefinition(string name, bool includeAncestors); + + /// + /// Gets the type for the given FactoryObject. + /// + /// The factory object instance to check. + /// the FactoryObject's object type + protected virtual Type GetTypeForFactoryObject(IFactoryObject factoryObject) + { + try + { + return factoryObject.ObjectType; + } + catch (Exception ex) + { + log.Warn("FactoryObject threw exception from ObjectType, despite the contract saying " + + "that it should return null if the type of its object cannot be determined yet", ex); + return null; + } + } + + /// + /// Gets the object type for the given FactoryObject definition, as far as possible. + /// Only called if there is no singleton instance registered for the target object already. + /// + /// + /// The default implementation creates the FactoryObject via GetObject + /// to call its ObjectType property. Subclasses are encouraged to optimize + /// this, typically by just instantiating the FactoryObject but not populating it yet, + /// trying whether its ObjectType property already returns a type. + /// If no type found, a full FactoryObject creation as performed by this implementation + /// should be used as fallback. + /// + /// Name of the object. + /// The merged object definition for the object. + /// The type for the object if determinable, or null otherwise + protected virtual Type GetTypeForFactoryObject(string objectName, RootObjectDefinition mod) + { + if (!mod.IsSingleton) + { + return null; + } + try + { + IFactoryObject factoryObject = GetFactoryObject(objectName); + return GetTypeForFactoryObject(factoryObject); + } catch (ObjectCreationException ex) + { + // Can only happen when getting a FactoryObject. + log.Debug("Ignoring object creation exception on FactoryObject type check", ex); + return null; + } + } + + /// + /// Predict the eventual object type (of the processed object instance) for the + /// specified object. + /// + /// + /// Does not need to handle FactoryObjects specifically, since it is only + /// supposed to operate on the raw object type. + /// This implementation is simplistic in that it is not able to + /// handle factory methods and InstantiationAwareBeanPostProcessors. + /// It only predicts the object type correctly for a standard object. + /// To be overridden in subclasses, applying more sophisticated type detection. + /// + /// Name of the object. + /// The merged object definition to determine the type for. + /// The type of the object, or null if not predictable + protected virtual Type PredictObjectType(string objectName, RootObjectDefinition mod) + { + if (StringUtils.HasText(mod.FactoryObjectName)) + { + return null; + } + return ResolveObjectType(mod, objectName); + } + + /// + /// Get the object for the given object instance, either the object + /// instance itself or its created object in case of an + /// . + /// + /// + /// The name that may include the factory dereference prefix. + /// + /// The object instance. + /// + /// The singleton instance of the object. + /// + protected virtual object GetObjectForInstance(string name, object instance) + { + //string objectName = TransformedObjectName(name); + + // don't let calling code try to dereference the + // object factory if the object isn't a factory + if (IsFactoryDereference(name) && !(instance is IFactoryObject)) + { + throw new ObjectIsNotAFactoryException(TransformedObjectName(name), instance); + } + + // now we have the object instance, which may be a normal object + // or an IFactoryObject. If it's an IFactoryObject, we use it to + // create an object instance, unless the caller actually wants + // a reference to the factory. + if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IFactoryObject), instance)) + { + if (!IsFactoryDereference(name)) + { + + // return object instance from factory... + IFactoryObject factory = (IFactoryObject) instance; + string objectName = TransformedObjectName(name); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format("Object with name '{0}' is a factory object.", objectName)); + } + + #endregion + + RootObjectDefinition rod = + (ContainsObjectDefinition(objectName) ? GetMergedObjectDefinition(objectName,true) : null); + instance = GetObjectFromFactoryObject(factory, objectName, rod); + + if (instance == null) + { + throw new FactoryObjectNotInitializedException(TransformedObjectName(name), + "Factory object returned null object - " + + "possible cause: not fully initialized due to " + + "circular object reference."); + } + } + else + { + // the user wants the factory itself... + if (log.IsDebugEnabled) + { + log.Debug( + string.Format("Calling code asked for IFactoryObject instance for name '{0}'.", + TransformedObjectName(name))); + } + } + } + return instance; + } + + /// + /// Obtain an object to expose from the given IFactoryObject. + /// + /// The IFactoryObject instance. + /// Name of the object. + /// The merged object definition. + /// The object obtained from the IFactoryObject + /// If IFactoryObject object creation failed. + private object GetObjectFromFactoryObject(IFactoryObject factory, string objectName, RootObjectDefinition rod) + { + object instance; + + try + { + instance = factory.GetObject(); + } + catch (FactoryObjectNotInitializedException ex) + { + throw new ObjectCurrentlyInCreationException( + rod.ResourceDescription, objectName, ex); + } + catch (Exception ex) + { + throw new ObjectCreationException(rod.ResourceDescription, objectName, + "FactoryObject threw exception on object creation.", ex); + } + + // Do not accept a null value for a FactoryBean that's not fully + // initialized yet: Many FactoryBeans just return null then. + if (instance == null && IsSingletonCurrentlyInCreation(objectName)) { + throw new ObjectCurrentlyInCreationException(rod.ResourceDescription, objectName, + "FactoryObject which is currently in creation returned null from GetObject."); + } + + if (factory is IConfigurableFactoryObject) + { + IConfigurableFactoryObject configurableFactory = (IConfigurableFactoryObject)factory; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format("Factory object with name '{0}' is configurable.", TransformedObjectName(objectName))); + } + + #endregion + + if (configurableFactory.ProductTemplate != null) + { + instance = ConfigureObject(instance, + String.Format("{0}.ProductTemplate", objectName), + configurableFactory.ProductTemplate); + } + } + + if (instance != null) + { + try + { + instance = PostProcessObjectFromFactoryObject(instance, objectName); + } + catch (Exception ex) { + throw new ObjectCreationException(rod.ResourceDescription, objectName, + "Post-processing of the FactoryObject's object failed.", ex); + } + } + + return instance; + } + + /// + /// Post-process the given object that has been obtained from the FactoryObject. + /// The resulting object will be exposed for object references. + /// + /// The default implementation simply returns the given object + /// as-is. Subclasses may override this, for example, to apply + /// post-processors. + /// The instance obtained from the IFactoryObject. + /// Name of the object. + /// The object instance to expose + /// if any post-processing failed. + protected virtual object PostProcessObjectFromFactoryObject(object instance, string objectName) + { + return instance; + } + + /// + /// Convenience method to pull an + /// from this factory. + /// + /// + /// The name of the factory object to be retrieved. If this name is not a valid + /// name, it will be converted + /// into one. + /// + /// + /// The associated with the + /// supplied . + /// + protected IFactoryObject GetFactoryObject(string objectName) + { + if (!ObjectFactoryUtils.IsFactoryDereference(objectName)) + { + objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); + } + return (IFactoryObject) GetObject(objectName); + } + + /// + /// Is the supplied a factory object dereference? + /// + protected bool IsFactoryDereference(string name) + { + return ObjectFactoryUtils.IsFactoryDereference(name); + } + + /// + /// Determines whether the type of the given object definition matches the + /// specified target type. + /// + /// Allows for lazy load of the actual object type, provided that the + /// type match can be determined otherwise. + /// The default implementation simply delegates to the standard + /// ResolveObjectType method. Subclasses may override this to use + /// a differnt strategy. + /// + /// Name of the object (for error handling purposes). + /// The merged object definition to determine the type for. + /// Type to match against (never null). + /// + /// true if object definition matches tye specified target type; otherwise, false. + /// + /// if we failed to load the type." + protected bool IsObjectTypeMatch(string objectName, RootObjectDefinition rod, Type targetType) + { + Type objectType = ResolveObjectType(rod, objectName); + return (objectType != null && targetType.IsAssignableFrom(objectType)); + } + + /// + /// Resolves the type of the object for the specified object definition resolving + /// an object type name to a Type (if necessary) and storing the resolved Type + /// in the object definition for further use. + /// + /// The merged object definition to dertermine the type for. + /// Name of the object (for error handling purposes). + /// + protected Type ResolveObjectType(RootObjectDefinition rod, string objectName) + { + try + { + if (rod.HasObjectType) + { + return rod.ObjectType; + } + return rod.ResolveObjectType(); + } catch (TypeLoadException e) + { + throw new CannotLoadObjectTypeException(rod.ResourceDescription, objectName, rod.ObjectTypeName, e); + } + } + + /// + /// Is the object (definition) with the supplied an + /// ? + /// + /// The name of the object to be checked. + /// + /// the object (definition) with the supplied + /// an ? + /// + protected bool IsFactoryObject(string name) + { + string objectName = TransformedObjectName(name); + object objectInstance = GetSingleton(objectName); + //TODO investigate + if (IsSingletonCurrentlyInCreation(name)) + { + throw new ObjectCurrentlyInCreationException(objectName); + } + + if (objectInstance != null) + { + return (objectInstance is IFactoryObject); + } + else + { + RootObjectDefinition definition = GetMergedObjectDefinition(objectName, false); + if (definition != null) + { + return (definition.HasObjectType && typeof(IFactoryObject).IsAssignableFrom(definition.ObjectType)); + } + else + { + if (parentObjectFactory != null) + { + return ((AbstractObjectFactory) parentObjectFactory).IsFactoryObject(name); + } + else + { + throw new NoSuchObjectDefinitionException(objectName, + "Cannot find definition for object [" + objectName + + "]"); + } + } + } + } + + /// + /// Remove the object identified by the supplied + /// from this factory's singleton cache. + /// + /// + /// The name of the object that is to be removed from the singleton + /// cache. + /// + /// + /// If the argument is or + /// consists wholly of whitespace characters. + /// + protected void RemoveSingleton(string name) + { + AssertUtils.ArgumentHasText(name, "name"); + lock (singletonCache) + { + this.singletonCache.Remove(name); + } + } + + /// + /// Return the names of objects in the singleton cache that match the given + /// object type (including subclasses). + /// + /// + /// The class or interface to match, or for all object names. + /// + /// + ///

+ /// Will not consider s + /// as the type of their created objects is not known before instantiation. + ///

+ ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ ///
+ /// + /// The names of objects in the singleton cache that match the given + /// object type (including subclasses), or an empty array if none. + /// + public virtual string[] GetSingletonNames(Type type) + { + lock (singletonCache) + { + ArrayList matches = new ArrayList(); + foreach (string name in singletonCache.Keys) + { + object singletonObject = singletonCache[name]; + if (singletonObject != null && type.IsAssignableFrom(singletonObject.GetType()) + && !matches.Contains(name)) + { + matches.Add(name); + } + } + return (string[]) matches.ToArray(typeof(string)); + } + } + + /// + /// Determines whether the object with the given name matches the specified type. + /// + /// More specifically, check whether a GetObject call for the given name + /// would return an object that is assignable to the specified target type. + /// Translates aliases back to the corresponding canonical bean name. + /// Will ask the parent factory if the bean cannot be found in this factory instance. + /// + /// The name of the object to query. + /// Type of the target to match against. + /// + /// true if the object type matches; otherwise, false + /// if it doesn't match or cannot be determined yet. + /// + /// Ff there is no object with the given name + /// + public bool IsTypeMatch(string name, Type targetType) + { + string objectName = TransformedObjectName(name); + Type typeToMatch = (targetType != null ? targetType : typeof (object)); + + //Check manually registered singletons. + object objectInstance = GetSingleton(objectName); + if (objectInstance != null) + { + if (objectInstance is IFactoryObject) + { + if (!IsFactoryDereference(name)) + { + Type type = GetTypeForFactoryObject((IFactoryObject)objectInstance); + return (type != null && typeToMatch.IsAssignableFrom(type)); + } + else + { + return typeToMatch.IsAssignableFrom(objectInstance.GetType()); + } + } + else + { + return !IsFactoryDereference(name) && typeToMatch.IsAssignableFrom(objectInstance.GetType()); + } + } + else + { + // No singleton instance found -> check object definition + IObjectFactory parentFactory = ParentObjectFactory; + if (parentFactory != null && !ContainsObjectDefinition(name)) + { + // No object definition found in this factory -> delegate to parent + return parentFactory.IsTypeMatch(OriginalObjectName(name), targetType); + } + + RootObjectDefinition mod = GetMergedObjectDefinition(objectName, false); + Type objectType = PredictObjectType(objectName, mod); + + if (objectType == null) + { + return false; + } + + // Check object class whether we're dealing with a FactoryObject + if (typeof(IFactoryObject).IsAssignableFrom(objectType)) + { + if (!IsFactoryDereference(name)) + { + // If it's a FactoryObject, we want to look at what it creates, not the factory class. + Type type = GetTypeForFactoryObject(objectName, mod); + return (type != null && typeToMatch.IsAssignableFrom(type)); + } + else + { + return typeToMatch.IsAssignableFrom(objectType); + } + } + else + { + return !IsFactoryDereference(name) && typeToMatch.IsAssignableFrom(objectType); + } + } + } + + /// + /// Determines the of the object with the + /// supplied . + /// + /// + ///

+ /// More specifically, checks the of object that + /// would return. + /// For an , returns the + /// of object that the + /// creates. + ///

+ ///

+ /// Please note that (prototype) objects created via a factory method or + /// objects are handled + /// slightly differently, in that we don't want to needlessly create + /// instances of such objects just to determine the + /// of object that they create. + ///

+ ///
+ /// The name of the object to query. + /// + /// The of the object or + /// if not determinable. + /// + public virtual Type GetType(string name) + { + string objectName = TransformedObjectName(name); + + // check manually registered singletons... + object objectInstance = GetSingleton(objectName); + + if (objectInstance != null) + { + IFactoryObject factoryObject = objectInstance as IFactoryObject; + if (factoryObject != null & !IsFactoryDereference(objectName)) + { + return GetTypeForFactoryObject(factoryObject); + } + else + { + return objectInstance.GetType(); + } + } + else + { + // No singleton instance found -> check bean definition. + IObjectFactory parentFactory = ParentObjectFactory; + if (parentFactory != null && !ContainsObjectDefinition(objectName)) + { + // No bean definition found in this factory -> delegate to parent. + return parentFactory.GetType(this.OriginalObjectName(name)); + } + + RootObjectDefinition mod = this.GetMergedObjectDefinition(objectName, false); + Type objectType = PredictObjectType(objectName, mod); + + if (objectType != null && typeof (IFactoryObject).IsAssignableFrom(objectType)) + { + if (!IsFactoryDereference(name)) + { + // If it's a FactoryBean, we want to look at what it creates, not the factory class. + return GetTypeForFactoryObject(objectName, mod); + } + else + { + return objectType; + } + } + else + { + return (!IsFactoryDereference(name) ? objectType : null); + } + } + } + + /// + /// Determines the of the object defined + /// by the supplied object . + /// + /// + ///

+ /// This, the default, implementation returns + /// to indicate that the type cannot be determined. Subclasses are + /// encouraged to try to determine the actual return + /// here, matching their strategy of resolving + /// factory methods in the + /// + /// implementation. + ///

+ ///
+ /// + /// The name associated with the supplied object . + /// + /// + /// The + /// that the is to be determined for. + /// + /// + /// The of the object defined by the supplied + /// object ; or if the + /// cannot be determined. + /// + protected virtual Type GetTypeForFactoryMethod(string objectName, RootObjectDefinition definition) + { + return null; + } + + /// + /// Returns the names of the objects in the singleton cache. + /// + /// + ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ ///
+ /// The names of the objects in the singleton cache. + public virtual string[] GetSingletonNames() + { + lock (singletonCache) + { + return (string[]) new ArrayList(singletonCache.Keys).ToArray(typeof(string)); + } + } + + /// + /// Returns the number of objects in the singleton cache. + /// + /// + ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ ///
+ /// The number of objects in the singleton cache. + public virtual int GetSingletonCount() + { + lock (singletonCache) + { + return singletonCache.Count; + } + } + + /// + /// Destroys the named singleton object. + /// + /// + ///

+ /// Delegates to + /// + /// if a corresponding singleton instance is found. + ///

+ ///
+ /// + /// The name of the singleton object that is to be destroyed. + /// + /// + protected virtual void DestroySingleton(string name) + { + lock (singletonCache) + { + object tempObject = singletonCache[name]; + singletonCache.Remove(name); + + object singletonInstance = tempObject; + if (singletonInstance != null) + { + DestroyObject(name, singletonInstance); + } + } + } + + /// + /// Check the supplied merged object definition for any possible + /// validation errors. + /// + /// + /// The object definition to be checked for validation errors. + /// + /// + /// The name of the object associated with the supplied object definition. + /// + /// + /// The the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a factory method. If there is no factory method and the + /// supplied array is not , then + /// match the argument values by type and call the object's constructor. + /// + /// + /// In the case of object validation errors. + /// + protected void CheckMergedObjectDefinition(RootObjectDefinition mergedObjectDefinition, String objectName, + Type requiredType, params object[] arguments) + { + // check if required type can match according to the object definition; + // this is only possible at this early stage for conventional objects! + if (mergedObjectDefinition.HasObjectType) + { + Type objectType = mergedObjectDefinition.ObjectType; + if (requiredType != null && StringUtils.IsNullOrEmpty(mergedObjectDefinition.FactoryMethodName) + && !typeof(IFactoryObject).IsAssignableFrom(objectType) + && !requiredType.IsAssignableFrom(objectType)) + { + throw new ObjectNotOfRequiredTypeException(objectName, requiredType, objectType); + } + } + // check validity of the usage of the args parameter; this can + // only be used for prototypes constructed via a factory method... + if (arguments != null && arguments.Length > 0) + { + if (mergedObjectDefinition.IsSingleton) + { + throw new ObjectDefinitionStoreException("Cannot specify arguments in the GetObject () method when " + + "referring to a singleton object definition."); + } + //MLP lets skip this check for now. + /* + else if (StringUtils.IsNullOrEmpty(mergedObjectDefinition.FactoryMethodName)) + { + throw new ObjectDefinitionStoreException( + "Can only specify arguments in the GetObject () method in " + + "conjunction with a factory method."); + } + */ + } + } + + /// + /// Gets the temporary object that is placed + /// into the singleton cache during object resolution. + /// + protected object TemporarySingletonPlaceHolder + { + get { return CURRENTLY_IN_CREATION; } + } + + #endregion + + #region Fields + + /// + /// Parent object factory, for object inheritance support + /// + private IObjectFactory parentObjectFactory; + + /// + /// Dependency types to ignore on dependency check and autowire, as Set of + /// Type objects: for example, string. Default is none. + /// + private ISet ignoreDependencyTypes = new HybridSet(); + + + /// + /// ObjectPostProcessors to apply in CreateObject + /// + private IList objectPostProcessors = new ArrayList(); + + /// + /// Indicates whether any IInstantiationAwareBeanPostProcessors have been registered + /// + private bool hasInstantiationAwareBeanPostProcessors; + + /// + /// Indicates whether any IDestructionAwareBeanPostProcessors have been registered + /// + private bool hasDestructionAwareBeanPostProcessors; + + private IDictionary aliasMap; + private IDictionary singletonCache; + private IDictionary singletonsInCreation; + + #endregion + + #region IHierarchicalObjectFactory Members + + /// + /// The parent object factory, or if there is none. + /// + /// + /// The parent object factory, or if there is none. + /// + public IObjectFactory ParentObjectFactory + { + get { return parentObjectFactory; } + set { parentObjectFactory = value; } + } + + #endregion + + #region IObjectFactory Members + + /// + /// Is this object a singleton? + /// + /// + public bool IsSingleton(string name) + { + string objectName = TransformedObjectName(name); + object objectInstance = this.GetSingleton(objectName); + if (objectInstance != null) + { + IFactoryObject factoryObject = objectInstance as IFactoryObject; + if (factoryObject != null) + { + return IsFactoryDereference(name) || factoryObject.IsSingleton; + } + else + { + return !IsFactoryDereference(name); + } + } + else + { + // No singleton instance found -> check object definition + IObjectFactory pof = ParentObjectFactory; + if (pof != null && !ContainsObjectDefinition(objectName)) + { + // No object definition found in this factory -> delegate to parent + return pof.IsSingleton(OriginalObjectName(name)); + } + RootObjectDefinition od = GetMergedObjectDefinition(objectName, false); + + // In case of IFactoryObject, return singleton status of created object if not a dereference + if (od.IsSingleton) + { + if (IsObjectTypeMatch(objectName, od, typeof(IFactoryObject))) + { + if (IsFactoryDereference(name)) + { + return true; + } + IFactoryObject factoryObject = + (IFactoryObject) GetObject(ObjectFactoryUtils.BuildFactoryObjectName(objectName)); + return factoryObject.IsSingleton; + } + else + { + return !IsFactoryDereference(name); + } + } + else + { + return false; + } + } + } + + /// + /// Determines whether the specified object name is prototype. That is, will GetObject + /// always return independent instances? + /// + /// The name of the object to query + /// + /// true if the specified object name will always deliver independent instances; otherwise, false. + /// + /// This method returning false does not clearly indicate a singleton object. + /// It indicated non-independent instances, which may correspond to a scoped object as + /// well. use the IsSingleton property to explicitly check for a shared + /// singleton instance. + /// Translates aliases back to the corresponding canonical object name. Will ask the + /// parent factory if the object can not be found in this factory instance. + /// + /// + /// if there is no object with the given name. + public bool IsPrototype(string name) + { + string objectName = TransformedObjectName(name); + IObjectFactory parentFactory = ParentObjectFactory; + if (parentFactory != null && !this.ContainsObjectDefinition(objectName)) + { + // No object definition found in this factory -> delegate to parent + return parentFactory.IsPrototype(OriginalObjectName(name)); + } + + RootObjectDefinition od = GetMergedObjectDefinition(objectName, false); + + // In case of FactoryObject, return singleton status of created object if not a dereference + if (od.IsPrototype) + { + return (!IsFactoryDereference(name) || IsObjectTypeMatch(objectName, od, typeof(IFactoryObject))); + } + else + { + // not a prototype, however factory object may still produce a prototype object + if (IsFactoryDereference(name) && IsObjectTypeMatch(objectName, od, typeof (IFactoryObject))) + { + IFactoryObject factoryObject = GetFactoryObject(objectName); + return (!factoryObject.IsSingleton); + } + else + { + return false; + } + } + } + + /// + /// Does this object factory contain an object with the given name? + /// + /// + /// This method does not (and it should not) check if the specified + /// object exists in one of the parent object factories. If it did, + /// message sources and event registries within application context + /// hierarchy would have circular references, which would cause stack + /// overflows during message lookup, for example. (A. Seovic) + /// + /// . + public bool ContainsObject(string name) + { + string objectName = TransformedObjectName(name); + lock (singletonCache) + { + if (singletonCache.Contains(objectName)) + { + return true; + } + } + if (ContainsObjectDefinition(objectName)) + { + return true; + } + else + { + return false; + } + } + + /// + /// Return the aliases for the given object name, if defined. + /// + /// . + public string[] GetAliases(string name) + { + string objectName = TransformedObjectName(name); + // check if object actually exists in this object factory... + bool isInSingletonCache = false; + lock(singletonCache) + { + isInSingletonCache = singletonCache.Contains(objectName); + } + if (isInSingletonCache || ContainsObjectDefinition(objectName)) + { + // if found, gather aliases... + ArrayList matches = new ArrayList(); + lock (aliasMap) + { + foreach (DictionaryEntry aliasEntry in aliasMap) + { + if (aliasEntry.Value.Equals(objectName)) + { + matches.Add(aliasEntry.Key); + } + } + } + return (string[]) matches.ToArray(typeof(string)); + } + else + { + // not found, so check parent... + if (ParentObjectFactory != null) + { + return ParentObjectFactory.GetAliases(objectName); + } + throw new NoSuchObjectDefinitionException(objectName, ToString()); + } + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// . + public object this[string name] + { + get { return GetObject(name); } + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// . + public object GetObject(string name) + { + return GetObject(name, typeof(object), ObjectUtils.EmptyObjects); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to return. + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. If there is no factory method and the + /// arguments are not null, then match the argument values by type and + /// call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the supplied is . + /// + public object GetObject(string name, object[] arguments) + { + object instance = null; + string objectName = TransformedObjectName(name); + + // check if object definition exists + RootObjectDefinition mergedObjectDefinition = null; + mergedObjectDefinition = GetMergedObjectDefinition(objectName, false); + if (mergedObjectDefinition == null) + { + if (ParentObjectFactory != null) + { + return ParentObjectFactory.GetObject(name, arguments); + } + throw new NoSuchObjectDefinitionException(name, "Cannot find definition for object [" + name + "]"); + } + + // Override constructor values and configure as a prototype + RootObjectDefinition tmpObjectDefinition = new RootObjectDefinition(mergedObjectDefinition); + tmpObjectDefinition.ConstructorArgumentValues = null; + tmpObjectDefinition.IsSingleton = false; + + // create a new instance... + instance = CreateObject(name, tmpObjectDefinition, arguments); + + return GetObjectForInstance(name, instance); + } + + /// + /// Tries to find a cached object for the specified name. + /// + /// Teh object name to look for. + /// The cached object if found, otherwise. + protected virtual object GetSingleton(string objectName) + { + lock (singletonCache) + { + return singletonCache[objectName]; + } + } + + /// + /// Creates a singleton instance for the specified object name and definition. + /// + /// + /// The object name (will be used as the key in the singleton cache key). + /// + /// The object definition. + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. If there is no factory method and the + /// arguments are not null, then match the argument values by type and + /// call the object's constructor. + /// + /// The created object instance. + protected virtual object CreateAndCacheSingletonInstance(string objectName, + RootObjectDefinition objectDefinition, + object[] arguments) + { + lock (singletonCache) + { + object sharedInstance = singletonCache[objectName]; + if (sharedInstance == null) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Creating shared instance of singleton object '" + objectName + "'"); + } + + #endregion + + BeforeSingletonCreation(objectName); + try + { + sharedInstance = CreateObject(objectName, objectDefinition, arguments); + } + finally + { + AfterSingletonCreation(objectName); + } + AddSingleton(objectName, sharedInstance); + } + return sharedInstance; + } + } + + private void AfterSingletonCreation(string name) + { + if (!singletonsInCreation.Contains(name)) + { + throw new InvalidOperationException("Singleton " + name + " isn't currently in creation."); + } + singletonsInCreation.Remove(name); + } + + private void BeforeSingletonCreation(string name) + { + if (this.singletonsInCreation.Contains(name)) + { + throw new ObjectCurrentlyInCreationException(name); + } + singletonsInCreation.Add(name, emptyObject); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + public object GetObject(string name, Type requiredType) + { + return GetObject(name, requiredType, ObjectUtils.EmptyObjects); + } + + /// + /// Injects dependencies into the supplied instance + /// using the named object definition. + /// + /// + public abstract object ConfigureObject(object target, string name); + + /// + /// Injects dependencies into the supplied instance + /// using the supplied . + /// + /// + public abstract object ConfigureObject(object target, string name, IObjectDefinition definition); + + #endregion + + #region IConfigurableObjectFactory Members + + /// + /// Destroy all cached singletons in this factory. + /// + public virtual void Dispose() + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format("Destroying singletons in factory [{0}].", this)); + } + + #endregion + + lock (singletonCache) + { + // copy the keys into a new set, 'cos we are going to modifying the + // original collection (_singletonCache) as we destroy each singleton. + ISet keys = new HashedSet(singletonCache.Keys); + foreach (string name in keys) + { + DestroySingleton(name); + } + } + } + + /// + /// Ignore the given dependency type for autowiring + /// + /// . + public void IgnoreDependencyType(Type type) + { + IgnoredDependencyTypes.Add(type); + } + + /// + /// Determines whether the specified object name is currently in creation.. + /// + /// Name of the object. + /// + /// true if the specified object name is currently in creation; otherwise, false. + /// + public bool IsCurrentlyInCreation(string objectName) + { + return IsSingletonCurrentlyInCreation(objectName) || IsPrototypeCurrentlyInCreation(objectName); + } + + private bool IsPrototypeCurrentlyInCreation(string name) + { + //TODO + return false; + } + + private bool IsSingletonCurrentlyInCreation(string name) + { + if (this.singletonsInCreation.Contains(name)) + { + return true; + } + else + { + return false; + } + } + + /// + /// Add a new + /// that will get applied to objects created by this factory. + /// + /// + /// The + /// to register. + /// + /// . + public void AddObjectPostProcessor(IObjectPostProcessor objectPostProcessor) + { + // ensure the same instance doesn't get registered twice + if (!ObjectPostProcessors.Contains(objectPostProcessor)) + { + ObjectPostProcessors.Add(objectPostProcessor); + } + if (typeof (IInstantiationAwareObjectPostProcessor).IsInstanceOfType(objectPostProcessor)) + { + hasInstantiationAwareBeanPostProcessors = true; + } + if (typeof (IDestructionAwareObjectPostProcessor).IsInstanceOfType(objectPostProcessor)) + { + hasDestructionAwareBeanPostProcessors = true; + } + } + + /// + /// Returns the current number of registered + /// s. + /// + /// + /// The current number of registered + /// s. + /// + /// . + public int ObjectPostProcessorCount + { + get { return ObjectPostProcessors.Count; } + } + + /// + /// Given an object name, create an alias. + /// + /// . + public void RegisterAlias(string name, string alias) + { + #region Sanity Checks + + AssertUtils.ArgumentHasText(name, "The object name must not be empty."); + AssertUtils.ArgumentHasText(alias, "The alias must not be empty."); + + #endregion + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format("Registering alias '{0}' for object with name '{1}'.", alias, name)); + } + + #endregion + + lock (aliasMap) + { + object registeredName = aliasMap[alias]; + if (registeredName != null) + { + throw new ObjectDefinitionStoreException( + string.Format( + "Cannot register alias '{0}' for object with name '{1}': it's already registered for object name '{2}'.", + alias, name, registeredName)); + } + aliasMap[alias] = name; + } + } + + /// + /// Register the given existing object as singleton in the object factory, + /// under the given object name. + /// + /// . + public void RegisterSingleton(string name, object singletonObject) + { + AssertUtils.ArgumentHasText(name, "name", "The singleton object cannot be registered under an empty name."); + lock (singletonCache) + { + object oldObject = singletonCache[name]; + if (oldObject != null) + { + throw new ObjectDefinitionStoreException( + string.Format( + "Could not register object [{0}] under object name '{1}': there's already object [{2}] bound.", + singletonObject, name, oldObject)); + } + AddSingleton(name, singletonObject); + } + } + + /// + /// Register the given custom + /// for all properties of the given . + /// + /// . + public void RegisterCustomConverter(Type requiredType, TypeConverter converter) + { + AssertUtils.ArgumentNotNull(requiredType, "requiredType"); + TypeConverterRegistry.RegisterConverter(requiredType, converter); + } + + /// + /// Does this object factory contains a singleton instance with the + /// supplied ? + /// + /// + public bool ContainsSingleton(string name) + { + AssertUtils.ArgumentHasText(name, "name"); + lock (singletonCache) + { + return singletonCache.Contains(name); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AutowireUtils.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AutowireUtils.cs index 73005c0a..d4280662 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AutowireUtils.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AutowireUtils.cs @@ -1,286 +1,285 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using Spring.Collections; -using Spring.Core; -using Spring.Objects.Factory.Config; -using Spring.Objects.Support; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Utility class that contains various methods useful for the implementation of - /// autowire-capable object factories. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: AutowireUtils.cs,v 1.7 2008/04/02 18:02:24 markpollack Exp $ - public sealed class AutowireUtils - { - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the AutowireUtils class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly - /// visible constructors. - ///

- ///
- private AutowireUtils() - { - } - - // CLOVER:ON - - #endregion - - /// - /// Gets those s - /// that are applicable for autowiring the supplied . - /// - /// - /// The - /// (definition) that is being autowired by constructor. - /// - /// - /// The absolute minimum number of arguments that any returned constructor - /// must have. If this parameter is equal to zero (0), then all constructors - /// are valid (regardless of their argument count), including any default - /// constructor. - /// - /// - /// Those s - /// that are applicable for autowiring the supplied . - /// - public static ConstructorInfo[] GetConstructors( - IObjectDefinition definition, int minimumArgumentCount) - { - const BindingFlags flags = - BindingFlags.Public | BindingFlags.NonPublic - | BindingFlags.Instance | BindingFlags.DeclaredOnly; - ConstructorInfo[] constructors = null; - if (minimumArgumentCount > 0) - { - MemberInfo[] ctors = definition.ObjectType.FindMembers( - MemberTypes.Constructor, - flags, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - new MinimumArgumentCountCriteria(minimumArgumentCount)); - constructors = (ConstructorInfo[]) ArrayList.Adapter(ctors).ToArray(typeof (ConstructorInfo)); - } - else - { - constructors = definition.ObjectType.GetConstructors(flags); - } - AutowireUtils.SortConstructors(constructors); - return constructors; - } - - /// - /// Determine a weight that represents the class hierarchy difference between types and - /// arguments. - /// - /// - ///

- /// A direct match, i.e. type MyInteger -> arg of class MyInteger, does not increase - /// the result - all direct matches means weight zero (0). A match between the argument type - /// and a MyInteger instance argument would increase the weight by - /// 1, due to the superclass () being one (1) steps up in the - /// class hierarchy being the last one that still matches the required type. - ///

- ///

- /// Therefore, with an argument of type , a - /// constructor taking a argument would be - /// preferred to a constructor taking an argument - /// which would be preferred to a constructor taking an - /// argument which would in turn be preferred - /// to a constructor taking an argument. - ///

- ///

- /// All argument weights get accumulated. - ///

- ///
- /// - /// The argument s to match. - /// - /// The arguments to match. - /// The accumulated weight for all arguments. - public static int GetTypeDifferenceWeight(ParameterInfo[] argTypes, object[] args) - { - if (argTypes.Length != args.Length) - { - throw new ArgumentException("Cannot calculate the type difference weight for argument types and arguments with differing lengths."); - } - int result = 0; - for (int i = 0; i < argTypes.Length; i++) - { - Type theParameterType = argTypes[i].ParameterType; - if (!ObjectUtils.IsAssignable(theParameterType, args[i])) - { - return Int32.MaxValue; - } - if (args[i] != null - && !(args[i].GetType().Equals(theParameterType))) - { - Type superType = args[i].GetType().BaseType; - while (superType != null) - { - if (theParameterType.IsAssignableFrom(superType)) - { - ++result; - superType = superType.BaseType; - } - else - { - superType = null; - } - } - } - } - return result; - } - - /// - /// Determines whether the given object property is excluded from dependency checks. - /// - /// The PropertyInfo of the object property. - /// - /// true if is excluded from dependency check; otherwise, false. - /// - public static Boolean IsExcludedFromDependencyCheck(PropertyInfo pi) - { - return (pi.GetSetMethod() == null) ? false : true; - } - - /// - /// Sorts the supplied , preferring - /// public constructors and "greedy" ones (that have lots of arguments). - /// - /// - ///

- /// The result will contain public constructors first, with a decreasing number - /// of arguments, then non-public constructors, again with a decreasing number - /// of arguments. - ///

- ///
- /// - /// The array to be sorted. - /// - public static void SortConstructors(ConstructorInfo[] constructors) - { - if (constructors != null - && constructors.Length > 0) - { - Array.Sort(constructors, new ConstructorComparer()); - } - } - - #region Inner Class : ConstructorComparer - - private sealed class ConstructorComparer : IComparer - { - public int Compare(object lhs, object rhs) - { - ConstructorInfo lhsCtor = (ConstructorInfo) lhs; - ConstructorInfo rhsCtor = (ConstructorInfo) rhs; - if (lhsCtor.IsPublic != rhsCtor.IsPublic) - { - return (lhsCtor.IsPublic ? -1 : 1); - } - int lhsParams = lhsCtor.GetParameters().Length; - int rhsParams = rhsCtor.GetParameters().Length; - - if (lhsParams < rhsParams) - { - return 1; - } - else if (lhsParams > rhsParams) - { - return -1; - } - else - { - return 0; - } - } - } - - #endregion - - #region Inner Class : MinimumArgumentCountCriteria - - private sealed class MinimumArgumentCountCriteria : ICriteria - { - public MinimumArgumentCountCriteria(int minimumArgumentCount) - { - _minimumArgumentCount = minimumArgumentCount; - } - - public bool IsSatisfied(object datum) - { - bool satisfied = false; - satisfied = ((MethodBase) datum).GetParameters().Length >= _minimumArgumentCount; - return satisfied; - } - - private int _minimumArgumentCount; - } - - #endregion - - /// - /// Determines whether the setter property is defined in any of the given interfaces. - /// - /// The PropertyInfo of the object property - /// The ISet of interfaces. - /// - /// true if setter property is defined in interface; otherwise, false. - /// - public static bool IsSetterDefinedInInterface(PropertyInfo propertyInfo, ISet interfaces) - { - MethodInfo setter = propertyInfo.GetSetMethod(); - if (setter != null) - { - Type targetType = setter.DeclaringType; - foreach (Type interfaceType in interfaces) - { - if (interfaceType.IsAssignableFrom(targetType) && - ReflectionUtils.GetMethod(interfaceType, setter.Name, ReflectionUtils.GetParameterTypes(setter)) != null) - { - return true; - } - } - } - return false; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using Spring.Collections; +using Spring.Core; +using Spring.Objects.Factory.Config; +using Spring.Objects.Support; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Utility class that contains various methods useful for the implementation of + /// autowire-capable object factories. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + public sealed class AutowireUtils + { + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the AutowireUtils class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ private AutowireUtils() + { + } + + // CLOVER:ON + + #endregion + + /// + /// Gets those s + /// that are applicable for autowiring the supplied . + /// + /// + /// The + /// (definition) that is being autowired by constructor. + /// + /// + /// The absolute minimum number of arguments that any returned constructor + /// must have. If this parameter is equal to zero (0), then all constructors + /// are valid (regardless of their argument count), including any default + /// constructor. + /// + /// + /// Those s + /// that are applicable for autowiring the supplied . + /// + public static ConstructorInfo[] GetConstructors( + IObjectDefinition definition, int minimumArgumentCount) + { + const BindingFlags flags = + BindingFlags.Public | BindingFlags.NonPublic + | BindingFlags.Instance | BindingFlags.DeclaredOnly; + ConstructorInfo[] constructors = null; + if (minimumArgumentCount > 0) + { + MemberInfo[] ctors = definition.ObjectType.FindMembers( + MemberTypes.Constructor, + flags, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + new MinimumArgumentCountCriteria(minimumArgumentCount)); + constructors = (ConstructorInfo[]) ArrayList.Adapter(ctors).ToArray(typeof (ConstructorInfo)); + } + else + { + constructors = definition.ObjectType.GetConstructors(flags); + } + AutowireUtils.SortConstructors(constructors); + return constructors; + } + + /// + /// Determine a weight that represents the class hierarchy difference between types and + /// arguments. + /// + /// + ///

+ /// A direct match, i.e. type MyInteger -> arg of class MyInteger, does not increase + /// the result - all direct matches means weight zero (0). A match between the argument type + /// and a MyInteger instance argument would increase the weight by + /// 1, due to the superclass () being one (1) steps up in the + /// class hierarchy being the last one that still matches the required type. + ///

+ ///

+ /// Therefore, with an argument of type , a + /// constructor taking a argument would be + /// preferred to a constructor taking an argument + /// which would be preferred to a constructor taking an + /// argument which would in turn be preferred + /// to a constructor taking an argument. + ///

+ ///

+ /// All argument weights get accumulated. + ///

+ ///
+ /// + /// The argument s to match. + /// + /// The arguments to match. + /// The accumulated weight for all arguments. + public static int GetTypeDifferenceWeight(ParameterInfo[] argTypes, object[] args) + { + if (argTypes.Length != args.Length) + { + throw new ArgumentException("Cannot calculate the type difference weight for argument types and arguments with differing lengths."); + } + int result = 0; + for (int i = 0; i < argTypes.Length; i++) + { + Type theParameterType = argTypes[i].ParameterType; + if (!ObjectUtils.IsAssignable(theParameterType, args[i])) + { + return Int32.MaxValue; + } + if (args[i] != null + && !(args[i].GetType().Equals(theParameterType))) + { + Type superType = args[i].GetType().BaseType; + while (superType != null) + { + if (theParameterType.IsAssignableFrom(superType)) + { + ++result; + superType = superType.BaseType; + } + else + { + superType = null; + } + } + } + } + return result; + } + + /// + /// Determines whether the given object property is excluded from dependency checks. + /// + /// The PropertyInfo of the object property. + /// + /// true if is excluded from dependency check; otherwise, false. + /// + public static Boolean IsExcludedFromDependencyCheck(PropertyInfo pi) + { + return (pi.GetSetMethod() == null) ? false : true; + } + + /// + /// Sorts the supplied , preferring + /// public constructors and "greedy" ones (that have lots of arguments). + /// + /// + ///

+ /// The result will contain public constructors first, with a decreasing number + /// of arguments, then non-public constructors, again with a decreasing number + /// of arguments. + ///

+ ///
+ /// + /// The array to be sorted. + /// + public static void SortConstructors(ConstructorInfo[] constructors) + { + if (constructors != null + && constructors.Length > 0) + { + Array.Sort(constructors, new ConstructorComparer()); + } + } + + #region Inner Class : ConstructorComparer + + private sealed class ConstructorComparer : IComparer + { + public int Compare(object lhs, object rhs) + { + ConstructorInfo lhsCtor = (ConstructorInfo) lhs; + ConstructorInfo rhsCtor = (ConstructorInfo) rhs; + if (lhsCtor.IsPublic != rhsCtor.IsPublic) + { + return (lhsCtor.IsPublic ? -1 : 1); + } + int lhsParams = lhsCtor.GetParameters().Length; + int rhsParams = rhsCtor.GetParameters().Length; + + if (lhsParams < rhsParams) + { + return 1; + } + else if (lhsParams > rhsParams) + { + return -1; + } + else + { + return 0; + } + } + } + + #endregion + + #region Inner Class : MinimumArgumentCountCriteria + + private sealed class MinimumArgumentCountCriteria : ICriteria + { + public MinimumArgumentCountCriteria(int minimumArgumentCount) + { + _minimumArgumentCount = minimumArgumentCount; + } + + public bool IsSatisfied(object datum) + { + bool satisfied = false; + satisfied = ((MethodBase) datum).GetParameters().Length >= _minimumArgumentCount; + return satisfied; + } + + private int _minimumArgumentCount; + } + + #endregion + + /// + /// Determines whether the setter property is defined in any of the given interfaces. + /// + /// The PropertyInfo of the object property + /// The ISet of interfaces. + /// + /// true if setter property is defined in interface; otherwise, false. + /// + public static bool IsSetterDefinedInInterface(PropertyInfo propertyInfo, ISet interfaces) + { + MethodInfo setter = propertyInfo.GetSetMethod(); + if (setter != null) + { + Type targetType = setter.DeclaringType; + foreach (Type interfaceType in interfaces) + { + if (interfaceType.IsAssignableFrom(targetType) && + ReflectionUtils.GetMethod(interfaceType, setter.Name, ReflectionUtils.GetParameterTypes(setter)) != null) + { + return true; + } + } + } + return false; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ChildObjectDefinition.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ChildObjectDefinition.cs index 917b43ee..91b72bf0 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ChildObjectDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ChildObjectDefinition.cs @@ -1,255 +1,255 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Object definition for definitions that inherit settings from their - /// parent (object definition). - /// - /// - ///

- /// Will use the - /// of the parent object definition if none is specified, but can also - /// override it. In the latter case, the child's - /// - /// must be compatible with the parent, i.e. accept the parent's property values - /// and constructor argument values (if any). - ///

- ///

- /// A will - /// inherit all of the , - /// , and - /// from it's parent - /// object definition, with the option to add new values. If the - /// , - /// , - /// and / or - /// - /// properties are specified, they will override the corresponding parent settings. - ///

- ///

- /// The remaining settings will always be taken from the child definition: - /// , - /// , - /// , - /// , - /// and - /// - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// - [Serializable] - public class ChildObjectDefinition : AbstractObjectDefinition - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The name of the parent object. - /// - public ChildObjectDefinition(string parentName) - { - this.parentName = parentName; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The name of the parent object. - /// - /// - /// The additional property values (if any) of the child. - /// - public ChildObjectDefinition(string parentName, MutablePropertyValues properties) - : base(null, properties) - { - this.parentName = parentName; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The name of the parent object. - /// - /// - /// The - /// to be applied to a new instance of the object. - /// - /// - /// The additional property values (if any) of the child. - /// - public ChildObjectDefinition( - string parentName, ConstructorArgumentValues arguments, MutablePropertyValues properties) - : base(arguments, properties) - { - this.parentName = parentName; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The name of the parent object. - /// - /// - /// The class of the object to instantiate. - /// - /// - /// The - /// to be applied to a new instance of the object. - /// - /// - /// The additional property values (if any) of the child. - /// - public ChildObjectDefinition( - string parentName, Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties) - : base(arguments, properties) - { - this.parentName = parentName; - ObjectType = type; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The name of the parent object. - /// - /// - /// The of the object to - /// instantiate. - /// - /// - /// The - /// to be applied to a new instance of the object. - /// - /// - /// The additional property values (if any) of the child. - /// - public ChildObjectDefinition( - string parentName, string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) - : base(arguments, properties) - { - this.parentName = parentName; - ObjectTypeName = typeName; - } - - #endregion - - #region Properties - - /// - /// The name of the parent object definition. - /// - /// - ///

- /// This value is required. - ///

- ///
- /// - /// The name of the parent object definition. - /// - public string ParentName - { - get { return parentName; } - } - - #endregion - - #region Methods - - /// - /// Validate this object definition. - /// - /// - ///

- /// A common cause of validation failures is a missing value for the - /// - /// property; by - /// their very nature require that the - /// - /// be set. - ///

- ///
- /// - /// In the case of a validation failure. - /// - public override void Validate() - { - base.Validate(); - if (StringUtils.IsNullOrEmpty(parentName)) - { - throw new ObjectDefinitionValidationException( - "The 'ParentName' property must be set in ChildObjectDefinition."); - } - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - StringBuilder buffer = new StringBuilder(); - buffer.Append(GetType().Name).Append(" with parent '"); - buffer.Append(ParentName).Append("' : ").Append(base.ToString()); - return buffer.ToString(); - } - - #endregion - - #region Fields - - private string parentName; - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Object definition for definitions that inherit settings from their + /// parent (object definition). + /// + /// + ///

+ /// Will use the + /// of the parent object definition if none is specified, but can also + /// override it. In the latter case, the child's + /// + /// must be compatible with the parent, i.e. accept the parent's property values + /// and constructor argument values (if any). + ///

+ ///

+ /// A will + /// inherit all of the , + /// , and + /// from it's parent + /// object definition, with the option to add new values. If the + /// , + /// , + /// and / or + /// + /// properties are specified, they will override the corresponding parent settings. + ///

+ ///

+ /// The remaining settings will always be taken from the child definition: + /// , + /// , + /// , + /// , + /// and + /// + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + /// + [Serializable] + public class ChildObjectDefinition : AbstractObjectDefinition + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The name of the parent object. + /// + public ChildObjectDefinition(string parentName) + { + this.parentName = parentName; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The name of the parent object. + /// + /// + /// The additional property values (if any) of the child. + /// + public ChildObjectDefinition(string parentName, MutablePropertyValues properties) + : base(null, properties) + { + this.parentName = parentName; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The name of the parent object. + /// + /// + /// The + /// to be applied to a new instance of the object. + /// + /// + /// The additional property values (if any) of the child. + /// + public ChildObjectDefinition( + string parentName, ConstructorArgumentValues arguments, MutablePropertyValues properties) + : base(arguments, properties) + { + this.parentName = parentName; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The name of the parent object. + /// + /// + /// The class of the object to instantiate. + /// + /// + /// The + /// to be applied to a new instance of the object. + /// + /// + /// The additional property values (if any) of the child. + /// + public ChildObjectDefinition( + string parentName, Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties) + : base(arguments, properties) + { + this.parentName = parentName; + ObjectType = type; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The name of the parent object. + /// + /// + /// The of the object to + /// instantiate. + /// + /// + /// The + /// to be applied to a new instance of the object. + /// + /// + /// The additional property values (if any) of the child. + /// + public ChildObjectDefinition( + string parentName, string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) + : base(arguments, properties) + { + this.parentName = parentName; + ObjectTypeName = typeName; + } + + #endregion + + #region Properties + + /// + /// The name of the parent object definition. + /// + /// + ///

+ /// This value is required. + ///

+ ///
+ /// + /// The name of the parent object definition. + /// + public string ParentName + { + get { return parentName; } + } + + #endregion + + #region Methods + + /// + /// Validate this object definition. + /// + /// + ///

+ /// A common cause of validation failures is a missing value for the + /// + /// property; by + /// their very nature require that the + /// + /// be set. + ///

+ ///
+ /// + /// In the case of a validation failure. + /// + public override void Validate() + { + base.Validate(); + if (StringUtils.IsNullOrEmpty(parentName)) + { + throw new ObjectDefinitionValidationException( + "The 'ParentName' property must be set in ChildObjectDefinition."); + } + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + StringBuilder buffer = new StringBuilder(); + buffer.Append(GetType().Name).Append(" with parent '"); + buffer.Append(ParentName).Append("' : ").Append(base.ToString()); + return buffer.ToString(); + } + + #endregion + + #region Fields + + private string parentName; + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/DefaultListableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/DefaultListableObjectFactory.cs index 8b34d12b..0dac1009 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/DefaultListableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/DefaultListableObjectFactory.cs @@ -1,893 +1,892 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Globalization; -using Common.Logging; -using Spring.Core; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Concrete implementation of the - /// and - /// - /// interfaces. - /// - /// - ///

- /// This class is a full-fledged object factory based on object definitions - /// that is usable straight out of the box. - ///

- ///

- /// Can be used as an object factory in and of itself, or as a superclass - /// for custom object factory implementations. Note that readers for - /// specific object definition formats are typically implemented separately - /// rather than as object factory subclasses. - ///

- ///

- /// For an alternative implementation of the - /// interface, - /// have a look at the - /// - /// class, which manages existing object instances rather than creating new - /// ones based on object definitions. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// - /// $Id: DefaultListableObjectFactory.cs,v 1.42 2007/10/10 19:17:07 bbaia Exp $ - [Serializable] - public class DefaultListableObjectFactory : - AbstractAutowireCapableObjectFactory, - IConfigurableListableObjectFactory, - IObjectDefinitionRegistry - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public DefaultListableObjectFactory() : this(true, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// Flag specifying whether to make this object factory case sensitive or not. - public DefaultListableObjectFactory(bool caseSensitive) : this(caseSensitive, null) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The parent object factory. - public DefaultListableObjectFactory(IObjectFactory parentFactory) - : this(true, parentFactory) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// Flag specifying whether to make this object factory case sensitive or not. - /// The parent object factory. - public DefaultListableObjectFactory(bool caseSensitive, IObjectFactory parentFactory) - : base(caseSensitive, parentFactory) - { - if (caseSensitive) - { - objectDefinitionMap = new Hashtable(); - } - else - { - objectDefinitionMap = CollectionsUtil.CreateCaseInsensitiveHashtable(); - } - } - - #endregion - - #region Properties - - /// - /// Should object definitions registered under the same name as an - /// existing object definition be allowed? - /// - /// - ///

- /// If , then the new object definition will - /// replace (override) the existing object definition. If - /// , an exception will be thrown when - /// an attempt is made to register an object definition under the same - /// name as an already existing object definition. - ///

- ///

- /// The default is . - ///

- ///
- /// - /// is the registration of an object definition - /// under the same name as an existing object definition is allowed. - /// - public bool AllowObjectDefinitionOverriding - { - get { return allowObjectDefinitionOverriding; } - set { allowObjectDefinitionOverriding = value; } - } - - #endregion - - #region Methods - - /// - /// Find object instances that match the . - /// - /// - ///

- /// Called by autowiring. If a subclass cannot obtain information about object - /// names by , a corresponding exception should be thrown. - ///

- ///
- /// - /// The type of the objects to look up. - /// - /// - /// An of object names and object - /// instances that match the , or - /// if none is found. - /// - /// - /// In case of errors. - /// - protected override IDictionary FindMatchingObjects(Type requiredType) - { - return ObjectFactoryUtils.ObjectsOfTypeIncludingAncestors( - this, requiredType, true, true); - } - - /// - /// Return the names of the objects that depend on the given object. - /// - /// - ///

- /// Called by the - /// - /// so that dependant objects are able to be disposed of first. - ///

- ///
- /// - /// The name of the object to find depending objects for. - /// - /// - /// The array of names of depending objects, or the empty string array if none. - /// - /// - /// In case of errors. - /// - protected override string[] GetDependingObjectNames(string objectName) - { - ArrayList dependingObjectNames = new ArrayList(); - string[] allObjectDefinitionNames = GetObjectDefinitionNames(); - foreach (string name in allObjectDefinitionNames) - { - if (ContainsObjectDefinition(name)) - { - RootObjectDefinition rod - = GetMergedObjectDefinition(name, false); - if (rod.DependsOn != null) - { - IList dependsOn = new ArrayList(rod.DependsOn); - if (dependsOn.Contains(objectName)) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Found depending object '{0}' for object '{1}'.", - name, objectName)); - } - - #endregion - - dependingObjectNames.Add(name); - } - } - } - } - return (string[]) dependingObjectNames.ToArray(typeof(string)); - } - - /// - /// Check whether the specified object matches the supplied . - /// - /// The name of the object to check. - /// - /// The to check for. - /// - /// - /// if the object matches the supplied , - /// or if the supplied is . - /// - private bool IsObjectTypeMatch(string objectName, Type type) - { - if (type == null) - { - return true; - } - Type objectType = GetType(objectName); - return (objectType != null && type.IsAssignableFrom(objectType)); - } - - private bool IsObjectDefinitionTypeMatch(string name, Type checkedType) - { - if (checkedType == null) - { - return true; - } - RootObjectDefinition rod = GetMergedObjectDefinition(name, false); - return (rod.HasObjectType && checkedType.IsAssignableFrom(rod.ObjectType)); - } -/* - /// - /// Merges the object definitions. - /// - /// Object definition name. - /// The parent definition. - /// The child definition. - /// Merged object definition. - protected override RootObjectDefinition MergeObjectDefinitions(string name, IObjectDefinition parentDefinition, - IObjectDefinition childDefinition) - { - RootObjectDefinition rootDefinition = base.MergeObjectDefinitions(name, parentDefinition, childDefinition); - RegisterObjectDefinition(name, rootDefinition); - return rootDefinition; - } -*/ - #endregion - - #region Fields - - /// - /// The instance for this class. - /// - private readonly ILog log = LogManager.GetLogger(typeof(DefaultListableObjectFactory)); - - /// - /// Whether to allow re-registration of a different definition with the - /// same name. - /// - private bool allowObjectDefinitionOverriding = true; - - /// - /// The mapping of object definition objects, keyed by object name. - /// - private readonly IDictionary objectDefinitionMap; - - /// - /// List of object definition names, in registration order. - /// - private readonly IList objectDefinitionNames = new ArrayList(); - - #endregion - - #region IObjectDefinitionRegistry Members - - /// - /// Return the number of objects defined in this registry. - /// - /// - /// The number of objects defined in this registry. - /// - /// - public int ObjectDefinitionCount - { - get { return objectDefinitionMap.Count; } - } - - /// - /// Check if this registry contains a object definition with the given - /// name. - /// - /// - /// The name of the object to look for. - /// - /// - /// if this object factory contains an object - /// definition with the given name. - /// - /// - public override bool ContainsObjectDefinition(string name) - { - return objectDefinitionMap.Contains(name); - } - - /// - /// Register a new object definition with this registry. - /// - /// - /// The name of the object instance to register. - /// - /// - /// The definition of the object instance to register. - /// - /// - /// If the object definition is invalid. - /// - /// - public void RegisterObjectDefinition( - string name, IObjectDefinition objectDefinition) - { - if (objectDefinition is AbstractObjectDefinition) - { - try - { - ((AbstractObjectDefinition) objectDefinition).Validate(); - } - catch (ObjectDefinitionValidationException ex) - { - throw new ObjectDefinitionStoreException( - objectDefinition.ResourceDescription, - name, - "Validation of object definition failed.", - ex); - } - } - object oldObjectDefinition = objectDefinitionMap[name]; - if (oldObjectDefinition != null) - { - if (!AllowObjectDefinitionOverriding) - { - throw new ObjectDefinitionStoreException( - string.Format( - "Cannot register object definition [{0}] for object '{1}': there's already [{2}] bound.", - objectDefinition, name, oldObjectDefinition)); - } - else - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - "Overriding object definition for object '{0}': replacing [{1}] with [{2}].", - name, oldObjectDefinition, objectDefinition)); - } - - #endregion - } - } - else - { - objectDefinitionNames.Add(name); - } - objectDefinitionMap[name] = objectDefinition; - } - - #endregion - - #region IConfigurableListableObjectFactory Members - - /// - /// Ensure that all non-lazy-init singletons are instantiated, also - /// considering s. - /// - /// - /// If one of the singleton objects could not be created. - /// - /// - public void PreInstantiateSingletons() - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Pre-instantiating singletons in factory [" + this + "]"); - } - - #endregion - - try - { - int definitionCount = objectDefinitionNames.Count; - for (int i = 0; i < definitionCount; i++) - { - string name = (string) objectDefinitionNames[i]; - if (!ContainsSingleton(name) && ContainsObjectDefinition(name)) - { - RootObjectDefinition definition - = GetMergedObjectDefinition(name, false); - if (!definition.IsAbstract - && definition.IsSingleton - && !definition.IsLazyInit) - { - Type objectType = ResolveObjectType(definition, name); - if (objectType != null - && typeof(IFactoryObject).IsAssignableFrom(definition.ObjectType)) - { - IFactoryObject factoryObject = (IFactoryObject) GetObject( - ObjectFactoryUtils. - BuildFactoryObjectName(name)); - if (factoryObject.IsSingleton) - { - GetObject(name); - } - } - else - { - GetObject(name); - } - } - } - } - } - catch (ObjectsException) - { - // destroy already created singletons to avoid dangling resources... - try - { - Dispose(); - } - catch (Exception ex) - { - log.Error( - "PreInstantiateSingletons failed but couldn't destroy any already-created singletons.", - ex); - } - throw; - } - } - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// - /// The registered , - /// or null, if specified object definitions does not exist. - /// - /// - /// If is null or empty string. - /// - /// - public override IObjectDefinition GetObjectDefinition(string name) - { - return GetObjectDefinition(name, false); - } - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// Whether to search parent object factories. - /// - /// The registered , - /// or null, if specified object definitions does not exist. - /// - /// - /// If is null or empty string. - /// - /// - public override IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) - { - if (StringUtils.IsNullOrEmpty(name)) - { - throw new ArgumentException( - "Cannot get an object definition with a null or zero length object name string."); - } - - name = TransformedObjectName(name); - IObjectDefinition definition = (IObjectDefinition) objectDefinitionMap[name]; - if (definition == null) - { - if (!includeAncestors || ParentObjectFactory == null) - { - return null; - } - else if (ParentObjectFactory is AbstractObjectFactory) - { - definition = - ((AbstractObjectFactory) ParentObjectFactory).GetObjectDefinition(name, includeAncestors); - } - } - return definition; - } - - #endregion - - #region IListableObjectFactory Members - - /// - /// Return the names of all objects defined in this factory. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectDefinitionNames() - { - return (string[]) ((ArrayList) objectDefinitionNames).ToArray(typeof(string)); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectDefinitionNames(Type type) - { - ArrayList matches = new ArrayList(); - foreach (string name in objectDefinitionNames) - { - if (IsObjectDefinitionTypeMatch(name, type)) - { - matches.Add(name); - } - } - return (string[]) matches.ToArray(typeof(string)); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectNamesForType(Type type) - { - return GetObjectNamesForType(type, true, true); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectNamesForType( - Type type, bool includePrototypes, bool includeFactoryObjects) - { - IList objectNames = DoGetObjectNamesForType(type, includePrototypes, includeFactoryObjects); - return (string[]) ArrayList.Adapter(objectNames).ToArray(typeof(string)); - } - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - /// The (class or interface) to match. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - /// - public IDictionary GetObjectsOfType(Type type) - { - return GetObjectsOfType(type, true, true); - } - - /// - /// Return the object instances that match the given object - /// (including subclasses). - /// - /// - /// The (class or interface) to match. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// An of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If any of the objects could not be created. - /// - /// - public IDictionary GetObjectsOfType( - Type type, bool includePrototypes, bool includeFactoryObjects) - { - IDictionary result = new Hashtable(); - IList objectNames = DoGetObjectNamesForType(type, includePrototypes, includeFactoryObjects); - foreach (string objectName in objectNames) - { - try - { - result.Add(objectName, GetObject(objectName)); - } - catch (ObjectCreationException ex) - { - if (ex.InnerException != null - && ex.GetBaseException().GetType().Equals(typeof(ObjectCurrentlyInCreationException))) - { - // ignoring this is ok... it indicates a circular reference when autowiring - // constructors; we want to find matches other than the currently - // created object itself... - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Ignoring match to currently created object '{0}'.", - objectName), ex); - } - } - else - { - throw; - } - } - } - return result; - } - - // TODO: (ee) What's this method for? It's never used. -/* - protected IList DoGetObjectNamesForTypeNew(Type type, bool includePrototypes, bool includeFactoryObjects) - { - IList result = new ArrayList(); - string[] objectNames = GetObjectDefinitionNames(); - foreach (string objectNam in objectNames) - { - string objectName = objectNam; - if (!IsAlias(objectName)) - { - RootObjectDefinition mod = GetMergedObjectDefinition(objectName, false); - // Only check object definition if it is complete - if (!mod.IsAbstract && - (mod.HasObjectType || !mod.IsLazyInit)) - { - // In case of FactoryObject, match object created by FactoryObject - } - try - { - bool isFactoryObject = IsObjectTypeMatch(objectName, mod, typeof(IFactoryObject)); - bool matchFound = (includePrototypes || mod.IsSingleton) && IsTypeMatch(objectName, type); - if (!matchFound && isFactoryObject) - { - objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); - matchFound = (includePrototypes || mod.IsSingleton) && IsTypeMatch(objectName, type); - } - if (matchFound) - { - result.Add(objectName); - } - } - catch (CannotLoadObjectTypeException ex) - { - // Probably contains a placeholder; lets ignore it for type matching purposes. - if (log.IsDebugEnabled) - { - log.Debug("Ignoring object class loading failure for object '" + objectName + "'", ex); - } - } - } - } - // check singletons too, to catch manually registered singletons... - string[] singletonNames = GetSingletonNames(); - foreach (string objectNam in singletonNames) - { - string objectName = objectNam; - // only check if manually registered... - if (!ContainsObjectDefinition(objectName)) - { - // in the case of an IFactoryObject, match the object created by the IFactoryObject... - if (IsFactoryObject(objectName)) - { - if ((includePrototypes || IsSingleton(objectName)) && IsTypeMatch(objectName, type)) - { - result.Add(objectName); - continue; - } - objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); - } - if (IsTypeMatch(objectName, type)) - { - result.Add(objectName); - } - } - } - return result; - } -*/ - - /// - /// Return the object instances that match the given object - /// (including subclasses). - /// - /// - /// The (class or interface) to match. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// An of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If any of the objects could not be created. - /// - /// - protected IList DoGetObjectNamesForType( - Type type, bool includePrototypes, bool includeFactoryObjects) - { - bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type)); - IList result = new ArrayList(); - if (type != null) - { - string[] objectNames = GetObjectDefinitionNames(); - foreach (string objectName in objectNames) - { - RootObjectDefinition rod = GetMergedObjectDefinition(objectName, false); - // only check complete object definitions... - if (!rod.IsAbstract && rod.HasObjectType) - { - // return the return type of an object created via a factory method... - if (StringUtils.HasText(rod.FactoryMethodName)) - { - Type methodType = GetTypeForFactoryMethod(objectName, rod); - if (methodType != null - && type.IsAssignableFrom(methodType)) - { - result.Add(objectName); - } - } - // in the case of an IFactoryObject, match the object created by the IFactoryObject... - else if (typeof(IFactoryObject).IsAssignableFrom(rod.ObjectType) && !isFactoryType) - { - if (includeFactoryObjects && (includePrototypes || IsSingleton(objectName)) && - IsObjectTypeMatch(objectName, type)) - { - result.Add(objectName); - } - } - else - { - string factoryObjectName = objectName; - // if type to match is an IFactoryObject, match the IFactoryObject itself; - // else, match the object instance... - if (isFactoryType) - { - factoryObjectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); - } - if ((includePrototypes || rod.IsSingleton) && //MLP - (type.IsAssignableFrom(rod.ObjectType))) - { - result.Add(factoryObjectName); - } - } - } - } - - // check singletons too, to catch manually registered singletons... - string[] singletonNames = GetSingletonNames(); - foreach (string objectName in singletonNames) - { - // only check if manually registered... - if (!ContainsObjectDefinition(objectName)) - { - // in the case of an IFactoryObject, match the object created by the IFactoryObject... - if (IsFactoryObject(objectName) && !isFactoryType) - { - if (includeFactoryObjects && (includePrototypes || IsSingleton(objectName)) && - IsObjectTypeMatch(objectName, type)) - { - result.Add(objectName); - } - } - else - { - string factoryObjectName = objectName; - // if type to match is an IFactoryObject, match the IFactoryObject itself... - // else, match the object instance... - if (isFactoryType) - { - factoryObjectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); - } - if (IsObjectTypeMatch(factoryObjectName, type)) - { - result.Add(factoryObjectName); - } - } - } - } - } - return result; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Globalization; +using Common.Logging; +using Spring.Core; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Concrete implementation of the + /// and + /// + /// interfaces. + /// + /// + ///

+ /// This class is a full-fledged object factory based on object definitions + /// that is usable straight out of the box. + ///

+ ///

+ /// Can be used as an object factory in and of itself, or as a superclass + /// for custom object factory implementations. Note that readers for + /// specific object definition formats are typically implemented separately + /// rather than as object factory subclasses. + ///

+ ///

+ /// For an alternative implementation of the + /// interface, + /// have a look at the + /// + /// class, which manages existing object instances rather than creating new + /// ones based on object definitions. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// + [Serializable] + public class DefaultListableObjectFactory : + AbstractAutowireCapableObjectFactory, + IConfigurableListableObjectFactory, + IObjectDefinitionRegistry + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public DefaultListableObjectFactory() : this(true, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// Flag specifying whether to make this object factory case sensitive or not. + public DefaultListableObjectFactory(bool caseSensitive) : this(caseSensitive, null) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The parent object factory. + public DefaultListableObjectFactory(IObjectFactory parentFactory) + : this(true, parentFactory) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// Flag specifying whether to make this object factory case sensitive or not. + /// The parent object factory. + public DefaultListableObjectFactory(bool caseSensitive, IObjectFactory parentFactory) + : base(caseSensitive, parentFactory) + { + if (caseSensitive) + { + objectDefinitionMap = new Hashtable(); + } + else + { + objectDefinitionMap = CollectionsUtil.CreateCaseInsensitiveHashtable(); + } + } + + #endregion + + #region Properties + + /// + /// Should object definitions registered under the same name as an + /// existing object definition be allowed? + /// + /// + ///

+ /// If , then the new object definition will + /// replace (override) the existing object definition. If + /// , an exception will be thrown when + /// an attempt is made to register an object definition under the same + /// name as an already existing object definition. + ///

+ ///

+ /// The default is . + ///

+ ///
+ /// + /// is the registration of an object definition + /// under the same name as an existing object definition is allowed. + /// + public bool AllowObjectDefinitionOverriding + { + get { return allowObjectDefinitionOverriding; } + set { allowObjectDefinitionOverriding = value; } + } + + #endregion + + #region Methods + + /// + /// Find object instances that match the . + /// + /// + ///

+ /// Called by autowiring. If a subclass cannot obtain information about object + /// names by , a corresponding exception should be thrown. + ///

+ ///
+ /// + /// The type of the objects to look up. + /// + /// + /// An of object names and object + /// instances that match the , or + /// if none is found. + /// + /// + /// In case of errors. + /// + protected override IDictionary FindMatchingObjects(Type requiredType) + { + return ObjectFactoryUtils.ObjectsOfTypeIncludingAncestors( + this, requiredType, true, true); + } + + /// + /// Return the names of the objects that depend on the given object. + /// + /// + ///

+ /// Called by the + /// + /// so that dependant objects are able to be disposed of first. + ///

+ ///
+ /// + /// The name of the object to find depending objects for. + /// + /// + /// The array of names of depending objects, or the empty string array if none. + /// + /// + /// In case of errors. + /// + protected override string[] GetDependingObjectNames(string objectName) + { + ArrayList dependingObjectNames = new ArrayList(); + string[] allObjectDefinitionNames = GetObjectDefinitionNames(); + foreach (string name in allObjectDefinitionNames) + { + if (ContainsObjectDefinition(name)) + { + RootObjectDefinition rod + = GetMergedObjectDefinition(name, false); + if (rod.DependsOn != null) + { + IList dependsOn = new ArrayList(rod.DependsOn); + if (dependsOn.Contains(objectName)) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Found depending object '{0}' for object '{1}'.", + name, objectName)); + } + + #endregion + + dependingObjectNames.Add(name); + } + } + } + } + return (string[]) dependingObjectNames.ToArray(typeof(string)); + } + + /// + /// Check whether the specified object matches the supplied . + /// + /// The name of the object to check. + /// + /// The to check for. + /// + /// + /// if the object matches the supplied , + /// or if the supplied is . + /// + private bool IsObjectTypeMatch(string objectName, Type type) + { + if (type == null) + { + return true; + } + Type objectType = GetType(objectName); + return (objectType != null && type.IsAssignableFrom(objectType)); + } + + private bool IsObjectDefinitionTypeMatch(string name, Type checkedType) + { + if (checkedType == null) + { + return true; + } + RootObjectDefinition rod = GetMergedObjectDefinition(name, false); + return (rod.HasObjectType && checkedType.IsAssignableFrom(rod.ObjectType)); + } +/* + /// + /// Merges the object definitions. + /// + /// Object definition name. + /// The parent definition. + /// The child definition. + /// Merged object definition. + protected override RootObjectDefinition MergeObjectDefinitions(string name, IObjectDefinition parentDefinition, + IObjectDefinition childDefinition) + { + RootObjectDefinition rootDefinition = base.MergeObjectDefinitions(name, parentDefinition, childDefinition); + RegisterObjectDefinition(name, rootDefinition); + return rootDefinition; + } +*/ + #endregion + + #region Fields + + /// + /// The instance for this class. + /// + private readonly ILog log = LogManager.GetLogger(typeof(DefaultListableObjectFactory)); + + /// + /// Whether to allow re-registration of a different definition with the + /// same name. + /// + private bool allowObjectDefinitionOverriding = true; + + /// + /// The mapping of object definition objects, keyed by object name. + /// + private readonly IDictionary objectDefinitionMap; + + /// + /// List of object definition names, in registration order. + /// + private readonly IList objectDefinitionNames = new ArrayList(); + + #endregion + + #region IObjectDefinitionRegistry Members + + /// + /// Return the number of objects defined in this registry. + /// + /// + /// The number of objects defined in this registry. + /// + /// + public int ObjectDefinitionCount + { + get { return objectDefinitionMap.Count; } + } + + /// + /// Check if this registry contains a object definition with the given + /// name. + /// + /// + /// The name of the object to look for. + /// + /// + /// if this object factory contains an object + /// definition with the given name. + /// + /// + public override bool ContainsObjectDefinition(string name) + { + return objectDefinitionMap.Contains(name); + } + + /// + /// Register a new object definition with this registry. + /// + /// + /// The name of the object instance to register. + /// + /// + /// The definition of the object instance to register. + /// + /// + /// If the object definition is invalid. + /// + /// + public void RegisterObjectDefinition( + string name, IObjectDefinition objectDefinition) + { + if (objectDefinition is AbstractObjectDefinition) + { + try + { + ((AbstractObjectDefinition) objectDefinition).Validate(); + } + catch (ObjectDefinitionValidationException ex) + { + throw new ObjectDefinitionStoreException( + objectDefinition.ResourceDescription, + name, + "Validation of object definition failed.", + ex); + } + } + object oldObjectDefinition = objectDefinitionMap[name]; + if (oldObjectDefinition != null) + { + if (!AllowObjectDefinitionOverriding) + { + throw new ObjectDefinitionStoreException( + string.Format( + "Cannot register object definition [{0}] for object '{1}': there's already [{2}] bound.", + objectDefinition, name, oldObjectDefinition)); + } + else + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + "Overriding object definition for object '{0}': replacing [{1}] with [{2}].", + name, oldObjectDefinition, objectDefinition)); + } + + #endregion + } + } + else + { + objectDefinitionNames.Add(name); + } + objectDefinitionMap[name] = objectDefinition; + } + + #endregion + + #region IConfigurableListableObjectFactory Members + + /// + /// Ensure that all non-lazy-init singletons are instantiated, also + /// considering s. + /// + /// + /// If one of the singleton objects could not be created. + /// + /// + public void PreInstantiateSingletons() + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Pre-instantiating singletons in factory [" + this + "]"); + } + + #endregion + + try + { + int definitionCount = objectDefinitionNames.Count; + for (int i = 0; i < definitionCount; i++) + { + string name = (string) objectDefinitionNames[i]; + if (!ContainsSingleton(name) && ContainsObjectDefinition(name)) + { + RootObjectDefinition definition + = GetMergedObjectDefinition(name, false); + if (!definition.IsAbstract + && definition.IsSingleton + && !definition.IsLazyInit) + { + Type objectType = ResolveObjectType(definition, name); + if (objectType != null + && typeof(IFactoryObject).IsAssignableFrom(definition.ObjectType)) + { + IFactoryObject factoryObject = (IFactoryObject) GetObject( + ObjectFactoryUtils. + BuildFactoryObjectName(name)); + if (factoryObject.IsSingleton) + { + GetObject(name); + } + } + else + { + GetObject(name); + } + } + } + } + } + catch (ObjectsException) + { + // destroy already created singletons to avoid dangling resources... + try + { + Dispose(); + } + catch (Exception ex) + { + log.Error( + "PreInstantiateSingletons failed but couldn't destroy any already-created singletons.", + ex); + } + throw; + } + } + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// + /// The registered , + /// or null, if specified object definitions does not exist. + /// + /// + /// If is null or empty string. + /// + /// + public override IObjectDefinition GetObjectDefinition(string name) + { + return GetObjectDefinition(name, false); + } + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// Whether to search parent object factories. + /// + /// The registered , + /// or null, if specified object definitions does not exist. + /// + /// + /// If is null or empty string. + /// + /// + public override IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) + { + if (StringUtils.IsNullOrEmpty(name)) + { + throw new ArgumentException( + "Cannot get an object definition with a null or zero length object name string."); + } + + name = TransformedObjectName(name); + IObjectDefinition definition = (IObjectDefinition) objectDefinitionMap[name]; + if (definition == null) + { + if (!includeAncestors || ParentObjectFactory == null) + { + return null; + } + else if (ParentObjectFactory is AbstractObjectFactory) + { + definition = + ((AbstractObjectFactory) ParentObjectFactory).GetObjectDefinition(name, includeAncestors); + } + } + return definition; + } + + #endregion + + #region IListableObjectFactory Members + + /// + /// Return the names of all objects defined in this factory. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectDefinitionNames() + { + return (string[]) ((ArrayList) objectDefinitionNames).ToArray(typeof(string)); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectDefinitionNames(Type type) + { + ArrayList matches = new ArrayList(); + foreach (string name in objectDefinitionNames) + { + if (IsObjectDefinitionTypeMatch(name, type)) + { + matches.Add(name); + } + } + return (string[]) matches.ToArray(typeof(string)); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectNamesForType(Type type) + { + return GetObjectNamesForType(type, true, true); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectNamesForType( + Type type, bool includePrototypes, bool includeFactoryObjects) + { + IList objectNames = DoGetObjectNamesForType(type, includePrototypes, includeFactoryObjects); + return (string[]) ArrayList.Adapter(objectNames).ToArray(typeof(string)); + } + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + /// The (class or interface) to match. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + /// + public IDictionary GetObjectsOfType(Type type) + { + return GetObjectsOfType(type, true, true); + } + + /// + /// Return the object instances that match the given object + /// (including subclasses). + /// + /// + /// The (class or interface) to match. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// An of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If any of the objects could not be created. + /// + /// + public IDictionary GetObjectsOfType( + Type type, bool includePrototypes, bool includeFactoryObjects) + { + IDictionary result = new Hashtable(); + IList objectNames = DoGetObjectNamesForType(type, includePrototypes, includeFactoryObjects); + foreach (string objectName in objectNames) + { + try + { + result.Add(objectName, GetObject(objectName)); + } + catch (ObjectCreationException ex) + { + if (ex.InnerException != null + && ex.GetBaseException().GetType().Equals(typeof(ObjectCurrentlyInCreationException))) + { + // ignoring this is ok... it indicates a circular reference when autowiring + // constructors; we want to find matches other than the currently + // created object itself... + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Ignoring match to currently created object '{0}'.", + objectName), ex); + } + } + else + { + throw; + } + } + } + return result; + } + + // TODO: (ee) What's this method for? It's never used. +/* + protected IList DoGetObjectNamesForTypeNew(Type type, bool includePrototypes, bool includeFactoryObjects) + { + IList result = new ArrayList(); + string[] objectNames = GetObjectDefinitionNames(); + foreach (string objectNam in objectNames) + { + string objectName = objectNam; + if (!IsAlias(objectName)) + { + RootObjectDefinition mod = GetMergedObjectDefinition(objectName, false); + // Only check object definition if it is complete + if (!mod.IsAbstract && + (mod.HasObjectType || !mod.IsLazyInit)) + { + // In case of FactoryObject, match object created by FactoryObject + } + try + { + bool isFactoryObject = IsObjectTypeMatch(objectName, mod, typeof(IFactoryObject)); + bool matchFound = (includePrototypes || mod.IsSingleton) && IsTypeMatch(objectName, type); + if (!matchFound && isFactoryObject) + { + objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); + matchFound = (includePrototypes || mod.IsSingleton) && IsTypeMatch(objectName, type); + } + if (matchFound) + { + result.Add(objectName); + } + } + catch (CannotLoadObjectTypeException ex) + { + // Probably contains a placeholder; lets ignore it for type matching purposes. + if (log.IsDebugEnabled) + { + log.Debug("Ignoring object class loading failure for object '" + objectName + "'", ex); + } + } + } + } + // check singletons too, to catch manually registered singletons... + string[] singletonNames = GetSingletonNames(); + foreach (string objectNam in singletonNames) + { + string objectName = objectNam; + // only check if manually registered... + if (!ContainsObjectDefinition(objectName)) + { + // in the case of an IFactoryObject, match the object created by the IFactoryObject... + if (IsFactoryObject(objectName)) + { + if ((includePrototypes || IsSingleton(objectName)) && IsTypeMatch(objectName, type)) + { + result.Add(objectName); + continue; + } + objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); + } + if (IsTypeMatch(objectName, type)) + { + result.Add(objectName); + } + } + } + return result; + } +*/ + + /// + /// Return the object instances that match the given object + /// (including subclasses). + /// + /// + /// The (class or interface) to match. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// An of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If any of the objects could not be created. + /// + /// + protected IList DoGetObjectNamesForType( + Type type, bool includePrototypes, bool includeFactoryObjects) + { + bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type)); + IList result = new ArrayList(); + if (type != null) + { + string[] objectNames = GetObjectDefinitionNames(); + foreach (string objectName in objectNames) + { + RootObjectDefinition rod = GetMergedObjectDefinition(objectName, false); + // only check complete object definitions... + if (!rod.IsAbstract && rod.HasObjectType) + { + // return the return type of an object created via a factory method... + if (StringUtils.HasText(rod.FactoryMethodName)) + { + Type methodType = GetTypeForFactoryMethod(objectName, rod); + if (methodType != null + && type.IsAssignableFrom(methodType)) + { + result.Add(objectName); + } + } + // in the case of an IFactoryObject, match the object created by the IFactoryObject... + else if (typeof(IFactoryObject).IsAssignableFrom(rod.ObjectType) && !isFactoryType) + { + if (includeFactoryObjects && (includePrototypes || IsSingleton(objectName)) && + IsObjectTypeMatch(objectName, type)) + { + result.Add(objectName); + } + } + else + { + string factoryObjectName = objectName; + // if type to match is an IFactoryObject, match the IFactoryObject itself; + // else, match the object instance... + if (isFactoryType) + { + factoryObjectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); + } + if ((includePrototypes || rod.IsSingleton) && //MLP + (type.IsAssignableFrom(rod.ObjectType))) + { + result.Add(factoryObjectName); + } + } + } + } + + // check singletons too, to catch manually registered singletons... + string[] singletonNames = GetSingletonNames(); + foreach (string objectName in singletonNames) + { + // only check if manually registered... + if (!ContainsObjectDefinition(objectName)) + { + // in the case of an IFactoryObject, match the object created by the IFactoryObject... + if (IsFactoryObject(objectName) && !isFactoryType) + { + if (includeFactoryObjects && (includePrototypes || IsSingleton(objectName)) && + IsObjectTypeMatch(objectName, type)) + { + result.Add(objectName); + } + } + else + { + string factoryObjectName = objectName; + // if type to match is an IFactoryObject, match the IFactoryObject itself... + // else, match the object instance... + if (isFactoryType) + { + factoryObjectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName); + } + if (IsObjectTypeMatch(factoryObjectName, type)) + { + result.Add(factoryObjectName); + } + } + } + } + } + return result; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectDefinitionFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectDefinitionFactory.cs index e1e914c8..4c0c1080 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectDefinitionFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectDefinitionFactory.cs @@ -1,114 +1,113 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Default implementation of the - /// - /// interface. - /// - /// - ///

- /// Does not support per - /// loading. - ///

- ///
- /// Aleksandar Seovic - /// $Id: DefaultObjectDefinitionFactory.cs,v 1.13 2007/08/01 12:29:43 bbaia Exp $ - [Serializable] - public class DefaultObjectDefinitionFactory : IObjectDefinitionFactory - { - #region IObjectDefinitionFactory Members - - /// - /// Factory style method for getting concrete - /// - /// instances. - /// - /// /// If no parent is specified, a RootObjectDefinition is created, otherwise a - /// ChildObjectDefinition. - /// The of the defined object. - /// The name of the parent object definition (if any). - /// The against which any class names - /// will be resolved into instances. - /// - /// An - /// - /// instance. - /// - public virtual AbstractObjectDefinition CreateObjectDefinition(string typeName, string parent, AppDomain domain) - { - Type objectType = null; - if (StringUtils.HasText(typeName) && domain != null) - { - try - { - objectType = TypeResolutionUtils.ResolveType(typeName); - } - // try later.... - catch { } - } - if (StringUtils.IsNullOrEmpty(parent)) - { - if (objectType != null) - { - return new RootObjectDefinition(objectType); - - } - else - { - RootObjectDefinition rootObjectDefinition = new RootObjectDefinition(); - rootObjectDefinition.ObjectTypeName = typeName; - return rootObjectDefinition; - } - } - else - { - if (objectType != null) - { - ChildObjectDefinition childObjectDefinition = new ChildObjectDefinition(parent); - childObjectDefinition.ObjectType = objectType; - return childObjectDefinition; - } - else - { - ChildObjectDefinition childObjectDefinition = new ChildObjectDefinition(parent); - childObjectDefinition.ObjectTypeName = typeName; - return childObjectDefinition; - } - } - } - - #endregion - - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Default implementation of the + /// + /// interface. + /// + /// + ///

+ /// Does not support per + /// loading. + ///

+ ///
+ /// Aleksandar Seovic + [Serializable] + public class DefaultObjectDefinitionFactory : IObjectDefinitionFactory + { + #region IObjectDefinitionFactory Members + + /// + /// Factory style method for getting concrete + /// + /// instances. + /// + /// /// If no parent is specified, a RootObjectDefinition is created, otherwise a + /// ChildObjectDefinition. + /// The of the defined object. + /// The name of the parent object definition (if any). + /// The against which any class names + /// will be resolved into instances. + /// + /// An + /// + /// instance. + /// + public virtual AbstractObjectDefinition CreateObjectDefinition(string typeName, string parent, AppDomain domain) + { + Type objectType = null; + if (StringUtils.HasText(typeName) && domain != null) + { + try + { + objectType = TypeResolutionUtils.ResolveType(typeName); + } + // try later.... + catch { } + } + if (StringUtils.IsNullOrEmpty(parent)) + { + if (objectType != null) + { + return new RootObjectDefinition(objectType); + + } + else + { + RootObjectDefinition rootObjectDefinition = new RootObjectDefinition(); + rootObjectDefinition.ObjectTypeName = typeName; + return rootObjectDefinition; + } + } + else + { + if (objectType != null) + { + ChildObjectDefinition childObjectDefinition = new ChildObjectDefinition(parent); + childObjectDefinition.ObjectType = objectType; + return childObjectDefinition; + } + else + { + ChildObjectDefinition childObjectDefinition = new ChildObjectDefinition(parent); + childObjectDefinition.ObjectTypeName = typeName; + return childObjectDefinition; + } + } + } + + #endregion + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectNameGenerator.cs b/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectNameGenerator.cs index 87a3cb75..12838ee6 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectNameGenerator.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/DefaultObjectNameGenerator.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Objects.Factory.Config; - -namespace Spring.Objects.Factory.Support -{ - /// - /// Default implementation of the interface, deleagting to - /// . - /// - /// Note that this implementation is only able to handle - /// subclasses such as - /// and - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: DefaultObjectNameGenerator.cs,v 1.1 2007/05/23 20:16:13 markpollack Exp $ - public class DefaultObjectNameGenerator : IObjectNameGenerator - { - #region IObjectNameGenerator Members - - /// - /// Generates an object name for the given object definition. - /// - /// The object definition to generate a name for. - /// The object definitions registry that the given definition is - /// supposed to be registerd with - /// the generated object name - public string GenerateObjectName(IObjectDefinition definition, IObjectDefinitionRegistry registry) - { - IConfigurableObjectDefinition objectDef = definition as IConfigurableObjectDefinition; - if (objectDef == null) - { - throw new ArgumentException( - "DefaultObjectNameGenerator is only able to handle IConfigurableObjectDefinition subclasses: " + - definition); - } - return ObjectDefinitionReaderUtils.GenerateObjectName(objectDef, registry); - } - - #endregion - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Objects.Factory.Config; + +namespace Spring.Objects.Factory.Support +{ + /// + /// Default implementation of the interface, deleagting to + /// . + /// + /// Note that this implementation is only able to handle + /// subclasses such as + /// and + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class DefaultObjectNameGenerator : IObjectNameGenerator + { + #region IObjectNameGenerator Members + + /// + /// Generates an object name for the given object definition. + /// + /// The object definition to generate a name for. + /// The object definitions registry that the given definition is + /// supposed to be registerd with + /// the generated object name + public string GenerateObjectName(IObjectDefinition definition, IObjectDefinitionRegistry registry) + { + IConfigurableObjectDefinition objectDef = definition as IConfigurableObjectDefinition; + if (objectDef == null) + { + throw new ArgumentException( + "DefaultObjectNameGenerator is only able to handle IConfigurableObjectDefinition subclasses: " + + definition); + } + return ObjectDefinitionReaderUtils.GenerateObjectName(objectDef, registry); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/DelegatingMethodReplacer.cs b/src/Spring/Spring.Core/Objects/Factory/Support/DelegatingMethodReplacer.cs index 1a4815ab..be403259 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/DelegatingMethodReplacer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/DelegatingMethodReplacer.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// An - /// implementation that delegates to an - /// that is - /// obtained as the result of a lookup in an associated IoC container. - /// - /// - ///

- /// This class is reserved for internal use within the framework; it is - /// not intended to be used by application developers using Spring.NET. - ///

- ///
- /// Rick Evans - /// $Id: DelegatingMethodReplacer.cs,v 1.3 2007/07/30 17:52:22 markpollack Exp $ - public sealed class DelegatingMethodReplacer : AbstractMethodReplacer - { - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The object definition that is the target of the method replacement. - /// - /// - /// The enclosing IoC container with which the above - /// is associated. - /// - /// - /// If either of the supplied arguments is . - /// - public DelegatingMethodReplacer(IConfigurableObjectDefinition objectDefinition, IObjectFactory objectFactory) - : base(objectDefinition, objectFactory) - { - } - - /// - /// Reimplements the supplied by delegating to - /// another - /// looked up in an enclosing IoC container. - /// - /// - /// The instance whose is to be - /// (re)implemented. - /// - /// - /// The method that is to be (re)implemented. - /// - /// The target method's arguments. - /// - /// The result of the delegated call to the looked up - /// . - /// - public override object Implement(object target, MethodInfo method, object[] arguments) - { - ReplacedMethodOverride ovr = (ReplacedMethodOverride) GetOverride(method); - IMethodReplacer methodReplacement = (IMethodReplacer) GetObject(ovr.MethodReplacerObjectName); - return methodReplacement.Implement(target, method, arguments); - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// An + /// implementation that delegates to an + /// that is + /// obtained as the result of a lookup in an associated IoC container. + /// + /// + ///

+ /// This class is reserved for internal use within the framework; it is + /// not intended to be used by application developers using Spring.NET. + ///

+ ///
+ /// Rick Evans + public sealed class DelegatingMethodReplacer : AbstractMethodReplacer + { + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The object definition that is the target of the method replacement. + /// + /// + /// The enclosing IoC container with which the above + /// is associated. + /// + /// + /// If either of the supplied arguments is . + /// + public DelegatingMethodReplacer(IConfigurableObjectDefinition objectDefinition, IObjectFactory objectFactory) + : base(objectDefinition, objectFactory) + { + } + + /// + /// Reimplements the supplied by delegating to + /// another + /// looked up in an enclosing IoC container. + /// + /// + /// The instance whose is to be + /// (re)implemented. + /// + /// + /// The method that is to be (re)implemented. + /// + /// The target method's arguments. + /// + /// The result of the delegated call to the looked up + /// . + /// + public override object Implement(object target, MethodInfo method, object[] arguments) + { + ReplacedMethodOverride ovr = (ReplacedMethodOverride) GetOverride(method); + IMethodReplacer methodReplacement = (IMethodReplacer) GetObject(ovr.MethodReplacerObjectName); + return methodReplacement.Implement(target, method, arguments); + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/DependencyCheckingMode.cs b/src/Spring/Spring.Core/Objects/Factory/Support/DependencyCheckingMode.cs index 2a9acdc9..2587917d 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/DependencyCheckingMode.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/DependencyCheckingMode.cs @@ -1,58 +1,58 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -using System; - -namespace Spring.Objects.Factory.Support { - - /// - /// The various modes of dependency checking. - /// - /// Rick Evans (.NET) - [Serializable] - public enum DependencyCheckingMode - { - /// - /// DO not do any dependency checking. - /// - None = 0, - - /// - /// Check object references. - /// - Objects = 1, - - /// - /// Just check primitive (string, int, etc) values. - /// - Simple = 2, - - /// - /// Check everything. - /// - All = 3 - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +using System; + +namespace Spring.Objects.Factory.Support { + + /// + /// The various modes of dependency checking. + /// + /// Rick Evans (.NET) + [Serializable] + public enum DependencyCheckingMode + { + /// + /// DO not do any dependency checking. + /// + None = 0, + + /// + /// Check object references. + /// + Objects = 1, + + /// + /// Just check primitive (string, int, etc) values. + /// + Simple = 2, + + /// + /// Check everything. + /// + All = 3 + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IConfigurableObjectDefinition.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IConfigurableObjectDefinition.cs index 5afc8051..211efe2e 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IConfigurableObjectDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IConfigurableObjectDefinition.cs @@ -1,197 +1,196 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Describes a configurable object instance, which has property values, - /// constructor argument values, and further information supplied by concrete - /// implementations. - /// - /// Rick Evans - /// $Id: IConfigurableObjectDefinition.cs,v 1.1 2007/07/30 17:52:22 markpollack Exp $ - public interface IConfigurableObjectDefinition : IObjectDefinition - { - /// - /// Return the property values to be applied to a new instance of the object. - /// - new MutablePropertyValues PropertyValues { get; set; } - - /// - /// Return the constructor argument values for this object. - /// - new ConstructorArgumentValues ConstructorArgumentValues { get; set; } - - /// - /// The method overrides (if any) for this object. - /// - /// - /// The method overrides (if any) for this object; may be an - /// empty collection but is guaranteed not to be - /// . - /// - MethodOverrides MethodOverrides { get; set; } - - /// - /// Return the event handlers for any events exposed by this object. - /// - new EventValues EventHandlerValues { get; set; } - - /// - /// Return a description of the resource that this object definition - /// came from (for the purpose of showing context in case of errors). - /// - new string ResourceDescription { get; set; } - - /// - /// Is this object definition "abstract", i.e. not meant to be instantiated - /// itself but rather just serving as parent for concrete child object - /// definitions. - /// - /// - /// if this object definition is "abstract". - /// - new bool IsAbstract { get; set; } - - /// - /// Returns the of the object definition (if any). - /// - /// - /// A resolved object . - /// - /// - /// If the of the object definition is not a - /// resolved or . - /// - new Type ObjectType { get; set; } - - /// - /// Returns the of the - /// of the object definition (if any). - /// - new string ObjectTypeName { get; set; } - - /// - /// Return whether this a Singleton, with a single, shared instance - /// returned on all calls. - /// - /// - ///

- /// If , an object factory will apply the Prototype - /// design pattern, with each caller requesting an instance getting an - /// independent instance. How this is defined will depend on the - /// object factory implementation. Singletons are the commoner type. - ///

- ///
- new bool IsSingleton { get; set; } - - /// - /// Is this object lazily initialized? - /// - ///

- /// Only applicable to a singleton object. - ///

- ///

- /// If , it will get instantiated on startup by object factories - /// that perform eager initialization of singletons. - ///

- ///
- new bool IsLazyInit { get; set; } - - /// - /// The autowire mode as specified in the object definition. - /// - /// - ///

- /// This determines whether any automagical detection and setting of - /// object references will happen. Default is - /// , - /// which means there's no autowire. - ///

- ///
- new AutoWiringMode AutowireMode { get; set; } - - /// - /// The dependency check code. - /// - DependencyCheckingMode DependencyCheck { get; set; } - - /// - /// The object names that this object depends on. - /// - /// - ///

- /// The object factory will guarantee that these objects get initialized - /// before. - ///

- ///

- /// Note that dependencies are normally expressed through object properties - /// or constructor arguments. This property should just be necessary for - /// other kinds of dependencies like statics (*ugh*) or database - /// preparation on startup. - ///

- ///
- new string[] DependsOn { get; set; } - - /// - /// The name of the initializer method. - /// - /// - ///

- /// The default is , in which case there is no initializer method. - ///

- ///
- new string InitMethodName { get; set; } - - /// - /// Return the name of the destroy method. - /// - /// - ///

- /// The default is , in which case there is no destroy method. - ///

- ///
- new string DestroyMethodName { get; set; } - - /// - /// The name of the factory method to use (if any). - /// - /// - ///

- /// This method will be invoked with constructor arguments, or with no - /// arguments if none are specified. The static method will be invoked on - /// the specified . - ///

- ///
- new string FactoryMethodName { get; set; } - - /// - /// The name of the factory object to use (if any). - /// - new string FactoryObjectName { get; set; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Describes a configurable object instance, which has property values, + /// constructor argument values, and further information supplied by concrete + /// implementations. + /// + /// Rick Evans + public interface IConfigurableObjectDefinition : IObjectDefinition + { + /// + /// Return the property values to be applied to a new instance of the object. + /// + new MutablePropertyValues PropertyValues { get; set; } + + /// + /// Return the constructor argument values for this object. + /// + new ConstructorArgumentValues ConstructorArgumentValues { get; set; } + + /// + /// The method overrides (if any) for this object. + /// + /// + /// The method overrides (if any) for this object; may be an + /// empty collection but is guaranteed not to be + /// . + /// + MethodOverrides MethodOverrides { get; set; } + + /// + /// Return the event handlers for any events exposed by this object. + /// + new EventValues EventHandlerValues { get; set; } + + /// + /// Return a description of the resource that this object definition + /// came from (for the purpose of showing context in case of errors). + /// + new string ResourceDescription { get; set; } + + /// + /// Is this object definition "abstract", i.e. not meant to be instantiated + /// itself but rather just serving as parent for concrete child object + /// definitions. + /// + /// + /// if this object definition is "abstract". + /// + new bool IsAbstract { get; set; } + + /// + /// Returns the of the object definition (if any). + /// + /// + /// A resolved object . + /// + /// + /// If the of the object definition is not a + /// resolved or . + /// + new Type ObjectType { get; set; } + + /// + /// Returns the of the + /// of the object definition (if any). + /// + new string ObjectTypeName { get; set; } + + /// + /// Return whether this a Singleton, with a single, shared instance + /// returned on all calls. + /// + /// + ///

+ /// If , an object factory will apply the Prototype + /// design pattern, with each caller requesting an instance getting an + /// independent instance. How this is defined will depend on the + /// object factory implementation. Singletons are the commoner type. + ///

+ ///
+ new bool IsSingleton { get; set; } + + /// + /// Is this object lazily initialized? + /// + ///

+ /// Only applicable to a singleton object. + ///

+ ///

+ /// If , it will get instantiated on startup by object factories + /// that perform eager initialization of singletons. + ///

+ ///
+ new bool IsLazyInit { get; set; } + + /// + /// The autowire mode as specified in the object definition. + /// + /// + ///

+ /// This determines whether any automagical detection and setting of + /// object references will happen. Default is + /// , + /// which means there's no autowire. + ///

+ ///
+ new AutoWiringMode AutowireMode { get; set; } + + /// + /// The dependency check code. + /// + DependencyCheckingMode DependencyCheck { get; set; } + + /// + /// The object names that this object depends on. + /// + /// + ///

+ /// The object factory will guarantee that these objects get initialized + /// before. + ///

+ ///

+ /// Note that dependencies are normally expressed through object properties + /// or constructor arguments. This property should just be necessary for + /// other kinds of dependencies like statics (*ugh*) or database + /// preparation on startup. + ///

+ ///
+ new string[] DependsOn { get; set; } + + /// + /// The name of the initializer method. + /// + /// + ///

+ /// The default is , in which case there is no initializer method. + ///

+ ///
+ new string InitMethodName { get; set; } + + /// + /// Return the name of the destroy method. + /// + /// + ///

+ /// The default is , in which case there is no destroy method. + ///

+ ///
+ new string DestroyMethodName { get; set; } + + /// + /// The name of the factory method to use (if any). + /// + /// + ///

+ /// This method will be invoked with constructor arguments, or with no + /// arguments if none are specified. The static method will be invoked on + /// the specified . + ///

+ ///
+ new string FactoryMethodName { get; set; } + + /// + /// The name of the factory object to use (if any). + /// + new string FactoryObjectName { get; set; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IInstantiationStrategy.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IInstantiationStrategy.cs index 756f02f9..02d3c19a 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IInstantiationStrategy.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IInstantiationStrategy.cs @@ -1,119 +1,118 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Reflection; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Responsible for creating instances corresponding to a - /// . - /// - /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: IInstantiationStrategy.cs,v 1.6 2006/04/09 07:18:49 markpollack Exp $ - public interface IInstantiationStrategy - { - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory); - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to instantiate - /// the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory, - ConstructorInfo constructor, object[] arguments); - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to get the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory, - MethodInfo factoryMethod, object[] arguments); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Reflection; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Responsible for creating instances corresponding to a + /// . + /// + /// Rod Johnson + /// Rick Evans (.NET) + public interface IInstantiationStrategy + { + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory); + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to instantiate + /// the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory, + ConstructorInfo constructor, object[] arguments); + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to get the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory, + MethodInfo factoryMethod, object[] arguments); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IManagedCollection.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IManagedCollection.cs index fe86b352..bb16bd5b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IManagedCollection.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IManagedCollection.cs @@ -1,165 +1,164 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Denotes a special placeholder collection that may contain - /// s or - /// other placeholder objects that will need to be resolved. - /// - /// - ///

- /// 'A special placeholder collection' means that the elements of this - /// collection can be placeholders for objects that will be resolved later by - /// a Spring.NET IoC container, i.e. the elements themselves will be - /// resolved at runtime by the enclosing IoC container. - ///

- ///

- /// The core Spring.NET library already provides three implementations of this interface - /// straight out of the box; they are... - ///

- /// - /// - /// - /// . - /// - /// - /// - /// - /// . - /// - /// - /// - /// - /// . - /// - /// - /// - ///

- /// If you have a custom collection class (i.e. a class that either implements the - /// directly or derives from a class that does) - /// that you would like to expose as a special placeholder collection (i.e. one that can - /// have s as elements - /// that will be resolved at runtime by an appropriate Spring.NET IoC container, just - /// implement this interface. - ///

- ///
- /// - ///

- /// Lets say one has a Bag class (i.e. a collection that supports bag style semantics). - ///

- /// - /// using System; - /// - /// using Spring.Objects.Factory.Support; - /// - /// namespace MyNamespace - /// { - /// public sealed class Bag : ICollection - /// { - /// // ICollection implementation elided for clarity... - /// - /// public void Add(object o) - /// { - /// // implementation elided for clarity... - /// } - /// } - /// - /// public class ManagedBag : Bag, IManagedCollection - /// { - /// public ICollection Resolve( - /// string objectName, RootObjectDefinition definition, - /// string propertyName, ManagedCollectionElementResolver resolver) - /// { - /// Bag newBag = new Bag(); - /// string elementName = propertyName + "[bag-element]"; - /// foreach(object element in this) - /// { - /// object resolvedElement = resolver(objectName, definition, elementName, element); - /// newBag.Add(resolvedElement); - /// } - /// return newBag; - /// } - /// } - /// } - /// - ///
- /// Rick Evans - /// $Id: IManagedCollection.cs,v 1.5 2007/03/16 03:05:37 bbaia Exp $ - public interface IManagedCollection : ICollection - { - /// - /// Resolves this managed collection at runtime. - /// - /// - /// The name of the top level object that is having the value of one of it's - /// collection properties resolved. - /// - /// - /// The definition of the named top level object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The callback that will actually do the donkey work of resolving - /// this managed collection. - /// - /// A fully resolved collection. - ICollection Resolve(string objectName, RootObjectDefinition definition, - string propertyName, ManagedCollectionElementResolver resolver); - } - - /// - /// Resolves a single element value of a managed collection. - /// - /// - ///

- /// If the does not need to be resolved or - /// converted to an appropriate , the - /// will be returned as-is. - ///

- ///
- /// - /// The name of the top level object that is having the value of one of it's - /// collection properties resolved. - /// - /// - /// The definition of the named top level object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// That element of a managed collection that may need to be resolved - /// to a concrete value. - /// - /// A fully resolved element. - public delegate object ManagedCollectionElementResolver( - string name, RootObjectDefinition definition, string argumentName, object element); +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Denotes a special placeholder collection that may contain + /// s or + /// other placeholder objects that will need to be resolved. + /// + /// + ///

+ /// 'A special placeholder collection' means that the elements of this + /// collection can be placeholders for objects that will be resolved later by + /// a Spring.NET IoC container, i.e. the elements themselves will be + /// resolved at runtime by the enclosing IoC container. + ///

+ ///

+ /// The core Spring.NET library already provides three implementations of this interface + /// straight out of the box; they are... + ///

+ /// + /// + /// + /// . + /// + /// + /// + /// + /// . + /// + /// + /// + /// + /// . + /// + /// + /// + ///

+ /// If you have a custom collection class (i.e. a class that either implements the + /// directly or derives from a class that does) + /// that you would like to expose as a special placeholder collection (i.e. one that can + /// have s as elements + /// that will be resolved at runtime by an appropriate Spring.NET IoC container, just + /// implement this interface. + ///

+ ///
+ /// + ///

+ /// Lets say one has a Bag class (i.e. a collection that supports bag style semantics). + ///

+ /// + /// using System; + /// + /// using Spring.Objects.Factory.Support; + /// + /// namespace MyNamespace + /// { + /// public sealed class Bag : ICollection + /// { + /// // ICollection implementation elided for clarity... + /// + /// public void Add(object o) + /// { + /// // implementation elided for clarity... + /// } + /// } + /// + /// public class ManagedBag : Bag, IManagedCollection + /// { + /// public ICollection Resolve( + /// string objectName, RootObjectDefinition definition, + /// string propertyName, ManagedCollectionElementResolver resolver) + /// { + /// Bag newBag = new Bag(); + /// string elementName = propertyName + "[bag-element]"; + /// foreach(object element in this) + /// { + /// object resolvedElement = resolver(objectName, definition, elementName, element); + /// newBag.Add(resolvedElement); + /// } + /// return newBag; + /// } + /// } + /// } + /// + ///
+ /// Rick Evans + public interface IManagedCollection : ICollection + { + /// + /// Resolves this managed collection at runtime. + /// + /// + /// The name of the top level object that is having the value of one of it's + /// collection properties resolved. + /// + /// + /// The definition of the named top level object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The callback that will actually do the donkey work of resolving + /// this managed collection. + /// + /// A fully resolved collection. + ICollection Resolve(string objectName, RootObjectDefinition definition, + string propertyName, ManagedCollectionElementResolver resolver); + } + + /// + /// Resolves a single element value of a managed collection. + /// + /// + ///

+ /// If the does not need to be resolved or + /// converted to an appropriate , the + /// will be returned as-is. + ///

+ ///
+ /// + /// The name of the top level object that is having the value of one of it's + /// collection properties resolved. + /// + /// + /// The definition of the named top level object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// That element of a managed collection that may need to be resolved + /// to a concrete value. + /// + /// A fully resolved element. + public delegate object ManagedCollectionElementResolver( + string name, RootObjectDefinition definition, string argumentName, object element); } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IMethodReplacer.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IMethodReplacer.cs index e61a5634..89fd74d5 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IMethodReplacer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IMethodReplacer.cs @@ -1,71 +1,70 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Permits the (re)implementation of an arbitrary method on a Spring.NET - /// IoC container managed object. - /// - /// - ///

- /// Encapsulates the notion of the Method-Injection form of Dependency - /// Injection. - ///

- ///

- /// Methods that are dependency injected with implementations of this - /// interface may be (but need not be) , in which - /// case the container will create a concrete subclass of the - /// class prior to instantiation. - ///

- ///

- /// Do not use this mechanism as a means of AOP. See the reference - /// manual for examples of appropriate usages of this interface. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: IMethodReplacer.cs,v 1.2 2006/04/09 07:18:49 markpollack Exp $ - public interface IMethodReplacer - { - /// - /// Reimplement the supplied . - /// - /// - /// The instance whose is to be - /// (re)implemented. - /// - /// - /// The method that is to be (re)implemented. - /// - /// The target method's arguments. - /// - /// The result of the (re)implementation of the method call. - /// - object Implement(object target, MethodInfo method, object[] arguments); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Permits the (re)implementation of an arbitrary method on a Spring.NET + /// IoC container managed object. + /// + /// + ///

+ /// Encapsulates the notion of the Method-Injection form of Dependency + /// Injection. + ///

+ ///

+ /// Methods that are dependency injected with implementations of this + /// interface may be (but need not be) , in which + /// case the container will create a concrete subclass of the + /// class prior to instantiation. + ///

+ ///

+ /// Do not use this mechanism as a means of AOP. See the reference + /// manual for examples of appropriate usages of this interface. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + public interface IMethodReplacer + { + /// + /// Reimplement the supplied . + /// + /// + /// The instance whose is to be + /// (re)implemented. + /// + /// + /// The method that is to be (re)implemented. + /// + /// The target method's arguments. + /// + /// The result of the (re)implementation of the method call. + /// + object Implement(object target, MethodInfo method, object[] arguments); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionReader.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionReader.cs index 4295649f..0338a29e 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionReader.cs @@ -1,127 +1,126 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Core.IO; - -#endregion - -namespace Spring.Objects.Factory.Support { - - /// - /// Simple interface for object definition readers. - /// - /// Juergen Hoeller - /// Rick Evans - /// $Id: IObjectDefinitionReader.cs,v 1.8 2007/08/08 17:47:13 bbaia Exp $ - public interface IObjectDefinitionReader - { - /// - /// Gets the - /// - /// instance that this reader works on. - /// - IObjectDefinitionRegistry Registry - { - get; - } - - /// - /// The against which any class names - /// will be resolved into instances. - /// - AppDomain Domain - { - get; - } - - /// - /// The to use for anonymous - /// objects (wihtout explicit object name specified). - /// - IObjectNameGenerator ObjectNameGenerator - { - get; - } - - /// - /// Gets the resource loader to use for resource locations. - /// - /// There is also a method - /// available for loading object definitions from a resource location. This is - /// a convenience to avoid explicit ResourceLoader handling. - /// The resource loader. - IResourceLoader ResourceLoader - { - get; - } - - /// - /// Load object definitions from the supplied . - /// - /// - /// The resource for the object definitions that are to be loaded. - /// - /// - /// The number of object definitions found - /// - /// - /// In the case of loading or parsing errors. - /// - int LoadObjectDefinitions (IResource resource); - - /// - /// Load object definitions from the supplied . - /// - /// - /// The resources for the object definitions that are to be loaded. - /// - /// - /// The number of object definitions found - /// - /// - /// In the case of loading or parsing errors. - /// - int LoadObjectDefinitions(IResource[] resources); - - - /// - /// Loads the object definitions from the specified resource location. - /// - /// The resource location, to be loaded with the - /// IResourceLoader location . - /// - /// The number of object definitions found - /// - int LoadObjectDefinitions(string location); - - /// - /// Loads the object definitions from the specified resource locations. - /// - /// The the resource locations to be loaded with the - /// IResourceLoader of this object definition reader. - /// - /// The number of object definitions found - /// - int LoadObjectDefinitions(string[] locations); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Core.IO; + +#endregion + +namespace Spring.Objects.Factory.Support { + + /// + /// Simple interface for object definition readers. + /// + /// Juergen Hoeller + /// Rick Evans + public interface IObjectDefinitionReader + { + /// + /// Gets the + /// + /// instance that this reader works on. + /// + IObjectDefinitionRegistry Registry + { + get; + } + + /// + /// The against which any class names + /// will be resolved into instances. + /// + AppDomain Domain + { + get; + } + + /// + /// The to use for anonymous + /// objects (wihtout explicit object name specified). + /// + IObjectNameGenerator ObjectNameGenerator + { + get; + } + + /// + /// Gets the resource loader to use for resource locations. + /// + /// There is also a method + /// available for loading object definitions from a resource location. This is + /// a convenience to avoid explicit ResourceLoader handling. + /// The resource loader. + IResourceLoader ResourceLoader + { + get; + } + + /// + /// Load object definitions from the supplied . + /// + /// + /// The resource for the object definitions that are to be loaded. + /// + /// + /// The number of object definitions found + /// + /// + /// In the case of loading or parsing errors. + /// + int LoadObjectDefinitions (IResource resource); + + /// + /// Load object definitions from the supplied . + /// + /// + /// The resources for the object definitions that are to be loaded. + /// + /// + /// The number of object definitions found + /// + /// + /// In the case of loading or parsing errors. + /// + int LoadObjectDefinitions(IResource[] resources); + + + /// + /// Loads the object definitions from the specified resource location. + /// + /// The resource location, to be loaded with the + /// IResourceLoader location . + /// + /// The number of object definitions found + /// + int LoadObjectDefinitions(string location); + + /// + /// Loads the object definitions from the specified resource locations. + /// + /// The the resource locations to be loaded with the + /// IResourceLoader of this object definition reader. + /// + /// The number of object definitions found + /// + int LoadObjectDefinitions(string[] locations); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionRegistry.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionRegistry.cs index 24098cfc..aa5c8915 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionRegistry.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IObjectDefinitionRegistry.cs @@ -1,161 +1,161 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Interface for registries that hold object definitions, i.e. - /// - /// and - /// - /// instances. - /// - /// - ///

- /// Typically implemented by object factories that work with the - /// - /// hierarchy internally. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - public interface IObjectDefinitionRegistry - { - /// - /// Return the number of objects defined in the registry. - /// - /// - /// The number of objects defined in the registry. - /// - int ObjectDefinitionCount - { - get; - } - - /// - /// Return the names of all objects defined in this registry. - /// - /// - /// The names of all objects defined in this registry, or an empty array - /// if none defined - /// - string [] GetObjectDefinitionNames (); - - /// - /// Check if this registry contains a object definition with the given name. - /// - /// - /// The name of the object to look for. - /// - /// - /// True if this object factory contains an object definition with the - /// given name. - /// - bool ContainsObjectDefinition (string name); - - /// - /// Returns the - /// - /// for the given object name. - /// - /// - /// The name of the object to find a definition for. - /// - /// - /// The for - /// the given name (never null). - /// - /// - /// If the object definition cannot be resolved. - /// - /// - /// In case of errors. - /// - IObjectDefinition GetObjectDefinition (string name); - - /// - /// Register a new object definition with this registry. - /// Must support - /// - /// and . - /// - /// - /// The name of the object instance to register. - /// - /// - /// The definition of the object instance to register. - /// - /// - ///

- /// Must support - /// and - /// . - ///

- ///
- /// - /// If the object definition is invalid. - /// - void RegisterObjectDefinition (string name, IObjectDefinition definition); - - /// - /// Return the aliases for the given object name, if defined. - /// - /// the object name to check for aliases - /// - /// - ///

- /// Will ask the parent factory if the object cannot be found in this - /// factory instance. - ///

- ///
- /// - /// The aliases, or an empty array if none. - /// - /// - /// If there's no such object definition. - /// - string [] GetAliases (string name); - - /// - /// Given a object name, create an alias. We typically use this method to - /// support names that are illegal within XML ids (used for object names). - /// - /// - /// The name of the object. - /// - /// - /// The alias that will behave the same as the object name. - /// - /// - /// If there is no object with the given name. - /// - /// - /// If the alias is already in use. - /// - void RegisterAlias (string name, string theAlias); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Interface for registries that hold object definitions, i.e. + /// + /// and + /// + /// instances. + /// + /// + ///

+ /// Typically implemented by object factories that work with the + /// + /// hierarchy internally. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public interface IObjectDefinitionRegistry + { + /// + /// Return the number of objects defined in the registry. + /// + /// + /// The number of objects defined in the registry. + /// + int ObjectDefinitionCount + { + get; + } + + /// + /// Return the names of all objects defined in this registry. + /// + /// + /// The names of all objects defined in this registry, or an empty array + /// if none defined + /// + string [] GetObjectDefinitionNames (); + + /// + /// Check if this registry contains a object definition with the given name. + /// + /// + /// The name of the object to look for. + /// + /// + /// True if this object factory contains an object definition with the + /// given name. + /// + bool ContainsObjectDefinition (string name); + + /// + /// Returns the + /// + /// for the given object name. + /// + /// + /// The name of the object to find a definition for. + /// + /// + /// The for + /// the given name (never null). + /// + /// + /// If the object definition cannot be resolved. + /// + /// + /// In case of errors. + /// + IObjectDefinition GetObjectDefinition (string name); + + /// + /// Register a new object definition with this registry. + /// Must support + /// + /// and . + /// + /// + /// The name of the object instance to register. + /// + /// + /// The definition of the object instance to register. + /// + /// + ///

+ /// Must support + /// and + /// . + ///

+ ///
+ /// + /// If the object definition is invalid. + /// + void RegisterObjectDefinition (string name, IObjectDefinition definition); + + /// + /// Return the aliases for the given object name, if defined. + /// + /// the object name to check for aliases + /// + /// + ///

+ /// Will ask the parent factory if the object cannot be found in this + /// factory instance. + ///

+ ///
+ /// + /// The aliases, or an empty array if none. + /// + /// + /// If there's no such object definition. + /// + string [] GetAliases (string name); + + /// + /// Given a object name, create an alias. We typically use this method to + /// support names that are illegal within XML ids (used for object names). + /// + /// + /// The name of the object. + /// + /// + /// The alias that will behave the same as the object name. + /// + /// + /// If there is no object with the given name. + /// + /// + /// If the alias is already in use. + /// + void RegisterAlias (string name, string theAlias); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/IObjectNameGenerator.cs b/src/Spring/Spring.Core/Objects/Factory/Support/IObjectNameGenerator.cs index 5ac7b471..b55d4e2b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/IObjectNameGenerator.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/IObjectNameGenerator.cs @@ -1,43 +1,42 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using Spring.Objects.Factory.Config; - -namespace Spring.Objects.Factory.Support -{ - - /// - /// Strategy interface for generating object names for object definitions - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: IObjectNameGenerator.cs,v 1.1 2007/05/23 20:16:13 markpollack Exp $ - public interface IObjectNameGenerator - { - /// - /// Generates an object name for the given object definition. - /// - /// The object definition to generate a name for. - /// The object definitions registry that the given definition is - /// supposed to be registerd with - /// the generated object name - string GenerateObjectName(IObjectDefinition definition, IObjectDefinitionRegistry registry); - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using Spring.Objects.Factory.Config; + +namespace Spring.Objects.Factory.Support +{ + + /// + /// Strategy interface for generating object names for object definitions + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + public interface IObjectNameGenerator + { + /// + /// Generates an object name for the given object definition. + /// + /// The object definition to generate a name for. + /// The object definitions registry that the given definition is + /// supposed to be registerd with + /// the generated object name + string GenerateObjectName(IObjectDefinition definition, IObjectDefinitionRegistry registry); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodOverride.cs b/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodOverride.cs index f1662ea8..1051cb32 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodOverride.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodOverride.cs @@ -1,116 +1,115 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Text; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Represents an override of a method that looks up an object in the same IoC context. - /// - /// - ///

- /// Methods eligible for lookup override must not have arguments. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: LookupMethodOverride.cs,v 1.3 2007/03/16 04:01:41 aseovic Exp $ - [Serializable] - public sealed class LookupMethodOverride : MethodOverride - { - private readonly string objectName; - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Methods eligible for lookup override must not have arguments. - ///

- ///
- /// - /// The name of the method that is to be overridden. - /// - /// - /// The name of the object in the current IoC context that the - /// dependency injected method must return. - /// - /// - /// If either of the supplied arguments is or - /// contains only whitespace character(s). - /// - public LookupMethodOverride(string methodName, string objectName) - : base(methodName) - { - AssertUtils.ArgumentHasText(objectName, "objectName"); - this.objectName = objectName; - } - - /// - /// The name of the object in the current IoC context that the - /// dependency injected method must return. - /// - public string ObjectName - { - get { return objectName; } - } - - /// - /// Does this - /// match the supplied ? - /// - /// The method to be checked. - /// - /// if this override matches the supplied . - /// - /// - /// If the supplied is . - /// - public override bool Matches(MethodInfo method) - { - AssertUtils.ArgumentNotNull(method, "method"); - return MethodName == method.Name || method.Name.EndsWith(MethodName); - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return new StringBuilder(GetType().Name).Append(" for method '") - .Append(MethodName).Append("'; will return object '").Append(this.objectName) - .Append("'.").ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Text; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Represents an override of a method that looks up an object in the same IoC context. + /// + /// + ///

+ /// Methods eligible for lookup override must not have arguments. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public sealed class LookupMethodOverride : MethodOverride + { + private readonly string objectName; + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Methods eligible for lookup override must not have arguments. + ///

+ ///
+ /// + /// The name of the method that is to be overridden. + /// + /// + /// The name of the object in the current IoC context that the + /// dependency injected method must return. + /// + /// + /// If either of the supplied arguments is or + /// contains only whitespace character(s). + /// + public LookupMethodOverride(string methodName, string objectName) + : base(methodName) + { + AssertUtils.ArgumentHasText(objectName, "objectName"); + this.objectName = objectName; + } + + /// + /// The name of the object in the current IoC context that the + /// dependency injected method must return. + /// + public string ObjectName + { + get { return objectName; } + } + + /// + /// Does this + /// match the supplied ? + /// + /// The method to be checked. + /// + /// if this override matches the supplied . + /// + /// + /// If the supplied is . + /// + public override bool Matches(MethodInfo method) + { + AssertUtils.ArgumentNotNull(method, "method"); + return MethodName == method.Name || method.Name.EndsWith(MethodName); + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return new StringBuilder(GetType().Name).Append(" for method '") + .Append(MethodName).Append("'; will return object '").Append(this.objectName) + .Append("'.").ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodReplacer.cs b/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodReplacer.cs index f17e677f..79772f22 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodReplacer.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/LookupMethodReplacer.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// An - /// implementation that simply returns the result of a lookup in an - /// associated IoC container. - /// - /// - ///

- /// This class is Spring.NET's implementation of Dependency Lookup via - /// Method Injection. - ///

- ///

- /// This class is reserved for internal use within the framework; it is - /// not intended to be used by application developers using Spring.NET. - ///

- ///
- /// Rick Evans - /// $Id: LookupMethodReplacer.cs,v 1.3 2007/07/30 17:52:22 markpollack Exp $ - public sealed class LookupMethodReplacer : AbstractMethodReplacer - { - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object definition that is the target of the method replacement. - /// - /// - /// The enclosing IoC container with which the above - /// is associated. - /// - /// - /// If either of the supplied arguments is . - /// - public LookupMethodReplacer(IConfigurableObjectDefinition objectDefinition, IObjectFactory objectFactory) - : base(objectDefinition, objectFactory) - { - } - - /// - /// Reimplements the supplied by returning the - /// result of an object lookup in an enclosing IoC container. - /// - /// - /// The instance whose is to be - /// (re)implemented. - /// - /// - /// The method that is to be (re)implemented. - /// - /// The target method's arguments. - /// - /// The result of the object lookup. - /// - public override object Implement(object target, MethodInfo method, object[] arguments) - { - return GetObject(((LookupMethodOverride) GetOverride(method)).ObjectName); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// An + /// implementation that simply returns the result of a lookup in an + /// associated IoC container. + /// + /// + ///

+ /// This class is Spring.NET's implementation of Dependency Lookup via + /// Method Injection. + ///

+ ///

+ /// This class is reserved for internal use within the framework; it is + /// not intended to be used by application developers using Spring.NET. + ///

+ ///
+ /// Rick Evans + public sealed class LookupMethodReplacer : AbstractMethodReplacer + { + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object definition that is the target of the method replacement. + /// + /// + /// The enclosing IoC container with which the above + /// is associated. + /// + /// + /// If either of the supplied arguments is . + /// + public LookupMethodReplacer(IConfigurableObjectDefinition objectDefinition, IObjectFactory objectFactory) + : base(objectDefinition, objectFactory) + { + } + + /// + /// Reimplements the supplied by returning the + /// result of an object lookup in an enclosing IoC container. + /// + /// + /// The instance whose is to be + /// (re)implemented. + /// + /// + /// The method that is to be (re)implemented. + /// + /// The target method's arguments. + /// + /// The result of the object lookup. + /// + public override object Implement(object target, MethodInfo method, object[] arguments) + { + return GetObject(((LookupMethodOverride) GetOverride(method)).ObjectName); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ManagedDictionary.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ManagedDictionary.cs index 017e1e8a..950038e0 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ManagedDictionary.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ManagedDictionary.cs @@ -1,171 +1,170 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -#if NET_2_0 -using System.Collections.Generic; -#endif -using System.Collections.Specialized; -using System.Globalization; - -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Tag subclass used to hold a dictionary of managed elements. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ManagedDictionary.cs,v 1.14 2007/11/26 14:15:54 bbaia Exp $ - [Serializable] - public class ManagedDictionary : Hashtable, IManagedCollection - { - private string keyTypeName; - private string valueTypeName; - - /// - /// Gets or sets the unresolved name for the - /// of the keys of this managed dictionary. - /// - /// The unresolved name for the type of the keys of this managed dictionary. - public string KeyTypeName - { - get { return this.keyTypeName; } - set { this.keyTypeName = value; } - } - - /// - /// Gets or sets the unresolved name for the - /// of the values of this managed dictionary. - /// - /// The unresolved name for the type of the values of this managed dictionary. - public string ValueTypeName - { - get { return this.valueTypeName; } - set { this.valueTypeName = value; } - } - - /// - /// Resolves this managed collection at runtime. - /// - /// - /// The name of the top level object that is having the value of one of it's - /// collection properties resolved. - /// - /// - /// The definition of the named top level object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The callback that will actually do the donkey work of resolving - /// this managed collection. - /// - /// A fully resolved collection. - public ICollection Resolve( - string objectName, RootObjectDefinition definition, - string propertyName, ManagedCollectionElementResolver resolver) - { - IDictionary dictionary; - - Type keyType = null; - if (StringUtils.HasText(this.keyTypeName)) - { - keyType = TypeResolutionUtils.ResolveType(this.keyTypeName); - } - - Type valueType = null; - if (StringUtils.HasText(this.valueTypeName)) - { - valueType = TypeResolutionUtils.ResolveType(this.valueTypeName); - } -#if NET_2_0 - if ((keyType == null) && (valueType == null)) - { - dictionary = new HybridDictionary(); - } - else - { - Type type = typeof(Dictionary<,>); - Type[] genericArgs = new Type[2] { - (keyType == null) ? typeof(object) : keyType, - (valueType == null) ? typeof(object) : valueType }; - type = type.MakeGenericType(genericArgs); - - dictionary = (IDictionary)ObjectUtils.InstantiateType(type); - } -#else - dictionary = new HybridDictionary(); -#endif - foreach (object key in this.Keys) - { - string elementName = string.Format(CultureInfo.InvariantCulture, "{0}[{1}]", propertyName, key); - object resolvedKey = resolver(objectName, definition, elementName, key); - object resolvedValue = resolver(objectName, definition, elementName, this[key]); - - if (keyType != null) - { - try - { - resolvedKey = TypeConversionUtils.ConvertValueIfNecessary(keyType, resolvedKey, propertyName); - } - catch (TypeMismatchException) - { - throw new TypeMismatchException( - String.Format( - "Unable to convert managed dictionary key '{0}' from [{1}] into [{2}] during initialization" - + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", - resolvedKey, resolvedKey.GetType(), keyType, propertyName, objectName)); - } - } - - if (valueType != null) - { - try - { - resolvedValue = TypeConversionUtils.ConvertValueIfNecessary(valueType, resolvedValue, propertyName + "[" + resolvedKey + "]"); - } - catch (TypeMismatchException) - { - throw new TypeMismatchException( - String.Format( - "Unable to convert managed dictionary value '{0}' from [{1}] into [{2}] during initialization" - + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", - resolvedValue, resolvedValue.GetType(), valueType, propertyName, objectName)); - } - } - - dictionary.Add(resolvedKey, resolvedValue); - } - - return dictionary; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +#if NET_2_0 +using System.Collections.Generic; +#endif +using System.Collections.Specialized; +using System.Globalization; + +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Tag subclass used to hold a dictionary of managed elements. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class ManagedDictionary : Hashtable, IManagedCollection + { + private string keyTypeName; + private string valueTypeName; + + /// + /// Gets or sets the unresolved name for the + /// of the keys of this managed dictionary. + /// + /// The unresolved name for the type of the keys of this managed dictionary. + public string KeyTypeName + { + get { return this.keyTypeName; } + set { this.keyTypeName = value; } + } + + /// + /// Gets or sets the unresolved name for the + /// of the values of this managed dictionary. + /// + /// The unresolved name for the type of the values of this managed dictionary. + public string ValueTypeName + { + get { return this.valueTypeName; } + set { this.valueTypeName = value; } + } + + /// + /// Resolves this managed collection at runtime. + /// + /// + /// The name of the top level object that is having the value of one of it's + /// collection properties resolved. + /// + /// + /// The definition of the named top level object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The callback that will actually do the donkey work of resolving + /// this managed collection. + /// + /// A fully resolved collection. + public ICollection Resolve( + string objectName, RootObjectDefinition definition, + string propertyName, ManagedCollectionElementResolver resolver) + { + IDictionary dictionary; + + Type keyType = null; + if (StringUtils.HasText(this.keyTypeName)) + { + keyType = TypeResolutionUtils.ResolveType(this.keyTypeName); + } + + Type valueType = null; + if (StringUtils.HasText(this.valueTypeName)) + { + valueType = TypeResolutionUtils.ResolveType(this.valueTypeName); + } +#if NET_2_0 + if ((keyType == null) && (valueType == null)) + { + dictionary = new HybridDictionary(); + } + else + { + Type type = typeof(Dictionary<,>); + Type[] genericArgs = new Type[2] { + (keyType == null) ? typeof(object) : keyType, + (valueType == null) ? typeof(object) : valueType }; + type = type.MakeGenericType(genericArgs); + + dictionary = (IDictionary)ObjectUtils.InstantiateType(type); + } +#else + dictionary = new HybridDictionary(); +#endif + foreach (object key in this.Keys) + { + string elementName = string.Format(CultureInfo.InvariantCulture, "{0}[{1}]", propertyName, key); + object resolvedKey = resolver(objectName, definition, elementName, key); + object resolvedValue = resolver(objectName, definition, elementName, this[key]); + + if (keyType != null) + { + try + { + resolvedKey = TypeConversionUtils.ConvertValueIfNecessary(keyType, resolvedKey, propertyName); + } + catch (TypeMismatchException) + { + throw new TypeMismatchException( + String.Format( + "Unable to convert managed dictionary key '{0}' from [{1}] into [{2}] during initialization" + + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", + resolvedKey, resolvedKey.GetType(), keyType, propertyName, objectName)); + } + } + + if (valueType != null) + { + try + { + resolvedValue = TypeConversionUtils.ConvertValueIfNecessary(valueType, resolvedValue, propertyName + "[" + resolvedKey + "]"); + } + catch (TypeMismatchException) + { + throw new TypeMismatchException( + String.Format( + "Unable to convert managed dictionary value '{0}' from [{1}] into [{2}] during initialization" + + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", + resolvedValue, resolvedValue.GetType(), valueType, propertyName, objectName)); + } + } + + dictionary.Add(resolvedKey, resolvedValue); + } + + return dictionary; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ManagedList.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ManagedList.cs index 2315f496..ff65597b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ManagedList.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ManagedList.cs @@ -1,134 +1,133 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -#if NET_2_0 -using System.Collections.Generic; -#endif -using System.Globalization; - -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Tag subclass used to hold a list of managed elements. - /// - /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: ManagedList.cs,v 1.15 2007/11/26 14:15:54 bbaia Exp $ - [Serializable] - public class ManagedList : ArrayList, IManagedCollection - { - private string elementTypeName; - - /// - /// Gets or sets the unresolved name for the - /// of the elements of this managed list. - /// - /// The unresolved name for the type of the elements of this managed list. - public string ElementTypeName - { - get { return this.elementTypeName; } - set { this.elementTypeName = value; } - } - - /// - /// Resolves this managed collection at runtime. - /// - /// - /// The name of the top level object that is having the value of one of it's - /// collection properties resolved. - /// - /// - /// The definition of the named top level object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The callback that will actually do the donkey work of resolving - /// this managed collection. - /// - /// A fully resolved collection. - public ICollection Resolve(string objectName, RootObjectDefinition definition, string propertyName, ManagedCollectionElementResolver resolver) - { - IList list; - - Type elementType = null; - if (StringUtils.HasText(this.elementTypeName)) - { - elementType = TypeResolutionUtils.ResolveType(this.elementTypeName); - } -#if NET_2_0 - if (elementType == null) - { - list = new ArrayList(); - } - else - { - // CLOVER:ON - Type type = typeof(List<>); - Type[] genericArgs = new Type[1] { elementType }; - type = type.MakeGenericType(genericArgs); - - list = (IList)ObjectUtils.InstantiateType(type); - // CLOVER:OFF - } -#else - list = new ArrayList(); -#endif - for (int i = 0; i < Count; ++i) - { - object element = this[i]; - object resolvedElement = - resolver(objectName, definition, String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", propertyName, i), element); - - if (elementType != null) - { - try - { - resolvedElement = TypeConversionUtils.ConvertValueIfNecessary(elementType, resolvedElement, propertyName + "[" + i + "]"); - } - catch (TypeMismatchException) - { - throw new TypeMismatchException( - String.Format( - "Unable to convert managed list element '{0}' from [{1}] into [{2}] during initialization" - + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", - resolvedElement, resolvedElement.GetType(), elementType, propertyName, objectName)); - } - } - - list.Add(resolvedElement); - } - - return list; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +#if NET_2_0 +using System.Collections.Generic; +#endif +using System.Globalization; + +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Tag subclass used to hold a list of managed elements. + /// + /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public class ManagedList : ArrayList, IManagedCollection + { + private string elementTypeName; + + /// + /// Gets or sets the unresolved name for the + /// of the elements of this managed list. + /// + /// The unresolved name for the type of the elements of this managed list. + public string ElementTypeName + { + get { return this.elementTypeName; } + set { this.elementTypeName = value; } + } + + /// + /// Resolves this managed collection at runtime. + /// + /// + /// The name of the top level object that is having the value of one of it's + /// collection properties resolved. + /// + /// + /// The definition of the named top level object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The callback that will actually do the donkey work of resolving + /// this managed collection. + /// + /// A fully resolved collection. + public ICollection Resolve(string objectName, RootObjectDefinition definition, string propertyName, ManagedCollectionElementResolver resolver) + { + IList list; + + Type elementType = null; + if (StringUtils.HasText(this.elementTypeName)) + { + elementType = TypeResolutionUtils.ResolveType(this.elementTypeName); + } +#if NET_2_0 + if (elementType == null) + { + list = new ArrayList(); + } + else + { + // CLOVER:ON + Type type = typeof(List<>); + Type[] genericArgs = new Type[1] { elementType }; + type = type.MakeGenericType(genericArgs); + + list = (IList)ObjectUtils.InstantiateType(type); + // CLOVER:OFF + } +#else + list = new ArrayList(); +#endif + for (int i = 0; i < Count; ++i) + { + object element = this[i]; + object resolvedElement = + resolver(objectName, definition, String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", propertyName, i), element); + + if (elementType != null) + { + try + { + resolvedElement = TypeConversionUtils.ConvertValueIfNecessary(elementType, resolvedElement, propertyName + "[" + i + "]"); + } + catch (TypeMismatchException) + { + throw new TypeMismatchException( + String.Format( + "Unable to convert managed list element '{0}' from [{1}] into [{2}] during initialization" + + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", + resolvedElement, resolvedElement.GetType(), elementType, propertyName, objectName)); + } + } + + list.Add(resolvedElement); + } + + return list; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ManagedSet.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ManagedSet.cs index db493212..1d4ee2a5 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ManagedSet.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ManagedSet.cs @@ -1,112 +1,112 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -using Spring.Collections; -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Tag subclass used to hold a set of managed elements. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - [Serializable] - public class ManagedSet : HybridSet, IManagedCollection - { - private string elementTypeName; - - /// - /// Gets or sets the unresolved name for the - /// of the elements of this managed set. - /// - /// The unresolved name for the type of the elements of this managed set. - public string ElementTypeName - { - get { return this.elementTypeName; } - set { this.elementTypeName = value; } - } - - /// - /// Resolves this managed collection at runtime. - /// - /// - /// The name of the top level object that is having the value of one of it's - /// collection properties resolved. - /// - /// - /// The definition of the named top level object. - /// - /// - /// The name of the property the value of which is being resolved. - /// - /// - /// The callback that will actually do the donkey work of resolving - /// this managed collection. - /// - /// A fully resolved collection. - public ICollection Resolve(string objectName, RootObjectDefinition definition, string propertyName, ManagedCollectionElementResolver resolver) - { - ISet set = new HybridSet(); - - Type elementType = null; - if (StringUtils.HasText(this.elementTypeName)) - { - elementType = TypeResolutionUtils.ResolveType(this.elementTypeName); - } - - string elementName = propertyName + "[(set-element)]"; - foreach (object element in this) - { - object resolvedElement = resolver(objectName, definition, elementName, element); - - if (elementType != null) - { - try - { - resolvedElement = TypeConversionUtils.ConvertValueIfNecessary(elementType, resolvedElement, propertyName); - } - catch (TypeMismatchException) - { - throw new TypeMismatchException( - String.Format( - "Unable to convert managed set element '{0}' from [{1}] into [{2}] during initialization" - + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", - resolvedElement, resolvedElement.GetType(), elementType, propertyName, objectName)); - } - } - - set.Add(resolvedElement); - } - - return set; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +using Spring.Collections; +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Tag subclass used to hold a set of managed elements. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class ManagedSet : HybridSet, IManagedCollection + { + private string elementTypeName; + + /// + /// Gets or sets the unresolved name for the + /// of the elements of this managed set. + /// + /// The unresolved name for the type of the elements of this managed set. + public string ElementTypeName + { + get { return this.elementTypeName; } + set { this.elementTypeName = value; } + } + + /// + /// Resolves this managed collection at runtime. + /// + /// + /// The name of the top level object that is having the value of one of it's + /// collection properties resolved. + /// + /// + /// The definition of the named top level object. + /// + /// + /// The name of the property the value of which is being resolved. + /// + /// + /// The callback that will actually do the donkey work of resolving + /// this managed collection. + /// + /// A fully resolved collection. + public ICollection Resolve(string objectName, RootObjectDefinition definition, string propertyName, ManagedCollectionElementResolver resolver) + { + ISet set = new HybridSet(); + + Type elementType = null; + if (StringUtils.HasText(this.elementTypeName)) + { + elementType = TypeResolutionUtils.ResolveType(this.elementTypeName); + } + + string elementName = propertyName + "[(set-element)]"; + foreach (object element in this) + { + object resolvedElement = resolver(objectName, definition, elementName, element); + + if (elementType != null) + { + try + { + resolvedElement = TypeConversionUtils.ConvertValueIfNecessary(elementType, resolvedElement, propertyName); + } + catch (TypeMismatchException) + { + throw new TypeMismatchException( + String.Format( + "Unable to convert managed set element '{0}' from [{1}] into [{2}] during initialization" + + " of property '{3}' for object '{4}'. Do you have an appropriate type converter registered?", + resolvedElement, resolvedElement.GetType(), elementType, propertyName, objectName)); + } + } + + set.Add(resolvedElement); + } + + return set; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/MethodInjectingInstantiationStrategy.cs b/src/Spring/Spring.Core/Objects/Factory/Support/MethodInjectingInstantiationStrategy.cs index 0b2a43a5..e3f8808e 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/MethodInjectingInstantiationStrategy.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/MethodInjectingInstantiationStrategy.cs @@ -1,617 +1,616 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using Spring.Collections; -using Spring.Core; -using Spring.Util; -using Spring.Reflection.Dynamic; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// An - /// implementation that supports method injection. - /// - /// - ///

- /// Classes that want to take advantage of method injection must meet some - /// stringent criteria. Every method that is to be method injected - /// must be defined as either or - /// . An - /// will be thrown if these criteria are not met. - ///

- ///
- /// Rick Evans - /// $Id: MethodInjectingInstantiationStrategy.cs,v 1.13 2008/05/02 16:44:44 markpollack Exp $ - [Serializable] - public class MethodInjectingInstantiationStrategy : SimpleInstantiationStrategy - { - /// - /// The name of the dynamic assembly that holds dynamically created code - /// - private const string DYNAMIC_ASSEMBLY_NAME = "Spring.MethodInjected"; - - /// - /// A cache of generated instances, keyed on - /// the object name for which the was generated. - /// - private IDictionary typeCache = new Hashtable(); - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the - /// or zero length string if we're autowiring an - /// object that doesn't belong to the supplied - /// . - /// - /// - /// The owning - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - /// - protected override object InstantiateWithMethodInjection( - RootObjectDefinition definition, string objectName, IObjectFactory factory) - { - return DoInstantiate(definition, objectName, factory, Type.EmptyTypes, ObjectUtils.EmptyObjects); - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the - /// or zero length string if we're autowiring an - /// object that doesn't belong to the supplied - /// . - /// - /// - /// The owning - /// - /// - /// The to be used to instantiate - /// the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - /// - protected override object InstantiateWithMethodInjection( - RootObjectDefinition definition, string objectName, IObjectFactory factory, ConstructorInfo constructor, object[] arguments) - { - return DoInstantiate(definition, objectName, factory, ReflectionUtils.GetParameterTypes(constructor), arguments); - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - ///

- /// This method dynamically generates a subclass that supports method - /// injection for the supplied . It then - /// instantiates an new instance of said type using the constructor - /// identified by the supplied , - /// passing the supplied to said - /// constructor. It then manually injects (generic) method replacement - /// and method lookup instances (of - /// ) into - /// the new instance: those methods that are 'method-injected' will - /// then delegate to the approriate - /// - /// instance to effect the actual method injection. - ///

- ///
- /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the - /// or zero length string if we're autowiring an - /// object that doesn't belong to the supplied - /// . - /// - /// - /// The owning - /// - /// - /// The parameter s to use to find the - /// appropriate constructor to invoke. - /// - /// - /// The aguments that are to be passed to the appropriate constructor - /// when the object is being instantiated. - /// - /// - /// A new instance of the defined by the - /// supplied . - /// - private object DoInstantiate( - RootObjectDefinition definition, string objectName, IObjectFactory factory, Type[] ctorParameterTypes, object[] arguments) - { - Type type = GetGeneratedType(objectName, definition); - object instance = type.GetConstructor(ctorParameterTypes).Invoke(arguments); - IObjectWrapper wrapper = new ObjectWrapper(instance); - wrapper.SetPropertyValue( - MethodInjectingTypeBuilder.MethodReplacementPropertyName, - new DelegatingMethodReplacer(definition, factory)); - wrapper.SetPropertyValue( - MethodInjectingTypeBuilder.MethodLookupPropertyName, - new LookupMethodReplacer(definition, factory)); - return instance; - } - - private Type GetGeneratedType(string objectName, RootObjectDefinition definition) - { - lock (typeCache.SyncRoot) - { - Type generatedType = (Type) typeCache[objectName]; - if (generatedType == null) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, - "Generating a subclass of the [{0}] class for the '{1}' " + - "object definition for the purposes of method injection.", - definition.ObjectType, objectName)); - } - - #endregion - - ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(DYNAMIC_ASSEMBLY_NAME); - generatedType = new MethodInjectingTypeBuilder(module, definition).BuildType(); - typeCache[objectName] = generatedType; - } - return generatedType; - } - } - - #region Inner Class : MethodInjectingTypeBuilder - - /// - /// A factory that generates subclasses of those - /// classes that have been configured for the Method-Injection form of - /// Dependency Injection. - /// - /// - ///

- /// This class is designed as for one-shot usage; i.e. it must - /// be used to generate exactly one method injected subclass and - /// then discarded (it maintains state in instance fields). - ///

- ///
- private sealed class MethodInjectingTypeBuilder - { - /// - /// The name of the generated - /// property (for method replacement). - /// - /// - ///

- /// Exists so that clients of this class can use this name to set properties reflectively - /// on the dynamically generated subclass. - ///

- ///
- internal const string MethodReplacementPropertyName = "MethodReplacement"; - - /// - /// The name of the generated - /// property (for method lookup). - /// - /// - ///

- /// Exists so that clients of this class can use this name to set properties reflectively - /// on the dynamically generated subclass. - ///

- ///
- internal const string MethodLookupPropertyName = "MethodLookup"; - - private RootObjectDefinition objectDefinition; - private FieldBuilder methodReplacementField; - private FieldBuilder methodLookupField; - private ModuleBuilder module; - - private readonly MethodInfo MethodReplacerImplementMethod - = typeof (IMethodReplacer).GetMethod("Implement", new Type[] {typeof (object), typeof (MethodInfo), typeof (object[])}); - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The in which - /// the generated is to be defined. - /// - /// - /// The object definition that is the target of the method injection. - /// - /// - /// If either of the supplied arguments is . - /// - public MethodInjectingTypeBuilder(ModuleBuilder module, RootObjectDefinition objectDefinition) - { - AssertUtils.ArgumentNotNull(module, "module"); - AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); - this.module = module; - this.objectDefinition = objectDefinition; - } - - /// - /// Builds a suitable for Method-Injection. - /// - /// - /// A suitable for Method-Injection. - /// - public Type BuildType() - { - TypeBuilder typeBuilder = DefineType(); - DefineFields(typeBuilder); - DefineConstructors(typeBuilder); - DefineProperties(typeBuilder); - DefineMethods(typeBuilder); - return typeBuilder.CreateType(); - } - - private Type BaseType - { - get { return this.objectDefinition.ObjectType; } - } - - private TypeBuilder DefineProperties(TypeBuilder typeBuilder) - { - DefineWritePropertyForMethodReplacement(typeBuilder, MethodReplacementPropertyName, this.methodReplacementField); - DefineWritePropertyForMethodReplacement(typeBuilder, MethodLookupPropertyName, this.methodLookupField); - return typeBuilder; - } - - private TypeBuilder DefineType() - { - // Generates unique type name - string generatedSubclassName = String.Format("{0}_{1}", - BaseType.FullName, Guid.NewGuid().ToString("N")); - return this.module.DefineType( - generatedSubclassName, TypeAttributes.BeforeFieldInit | TypeAttributes.Public, BaseType); - } - - private TypeBuilder DefineFields(TypeBuilder typeBuilder) - { - methodReplacementField = typeBuilder.DefineField("methodReplacement", typeof (IMethodReplacer), FieldAttributes.Private); - methodLookupField = typeBuilder.DefineField("methodLookup", typeof (IMethodReplacer), FieldAttributes.Private); - return typeBuilder; - } - - private TypeBuilder DefineConstructors(TypeBuilder typeBuilder) - { - ConstructorInfo[] constructors = BaseType.GetConstructors( - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - for (int i = 0; i < constructors.Length; ++i) - { - ConstructorInfo constructor = constructors[i]; - if (constructor.IsPublic || constructor.IsFamily) - { - MethodAttributes attributes = MethodAttributes.Public | - MethodAttributes.HideBySig | MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - ConstructorBuilder cb = typeBuilder.DefineConstructor(attributes, - constructor.CallingConvention, - ReflectionUtils.GetParameterTypes(constructor.GetParameters())); - ILGenerator il = cb.GetILGenerator(); - int paramCount = constructor.GetParameters().Length; - il.Emit(OpCodes.Ldarg_0); - for (int j = 1; j <= paramCount; ++j) - { - il.Emit(OpCodes.Ldarg_S, j); - } - il.Emit(OpCodes.Call, constructor); - il.Emit(OpCodes.Ret); - } - } - return typeBuilder; - } - - /// - /// Defines overrides for those methods that are configured with an appropriate - /// . - /// - /// - /// The overarching that is defining - /// the generated . - /// - private TypeBuilder DefineMethods(TypeBuilder typeBuilder) - { - MethodInfo[] methods = BaseType.GetMethods( - BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); - for (int i = 0; i < methods.Length; ++i) - { - MethodInfo method = methods[i]; - MethodOverride methodOverride - = this.objectDefinition.MethodOverrides.GetOverride(method); - if (methodOverride != null) - { - if (!method.IsVirtual || method.IsFinal) - { - throw new ObjectCreationException( - "A replaced method must be marked as either abstract or virtual."); - } - FieldBuilder field = null; - if (methodOverride is ReplacedMethodOverride) - { - field = this.methodReplacementField; - } - else - { - // lookup methods cannot have any arguments... - if (method.GetParameters().Length > 0) - { - throw new ObjectCreationException( - "The signature of a lookup method cannot have any arguments."); - } - // lookup methods cannot return void... - if (method.ReturnType == typeof (void)) - { - throw new ObjectCreationException( - "A lookup method cannot be declared with a void return type."); - } - field = this.methodLookupField; - } - DefineReplacedMethod(typeBuilder, method, field); - } - } - return typeBuilder; - } - - /// - /// Override the supplied with the logic - /// encapsulated by the - /// - /// defined by the supplied . - /// - /// - /// The builder for the subclass that is being generated. - /// - /// - /// The method on the superclass that is to be overridden. - /// - /// - /// The field defining the - /// - /// that the overridden method will delegate to to do the 'actual' - /// method injection logic. - /// - private void DefineReplacedMethod(TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field) - { - ParameterInfo[] methodParameters = method.GetParameters(); - MethodBuilder methodBuilder - = typeBuilder.DefineMethod(method.Name, - CalculateMethodAttributes(method), - method.CallingConvention, - method.ReturnType, - ReflectionUtils.GetParameterTypes(methodParameters)); - DefineOverrideMethodParameters(methodParameters, methodBuilder); - ILGenerator il = methodBuilder.GetILGenerator(); - LocalBuilder returnValue = DefineReturnValueIfAny(method, il); - // prepare the invocation of the 'Implement' method for the 'field' (an IMethodReplacer)... - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, field); - PushArguments(methodParameters, il); - // invoke the 'Implement' method of the IMethodReplacer in the 'field'... - il.Emit(OpCodes.Callvirt, MethodReplacerImplementMethod); - SetupTheReturnValueIfAny(returnValue, il); - il.Emit(OpCodes.Ret); - } - - /// - /// Defines the parameters to the method that is being overridden. - /// - /// - ///

- /// Since we are simply overridding a method (in this method - /// injection context), all we do here is simply copy the - /// parameters (since we want a method with the exact same parameters). - ///

- ///
- /// - /// The parameters to the original method that is being overridden. - /// - /// - /// The builder we are using to define the new overridden method. - /// - private static void DefineOverrideMethodParameters( - ParameterInfo[] methodParameters, MethodBuilder methodBuilder) - { - for (int i = 0; i < methodParameters.Length; ++i) - { - ParameterInfo parameter = methodParameters[i]; - methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name); - } - } - - /// - /// Generates the MSIL for actually returning a return value if the - /// supplied is not - /// . - /// - /// - /// The definition of the return value; if , it - /// means that no return value is to required (a void - /// return type). - /// - /// - /// The to emit - /// the MSIL to. - /// - private static void SetupTheReturnValueIfAny(LocalBuilder returnValue, ILGenerator il) - { - if (returnValue != null) - { - il.Emit(OpCodes.Castclass, returnValue.LocalType); - il.Emit(OpCodes.Stloc, returnValue); - il.Emit(OpCodes.Ldloc, returnValue); - } - else - { - il.Emit(OpCodes.Pop); - } - } - - /// - /// Generates the MSIL for a return value if the supplied - /// returns a value. - /// - /// - /// The method to be checked. - /// - /// - /// The to emit - /// the MSIL to. - /// - /// - /// The return value, or if the method does not - /// return a value (has a void return type). - /// - private static LocalBuilder DefineReturnValueIfAny(MethodInfo method, ILGenerator il) - { - LocalBuilder returnValue = null; - if (method.ReturnType != typeof (void)) - { - returnValue = il.DeclareLocal(method.ReturnType); - } - return returnValue; - } - - /// - /// Pushes (sets up) the arguments for a call to the - /// - /// method of an appropriate - /// . - /// - /// - /// The parameters to the original method (will be bundled - /// up into a generic object[] and passed as the third - /// argument to the - /// - /// invocation. - /// - /// - /// The to emit - /// the MSIL to. - /// - private static void PushArguments(ParameterInfo[] methodParameters, ILGenerator il) - { - // push 'this' (1st arg)... - il.Emit(OpCodes.Ldarg_0); - // push the currently executing method (2nd arg)... - il.Emit(OpCodes.Call, typeof (MethodBase).GetMethod("GetCurrentMethod", BindingFlags.Static | BindingFlags.Public)); - il.Emit(OpCodes.Castclass, typeof (MethodInfo)); - // push the arguments to the currently executing method as an object [] (3rd arg)... - il.Emit(OpCodes.Ldc_I4, methodParameters.Length); - LocalBuilder args = il.DeclareLocal(typeof (object[])); - il.Emit(OpCodes.Newarr, typeof (object)); - il.Emit(OpCodes.Stloc, args); - for (int i = 0; i < methodParameters.Length; ++i) - { - il.Emit(OpCodes.Ldloc, args); - il.Emit(OpCodes.Ldc_I4, i); - il.Emit(OpCodes.Ldarg_S, i + 1); - ParameterInfo parameter = methodParameters[i]; - if (parameter.ParameterType.IsEnum || parameter.ParameterType.IsValueType) - { - il.Emit(OpCodes.Box, parameter.ParameterType); - } - il.Emit(OpCodes.Stelem_Ref); - } - il.Emit(OpCodes.Ldloc, args); - } - - /// - /// Simply generates the IL for a write only property for the - /// . - /// - /// - /// The in which the property is defined. - /// - /// - /// The name of the (to be) generated property. - /// - /// - /// The (instance) field that the property is to 'set'. - /// - private void DefineWritePropertyForMethodReplacement( - TypeBuilder typeBuilder, string propertyName, FieldBuilder field) - { - MethodBuilder setMethodBuilder = typeBuilder.DefineMethod( - "set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName, - typeof (void), new Type[] {typeof (IMethodReplacer)}); - ILGenerator il = setMethodBuilder.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Stfld, field); - il.Emit(OpCodes.Ret); - PropertyBuilder propertyBuilder = typeBuilder.DefineProperty( - propertyName, PropertyAttributes.None, typeof (IMethodReplacer), Type.EmptyTypes); - propertyBuilder.SetSetMethod(setMethodBuilder); - } - - private MethodAttributes CalculateMethodAttributes(MethodInfo method) - { - MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.ReuseSlot - | MethodAttributes.HideBySig | MethodAttributes.Virtual; - if (method.IsSpecialName) - { - return attributes | MethodAttributes.SpecialName; - } - return attributes; - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using Spring.Collections; +using Spring.Core; +using Spring.Util; +using Spring.Reflection.Dynamic; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// An + /// implementation that supports method injection. + /// + /// + ///

+ /// Classes that want to take advantage of method injection must meet some + /// stringent criteria. Every method that is to be method injected + /// must be defined as either or + /// . An + /// will be thrown if these criteria are not met. + ///

+ ///
+ /// Rick Evans + [Serializable] + public class MethodInjectingInstantiationStrategy : SimpleInstantiationStrategy + { + /// + /// The name of the dynamic assembly that holds dynamically created code + /// + private const string DYNAMIC_ASSEMBLY_NAME = "Spring.MethodInjected"; + + /// + /// A cache of generated instances, keyed on + /// the object name for which the was generated. + /// + private IDictionary typeCache = new Hashtable(); + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the + /// or zero length string if we're autowiring an + /// object that doesn't belong to the supplied + /// . + /// + /// + /// The owning + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + /// + protected override object InstantiateWithMethodInjection( + RootObjectDefinition definition, string objectName, IObjectFactory factory) + { + return DoInstantiate(definition, objectName, factory, Type.EmptyTypes, ObjectUtils.EmptyObjects); + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the + /// or zero length string if we're autowiring an + /// object that doesn't belong to the supplied + /// . + /// + /// + /// The owning + /// + /// + /// The to be used to instantiate + /// the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + /// + protected override object InstantiateWithMethodInjection( + RootObjectDefinition definition, string objectName, IObjectFactory factory, ConstructorInfo constructor, object[] arguments) + { + return DoInstantiate(definition, objectName, factory, ReflectionUtils.GetParameterTypes(constructor), arguments); + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + ///

+ /// This method dynamically generates a subclass that supports method + /// injection for the supplied . It then + /// instantiates an new instance of said type using the constructor + /// identified by the supplied , + /// passing the supplied to said + /// constructor. It then manually injects (generic) method replacement + /// and method lookup instances (of + /// ) into + /// the new instance: those methods that are 'method-injected' will + /// then delegate to the approriate + /// + /// instance to effect the actual method injection. + ///

+ ///
+ /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the + /// or zero length string if we're autowiring an + /// object that doesn't belong to the supplied + /// . + /// + /// + /// The owning + /// + /// + /// The parameter s to use to find the + /// appropriate constructor to invoke. + /// + /// + /// The aguments that are to be passed to the appropriate constructor + /// when the object is being instantiated. + /// + /// + /// A new instance of the defined by the + /// supplied . + /// + private object DoInstantiate( + RootObjectDefinition definition, string objectName, IObjectFactory factory, Type[] ctorParameterTypes, object[] arguments) + { + Type type = GetGeneratedType(objectName, definition); + object instance = type.GetConstructor(ctorParameterTypes).Invoke(arguments); + IObjectWrapper wrapper = new ObjectWrapper(instance); + wrapper.SetPropertyValue( + MethodInjectingTypeBuilder.MethodReplacementPropertyName, + new DelegatingMethodReplacer(definition, factory)); + wrapper.SetPropertyValue( + MethodInjectingTypeBuilder.MethodLookupPropertyName, + new LookupMethodReplacer(definition, factory)); + return instance; + } + + private Type GetGeneratedType(string objectName, RootObjectDefinition definition) + { + lock (typeCache.SyncRoot) + { + Type generatedType = (Type) typeCache[objectName]; + if (generatedType == null) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format(CultureInfo.InvariantCulture, + "Generating a subclass of the [{0}] class for the '{1}' " + + "object definition for the purposes of method injection.", + definition.ObjectType, objectName)); + } + + #endregion + + ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(DYNAMIC_ASSEMBLY_NAME); + generatedType = new MethodInjectingTypeBuilder(module, definition).BuildType(); + typeCache[objectName] = generatedType; + } + return generatedType; + } + } + + #region Inner Class : MethodInjectingTypeBuilder + + /// + /// A factory that generates subclasses of those + /// classes that have been configured for the Method-Injection form of + /// Dependency Injection. + /// + /// + ///

+ /// This class is designed as for one-shot usage; i.e. it must + /// be used to generate exactly one method injected subclass and + /// then discarded (it maintains state in instance fields). + ///

+ ///
+ private sealed class MethodInjectingTypeBuilder + { + /// + /// The name of the generated + /// property (for method replacement). + /// + /// + ///

+ /// Exists so that clients of this class can use this name to set properties reflectively + /// on the dynamically generated subclass. + ///

+ ///
+ internal const string MethodReplacementPropertyName = "MethodReplacement"; + + /// + /// The name of the generated + /// property (for method lookup). + /// + /// + ///

+ /// Exists so that clients of this class can use this name to set properties reflectively + /// on the dynamically generated subclass. + ///

+ ///
+ internal const string MethodLookupPropertyName = "MethodLookup"; + + private RootObjectDefinition objectDefinition; + private FieldBuilder methodReplacementField; + private FieldBuilder methodLookupField; + private ModuleBuilder module; + + private readonly MethodInfo MethodReplacerImplementMethod + = typeof (IMethodReplacer).GetMethod("Implement", new Type[] {typeof (object), typeof (MethodInfo), typeof (object[])}); + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The in which + /// the generated is to be defined. + /// + /// + /// The object definition that is the target of the method injection. + /// + /// + /// If either of the supplied arguments is . + /// + public MethodInjectingTypeBuilder(ModuleBuilder module, RootObjectDefinition objectDefinition) + { + AssertUtils.ArgumentNotNull(module, "module"); + AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); + this.module = module; + this.objectDefinition = objectDefinition; + } + + /// + /// Builds a suitable for Method-Injection. + /// + /// + /// A suitable for Method-Injection. + /// + public Type BuildType() + { + TypeBuilder typeBuilder = DefineType(); + DefineFields(typeBuilder); + DefineConstructors(typeBuilder); + DefineProperties(typeBuilder); + DefineMethods(typeBuilder); + return typeBuilder.CreateType(); + } + + private Type BaseType + { + get { return this.objectDefinition.ObjectType; } + } + + private TypeBuilder DefineProperties(TypeBuilder typeBuilder) + { + DefineWritePropertyForMethodReplacement(typeBuilder, MethodReplacementPropertyName, this.methodReplacementField); + DefineWritePropertyForMethodReplacement(typeBuilder, MethodLookupPropertyName, this.methodLookupField); + return typeBuilder; + } + + private TypeBuilder DefineType() + { + // Generates unique type name + string generatedSubclassName = String.Format("{0}_{1}", + BaseType.FullName, Guid.NewGuid().ToString("N")); + return this.module.DefineType( + generatedSubclassName, TypeAttributes.BeforeFieldInit | TypeAttributes.Public, BaseType); + } + + private TypeBuilder DefineFields(TypeBuilder typeBuilder) + { + methodReplacementField = typeBuilder.DefineField("methodReplacement", typeof (IMethodReplacer), FieldAttributes.Private); + methodLookupField = typeBuilder.DefineField("methodLookup", typeof (IMethodReplacer), FieldAttributes.Private); + return typeBuilder; + } + + private TypeBuilder DefineConstructors(TypeBuilder typeBuilder) + { + ConstructorInfo[] constructors = BaseType.GetConstructors( + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + for (int i = 0; i < constructors.Length; ++i) + { + ConstructorInfo constructor = constructors[i]; + if (constructor.IsPublic || constructor.IsFamily) + { + MethodAttributes attributes = MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName; + ConstructorBuilder cb = typeBuilder.DefineConstructor(attributes, + constructor.CallingConvention, + ReflectionUtils.GetParameterTypes(constructor.GetParameters())); + ILGenerator il = cb.GetILGenerator(); + int paramCount = constructor.GetParameters().Length; + il.Emit(OpCodes.Ldarg_0); + for (int j = 1; j <= paramCount; ++j) + { + il.Emit(OpCodes.Ldarg_S, j); + } + il.Emit(OpCodes.Call, constructor); + il.Emit(OpCodes.Ret); + } + } + return typeBuilder; + } + + /// + /// Defines overrides for those methods that are configured with an appropriate + /// . + /// + /// + /// The overarching that is defining + /// the generated . + /// + private TypeBuilder DefineMethods(TypeBuilder typeBuilder) + { + MethodInfo[] methods = BaseType.GetMethods( + BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); + for (int i = 0; i < methods.Length; ++i) + { + MethodInfo method = methods[i]; + MethodOverride methodOverride + = this.objectDefinition.MethodOverrides.GetOverride(method); + if (methodOverride != null) + { + if (!method.IsVirtual || method.IsFinal) + { + throw new ObjectCreationException( + "A replaced method must be marked as either abstract or virtual."); + } + FieldBuilder field = null; + if (methodOverride is ReplacedMethodOverride) + { + field = this.methodReplacementField; + } + else + { + // lookup methods cannot have any arguments... + if (method.GetParameters().Length > 0) + { + throw new ObjectCreationException( + "The signature of a lookup method cannot have any arguments."); + } + // lookup methods cannot return void... + if (method.ReturnType == typeof (void)) + { + throw new ObjectCreationException( + "A lookup method cannot be declared with a void return type."); + } + field = this.methodLookupField; + } + DefineReplacedMethod(typeBuilder, method, field); + } + } + return typeBuilder; + } + + /// + /// Override the supplied with the logic + /// encapsulated by the + /// + /// defined by the supplied . + /// + /// + /// The builder for the subclass that is being generated. + /// + /// + /// The method on the superclass that is to be overridden. + /// + /// + /// The field defining the + /// + /// that the overridden method will delegate to to do the 'actual' + /// method injection logic. + /// + private void DefineReplacedMethod(TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field) + { + ParameterInfo[] methodParameters = method.GetParameters(); + MethodBuilder methodBuilder + = typeBuilder.DefineMethod(method.Name, + CalculateMethodAttributes(method), + method.CallingConvention, + method.ReturnType, + ReflectionUtils.GetParameterTypes(methodParameters)); + DefineOverrideMethodParameters(methodParameters, methodBuilder); + ILGenerator il = methodBuilder.GetILGenerator(); + LocalBuilder returnValue = DefineReturnValueIfAny(method, il); + // prepare the invocation of the 'Implement' method for the 'field' (an IMethodReplacer)... + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldfld, field); + PushArguments(methodParameters, il); + // invoke the 'Implement' method of the IMethodReplacer in the 'field'... + il.Emit(OpCodes.Callvirt, MethodReplacerImplementMethod); + SetupTheReturnValueIfAny(returnValue, il); + il.Emit(OpCodes.Ret); + } + + /// + /// Defines the parameters to the method that is being overridden. + /// + /// + ///

+ /// Since we are simply overridding a method (in this method + /// injection context), all we do here is simply copy the + /// parameters (since we want a method with the exact same parameters). + ///

+ ///
+ /// + /// The parameters to the original method that is being overridden. + /// + /// + /// The builder we are using to define the new overridden method. + /// + private static void DefineOverrideMethodParameters( + ParameterInfo[] methodParameters, MethodBuilder methodBuilder) + { + for (int i = 0; i < methodParameters.Length; ++i) + { + ParameterInfo parameter = methodParameters[i]; + methodBuilder.DefineParameter(i + 1, parameter.Attributes, parameter.Name); + } + } + + /// + /// Generates the MSIL for actually returning a return value if the + /// supplied is not + /// . + /// + /// + /// The definition of the return value; if , it + /// means that no return value is to required (a void + /// return type). + /// + /// + /// The to emit + /// the MSIL to. + /// + private static void SetupTheReturnValueIfAny(LocalBuilder returnValue, ILGenerator il) + { + if (returnValue != null) + { + il.Emit(OpCodes.Castclass, returnValue.LocalType); + il.Emit(OpCodes.Stloc, returnValue); + il.Emit(OpCodes.Ldloc, returnValue); + } + else + { + il.Emit(OpCodes.Pop); + } + } + + /// + /// Generates the MSIL for a return value if the supplied + /// returns a value. + /// + /// + /// The method to be checked. + /// + /// + /// The to emit + /// the MSIL to. + /// + /// + /// The return value, or if the method does not + /// return a value (has a void return type). + /// + private static LocalBuilder DefineReturnValueIfAny(MethodInfo method, ILGenerator il) + { + LocalBuilder returnValue = null; + if (method.ReturnType != typeof (void)) + { + returnValue = il.DeclareLocal(method.ReturnType); + } + return returnValue; + } + + /// + /// Pushes (sets up) the arguments for a call to the + /// + /// method of an appropriate + /// . + /// + /// + /// The parameters to the original method (will be bundled + /// up into a generic object[] and passed as the third + /// argument to the + /// + /// invocation. + /// + /// + /// The to emit + /// the MSIL to. + /// + private static void PushArguments(ParameterInfo[] methodParameters, ILGenerator il) + { + // push 'this' (1st arg)... + il.Emit(OpCodes.Ldarg_0); + // push the currently executing method (2nd arg)... + il.Emit(OpCodes.Call, typeof (MethodBase).GetMethod("GetCurrentMethod", BindingFlags.Static | BindingFlags.Public)); + il.Emit(OpCodes.Castclass, typeof (MethodInfo)); + // push the arguments to the currently executing method as an object [] (3rd arg)... + il.Emit(OpCodes.Ldc_I4, methodParameters.Length); + LocalBuilder args = il.DeclareLocal(typeof (object[])); + il.Emit(OpCodes.Newarr, typeof (object)); + il.Emit(OpCodes.Stloc, args); + for (int i = 0; i < methodParameters.Length; ++i) + { + il.Emit(OpCodes.Ldloc, args); + il.Emit(OpCodes.Ldc_I4, i); + il.Emit(OpCodes.Ldarg_S, i + 1); + ParameterInfo parameter = methodParameters[i]; + if (parameter.ParameterType.IsEnum || parameter.ParameterType.IsValueType) + { + il.Emit(OpCodes.Box, parameter.ParameterType); + } + il.Emit(OpCodes.Stelem_Ref); + } + il.Emit(OpCodes.Ldloc, args); + } + + /// + /// Simply generates the IL for a write only property for the + /// . + /// + /// + /// The in which the property is defined. + /// + /// + /// The name of the (to be) generated property. + /// + /// + /// The (instance) field that the property is to 'set'. + /// + private void DefineWritePropertyForMethodReplacement( + TypeBuilder typeBuilder, string propertyName, FieldBuilder field) + { + MethodBuilder setMethodBuilder = typeBuilder.DefineMethod( + "set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName, + typeof (void), new Type[] {typeof (IMethodReplacer)}); + ILGenerator il = setMethodBuilder.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Stfld, field); + il.Emit(OpCodes.Ret); + PropertyBuilder propertyBuilder = typeBuilder.DefineProperty( + propertyName, PropertyAttributes.None, typeof (IMethodReplacer), Type.EmptyTypes); + propertyBuilder.SetSetMethod(setMethodBuilder); + } + + private MethodAttributes CalculateMethodAttributes(MethodInfo method) + { + MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.ReuseSlot + | MethodAttributes.HideBySig | MethodAttributes.Virtual; + if (method.IsSpecialName) + { + return attributes | MethodAttributes.SpecialName; + } + return attributes; + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverride.cs b/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverride.cs index 3710c8e5..4492ff50 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverride.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverride.cs @@ -1,123 +1,122 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Represents the override of a method on a managed object by the IoC container. - /// - /// - ///

- /// Note that the override mechanism is not intended as a generic means of - /// inserting crosscutting code: use AOP for that. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: MethodOverride.cs,v 1.9 2007/08/22 08:52:03 markpollack Exp $ - [Serializable] - public abstract class MethodOverride - { - private readonly string methodName; - private bool isOverloaded = true; - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no - /// public constructors. - ///

- ///
- /// - /// The name of the method that is to be overridden. - /// - /// - /// If the supplied is or - /// contains only whitespace character(s). - /// - protected MethodOverride(string methodName) - { - AssertUtils.ArgumentHasText(methodName, "methodName"); - this.methodName = methodName.Trim(); - } - - /// - /// The name of the method that is to be overridden. - /// - public string MethodName - { - get { return methodName; } - } - - /// - /// Is the method that is ot be injected - /// () - /// to be considered as overloaded? - /// - /// - ///

- /// If (the default), then argument type matching - /// will be performed (because one would not want to override the wrong - /// method). - ///

- ///

- /// Setting the value of this property to can be used - /// to optimize runtime performance (ever so slightly). - ///

- ///
- public bool IsOverloaded - { - get { return isOverloaded; } - set { isOverloaded = value; } - } - - /// - /// Does this - /// match the supplied ? - /// - /// - ///

- /// By 'match' one means does this particular - /// - /// instance apply to the supplied ? - ///

- ///

- /// This allows for argument list checking as well as method name checking. - ///

- ///
- /// The method to be checked. - /// - /// if this override matches the supplied - /// . - /// - public abstract bool Matches(MethodInfo method); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Represents the override of a method on a managed object by the IoC container. + /// + /// + ///

+ /// Note that the override mechanism is not intended as a generic means of + /// inserting crosscutting code: use AOP for that. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public abstract class MethodOverride + { + private readonly string methodName; + private bool isOverloaded = true; + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no + /// public constructors. + ///

+ ///
+ /// + /// The name of the method that is to be overridden. + /// + /// + /// If the supplied is or + /// contains only whitespace character(s). + /// + protected MethodOverride(string methodName) + { + AssertUtils.ArgumentHasText(methodName, "methodName"); + this.methodName = methodName.Trim(); + } + + /// + /// The name of the method that is to be overridden. + /// + public string MethodName + { + get { return methodName; } + } + + /// + /// Is the method that is ot be injected + /// () + /// to be considered as overloaded? + /// + /// + ///

+ /// If (the default), then argument type matching + /// will be performed (because one would not want to override the wrong + /// method). + ///

+ ///

+ /// Setting the value of this property to can be used + /// to optimize runtime performance (ever so slightly). + ///

+ ///
+ public bool IsOverloaded + { + get { return isOverloaded; } + set { isOverloaded = value; } + } + + /// + /// Does this + /// match the supplied ? + /// + /// + ///

+ /// By 'match' one means does this particular + /// + /// instance apply to the supplied ? + ///

+ ///

+ /// This allows for argument list checking as well as method name checking. + ///

+ ///
+ /// The method to be checked. + /// + /// if this override matches the supplied + /// . + /// + public abstract bool Matches(MethodInfo method); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverrides.cs b/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverrides.cs index f177105e..9201050d 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverrides.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/MethodOverrides.cs @@ -1,200 +1,199 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using Spring.Collections; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// A collection (with set semantics) of method overrides, determining which, if any, - /// methods on a managed object the Spring.NET IoC container will override at runtime. - /// - /// Rod Johnson - /// Rick Evans - /// $Id: MethodOverrides.cs,v 1.8 2007/03/16 04:01:42 aseovic Exp $ - [Serializable] - public class MethodOverrides : IEnumerable - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public MethodOverrides() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Deep copy constructoe. - ///

- ///
- /// - /// The instance supplying initial overrides for this new instance. - /// - public MethodOverrides(MethodOverrides other) - { - AddAll(other); - } - - #endregion - - #region Properties - - /// - /// The collection of method overrides. - /// - public ISet Overrides - { - get { return _overrides; } - } - - /// - /// Returns true if this instance contains no overrides. - /// - public bool IsEmpty - { - get { return Overrides.IsEmpty; } - } - - #endregion - - #region Methods - - /// - /// Copy all given method overrides into this object. - /// - /// - /// The overrides to be copied into this object. - /// - public void AddAll(MethodOverrides other) - { - if (other != null) - { - Overrides.AddAll(other.Overrides); - _overloadedMethodNames.AddAll(other._overloadedMethodNames); - } - } - - /// - /// Adds the supplied to the overrides contained - /// within this instance. - /// - /// - /// The to be - /// added. - /// - public void Add(MethodOverride theOverride) - { - Overrides.Add(theOverride); - } - - /// - /// Adds the supplied to the overloaded method names - /// contained within this instance. - /// - /// - /// The overloaded method name to be added. - /// - public void AddOverloadedMethodName(string methodName) - { - _overloadedMethodNames.Add(methodName); - } - - /// - /// Returns true if the supplied is present within - /// the overloaded method names contained within this instance. - /// - /// - /// The overloaded method name to be checked. - /// - /// - /// True if the supplied is present within - /// the overloaded method names contained within this instance. - /// - public bool IsOverloadedMethodName(string methodName) - { - return _overloadedMethodNames.Contains(methodName); - } - - /// - /// Return the override for the given method, if any. - /// - /// - /// The method to check for overrides for. - /// - /// - /// the override for the given method, if any. - /// - public MethodOverride GetOverride(MethodInfo method) - { - foreach (MethodOverride ovr in Overrides) - { - if (ovr.Matches(method)) - { - return ovr; - } - } - return null; - } - - /// - /// Returns an that can iterate - /// through a collection. - /// - /// - ///

- /// The returned is the - /// exposed by the - /// - /// property. - ///

- ///
- /// - /// An that can iterate through a - /// collection. - /// - public IEnumerator GetEnumerator() - { - return Overrides.GetEnumerator(); - } - - #endregion - - #region Fields - - private ISet _overrides = new HybridSet(); - private ISet _overloadedMethodNames = new HybridSet(); - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using Spring.Collections; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// A collection (with set semantics) of method overrides, determining which, if any, + /// methods on a managed object the Spring.NET IoC container will override at runtime. + /// + /// Rod Johnson + /// Rick Evans + [Serializable] + public class MethodOverrides : IEnumerable + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public MethodOverrides() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Deep copy constructoe. + ///

+ ///
+ /// + /// The instance supplying initial overrides for this new instance. + /// + public MethodOverrides(MethodOverrides other) + { + AddAll(other); + } + + #endregion + + #region Properties + + /// + /// The collection of method overrides. + /// + public ISet Overrides + { + get { return _overrides; } + } + + /// + /// Returns true if this instance contains no overrides. + /// + public bool IsEmpty + { + get { return Overrides.IsEmpty; } + } + + #endregion + + #region Methods + + /// + /// Copy all given method overrides into this object. + /// + /// + /// The overrides to be copied into this object. + /// + public void AddAll(MethodOverrides other) + { + if (other != null) + { + Overrides.AddAll(other.Overrides); + _overloadedMethodNames.AddAll(other._overloadedMethodNames); + } + } + + /// + /// Adds the supplied to the overrides contained + /// within this instance. + /// + /// + /// The to be + /// added. + /// + public void Add(MethodOverride theOverride) + { + Overrides.Add(theOverride); + } + + /// + /// Adds the supplied to the overloaded method names + /// contained within this instance. + /// + /// + /// The overloaded method name to be added. + /// + public void AddOverloadedMethodName(string methodName) + { + _overloadedMethodNames.Add(methodName); + } + + /// + /// Returns true if the supplied is present within + /// the overloaded method names contained within this instance. + /// + /// + /// The overloaded method name to be checked. + /// + /// + /// True if the supplied is present within + /// the overloaded method names contained within this instance. + /// + public bool IsOverloadedMethodName(string methodName) + { + return _overloadedMethodNames.Contains(methodName); + } + + /// + /// Return the override for the given method, if any. + /// + /// + /// The method to check for overrides for. + /// + /// + /// the override for the given method, if any. + /// + public MethodOverride GetOverride(MethodInfo method) + { + foreach (MethodOverride ovr in Overrides) + { + if (ovr.Matches(method)) + { + return ovr; + } + } + return null; + } + + /// + /// Returns an that can iterate + /// through a collection. + /// + /// + ///

+ /// The returned is the + /// exposed by the + /// + /// property. + ///

+ ///
+ /// + /// An that can iterate through a + /// collection. + /// + public IEnumerator GetEnumerator() + { + return Overrides.GetEnumerator(); + } + + #endregion + + #region Fields + + private ISet _overrides = new HybridSet(); + private ISet _overloadedMethodNames = new HybridSet(); + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionBuilder.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionBuilder.cs index 034e386a..260eed0b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionBuilder.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionBuilder.cs @@ -1,374 +1,373 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports -using System; -using System.Collections; -using Spring.Objects.Factory.Config; -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Programmatic means of constructing a using the builder pattern. Intended primarily - /// for use when implementing custom namespace parsers. - /// - /// Set methods are used instead of properties, so that chaining of methods can be used to create - /// 'one-liner'definitions that set multiple properties at one. - /// Rod Johnson - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: ObjectDefinitionBuilder.cs,v 1.4 2007/05/29 20:00:20 markpollack Exp $ - public class ObjectDefinitionBuilder - { - #region Fields - private AbstractObjectDefinition objectDefinition; - - private IObjectDefinitionFactory objectDefinitionFactory; - - private int constructorArgIndex; - - #endregion - - #region Constructor(s) - - /// - /// Initializes a new instance of the class, private - /// to force use of factory methods. - /// - private ObjectDefinitionBuilder() - { - } - - #endregion - - #region Factory Methods - - - /// - /// Create a new ObjectDefinitionBuilder used to construct a root object definition. - /// - /// The object definition factory. - /// The type name of the object. - /// A new ObjectDefinitionBuilder instance. - public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, - string objectTypeName) - { - return RootObjectDefinition(objectDefinitionFactory, objectTypeName, null); - } - - /// - /// Create a new ObjectDefinitionBuilder used to construct a root object definition. - /// - /// The object definition factory. - /// Name of the object type. - /// Name of the factory method. - /// A new ObjectDefinitionBuilder instance. - public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, - string objectTypeName, - string factoryMethodName) - { - ObjectDefinitionBuilder builder = new ObjectDefinitionBuilder(); - - builder.objectDefinitionFactory = objectDefinitionFactory; - - // Pass in null for parent name and also AppDomain to force object definition to be register by name and not type. - builder.objectDefinition = - objectDefinitionFactory.CreateObjectDefinition(objectTypeName, null, null); - - builder.objectDefinition.FactoryMethodName = factoryMethodName; - - return builder; - - } - - /// - /// Create a new ObjectDefinitionBuilder used to construct a root object definition. - /// - /// The object definition factory. - /// Type of the object. - /// A new ObjectDefinitionBuilder instance. - public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, - Type objectType) - { - return RootObjectDefinition(objectDefinitionFactory, objectType, null); - } - - /// - /// Create a new ObjectDefinitionBuilder used to construct a root object definition. - /// - /// The object definition factory. - /// Type of the object. - /// Name of the factory method. - /// A new ObjectDefinitionBuilder instance. - public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, - Type objectType, string factoryMethodName) - { - ObjectDefinitionBuilder builder = new ObjectDefinitionBuilder(); - - builder.objectDefinitionFactory = objectDefinitionFactory; - - builder.objectDefinition = - objectDefinitionFactory.CreateObjectDefinition(objectType.FullName, null, AppDomain.CurrentDomain); - - builder.objectDefinition.ObjectType = objectType; - builder.objectDefinition.FactoryMethodName = factoryMethodName; - return builder; - } - - /// - /// Create a new ObjectDefinitionBuilder used to construct a child object definition.. - /// - /// The object definition factory. - /// Name of the parent object. - /// - public static ObjectDefinitionBuilder ChildObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, - string parentObjectName) - { - ObjectDefinitionBuilder builder = new ObjectDefinitionBuilder(); - - builder.objectDefinitionFactory = objectDefinitionFactory; - - builder.objectDefinition = - objectDefinitionFactory.CreateObjectDefinition(null, parentObjectName, AppDomain.CurrentDomain); - - return builder; - } - - #endregion - - - #region Properties - - /// - /// Gets the current object definition in its raw (unvalidated) form. - /// - /// The raw object definition. - public AbstractObjectDefinition RawObjectDefinition - { - get { return objectDefinition; } - - } - - /// - /// Validate and gets the object definition. - /// - /// The object definition. - public AbstractObjectDefinition ObjectDefinition - { - get - { - objectDefinition.Validate(); - return objectDefinition; - } - } - - - #endregion - - #region Methods - //TODO add expression support. - - /// - /// Adds the property value under the given name. - /// - /// The name. - /// The value. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder AddPropertyValue(string name, object value) - { - objectDefinition.PropertyValues.Add(new PropertyValue(name, value)); - return this; - } - - /// - /// Adds a reference to the specified object name under the property specified. - /// - /// The name. - /// Name of the object. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder AddPropertyReference(string name, string objectName) - { - objectDefinition.PropertyValues.Add(new PropertyValue(name, new RuntimeObjectReference(objectName))); - return this; - } - - - /// - /// Adds an index constructor arg value. The current index is tracked internally and all addtions are - /// at the present point - /// - /// The constructor arg value. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder AddConstructorArg(object value) - { - objectDefinition.ConstructorArgumentValues.AddIndexedArgumentValue(constructorArgIndex++,value); - return this; - } - - /// - /// Adds a reference to the named object as a constructor argument. - /// - /// Name of the object. - /// - public ObjectDefinitionBuilder AddConstructorArgReference(string objectName) - { - return AddConstructorArg(new RuntimeObjectReference(objectName)); - } - - - /// - /// Sets the name of the factory method to use for this definition. - /// - /// The factory method. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetFactoryMethod(string factoryMethod) - { - objectDefinition.FactoryMethodName = factoryMethod; - return this; - } - - /// - /// Sets the name of the factory object to use for this definition. - /// - /// The factory object. - /// The factory method. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetFactoryObject(string factoryObject, string factoryMethod) - { - objectDefinition.FactoryObjectName = factoryObject; - objectDefinition.FactoryMethodName = factoryMethod; - return this; - } - - /// - /// Sets whether or not this definition describes a singleton object. - /// - /// if set to true [singleton]. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetSingleton(bool singleton) - { - objectDefinition.IsSingleton = singleton; - return this; - } - - /// - /// Sets whether objects or not this definition is abstract. - /// - /// if set to true [flag]. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetAbstract(bool flag) - { - objectDefinition.IsAbstract = flag; - return this; - } - - /// - /// Sets whether objects for this definition should be lazily initialized or not. - /// - /// if set to true [lazy]. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetLazyInit(bool lazy) - { - objectDefinition.IsLazyInit = lazy; - return this; - } - - /// - /// Sets the autowire mode for this definition. - /// - /// The autowire mode. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetAutowireMode(AutoWiringMode autowireMode) - { - objectDefinition.AutowireMode = autowireMode; - return this; - } - - /// - /// Sets the dependency check mode for this definition. - /// - /// The dependency check. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetDependencyCheck(DependencyCheckingMode dependencyCheck) - { - objectDefinition.DependencyCheck = dependencyCheck; - return this; - } - - - /// - /// Sets the name of the destroy method for this definition. - /// - /// Name of the method. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetDestroyMethodName(string methodName) - { - objectDefinition.DestroyMethodName = methodName; - return this; - } - - /// - /// Sets the name of the init method for this definition. - /// - /// Name of the method. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetInitMethodName(string methodName) - { - objectDefinition.InitMethodName = methodName; - return this; - } - - /// - /// Sets the resource description for this definition. - /// - /// The resource description. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder SetResourceDescription(string resourceDescription) - { - objectDefinition.ResourceDescription = resourceDescription; - return this; - } - - /// - /// Adds the specified object name to the list of objects that this definition depends on. - /// - /// Name of the object. - /// The current ObjectDefinitionBuilder. - public ObjectDefinitionBuilder AddDependsOn(string objectName) - { - if (objectDefinition.DependsOn == null) - { - objectDefinition.DependsOn = new string[] {objectName}; - } - else - { - ArrayList arrayList = new ArrayList(); - arrayList.AddRange(objectDefinition.DependsOn); - arrayList.AddRange(new string[]{ objectName}); - objectDefinition.DependsOn = (string[])arrayList.ToArray(typeof(string)); - } - return this; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports +using System; +using System.Collections; +using Spring.Objects.Factory.Config; +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Programmatic means of constructing a using the builder pattern. Intended primarily + /// for use when implementing custom namespace parsers. + /// + /// Set methods are used instead of properties, so that chaining of methods can be used to create + /// 'one-liner'definitions that set multiple properties at one. + /// Rod Johnson + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class ObjectDefinitionBuilder + { + #region Fields + private AbstractObjectDefinition objectDefinition; + + private IObjectDefinitionFactory objectDefinitionFactory; + + private int constructorArgIndex; + + #endregion + + #region Constructor(s) + + /// + /// Initializes a new instance of the class, private + /// to force use of factory methods. + /// + private ObjectDefinitionBuilder() + { + } + + #endregion + + #region Factory Methods + + + /// + /// Create a new ObjectDefinitionBuilder used to construct a root object definition. + /// + /// The object definition factory. + /// The type name of the object. + /// A new ObjectDefinitionBuilder instance. + public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, + string objectTypeName) + { + return RootObjectDefinition(objectDefinitionFactory, objectTypeName, null); + } + + /// + /// Create a new ObjectDefinitionBuilder used to construct a root object definition. + /// + /// The object definition factory. + /// Name of the object type. + /// Name of the factory method. + /// A new ObjectDefinitionBuilder instance. + public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, + string objectTypeName, + string factoryMethodName) + { + ObjectDefinitionBuilder builder = new ObjectDefinitionBuilder(); + + builder.objectDefinitionFactory = objectDefinitionFactory; + + // Pass in null for parent name and also AppDomain to force object definition to be register by name and not type. + builder.objectDefinition = + objectDefinitionFactory.CreateObjectDefinition(objectTypeName, null, null); + + builder.objectDefinition.FactoryMethodName = factoryMethodName; + + return builder; + + } + + /// + /// Create a new ObjectDefinitionBuilder used to construct a root object definition. + /// + /// The object definition factory. + /// Type of the object. + /// A new ObjectDefinitionBuilder instance. + public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, + Type objectType) + { + return RootObjectDefinition(objectDefinitionFactory, objectType, null); + } + + /// + /// Create a new ObjectDefinitionBuilder used to construct a root object definition. + /// + /// The object definition factory. + /// Type of the object. + /// Name of the factory method. + /// A new ObjectDefinitionBuilder instance. + public static ObjectDefinitionBuilder RootObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, + Type objectType, string factoryMethodName) + { + ObjectDefinitionBuilder builder = new ObjectDefinitionBuilder(); + + builder.objectDefinitionFactory = objectDefinitionFactory; + + builder.objectDefinition = + objectDefinitionFactory.CreateObjectDefinition(objectType.FullName, null, AppDomain.CurrentDomain); + + builder.objectDefinition.ObjectType = objectType; + builder.objectDefinition.FactoryMethodName = factoryMethodName; + return builder; + } + + /// + /// Create a new ObjectDefinitionBuilder used to construct a child object definition.. + /// + /// The object definition factory. + /// Name of the parent object. + /// + public static ObjectDefinitionBuilder ChildObjectDefinition(IObjectDefinitionFactory objectDefinitionFactory, + string parentObjectName) + { + ObjectDefinitionBuilder builder = new ObjectDefinitionBuilder(); + + builder.objectDefinitionFactory = objectDefinitionFactory; + + builder.objectDefinition = + objectDefinitionFactory.CreateObjectDefinition(null, parentObjectName, AppDomain.CurrentDomain); + + return builder; + } + + #endregion + + + #region Properties + + /// + /// Gets the current object definition in its raw (unvalidated) form. + /// + /// The raw object definition. + public AbstractObjectDefinition RawObjectDefinition + { + get { return objectDefinition; } + + } + + /// + /// Validate and gets the object definition. + /// + /// The object definition. + public AbstractObjectDefinition ObjectDefinition + { + get + { + objectDefinition.Validate(); + return objectDefinition; + } + } + + + #endregion + + #region Methods + //TODO add expression support. + + /// + /// Adds the property value under the given name. + /// + /// The name. + /// The value. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder AddPropertyValue(string name, object value) + { + objectDefinition.PropertyValues.Add(new PropertyValue(name, value)); + return this; + } + + /// + /// Adds a reference to the specified object name under the property specified. + /// + /// The name. + /// Name of the object. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder AddPropertyReference(string name, string objectName) + { + objectDefinition.PropertyValues.Add(new PropertyValue(name, new RuntimeObjectReference(objectName))); + return this; + } + + + /// + /// Adds an index constructor arg value. The current index is tracked internally and all addtions are + /// at the present point + /// + /// The constructor arg value. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder AddConstructorArg(object value) + { + objectDefinition.ConstructorArgumentValues.AddIndexedArgumentValue(constructorArgIndex++,value); + return this; + } + + /// + /// Adds a reference to the named object as a constructor argument. + /// + /// Name of the object. + /// + public ObjectDefinitionBuilder AddConstructorArgReference(string objectName) + { + return AddConstructorArg(new RuntimeObjectReference(objectName)); + } + + + /// + /// Sets the name of the factory method to use for this definition. + /// + /// The factory method. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetFactoryMethod(string factoryMethod) + { + objectDefinition.FactoryMethodName = factoryMethod; + return this; + } + + /// + /// Sets the name of the factory object to use for this definition. + /// + /// The factory object. + /// The factory method. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetFactoryObject(string factoryObject, string factoryMethod) + { + objectDefinition.FactoryObjectName = factoryObject; + objectDefinition.FactoryMethodName = factoryMethod; + return this; + } + + /// + /// Sets whether or not this definition describes a singleton object. + /// + /// if set to true [singleton]. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetSingleton(bool singleton) + { + objectDefinition.IsSingleton = singleton; + return this; + } + + /// + /// Sets whether objects or not this definition is abstract. + /// + /// if set to true [flag]. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetAbstract(bool flag) + { + objectDefinition.IsAbstract = flag; + return this; + } + + /// + /// Sets whether objects for this definition should be lazily initialized or not. + /// + /// if set to true [lazy]. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetLazyInit(bool lazy) + { + objectDefinition.IsLazyInit = lazy; + return this; + } + + /// + /// Sets the autowire mode for this definition. + /// + /// The autowire mode. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetAutowireMode(AutoWiringMode autowireMode) + { + objectDefinition.AutowireMode = autowireMode; + return this; + } + + /// + /// Sets the dependency check mode for this definition. + /// + /// The dependency check. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetDependencyCheck(DependencyCheckingMode dependencyCheck) + { + objectDefinition.DependencyCheck = dependencyCheck; + return this; + } + + + /// + /// Sets the name of the destroy method for this definition. + /// + /// Name of the method. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetDestroyMethodName(string methodName) + { + objectDefinition.DestroyMethodName = methodName; + return this; + } + + /// + /// Sets the name of the init method for this definition. + /// + /// Name of the method. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetInitMethodName(string methodName) + { + objectDefinition.InitMethodName = methodName; + return this; + } + + /// + /// Sets the resource description for this definition. + /// + /// The resource description. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder SetResourceDescription(string resourceDescription) + { + objectDefinition.ResourceDescription = resourceDescription; + return this; + } + + /// + /// Adds the specified object name to the list of objects that this definition depends on. + /// + /// Name of the object. + /// The current ObjectDefinitionBuilder. + public ObjectDefinitionBuilder AddDependsOn(string objectName) + { + if (objectDefinition.DependsOn == null) + { + objectDefinition.DependsOn = new string[] {objectName}; + } + else + { + ArrayList arrayList = new ArrayList(); + arrayList.AddRange(objectDefinition.DependsOn); + arrayList.AddRange(new string[]{ objectName}); + objectDefinition.DependsOn = (string[])arrayList.ToArray(typeof(string)); + } + return this; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionReaderUtils.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionReaderUtils.cs index 8bc1d134..36329096 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionReaderUtils.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionReaderUtils.cs @@ -1,257 +1,256 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text; -using System.Text.RegularExpressions; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Xml; -using Spring.Objects.Support; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Utility methods that are useful for - /// - /// implementations. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - /// - /// $Id: ObjectDefinitionReaderUtils.cs,v 1.13 2007/08/07 22:05:20 markpollack Exp $ - public sealed class ObjectDefinitionReaderUtils - { - /// - /// The string used as a separator in the generation of synthetic id's - /// for those object definitions explicitly that aren't assigned one. - /// - /// - ///

- /// If a name or parent object definition - /// name is not unique, "#1", "#2" etc will be appended, until such - /// time that the name becomes unique. - ///

- ///
- public const string GeneratedObjectIdSeparator = "#"; - - /// - /// Registers the supplied with the - /// supplied . - /// - /// - ///

- /// This is a convenience method that registers the - /// - /// of the supplied under the - /// - /// property value of said . If the - /// supplied has any - /// , - /// then those aliases will also be registered with the supplied - /// . - ///

- ///
- /// - /// The object definition holder containing the - /// that - /// is to be registered. - /// - /// - /// The registry that the supplied - /// is to be registered with. - /// - /// - /// If either of the supplied arguments is . - /// - /// - /// If the could not be registered - /// with the . - /// - public static void RegisterObjectDefinition( - ObjectDefinitionHolder objectDefinition, IObjectDefinitionRegistry registry) - { - AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); - AssertUtils.ArgumentNotNull(registry, "registry"); - - registry.RegisterObjectDefinition(objectDefinition.ObjectName, objectDefinition.ObjectDefinition); - string[] aliases = objectDefinition.Aliases; - for (int i = 0; i < aliases.Length; ++i) - { - string alias = aliases[i]; - registry.RegisterAlias(objectDefinition.ObjectName, alias); - } - } - - /// - /// Generates an object definition name for the supplied - /// that is guaranteed to be unique - /// within the scope of the supplied . - /// - /// - /// The - /// that requires a generated name. - /// - /// - /// The - /// - /// that the supplied is to be - /// registered with (needed so that the uniqueness of any generated - /// name can be guaranteed). - /// - /// - /// An object definition name for the supplied - /// that is guaranteed to be unique - /// within the scope of the supplied and - /// never . - /// - /// - /// If either of the or - /// arguments is . - /// - /// - /// If a unique name cannot be generated. - /// - public static string GenerateObjectName( - IConfigurableObjectDefinition objectDefinition, IObjectDefinitionRegistry registry) - { - AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); - AssertUtils.ArgumentNotNull(registry, "registry"); - - string starterName = objectDefinition.ObjectTypeName; - if (StringUtils.IsNullOrEmpty(starterName)) - { - if (objectDefinition is ChildObjectDefinition) - { - starterName = ((ChildObjectDefinition) objectDefinition).ParentName + "$child"; - } - else if (objectDefinition.FactoryObjectName != null) - { - starterName = objectDefinition.FactoryObjectName + "$created"; - } - } - if (StringUtils.IsNullOrEmpty(starterName)) - { - throw new ObjectDefinitionStoreException( - objectDefinition.ResourceDescription, String.Empty, - "Unnamed object definition specifies neither 'Type' nor 'Parent' " + - "nor 'FactoryObject' property values so a unique name cannot be generated."); - } - String generatedName = starterName; - int counter = 0; - while (registry.ContainsObjectDefinition(generatedName)) - { - generatedName = new StringBuilder(starterName) - .Append(GeneratedObjectIdSeparator).Append(++counter).ToString(); - } - return generatedName; - } - - /// - /// Factory method for getting concrete - /// instances. - /// - /// - /// The name of the event handler method. This may be straight text, a regular - /// expression, , or empty. - /// - /// - /// The name of the event being wired. This too may be straight text, a regular - /// expression, , or empty. - /// - /// - /// A concrete - /// instance. - /// - public static IEventHandlerValue CreateEventHandlerValue( - string methodName, string eventName) - { - bool weAreAutowiring = false; - if (StringUtils.HasText(eventName)) - { - // does the value contain regular expression characters? mmm, totally trent... - if (Regex.IsMatch(eventName, @"[\*\.\[\]\{\},\(\)\$\^\+]+")) - { - // wildcarded event name - weAreAutowiring = true; - } - } - else - { - // we're definitely autowiring based on the event name - weAreAutowiring = true; - } - if (!weAreAutowiring) - { - if (StringUtils.HasText(methodName)) - { - // does the value contain the string ${event}? - if (methodName.IndexOf("${event}") >= 0) - { - // wildcarded method name - weAreAutowiring = true; - } - } - else - { - // we're definitely autowiring based on the method name - weAreAutowiring = true; - } - } - IEventHandlerValue myHandler; - if (weAreAutowiring) - { - myHandler = new AutoWiringEventHandlerValue(); - } - else - { - myHandler = new InstanceEventHandlerValue(); - } - myHandler.EventName = eventName; - myHandler.MethodName = methodName; - return myHandler; - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private ObjectDefinitionReaderUtils() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text; +using System.Text.RegularExpressions; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Xml; +using Spring.Objects.Support; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Utility methods that are useful for + /// + /// implementations. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + /// + public sealed class ObjectDefinitionReaderUtils + { + /// + /// The string used as a separator in the generation of synthetic id's + /// for those object definitions explicitly that aren't assigned one. + /// + /// + ///

+ /// If a name or parent object definition + /// name is not unique, "#1", "#2" etc will be appended, until such + /// time that the name becomes unique. + ///

+ ///
+ public const string GeneratedObjectIdSeparator = "#"; + + /// + /// Registers the supplied with the + /// supplied . + /// + /// + ///

+ /// This is a convenience method that registers the + /// + /// of the supplied under the + /// + /// property value of said . If the + /// supplied has any + /// , + /// then those aliases will also be registered with the supplied + /// . + ///

+ ///
+ /// + /// The object definition holder containing the + /// that + /// is to be registered. + /// + /// + /// The registry that the supplied + /// is to be registered with. + /// + /// + /// If either of the supplied arguments is . + /// + /// + /// If the could not be registered + /// with the . + /// + public static void RegisterObjectDefinition( + ObjectDefinitionHolder objectDefinition, IObjectDefinitionRegistry registry) + { + AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); + AssertUtils.ArgumentNotNull(registry, "registry"); + + registry.RegisterObjectDefinition(objectDefinition.ObjectName, objectDefinition.ObjectDefinition); + string[] aliases = objectDefinition.Aliases; + for (int i = 0; i < aliases.Length; ++i) + { + string alias = aliases[i]; + registry.RegisterAlias(objectDefinition.ObjectName, alias); + } + } + + /// + /// Generates an object definition name for the supplied + /// that is guaranteed to be unique + /// within the scope of the supplied . + /// + /// + /// The + /// that requires a generated name. + /// + /// + /// The + /// + /// that the supplied is to be + /// registered with (needed so that the uniqueness of any generated + /// name can be guaranteed). + /// + /// + /// An object definition name for the supplied + /// that is guaranteed to be unique + /// within the scope of the supplied and + /// never . + /// + /// + /// If either of the or + /// arguments is . + /// + /// + /// If a unique name cannot be generated. + /// + public static string GenerateObjectName( + IConfigurableObjectDefinition objectDefinition, IObjectDefinitionRegistry registry) + { + AssertUtils.ArgumentNotNull(objectDefinition, "objectDefinition"); + AssertUtils.ArgumentNotNull(registry, "registry"); + + string starterName = objectDefinition.ObjectTypeName; + if (StringUtils.IsNullOrEmpty(starterName)) + { + if (objectDefinition is ChildObjectDefinition) + { + starterName = ((ChildObjectDefinition) objectDefinition).ParentName + "$child"; + } + else if (objectDefinition.FactoryObjectName != null) + { + starterName = objectDefinition.FactoryObjectName + "$created"; + } + } + if (StringUtils.IsNullOrEmpty(starterName)) + { + throw new ObjectDefinitionStoreException( + objectDefinition.ResourceDescription, String.Empty, + "Unnamed object definition specifies neither 'Type' nor 'Parent' " + + "nor 'FactoryObject' property values so a unique name cannot be generated."); + } + String generatedName = starterName; + int counter = 0; + while (registry.ContainsObjectDefinition(generatedName)) + { + generatedName = new StringBuilder(starterName) + .Append(GeneratedObjectIdSeparator).Append(++counter).ToString(); + } + return generatedName; + } + + /// + /// Factory method for getting concrete + /// instances. + /// + /// + /// The name of the event handler method. This may be straight text, a regular + /// expression, , or empty. + /// + /// + /// The name of the event being wired. This too may be straight text, a regular + /// expression, , or empty. + /// + /// + /// A concrete + /// instance. + /// + public static IEventHandlerValue CreateEventHandlerValue( + string methodName, string eventName) + { + bool weAreAutowiring = false; + if (StringUtils.HasText(eventName)) + { + // does the value contain regular expression characters? mmm, totally trent... + if (Regex.IsMatch(eventName, @"[\*\.\[\]\{\},\(\)\$\^\+]+")) + { + // wildcarded event name + weAreAutowiring = true; + } + } + else + { + // we're definitely autowiring based on the event name + weAreAutowiring = true; + } + if (!weAreAutowiring) + { + if (StringUtils.HasText(methodName)) + { + // does the value contain the string ${event}? + if (methodName.IndexOf("${event}") >= 0) + { + // wildcarded method name + weAreAutowiring = true; + } + } + else + { + // we're definitely autowiring based on the method name + weAreAutowiring = true; + } + } + IEventHandlerValue myHandler; + if (weAreAutowiring) + { + myHandler = new AutoWiringEventHandlerValue(); + } + else + { + myHandler = new InstanceEventHandlerValue(); + } + myHandler.EventName = eventName; + myHandler.MethodName = methodName; + return myHandler; + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private ObjectDefinitionReaderUtils() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValidationException.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValidationException.cs index e52c19c8..29e2f5be 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValidationException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValidationException.cs @@ -1,93 +1,93 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Thrown when the validation of an object definition failed. - /// - /// Juergen Hoeller - /// Rick Evans (.NET) - [Serializable] - public class ObjectDefinitionValidationException : FatalObjectException - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// - /// class. - /// - public ObjectDefinitionValidationException () - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// The detail message. - public ObjectDefinitionValidationException (string message) - : base (message) - { - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The detail message. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectDefinitionValidationException (string message, Exception rootCause) - : base (message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectDefinitionValidationException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectDefinitionValidationException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Thrown when the validation of an object definition failed. + /// + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class ObjectDefinitionValidationException : FatalObjectException + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// + /// class. + /// + public ObjectDefinitionValidationException () + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// The detail message. + public ObjectDefinitionValidationException (string message) + : base (message) + { + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The detail message. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectDefinitionValidationException (string message, Exception rootCause) + : base (message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectDefinitionValidationException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectDefinitionValidationException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/PropertiesObjectDefinitionReader.cs b/src/Spring/Spring.Core/Objects/Factory/Support/PropertiesObjectDefinitionReader.cs index c1da557b..cba7fe89 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/PropertiesObjectDefinitionReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/PropertiesObjectDefinitionReader.cs @@ -1,517 +1,517 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.IO; -using System.Resources; - -using Spring.Core.IO; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Object definition reader for a simple properties format. - /// - /// - /// Provides object definition registration methods for - /// and - /// instances. Typically applied to a - /// . - /// - /// Rod Johnson - /// Juergen Hoeller - /// Simon White (.NET) - public class PropertiesObjectDefinitionReader : AbstractObjectDefinitionReader - { - /// - /// Value of a T/F attribute that represents true. - /// Anything else represents false. Case seNsItive. - /// - public const string TrueValue = "true"; - - /// - /// Separator between object name and property name. - /// - public const string Separator = "."; - - /// - /// Prefix for the class property of a root object definition. - /// - public const string ClassKey = "class"; - - /// - /// Special string added to distinguish if the object will be - /// a singleton. - /// - /// - ///

- /// Default is true. - ///

- ///
- /// - ///

- /// owner.(singleton)=true - ///

- ///
- public const string SingletonKey = "(singleton)"; - - /// - /// Special string added to distinguish if the object will be - /// lazily initialised. - /// - /// - ///

- /// Default is false. - ///

- ///
- /// - ///

- /// owner.(lazy-init)=true - ///

- ///
- public const string LazyInitKey = "(lazy-init)"; - - /// - /// Reserved "property" to indicate the parent of a child object definition. - /// - public const string ParentKey = "parent"; - - /// - /// Property suffix for references to other objects in the current - /// : e.g. - /// owner.dog(ref)=fido. - /// - /// - ///

- /// Whether this is a reference to a singleton or a prototype - /// will depend on the definition of the target object. - ///

- ///
- public const string RefSuffix = "(ref)"; - - /// - /// Prefix before values referencing other objects. - /// - public const string RefPrefix = "*"; - - private string _defaultParentObject = string.Empty; - - private IObjectDefinitionFactory _objectDefinitionFactory = new DefaultObjectDefinitionFactory(); - - /// - /// Name of default parent object - /// - public string DefaultParentObject - { - get { return _defaultParentObject; } - set { this._defaultParentObject = value; } - } - - /// - /// Gets or sets object definition factory to use. - /// - public IObjectDefinitionFactory ObjectDefinitionFactory - { - get { return _objectDefinitionFactory; } - set { _objectDefinitionFactory = value; } - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The - /// instance that this reader works on. - /// - public PropertiesObjectDefinitionReader(IObjectDefinitionRegistry registry) - : base(registry) - {} - - /// - /// Load object definitions from the supplied . - /// - /// - /// The resource for the object definitions that are to be loaded. - /// - /// - /// The number of object definitions that were loaded. - /// - /// - /// In the case of loading or parsing errors. - /// - public override int LoadObjectDefinitions(IResource resource) - { - return LoadObjectDefinitions(resource, string.Empty); - } - - /// - /// Load object definitions from the specified properties file. - /// - /// - /// The resource descriptor for the properties file. - /// - /// - /// The match or filter for object definition names, e.g. 'objects.' - /// - /// in case of loading or parsing errors - /// the number of object definitions found - public int LoadObjectDefinitions(IResource resource, string prefix) - { - Properties props = new Properties(); - try - { - Stream str = resource.InputStream; - try - { - props.Load(str); - } - finally - { - str.Close(); - } - return RegisterObjectDefinitions(props, prefix, resource.Description); - } - catch (IOException ex) - { - throw new ObjectDefinitionStoreException("IOException parsing properties from " + resource, ex); - } - } - - /// - /// Register object definitions contained in a - /// , using all property keys (i.e. - /// not filtering by prefix). - /// - /// - /// The containing object definitions. - /// - /// - /// In case of loading or parsing errors. - /// - /// The number of object definitions registered. - public int RegisterObjectDefinitions(ResourceSet rs) - { - return RegisterObjectDefinitions(rs, string.Empty); - } - - /// - /// Register object definitions contained in a - /// . - /// - /// - ///

- /// Similar syntax as for an . - /// This method is useful to enable standard .NET internationalization support. - ///

- ///
- /// - /// The containing object definitions. - /// - /// - /// The match or filter for object definition names, e.g. 'objects.' - /// - /// - /// In case of loading or parsing errors. - /// - /// The number of object definitions registered. - public int RegisterObjectDefinitions(ResourceSet rs, string prefix) - { -#if ! NET_1_0 - // Simply create a map and call overloaded method - IDictionary id = new Hashtable(); - foreach (DictionaryEntry de in rs) - { - id.Add(de.Key, de.Value); - } - return RegisterObjectDefinitions(id, prefix); -#else - throw new NotSupportedException("Operation not supported on NET 1.0"); -#endif - } - - /// - /// Register object definitions contained in an - /// , using all property keys - /// (i.e. not filtering by prefix). - /// - /// - /// The containing object definitions. - /// - /// - /// In case of loading or parsing errors. - /// - /// The number of object definitions registered. - public int RegisterObjectDefinitions(IDictionary id) - { - return RegisterObjectDefinitions(id, string.Empty); - } - - /// - /// Registers object definitions contained in an - /// using all property keys ( i.e. not filtering by prefix ) - /// - /// The containing - /// object definitions. - /// - /// - /// In case of loading or parsing errors. - /// - /// The number of object definitions registered. - public int RegisterObjectDefinitions(NameValueCollection nameValueCollection) - { - IDictionary id = new Hashtable(); - foreach (DictionaryEntry de in nameValueCollection) - { - id.Add(de.Key, de.Value); - } - - return RegisterObjectDefinitions(id); - } - - /// - /// Register object definitions contained in a - /// . - /// - /// - ///

- /// Ignores ineligible properties. - ///

- ///
- /// IDictionary name -> property (String or Object). Property values - /// will be strings if coming from a Properties file etc. Property names - /// (keys) must be strings. Type keys must be strings. - /// - /// - /// The match or filter within the keys in the map: e.g. 'objects.' - /// - /// - /// In case of loading or parsing errors. - /// - /// The number of object definitions found. - public int RegisterObjectDefinitions(IDictionary id, string prefix) - { - return RegisterObjectDefinitions(id, prefix, "(no description)"); - } - - /// - /// Register object definitions contained in a - /// . - /// - /// - ///

- /// Ignores ineligible properties. - ///

- ///
- /// IDictionary name -> property (String or Object). Property values - /// will be strings if coming from a Properties file etc. Property names - /// (keys) must be strings. Type keys must be strings. - /// - /// - /// The match or filter within the keys in the map: e.g. 'objects.' - /// - /// - /// The description of the resource that the - /// came from (for logging purposes). - /// - /// - /// In case of loading or parsing errors. - /// - /// The number of object definitions found. - public int RegisterObjectDefinitions( - IDictionary id, string prefix, string resourceDescription) - { - if (prefix == null) - { - prefix = string.Empty; - } - int objectCount = 0; - foreach (string key in id.Keys) - { - if (key.StartsWith(prefix)) - { - // Key is of form prefix.property - string nameAndProperty = key.Substring(prefix.Length); - int sepIndx = nameAndProperty.IndexOf(Separator); - if (sepIndx != -1) - { - string name = nameAndProperty.Substring(0, sepIndx); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Found object name '" + name + "'"); - } - - #endregion - - if (!Registry.ContainsObjectDefinition(name)) - { - ++objectCount; - } - RegisterObjectDefinition(name, id, prefix + name, resourceDescription); - } - else - { - // Ignore it: it wasn't a valid object name and property, - // although it did start with the required prefix - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Invalid object name and property [" + nameAndProperty + "]"); - } - - #endregion - } - } // if the key started with the prefix we're looking for - } // while there are more keys - return objectCount; - } - - /// - /// Get all property values, given a prefix (which will be stripped) - /// and add the object they define to the factory with the given name - /// - /// The name of the object to define. - /// - /// The containing string pairs. - /// - /// The prefix of each entry, which will be stripped. - /// - /// The description of the resource that the - /// came from (for logging purposes). - /// - /// - /// In case of loading or parsing errors. - /// - protected void RegisterObjectDefinition( - string name, IDictionary id, string prefix, string resourceDescription) - { - string typeName = null; - string parent = null; - bool singleton = true; - bool lazyInit = false; - - MutablePropertyValues pvs = new MutablePropertyValues(); - foreach (string key in id.Keys) - { - if (key.StartsWith(prefix + Separator)) - { - string property = key.Substring(prefix.Length + Separator.Length); - if (property.Equals(ClassKey)) - { - typeName = (string) id[key]; - } - else if (property.Equals(SingletonKey)) - { - string val = (string) id[key]; - singleton = (val == null) || val.Equals(TrueValue); - } - else if (property.Equals(LazyInitKey)) - { - string val = (string) id[key]; - lazyInit = val.Equals(TrueValue); - } - else if (property.Equals(ParentKey)) - { - parent = (string) id[key]; - } - else if (property.EndsWith(RefSuffix)) - { - // This isn't a real property, but a reference to another prototype - // Extract property name: property is of form dog(ref) - property = property.Substring(0, property.Length - RefSuffix.Length); - string reference = (String) id[key]; - - // It doesn't matter if the referenced object hasn't yet been registered: - // this will ensure that the reference is resolved at runtime - // Default is not to use singleton - object val = new RuntimeObjectReference(reference); - pvs.Add(new PropertyValue(property, val)); - } - else - { - // normal object property - object val = id[key]; - if (val is String) - { - string strVal = (string) val; - // if it starts with a reference prefix... - if (strVal.StartsWith(RefPrefix)) - { - // expand reference - string targetName = strVal.Substring(1); - if (targetName.StartsWith(RefPrefix)) - { - // escaped prefix -> use plain value - val = targetName; - } - else - { - val = new RuntimeObjectReference(targetName); - } - } - } - pvs.Add(new PropertyValue(property, val)); - } - } - } - if (log.IsDebugEnabled) - { - log.Debug(pvs.ToString()); - } - if (parent == null) - { - log.Debug(this.DefaultParentObject); - parent = this.DefaultParentObject; - } - if (typeName == null && parent == null) - { - throw new ObjectDefinitionStoreException(resourceDescription, name, - "Either 'type' or 'parent' is required"); - } - try - { - IConfigurableObjectDefinition objectDefinition = ObjectDefinitionFactory.CreateObjectDefinition(typeName, parent, Domain); - objectDefinition.PropertyValues = pvs; - objectDefinition.IsSingleton = singleton; - objectDefinition.IsLazyInit = lazyInit; - Registry.RegisterObjectDefinition(name, objectDefinition); - } - catch (Exception ex) - { - throw new ObjectDefinitionStoreException( - resourceDescription, name, "Unable to load type [" + typeName + "]", ex); - } - } - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.IO; +using System.Resources; + +using Spring.Core.IO; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Object definition reader for a simple properties format. + /// + /// + /// Provides object definition registration methods for + /// and + /// instances. Typically applied to a + /// . + /// + /// Rod Johnson + /// Juergen Hoeller + /// Simon White (.NET) + public class PropertiesObjectDefinitionReader : AbstractObjectDefinitionReader + { + /// + /// Value of a T/F attribute that represents true. + /// Anything else represents false. Case seNsItive. + /// + public const string TrueValue = "true"; + + /// + /// Separator between object name and property name. + /// + public const string Separator = "."; + + /// + /// Prefix for the class property of a root object definition. + /// + public const string ClassKey = "class"; + + /// + /// Special string added to distinguish if the object will be + /// a singleton. + /// + /// + ///

+ /// Default is true. + ///

+ ///
+ /// + ///

+ /// owner.(singleton)=true + ///

+ ///
+ public const string SingletonKey = "(singleton)"; + + /// + /// Special string added to distinguish if the object will be + /// lazily initialised. + /// + /// + ///

+ /// Default is false. + ///

+ ///
+ /// + ///

+ /// owner.(lazy-init)=true + ///

+ ///
+ public const string LazyInitKey = "(lazy-init)"; + + /// + /// Reserved "property" to indicate the parent of a child object definition. + /// + public const string ParentKey = "parent"; + + /// + /// Property suffix for references to other objects in the current + /// : e.g. + /// owner.dog(ref)=fido. + /// + /// + ///

+ /// Whether this is a reference to a singleton or a prototype + /// will depend on the definition of the target object. + ///

+ ///
+ public const string RefSuffix = "(ref)"; + + /// + /// Prefix before values referencing other objects. + /// + public const string RefPrefix = "*"; + + private string _defaultParentObject = string.Empty; + + private IObjectDefinitionFactory _objectDefinitionFactory = new DefaultObjectDefinitionFactory(); + + /// + /// Name of default parent object + /// + public string DefaultParentObject + { + get { return _defaultParentObject; } + set { this._defaultParentObject = value; } + } + + /// + /// Gets or sets object definition factory to use. + /// + public IObjectDefinitionFactory ObjectDefinitionFactory + { + get { return _objectDefinitionFactory; } + set { _objectDefinitionFactory = value; } + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The + /// instance that this reader works on. + /// + public PropertiesObjectDefinitionReader(IObjectDefinitionRegistry registry) + : base(registry) + {} + + /// + /// Load object definitions from the supplied . + /// + /// + /// The resource for the object definitions that are to be loaded. + /// + /// + /// The number of object definitions that were loaded. + /// + /// + /// In the case of loading or parsing errors. + /// + public override int LoadObjectDefinitions(IResource resource) + { + return LoadObjectDefinitions(resource, string.Empty); + } + + /// + /// Load object definitions from the specified properties file. + /// + /// + /// The resource descriptor for the properties file. + /// + /// + /// The match or filter for object definition names, e.g. 'objects.' + /// + /// in case of loading or parsing errors + /// the number of object definitions found + public int LoadObjectDefinitions(IResource resource, string prefix) + { + Properties props = new Properties(); + try + { + Stream str = resource.InputStream; + try + { + props.Load(str); + } + finally + { + str.Close(); + } + return RegisterObjectDefinitions(props, prefix, resource.Description); + } + catch (IOException ex) + { + throw new ObjectDefinitionStoreException("IOException parsing properties from " + resource, ex); + } + } + + /// + /// Register object definitions contained in a + /// , using all property keys (i.e. + /// not filtering by prefix). + /// + /// + /// The containing object definitions. + /// + /// + /// In case of loading or parsing errors. + /// + /// The number of object definitions registered. + public int RegisterObjectDefinitions(ResourceSet rs) + { + return RegisterObjectDefinitions(rs, string.Empty); + } + + /// + /// Register object definitions contained in a + /// . + /// + /// + ///

+ /// Similar syntax as for an . + /// This method is useful to enable standard .NET internationalization support. + ///

+ ///
+ /// + /// The containing object definitions. + /// + /// + /// The match or filter for object definition names, e.g. 'objects.' + /// + /// + /// In case of loading or parsing errors. + /// + /// The number of object definitions registered. + public int RegisterObjectDefinitions(ResourceSet rs, string prefix) + { +#if ! NET_1_0 + // Simply create a map and call overloaded method + IDictionary id = new Hashtable(); + foreach (DictionaryEntry de in rs) + { + id.Add(de.Key, de.Value); + } + return RegisterObjectDefinitions(id, prefix); +#else + throw new NotSupportedException("Operation not supported on NET 1.0"); +#endif + } + + /// + /// Register object definitions contained in an + /// , using all property keys + /// (i.e. not filtering by prefix). + /// + /// + /// The containing object definitions. + /// + /// + /// In case of loading or parsing errors. + /// + /// The number of object definitions registered. + public int RegisterObjectDefinitions(IDictionary id) + { + return RegisterObjectDefinitions(id, string.Empty); + } + + /// + /// Registers object definitions contained in an + /// using all property keys ( i.e. not filtering by prefix ) + /// + /// The containing + /// object definitions. + /// + /// + /// In case of loading or parsing errors. + /// + /// The number of object definitions registered. + public int RegisterObjectDefinitions(NameValueCollection nameValueCollection) + { + IDictionary id = new Hashtable(); + foreach (DictionaryEntry de in nameValueCollection) + { + id.Add(de.Key, de.Value); + } + + return RegisterObjectDefinitions(id); + } + + /// + /// Register object definitions contained in a + /// . + /// + /// + ///

+ /// Ignores ineligible properties. + ///

+ ///
+ /// IDictionary name -> property (String or Object). Property values + /// will be strings if coming from a Properties file etc. Property names + /// (keys) must be strings. Type keys must be strings. + /// + /// + /// The match or filter within the keys in the map: e.g. 'objects.' + /// + /// + /// In case of loading or parsing errors. + /// + /// The number of object definitions found. + public int RegisterObjectDefinitions(IDictionary id, string prefix) + { + return RegisterObjectDefinitions(id, prefix, "(no description)"); + } + + /// + /// Register object definitions contained in a + /// . + /// + /// + ///

+ /// Ignores ineligible properties. + ///

+ ///
+ /// IDictionary name -> property (String or Object). Property values + /// will be strings if coming from a Properties file etc. Property names + /// (keys) must be strings. Type keys must be strings. + /// + /// + /// The match or filter within the keys in the map: e.g. 'objects.' + /// + /// + /// The description of the resource that the + /// came from (for logging purposes). + /// + /// + /// In case of loading or parsing errors. + /// + /// The number of object definitions found. + public int RegisterObjectDefinitions( + IDictionary id, string prefix, string resourceDescription) + { + if (prefix == null) + { + prefix = string.Empty; + } + int objectCount = 0; + foreach (string key in id.Keys) + { + if (key.StartsWith(prefix)) + { + // Key is of form prefix.property + string nameAndProperty = key.Substring(prefix.Length); + int sepIndx = nameAndProperty.IndexOf(Separator); + if (sepIndx != -1) + { + string name = nameAndProperty.Substring(0, sepIndx); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Found object name '" + name + "'"); + } + + #endregion + + if (!Registry.ContainsObjectDefinition(name)) + { + ++objectCount; + } + RegisterObjectDefinition(name, id, prefix + name, resourceDescription); + } + else + { + // Ignore it: it wasn't a valid object name and property, + // although it did start with the required prefix + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Invalid object name and property [" + nameAndProperty + "]"); + } + + #endregion + } + } // if the key started with the prefix we're looking for + } // while there are more keys + return objectCount; + } + + /// + /// Get all property values, given a prefix (which will be stripped) + /// and add the object they define to the factory with the given name + /// + /// The name of the object to define. + /// + /// The containing string pairs. + /// + /// The prefix of each entry, which will be stripped. + /// + /// The description of the resource that the + /// came from (for logging purposes). + /// + /// + /// In case of loading or parsing errors. + /// + protected void RegisterObjectDefinition( + string name, IDictionary id, string prefix, string resourceDescription) + { + string typeName = null; + string parent = null; + bool singleton = true; + bool lazyInit = false; + + MutablePropertyValues pvs = new MutablePropertyValues(); + foreach (string key in id.Keys) + { + if (key.StartsWith(prefix + Separator)) + { + string property = key.Substring(prefix.Length + Separator.Length); + if (property.Equals(ClassKey)) + { + typeName = (string) id[key]; + } + else if (property.Equals(SingletonKey)) + { + string val = (string) id[key]; + singleton = (val == null) || val.Equals(TrueValue); + } + else if (property.Equals(LazyInitKey)) + { + string val = (string) id[key]; + lazyInit = val.Equals(TrueValue); + } + else if (property.Equals(ParentKey)) + { + parent = (string) id[key]; + } + else if (property.EndsWith(RefSuffix)) + { + // This isn't a real property, but a reference to another prototype + // Extract property name: property is of form dog(ref) + property = property.Substring(0, property.Length - RefSuffix.Length); + string reference = (String) id[key]; + + // It doesn't matter if the referenced object hasn't yet been registered: + // this will ensure that the reference is resolved at runtime + // Default is not to use singleton + object val = new RuntimeObjectReference(reference); + pvs.Add(new PropertyValue(property, val)); + } + else + { + // normal object property + object val = id[key]; + if (val is String) + { + string strVal = (string) val; + // if it starts with a reference prefix... + if (strVal.StartsWith(RefPrefix)) + { + // expand reference + string targetName = strVal.Substring(1); + if (targetName.StartsWith(RefPrefix)) + { + // escaped prefix -> use plain value + val = targetName; + } + else + { + val = new RuntimeObjectReference(targetName); + } + } + } + pvs.Add(new PropertyValue(property, val)); + } + } + } + if (log.IsDebugEnabled) + { + log.Debug(pvs.ToString()); + } + if (parent == null) + { + log.Debug(this.DefaultParentObject); + parent = this.DefaultParentObject; + } + if (typeName == null && parent == null) + { + throw new ObjectDefinitionStoreException(resourceDescription, name, + "Either 'type' or 'parent' is required"); + } + try + { + IConfigurableObjectDefinition objectDefinition = ObjectDefinitionFactory.CreateObjectDefinition(typeName, parent, Domain); + objectDefinition.PropertyValues = pvs; + objectDefinition.IsSingleton = singleton; + objectDefinition.IsLazyInit = lazyInit; + Registry.RegisterObjectDefinition(name, objectDefinition); + } + catch (Exception ex) + { + throw new ObjectDefinitionStoreException( + resourceDescription, name, "Unable to load type [" + typeName + "]", ex); + } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ReplacedMethodOverride.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ReplacedMethodOverride.cs index 771bae93..c5a480b8 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ReplacedMethodOverride.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ReplacedMethodOverride.cs @@ -1,160 +1,159 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections.Specialized; -using System.Reflection; -using System.Text; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Represents the replacement of a method on a managed object by the IoC - /// container. - /// - /// - ///

- /// Note that this mechanism is not intended as a generic means of - /// inserting crosscutting code: use AOP for that. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: ReplacedMethodOverride.cs,v 1.3 2007/03/16 04:01:42 aseovic Exp $ - [Serializable] - public sealed class ReplacedMethodOverride : MethodOverride - { - private readonly string methodReplacerObjectName; - private StringCollection typeIdentifiers = new StringCollection(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the method that is to be overridden. - /// - /// - /// The object name of the - /// instance in the surrounding IoC container. - /// - /// - /// If either of the supplied arguments is or - /// contains only whitespace character(s). - /// - public ReplacedMethodOverride(string methodName, string methodReplacerObjectName) - : base(methodName) - { - AssertUtils.ArgumentHasText(methodReplacerObjectName, "methodReplacerObjectName"); - this.methodReplacerObjectName = methodReplacerObjectName; - } - - /// - /// Add a fragment of a instance's - /// such as 'Exception or System.Excep to identify an argument - /// for a dependency injected method. - /// - /// - /// A (sub) string of a instance's . - /// - /// - /// If the supplied is or - /// contains only whitespace character(s). - /// - /// - public void AddTypeIdentifier(string identifier) - { - AssertUtils.ArgumentHasText(identifier, "identifier"); - this.typeIdentifiers.Add(identifier); - } - - /// - /// The object name of the - /// instance in the surrounding IoC container. - /// - public string MethodReplacerObjectName - { - get { return methodReplacerObjectName; } - } - - /// - /// Does this - /// match the supplied ? - /// - /// The method to be checked. - /// - /// if this override matches the supplied . - /// - /// - /// If the supplied is . - /// - public override bool Matches(MethodInfo method) - { - AssertUtils.ArgumentNotNull(method, "method"); - if (MethodName != method.Name && !(method.Name.EndsWith(MethodName))) - { - // can't ever match... - return false; - } - if (!IsOverloaded) - { - // no need to worry about overloading... - return true; - } - // if we get to here, we need to insist on precise argument matching... - ParameterInfo[] parameters = method.GetParameters(); - if (this.typeIdentifiers.Count != parameters.Length) - { - return false; - } - for (int i = 0; i < typeIdentifiers.Count; ++i) - { - string identifier = this.typeIdentifiers[i]; - ParameterInfo parameter = parameters[i]; - if (parameter.ParameterType.FullName.IndexOf(identifier) == -1) - { - // this parameter cannot match, so neither can the whole override... - return false; - } - } - return true; - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return new StringBuilder(GetType().Name).Append(" for method '") - .Append(MethodName).Append("'; will call object '").Append(this.methodReplacerObjectName) - .Append("'.").ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections.Specialized; +using System.Reflection; +using System.Text; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Represents the replacement of a method on a managed object by the IoC + /// container. + /// + /// + ///

+ /// Note that this mechanism is not intended as a generic means of + /// inserting crosscutting code: use AOP for that. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + [Serializable] + public sealed class ReplacedMethodOverride : MethodOverride + { + private readonly string methodReplacerObjectName; + private StringCollection typeIdentifiers = new StringCollection(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the method that is to be overridden. + /// + /// + /// The object name of the + /// instance in the surrounding IoC container. + /// + /// + /// If either of the supplied arguments is or + /// contains only whitespace character(s). + /// + public ReplacedMethodOverride(string methodName, string methodReplacerObjectName) + : base(methodName) + { + AssertUtils.ArgumentHasText(methodReplacerObjectName, "methodReplacerObjectName"); + this.methodReplacerObjectName = methodReplacerObjectName; + } + + /// + /// Add a fragment of a instance's + /// such as 'Exception or System.Excep to identify an argument + /// for a dependency injected method. + /// + /// + /// A (sub) string of a instance's . + /// + /// + /// If the supplied is or + /// contains only whitespace character(s). + /// + /// + public void AddTypeIdentifier(string identifier) + { + AssertUtils.ArgumentHasText(identifier, "identifier"); + this.typeIdentifiers.Add(identifier); + } + + /// + /// The object name of the + /// instance in the surrounding IoC container. + /// + public string MethodReplacerObjectName + { + get { return methodReplacerObjectName; } + } + + /// + /// Does this + /// match the supplied ? + /// + /// The method to be checked. + /// + /// if this override matches the supplied . + /// + /// + /// If the supplied is . + /// + public override bool Matches(MethodInfo method) + { + AssertUtils.ArgumentNotNull(method, "method"); + if (MethodName != method.Name && !(method.Name.EndsWith(MethodName))) + { + // can't ever match... + return false; + } + if (!IsOverloaded) + { + // no need to worry about overloading... + return true; + } + // if we get to here, we need to insist on precise argument matching... + ParameterInfo[] parameters = method.GetParameters(); + if (this.typeIdentifiers.Count != parameters.Length) + { + return false; + } + for (int i = 0; i < typeIdentifiers.Count; ++i) + { + string identifier = this.typeIdentifiers[i]; + ParameterInfo parameter = parameters[i]; + if (parameter.ParameterType.FullName.IndexOf(identifier) == -1) + { + // this parameter cannot match, so neither can the whole override... + return false; + } + } + return true; + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return new StringBuilder(GetType().Name).Append(" for method '") + .Append(MethodName).Append("'; will call object '").Append(this.methodReplacerObjectName) + .Append("'.").ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/RootObjectDefinition.cs b/src/Spring/Spring.Core/Objects/Factory/Support/RootObjectDefinition.cs index 1eec0f07..481e3a7f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/RootObjectDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/RootObjectDefinition.cs @@ -1,293 +1,292 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// A plain-vanilla object definition. - /// - /// - ///

- /// This is the most common type of object definition; - /// instances - /// do not derive from a parent - /// , and usually - /// (but not always - see below) have an - /// - /// and (optionally) some - /// and - /// . - ///

- ///

- /// Note that - /// instances do not have to specify an - /// : - /// This can be useful for deriving - /// instances - /// from such definitions, each with it's own - /// , - /// inheriting common property values and other settings from the parent. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: RootObjectDefinition.cs,v 1.20 2007/03/16 04:01:43 aseovic Exp $ - /// - [Serializable] - public class RootObjectDefinition : AbstractObjectDefinition - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public RootObjectDefinition() - {} - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The of the object to instantiate. - /// - public RootObjectDefinition(Type type) - { - ObjectType = type; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The of the object to instantiate. - /// - /// - /// if this object definition defines a singleton object. - /// - public RootObjectDefinition(Type type, bool singleton) - { - ObjectType = type; - IsSingleton = singleton; - } - - /// - /// Creates a new instance of the - /// class - /// for a singleton, providing property values and constructor arguments. - /// - /// - /// The of the object to instantiate. - /// - /// - /// The - /// to be applied to a new instance of the object. - /// - /// - /// The to be applied to - /// a new instance of the object. - /// - public RootObjectDefinition( - Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties) - : base(arguments, properties) - { - ObjectType = type; - } - - - /// - /// Creates a new instance of the - /// class - /// for a singleton using the supplied - /// . - /// - /// - /// The of the object to instantiate. - /// - /// - /// The autowiring mode. - /// - public RootObjectDefinition(Type type, AutoWiringMode autowireMode) - { - ObjectType = type; - AutowireMode = autowireMode; - } - - /// - /// Creates a new instance of the - /// class - /// for a singleton using the supplied - /// . - /// - /// - /// The of the object to instantiate. - /// - /// - /// The autowiring mode. - /// - /// - /// Whether to perform a dependency check for objects (not - /// applicable to autowiring a constructor, thus ignored there) - /// - public RootObjectDefinition( - Type type, AutoWiringMode autowireMode, bool dependencyCheck) - { - ObjectType = type; - AutowireMode = autowireMode; - if (dependencyCheck - && ResolvedAutowireMode != AutoWiringMode.Constructor) - { - DependencyCheck = DependencyCheckingMode.Objects; - } - } - - /// - /// Creates a new instance of the - /// class - /// with the given singleton status, providing property values. - /// - /// - /// The of the object to instantiate. - /// - /// - /// The to be applied to - /// a new instance of the object. - /// - public RootObjectDefinition( - Type type, MutablePropertyValues properties) : base(null, properties) - { - ObjectType = type; - } - - /// - /// Creates a new instance of the - /// class - /// with the given singleton status, providing property values. - /// - /// - /// The of the object to instantiate. - /// - /// - /// The to be applied to - /// a new instance of the object. - /// - /// - /// if this object definition defines a singleton object. - /// - public RootObjectDefinition( - Type type, MutablePropertyValues properties, bool singleton) : base(null, properties) - { - ObjectType = type; - IsSingleton = singleton; - } - - /// - /// Creates a new instance of the - /// class - /// for a singleton, providing property values and constructor arguments. - /// - /// - ///

- /// Takes an object class name to avoid eager loading of the object class. - ///

- ///
- /// - /// The assembly qualified of the object to instantiate. - /// - /// - /// The to be applied to - /// a new instance of the object. - /// - /// - /// The - /// to be applied to a new instance of the object. - /// - public RootObjectDefinition( - string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) - : base(arguments, properties) - { - ObjectTypeName = typeName; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Deep copy constructor. - ///

- ///
- /// - /// The definition that is to be copied. - /// - public RootObjectDefinition(IObjectDefinition other) : base(other) - {} - - #endregion - - /// - /// Validate this object definition. - /// - /// - /// In the case of a validation failure. - /// - public override void Validate() - { - base.Validate(); - if (HasObjectType) - { - if (typeof(IFactoryObject).IsAssignableFrom(ObjectType) - && !IsSingleton) - { - throw new ObjectDefinitionValidationException( - "IFactoryObject must be defined as a singleton - " + - "IFactoryObjects themselves are not allowed to be prototypes."); - } - } - } - - /// - /// A that represents the current - /// . - /// - /// - /// A that represents the current - /// . - /// - public override string ToString() - { - return String.Format("{0} : {1}", GetType().Name, base.ToString()); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// A plain-vanilla object definition. + /// + /// + ///

+ /// This is the most common type of object definition; + /// instances + /// do not derive from a parent + /// , and usually + /// (but not always - see below) have an + /// + /// and (optionally) some + /// and + /// . + ///

+ ///

+ /// Note that + /// instances do not have to specify an + /// : + /// This can be useful for deriving + /// instances + /// from such definitions, each with it's own + /// , + /// inheriting common property values and other settings from the parent. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + /// + [Serializable] + public class RootObjectDefinition : AbstractObjectDefinition + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public RootObjectDefinition() + {} + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The of the object to instantiate. + /// + public RootObjectDefinition(Type type) + { + ObjectType = type; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The of the object to instantiate. + /// + /// + /// if this object definition defines a singleton object. + /// + public RootObjectDefinition(Type type, bool singleton) + { + ObjectType = type; + IsSingleton = singleton; + } + + /// + /// Creates a new instance of the + /// class + /// for a singleton, providing property values and constructor arguments. + /// + /// + /// The of the object to instantiate. + /// + /// + /// The + /// to be applied to a new instance of the object. + /// + /// + /// The to be applied to + /// a new instance of the object. + /// + public RootObjectDefinition( + Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties) + : base(arguments, properties) + { + ObjectType = type; + } + + + /// + /// Creates a new instance of the + /// class + /// for a singleton using the supplied + /// . + /// + /// + /// The of the object to instantiate. + /// + /// + /// The autowiring mode. + /// + public RootObjectDefinition(Type type, AutoWiringMode autowireMode) + { + ObjectType = type; + AutowireMode = autowireMode; + } + + /// + /// Creates a new instance of the + /// class + /// for a singleton using the supplied + /// . + /// + /// + /// The of the object to instantiate. + /// + /// + /// The autowiring mode. + /// + /// + /// Whether to perform a dependency check for objects (not + /// applicable to autowiring a constructor, thus ignored there) + /// + public RootObjectDefinition( + Type type, AutoWiringMode autowireMode, bool dependencyCheck) + { + ObjectType = type; + AutowireMode = autowireMode; + if (dependencyCheck + && ResolvedAutowireMode != AutoWiringMode.Constructor) + { + DependencyCheck = DependencyCheckingMode.Objects; + } + } + + /// + /// Creates a new instance of the + /// class + /// with the given singleton status, providing property values. + /// + /// + /// The of the object to instantiate. + /// + /// + /// The to be applied to + /// a new instance of the object. + /// + public RootObjectDefinition( + Type type, MutablePropertyValues properties) : base(null, properties) + { + ObjectType = type; + } + + /// + /// Creates a new instance of the + /// class + /// with the given singleton status, providing property values. + /// + /// + /// The of the object to instantiate. + /// + /// + /// The to be applied to + /// a new instance of the object. + /// + /// + /// if this object definition defines a singleton object. + /// + public RootObjectDefinition( + Type type, MutablePropertyValues properties, bool singleton) : base(null, properties) + { + ObjectType = type; + IsSingleton = singleton; + } + + /// + /// Creates a new instance of the + /// class + /// for a singleton, providing property values and constructor arguments. + /// + /// + ///

+ /// Takes an object class name to avoid eager loading of the object class. + ///

+ ///
+ /// + /// The assembly qualified of the object to instantiate. + /// + /// + /// The to be applied to + /// a new instance of the object. + /// + /// + /// The + /// to be applied to a new instance of the object. + /// + public RootObjectDefinition( + string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) + : base(arguments, properties) + { + ObjectTypeName = typeName; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Deep copy constructor. + ///

+ ///
+ /// + /// The definition that is to be copied. + /// + public RootObjectDefinition(IObjectDefinition other) : base(other) + {} + + #endregion + + /// + /// Validate this object definition. + /// + /// + /// In the case of a validation failure. + /// + public override void Validate() + { + base.Validate(); + if (HasObjectType) + { + if (typeof(IFactoryObject).IsAssignableFrom(ObjectType) + && !IsSingleton) + { + throw new ObjectDefinitionValidationException( + "IFactoryObject must be defined as a singleton - " + + "IFactoryObjects themselves are not allowed to be prototypes."); + } + } + } + + /// + /// A that represents the current + /// . + /// + /// + /// A that represents the current + /// . + /// + public override string ToString() + { + return String.Format("{0} : {1}", GetType().Name, base.ToString()); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs b/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs index 24546a17..6bfc3a77 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs @@ -1,308 +1,307 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; - -using Common.Logging; -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Simple object instantiation strategy for use in - /// implementations. - /// - /// - ///

- /// Does not support method injection, although it provides hooks for subclasses - /// to override to add method injection support, for example by overriding methods. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// $Id: SimpleInstantiationStrategy.cs,v 1.18 2008/04/07 00:30:34 bbaia Exp $ - /// - [Serializable] - public class SimpleInstantiationStrategy : IInstantiationStrategy - { - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (SimpleInstantiationStrategy)); - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - public virtual object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory) - { - AssertUtils.ArgumentNotNull(definition, "definition"); - AssertUtils.ArgumentNotNull(factory, "factory"); - if (definition.HasMethodOverrides) - { - return InstantiateWithMethodInjection(definition, name, factory); - } - else - { - Type objectType = definition.HasObjectType - ? definition.ObjectType - : TypeResolutionUtils.ResolveType(definition.ObjectTypeName); - ConstructorInfo constructor = GetZeroArgConstructorInfo(objectType); - return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); - } - } - - /// - /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. - /// - /// The type. - /// Zero argument ConstructorInfo - /// - /// If the type does not have a zero-arg constructor. - /// - private ConstructorInfo GetZeroArgConstructorInfo(Type type) - { - const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.Instance | BindingFlags.DeclaredOnly; - - ConstructorInfo constructor = type.GetConstructor(flags, null, Type.EmptyTypes, null); - if (constructor == null) - { - throw new FatalReflectionException(string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a no-argument constructor [{0}].", type)); - } - return constructor; - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to instantiate - /// the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - public virtual object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory, - ConstructorInfo constructor, object[] arguments) - { - if (definition.HasMethodOverrides) - { - return InstantiateWithMethodInjection(definition, name, factory, constructor, arguments); - } - else - { - return ObjectUtils.InstantiateType(constructor, arguments); - } - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to get the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - public virtual object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory, - MethodInfo factoryMethod, object[] arguments) - { - object instance = null; - object target = null; - if (StringUtils.HasText(definition.FactoryObjectName)) - { - target = factory[definition.FactoryObjectName]; - } - try - { - // the target will be null if using a static factory method - instance = factoryMethod.Invoke(target, arguments); - } - catch (TargetInvocationException ex) - { - string msg = string.Format( - CultureInfo.InvariantCulture, - "Factory method '{0}' threw an Exception.", factoryMethod); - - #region Instrumentation - - if (log.IsWarnEnabled) - { - log.Warn(msg, ex.InnerException); - } - - #endregion - - throw new ObjectDefinitionStoreException(msg, ex.InnerException); - } - catch (Exception ex) - { - throw new ObjectDefinitionStoreException(string.Format( - CultureInfo.InvariantCulture, - "Factory method '{0}' threw an Exception.", factoryMethod), ex); - } - return instance; - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - ///

- /// The default implementation of this method is to throw a - /// . - ///

- ///

- /// Derived classes can override this method if they can instantiate an object - /// with the Method Injection specified in the supplied - /// . Instantiation should use a no-arg constructor. - ///

- ///
- /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be a - /// or zero length string if we're autowiring an object that - /// doesn't belong to the supplied . - /// - /// - /// The owning - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - protected virtual object InstantiateWithMethodInjection( - RootObjectDefinition definition, string objectName, IObjectFactory factory) - { - throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - ///

- /// The default implementation of this method is to throw a - /// . - ///

- ///

- /// Derived classes can override this method if they can instantiate an object - /// with the Method Injection specified in the supplied - /// . Instantiation should use the supplied - /// and attendant . - ///

- ///
- /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to instantiate - /// the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - protected virtual object InstantiateWithMethodInjection( - RootObjectDefinition definition, string objectName, IObjectFactory factory, - ConstructorInfo constructor, object[] arguments) - { - throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; + +using Common.Logging; +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Simple object instantiation strategy for use in + /// implementations. + /// + /// + ///

+ /// Does not support method injection, although it provides hooks for subclasses + /// to override to add method injection support, for example by overriding methods. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + /// + [Serializable] + public class SimpleInstantiationStrategy : IInstantiationStrategy + { + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (SimpleInstantiationStrategy)); + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + public virtual object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory) + { + AssertUtils.ArgumentNotNull(definition, "definition"); + AssertUtils.ArgumentNotNull(factory, "factory"); + if (definition.HasMethodOverrides) + { + return InstantiateWithMethodInjection(definition, name, factory); + } + else + { + Type objectType = definition.HasObjectType + ? definition.ObjectType + : TypeResolutionUtils.ResolveType(definition.ObjectTypeName); + ConstructorInfo constructor = GetZeroArgConstructorInfo(objectType); + return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); + } + } + + /// + /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. + /// + /// The type. + /// Zero argument ConstructorInfo + /// + /// If the type does not have a zero-arg constructor. + /// + private ConstructorInfo GetZeroArgConstructorInfo(Type type) + { + const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.Instance | BindingFlags.DeclaredOnly; + + ConstructorInfo constructor = type.GetConstructor(flags, null, Type.EmptyTypes, null); + if (constructor == null) + { + throw new FatalReflectionException(string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a no-argument constructor [{0}].", type)); + } + return constructor; + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to instantiate + /// the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + public virtual object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory, + ConstructorInfo constructor, object[] arguments) + { + if (definition.HasMethodOverrides) + { + return InstantiateWithMethodInjection(definition, name, factory, constructor, arguments); + } + else + { + return ObjectUtils.InstantiateType(constructor, arguments); + } + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to get the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + public virtual object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory, + MethodInfo factoryMethod, object[] arguments) + { + object instance = null; + object target = null; + if (StringUtils.HasText(definition.FactoryObjectName)) + { + target = factory[definition.FactoryObjectName]; + } + try + { + // the target will be null if using a static factory method + instance = factoryMethod.Invoke(target, arguments); + } + catch (TargetInvocationException ex) + { + string msg = string.Format( + CultureInfo.InvariantCulture, + "Factory method '{0}' threw an Exception.", factoryMethod); + + #region Instrumentation + + if (log.IsWarnEnabled) + { + log.Warn(msg, ex.InnerException); + } + + #endregion + + throw new ObjectDefinitionStoreException(msg, ex.InnerException); + } + catch (Exception ex) + { + throw new ObjectDefinitionStoreException(string.Format( + CultureInfo.InvariantCulture, + "Factory method '{0}' threw an Exception.", factoryMethod), ex); + } + return instance; + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + ///

+ /// The default implementation of this method is to throw a + /// . + ///

+ ///

+ /// Derived classes can override this method if they can instantiate an object + /// with the Method Injection specified in the supplied + /// . Instantiation should use a no-arg constructor. + ///

+ ///
+ /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be a + /// or zero length string if we're autowiring an object that + /// doesn't belong to the supplied . + /// + /// + /// The owning + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + protected virtual object InstantiateWithMethodInjection( + RootObjectDefinition definition, string objectName, IObjectFactory factory) + { + throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + ///

+ /// The default implementation of this method is to throw a + /// . + ///

+ ///

+ /// Derived classes can override this method if they can instantiate an object + /// with the Method Injection specified in the supplied + /// . Instantiation should use the supplied + /// and attendant . + ///

+ ///
+ /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to instantiate + /// the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + protected virtual object InstantiateWithMethodInjection( + RootObjectDefinition definition, string objectName, IObjectFactory factory, + ConstructorInfo constructor, object[] arguments) + { + throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs index dae2bfad..fcf79d3e 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs @@ -1,692 +1,691 @@ -#region License -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Static factory that permits the registration of existing singleton instances. - /// - /// - ///

- /// Does not have support for prototype objects, aliases, and post startup object - /// configuration. - ///

- ///

- /// Serves as a simple example implementation of the - /// interface, that manages existing object instances as opposed to creating new ones - /// based on object definitions. - ///

- ///

- /// The - /// method is not supported by this class; this class deals exclusively with - /// existing singleton instances, thus the methods mentioned previously make little sense in this context. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: StaticListableObjectFactory.cs,v 1.24 2007/12/05 00:28:05 bbaia Exp $ - [Serializable] - public class StaticListableObjectFactory : IListableObjectFactory - { - /// - /// Map from object name to object instance. - /// - private Hashtable objects = new Hashtable(); - - /// - /// Return the number of objects defined in the factory. - /// - /// - /// The number of objects defined in the factory. - /// - public int ObjectDefinitionCount - { - get { return objects.Count; } - } - - /// - /// Return an instance of the given object name. - /// - /// The name of the object to return. - /// The instance of the object. - /// - public object this[string name] - { - get { return GetObject(name); } - } - - /// - /// Return an instance of the given object name. - /// - /// The name of the object to return. - /// The instance of the object. - /// - /// is not currently supported. - /// - /// - public object GetObject(string name) - { - object instance = objects[name]; - if (instance is IFactoryObject) - { - if (instance is IConfigurableFactoryObject) - { - throw new NotSupportedException(); - } - try - { - return ((IFactoryObject) instance).GetObject(); - } - catch (Exception ex) - { - throw new ObjectCreationException(name, - "IFactoryObject threw an exception on object creation", ex); - } - } - if (instance == null) - { - throw new NoSuchObjectDefinitionException(name, GrabDefinedObjectsString()); - } - return instance; - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// - ///

- /// This method allows an object factory to be used as a replacement for the - /// Singleton or Prototype design pattern. - ///

- ///

- /// Note that callers should retain references to returned objects. There is no - /// guarantee that this method will be implemented to be efficient. For example, - /// it may be synchronized, or may need to run an RDBMS query. - ///

- ///

- /// Will ask the parent factory if the object cannot be found in this factory - /// instance. - ///

- ///
- /// The name of the object to return. - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a static factory method. If there is no factory method and the - /// arguments are not null, then match the argument values by type and - /// call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the supplied is . - /// - public object GetObject(string name, object[] arguments) - { - throw new NotSupportedException("StaticListableObjectFactory does not support this method."); - } - - /// - /// Return an instance (possibly shared or independent) of the given object name. - /// - /// The name of the object to return. - /// - /// The the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// - /// The arguments to use if creating a prototype using explicit arguments to - /// a factory method. If there is no factory method and the - /// supplied array is not , then - /// match the argument values by type and call the object's constructor. - /// - /// The instance of the object. - /// - /// If there's no such object definition. - /// - /// - /// If the object could not be created. - /// - /// - /// If the object is not of the required type. - /// - /// - /// If the supplied is . - /// - /// - public object GetObject(string name, Type requiredType, object[] arguments) - { - throw new NotSupportedException("StaticListableObjectFactory does not support this method."); - } - - /// - /// Return an instance of the given object name. - /// - /// The name of the object to return. - /// - /// the object may match. Can be an interface or - /// superclass of the actual class. For example, if the value is the - /// class, this method will succeed whatever the - /// class of the returned instance. - /// - /// The instance of the object. - /// - public object GetObject(string name, Type requiredType) - { - object instance = GetObject(name); - if (!requiredType.IsAssignableFrom(instance.GetType())) - { - throw new ObjectNotOfRequiredTypeException(name, requiredType, instance); - } - return instance; - } - - /// - /// Does this object factory contain an object with the given name? - /// - /// The name of the object to query. - /// True if an object with the given name is defined. - public bool ContainsObject(string name) - { - return objects.ContainsKey(name); - } - - /// - /// Is this object a singleton? - /// - /// - ///

- /// That is, will - /// or - /// always return the same object? - ///

- ///
- /// The name of the object to query. - /// True if the named object is a singleton. - /// - /// If there's no such object definition. - /// - public bool IsSingleton(string name) - { - bool isSingleton = true; - object instance = GetObject(name); - // in case of IFactoryObject, return singleton status of created object - if (instance is IFactoryObject) - { - isSingleton = ((IFactoryObject) instance).IsSingleton; - } - return isSingleton; - } - - - /// - /// Determines whether the specified object name is prototype. That is, will GetObject - /// always return independent instances? - /// - /// This method returning false does not clearly indicate a singleton object. - /// It indicated non-independent instances, which may correspond to a scoped object as - /// well. use the IsSingleton property to explicitly check for a shared - /// singleton instance. - /// Translates aliases back to the corresponding canonical object name. Will ask the - /// parent factory if the object can not be found in this factory instance. - /// - /// - /// - /// The name of the object to query - /// - /// true if the specified object name will always deliver independent instances; otherwise, false. - /// - /// if there is no object with the given name. - public bool IsPrototype(string name) - { - bool isPrototype = true; - object instance = GetObject(name); - if (instance is IFactoryObject) - { - isPrototype = !((IFactoryObject) instance).IsSingleton; - } - return isPrototype; - - } - - /// - /// Determine the type of the object with the given name. - /// - /// - ///

- /// More specifically, checks the type of object that - /// would return. - /// For an , returns the type - /// of object that the creates. - ///

- ///
- /// The name of the object to query. - /// - /// The of the object or if - /// not determinable. - /// - public Type GetType(string name) - { - string objectName = ObjectFactoryUtils.TransformedObjectName(name); - object instance = objects[objectName]; - if (instance == null) - { - throw new NoSuchObjectDefinitionException(name, GrabDefinedObjectsString()); - } - if (instance is IFactoryObject && !ObjectFactoryUtils.IsFactoryDereference(name)) - { - return ((IFactoryObject) instance).ObjectType; - } - return instance.GetType(); - } - - - /// - /// Determines whether the object with the given name matches the specified type. - /// - /// The name of the object to query. - /// Type of the target to match against. - /// - /// true if the object type matches; otherwise, false - /// if it doesn't match or cannot be determined yet. - /// - /// Ff there is no object with the given name - /// - public bool IsTypeMatch(string name, Type targetType) - { - Type type = GetType(name); - return (targetType == null || (type != null && targetType.IsAssignableFrom(type))); - } - - private string GrabDefinedObjectsString() - { - return "Defined objects are [" + - StringUtils.CollectionToDelimitedString(objects.Keys, ",") + "]"; - } - - /// - /// Return the aliases for the given object name, if defined. - /// - /// The object name to check for aliases. - /// The aliases, or an empty array if none. - /// - /// If there's no such object definition. - /// - public string[] GetAliases(string name) - { - return StringUtils.EmptyStrings; - } - - /// - /// Not supported. - /// - /// The name of the object. - /// - /// The registered - /// . - /// - /// - /// Always, as object definitions are not supported by this - /// implementation. - /// - public IObjectDefinition GetObjectDefinition(string name) - { - throw new NotSupportedException("StaticListableObjectFactory does not contain object definitions."); - } - - /// - /// Return the registered - /// for the - /// given object, allowing access to its property values and constructor - /// argument values. - /// - /// The name of the object. - /// Whether to search parent object factories. - /// - /// The registered - /// . - /// - /// - /// If there is no object with the given name. - /// - /// - /// In the case of errors. - /// - public IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) - { - throw new NotSupportedException("StaticListableObjectFactory does not contain object definitions."); - } - - - /// - /// Return the names of all objects defined in this factory. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - public string[] GetObjectDefinitionNames() - { - ArrayList names = new ArrayList(objects.Keys); - return (string[]) names.ToArray(typeof (string)); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - ///

- /// Will not consider s, - /// as the type of their created objects is not known before instantiation. - ///

- ///
- /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - public string[] GetObjectDefinitionNames(Type type) - { - ArrayList matches = new ArrayList(); - foreach (string name in objects.Keys) - { - Type t = objects[name].GetType(); - if (type.IsAssignableFrom(t)) - { - matches.Add(name); - } - } - return (string[]) matches.ToArray(typeof (string)); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - ///

- /// Does consider objects created by s, - /// or rather it considers the type of objects created by - /// (which means that - /// s will be instantiated). - ///

- ///

- /// Does not consider any hierarchy this factory may participate in. - ///

- ///
- /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - public string[] GetObjectNamesForType(Type type) - { - return GetObjectNamesForType(type, true, true); - } - - /// - /// Return the names of objects matching the given - /// (including subclasses), judging from the object definitions. - /// - /// - ///

- /// Since this implementation of the - /// - /// interface does not support the notion of ptototype objects, the - /// parameter is ignored. - ///

- ///
- /// - /// The (class or interface) to match, or - /// for all object names. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). Ignored. - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// The names of all objects defined in this factory, or an empty array if none - /// are defined. - /// - /// - public string[] GetObjectNamesForType( - Type type, bool includePrototypes, bool includeFactoryObjects) - { - bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type)); - IList matches = new ArrayList(); - foreach (string name in objects.Keys) - { - object instance = objects[name]; - if (instance is IFactoryObject && !isFactoryType) - { - if(includeFactoryObjects) - { - Type objectType = ((IFactoryObject) instance).ObjectType; - if (objectType != null && type.IsAssignableFrom(objectType)) - { - matches.Add(name); - } - } - } - else - { - if (type.IsInstanceOfType(instance)) - { - matches.Add(name); - } - } - } - return (string[]) ArrayList.Adapter(matches).ToArray(typeof(string)); - } - - /// - /// Tests whether this object factory contains an object definition for the - /// specified object name. - /// - /// The object name to query. - /// - /// True if an object defintion is contained within this object factory. - /// - public bool ContainsObjectDefinition(string name) - { - return objects.ContainsKey(name); - } - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - ///

- /// This version of the - /// method matches all kinds of object definitions, be they singletons, prototypes, or - /// s. Typically, the results - /// of this method call will be the same as a call to - /// IListableObjectFactory.GetObjectsOfType(type,true,true) . - ///

- ///
- /// - /// The (class or interface) to match. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - public IDictionary GetObjectsOfType(Type type) - { - return GetObjectsOfType(type, true, true); - } - - /// - /// Return the object instances that match the given object - /// (including subclasses), judging from either object - /// definitions or the value of - /// in the case of - /// s. - /// - /// - /// The (class or interface) to match. - /// - /// - /// Whether to include prototype objects too or just singletons (also applies to - /// s). - /// - /// - /// Whether to include s too - /// or just normal objects. - /// - /// - /// A of the matching objects, - /// containing the object names as keys and the corresponding object instances - /// as values. - /// - /// - /// If the objects could not be created. - /// - public IDictionary GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects) - { - bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type)); - IDictionary matches = new Hashtable(); - foreach (string name in objects.Keys) - { - object instance = objects[name]; - if (instance is IFactoryObject && includeFactoryObjects) - { - IFactoryObject factory = (IFactoryObject) instance; - Type objectType = factory.ObjectType; - if ((objectType == null && factory.IsSingleton) || - ((factory.IsSingleton || includePrototypes) && - objectType != null && type.IsAssignableFrom(objectType))) - { - object createdObject = GetObject(name); - if (type.IsInstanceOfType(createdObject)) - { - matches[name] = createdObject; - } - } - } - else if (type.IsAssignableFrom(instance.GetType())) - { - if (isFactoryType) - { - matches[ObjectFactoryUtils.BuildFactoryObjectName(name)] = instance; - } - else - { - matches[name] = instance; - } - } - } - return matches; - } - - /// - /// Add a new singleton object. - /// - /// - /// The name to be associated with the object name. - /// - /// The singleton object. - public void AddObject(string name, object instance) - { - objects[name] = instance; - } - - /// - /// Injects dependencies into the supplied instance - /// using the named object definition. - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// This feature is not currently supported. - /// - /// - public object ConfigureObject(object target, string name) - { - throw new NotSupportedException(); - } - - /// - /// Injects dependencies into the supplied instance - /// using the supplied . - /// - /// - /// The object instance that is to be so configured. - /// - /// - /// The name of the object definition expressing the dependencies that are to - /// be injected into the supplied instance. - /// - /// - /// An object definition that should be used to configure object. - /// - /// - public object ConfigureObject(object target, string name, IObjectDefinition definition) - { - throw new NotSupportedException(); - } - - /// - /// Defines a method to release allocated unmanaged resources. - /// - public virtual void Dispose() - { - } - } +#region License +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Static factory that permits the registration of existing singleton instances. + /// + /// + ///

+ /// Does not have support for prototype objects, aliases, and post startup object + /// configuration. + ///

+ ///

+ /// Serves as a simple example implementation of the + /// interface, that manages existing object instances as opposed to creating new ones + /// based on object definitions. + ///

+ ///

+ /// The + /// method is not supported by this class; this class deals exclusively with + /// existing singleton instances, thus the methods mentioned previously make little sense in this context. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Simon White (.NET) + [Serializable] + public class StaticListableObjectFactory : IListableObjectFactory + { + /// + /// Map from object name to object instance. + /// + private Hashtable objects = new Hashtable(); + + /// + /// Return the number of objects defined in the factory. + /// + /// + /// The number of objects defined in the factory. + /// + public int ObjectDefinitionCount + { + get { return objects.Count; } + } + + /// + /// Return an instance of the given object name. + /// + /// The name of the object to return. + /// The instance of the object. + /// + public object this[string name] + { + get { return GetObject(name); } + } + + /// + /// Return an instance of the given object name. + /// + /// The name of the object to return. + /// The instance of the object. + /// + /// is not currently supported. + /// + /// + public object GetObject(string name) + { + object instance = objects[name]; + if (instance is IFactoryObject) + { + if (instance is IConfigurableFactoryObject) + { + throw new NotSupportedException(); + } + try + { + return ((IFactoryObject) instance).GetObject(); + } + catch (Exception ex) + { + throw new ObjectCreationException(name, + "IFactoryObject threw an exception on object creation", ex); + } + } + if (instance == null) + { + throw new NoSuchObjectDefinitionException(name, GrabDefinedObjectsString()); + } + return instance; + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// + ///

+ /// This method allows an object factory to be used as a replacement for the + /// Singleton or Prototype design pattern. + ///

+ ///

+ /// Note that callers should retain references to returned objects. There is no + /// guarantee that this method will be implemented to be efficient. For example, + /// it may be synchronized, or may need to run an RDBMS query. + ///

+ ///

+ /// Will ask the parent factory if the object cannot be found in this factory + /// instance. + ///

+ ///
+ /// The name of the object to return. + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a static factory method. If there is no factory method and the + /// arguments are not null, then match the argument values by type and + /// call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the supplied is . + /// + public object GetObject(string name, object[] arguments) + { + throw new NotSupportedException("StaticListableObjectFactory does not support this method."); + } + + /// + /// Return an instance (possibly shared or independent) of the given object name. + /// + /// The name of the object to return. + /// + /// The the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// + /// The arguments to use if creating a prototype using explicit arguments to + /// a factory method. If there is no factory method and the + /// supplied array is not , then + /// match the argument values by type and call the object's constructor. + /// + /// The instance of the object. + /// + /// If there's no such object definition. + /// + /// + /// If the object could not be created. + /// + /// + /// If the object is not of the required type. + /// + /// + /// If the supplied is . + /// + /// + public object GetObject(string name, Type requiredType, object[] arguments) + { + throw new NotSupportedException("StaticListableObjectFactory does not support this method."); + } + + /// + /// Return an instance of the given object name. + /// + /// The name of the object to return. + /// + /// the object may match. Can be an interface or + /// superclass of the actual class. For example, if the value is the + /// class, this method will succeed whatever the + /// class of the returned instance. + /// + /// The instance of the object. + /// + public object GetObject(string name, Type requiredType) + { + object instance = GetObject(name); + if (!requiredType.IsAssignableFrom(instance.GetType())) + { + throw new ObjectNotOfRequiredTypeException(name, requiredType, instance); + } + return instance; + } + + /// + /// Does this object factory contain an object with the given name? + /// + /// The name of the object to query. + /// True if an object with the given name is defined. + public bool ContainsObject(string name) + { + return objects.ContainsKey(name); + } + + /// + /// Is this object a singleton? + /// + /// + ///

+ /// That is, will + /// or + /// always return the same object? + ///

+ ///
+ /// The name of the object to query. + /// True if the named object is a singleton. + /// + /// If there's no such object definition. + /// + public bool IsSingleton(string name) + { + bool isSingleton = true; + object instance = GetObject(name); + // in case of IFactoryObject, return singleton status of created object + if (instance is IFactoryObject) + { + isSingleton = ((IFactoryObject) instance).IsSingleton; + } + return isSingleton; + } + + + /// + /// Determines whether the specified object name is prototype. That is, will GetObject + /// always return independent instances? + /// + /// This method returning false does not clearly indicate a singleton object. + /// It indicated non-independent instances, which may correspond to a scoped object as + /// well. use the IsSingleton property to explicitly check for a shared + /// singleton instance. + /// Translates aliases back to the corresponding canonical object name. Will ask the + /// parent factory if the object can not be found in this factory instance. + /// + /// + /// + /// The name of the object to query + /// + /// true if the specified object name will always deliver independent instances; otherwise, false. + /// + /// if there is no object with the given name. + public bool IsPrototype(string name) + { + bool isPrototype = true; + object instance = GetObject(name); + if (instance is IFactoryObject) + { + isPrototype = !((IFactoryObject) instance).IsSingleton; + } + return isPrototype; + + } + + /// + /// Determine the type of the object with the given name. + /// + /// + ///

+ /// More specifically, checks the type of object that + /// would return. + /// For an , returns the type + /// of object that the creates. + ///

+ ///
+ /// The name of the object to query. + /// + /// The of the object or if + /// not determinable. + /// + public Type GetType(string name) + { + string objectName = ObjectFactoryUtils.TransformedObjectName(name); + object instance = objects[objectName]; + if (instance == null) + { + throw new NoSuchObjectDefinitionException(name, GrabDefinedObjectsString()); + } + if (instance is IFactoryObject && !ObjectFactoryUtils.IsFactoryDereference(name)) + { + return ((IFactoryObject) instance).ObjectType; + } + return instance.GetType(); + } + + + /// + /// Determines whether the object with the given name matches the specified type. + /// + /// The name of the object to query. + /// Type of the target to match against. + /// + /// true if the object type matches; otherwise, false + /// if it doesn't match or cannot be determined yet. + /// + /// Ff there is no object with the given name + /// + public bool IsTypeMatch(string name, Type targetType) + { + Type type = GetType(name); + return (targetType == null || (type != null && targetType.IsAssignableFrom(type))); + } + + private string GrabDefinedObjectsString() + { + return "Defined objects are [" + + StringUtils.CollectionToDelimitedString(objects.Keys, ",") + "]"; + } + + /// + /// Return the aliases for the given object name, if defined. + /// + /// The object name to check for aliases. + /// The aliases, or an empty array if none. + /// + /// If there's no such object definition. + /// + public string[] GetAliases(string name) + { + return StringUtils.EmptyStrings; + } + + /// + /// Not supported. + /// + /// The name of the object. + /// + /// The registered + /// . + /// + /// + /// Always, as object definitions are not supported by this + /// implementation. + /// + public IObjectDefinition GetObjectDefinition(string name) + { + throw new NotSupportedException("StaticListableObjectFactory does not contain object definitions."); + } + + /// + /// Return the registered + /// for the + /// given object, allowing access to its property values and constructor + /// argument values. + /// + /// The name of the object. + /// Whether to search parent object factories. + /// + /// The registered + /// . + /// + /// + /// If there is no object with the given name. + /// + /// + /// In the case of errors. + /// + public IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) + { + throw new NotSupportedException("StaticListableObjectFactory does not contain object definitions."); + } + + + /// + /// Return the names of all objects defined in this factory. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + public string[] GetObjectDefinitionNames() + { + ArrayList names = new ArrayList(objects.Keys); + return (string[]) names.ToArray(typeof (string)); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + ///

+ /// Will not consider s, + /// as the type of their created objects is not known before instantiation. + ///

+ ///
+ /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + public string[] GetObjectDefinitionNames(Type type) + { + ArrayList matches = new ArrayList(); + foreach (string name in objects.Keys) + { + Type t = objects[name].GetType(); + if (type.IsAssignableFrom(t)) + { + matches.Add(name); + } + } + return (string[]) matches.ToArray(typeof (string)); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + ///

+ /// Does consider objects created by s, + /// or rather it considers the type of objects created by + /// (which means that + /// s will be instantiated). + ///

+ ///

+ /// Does not consider any hierarchy this factory may participate in. + ///

+ ///
+ /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + public string[] GetObjectNamesForType(Type type) + { + return GetObjectNamesForType(type, true, true); + } + + /// + /// Return the names of objects matching the given + /// (including subclasses), judging from the object definitions. + /// + /// + ///

+ /// Since this implementation of the + /// + /// interface does not support the notion of ptototype objects, the + /// parameter is ignored. + ///

+ ///
+ /// + /// The (class or interface) to match, or + /// for all object names. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). Ignored. + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// The names of all objects defined in this factory, or an empty array if none + /// are defined. + /// + /// + public string[] GetObjectNamesForType( + Type type, bool includePrototypes, bool includeFactoryObjects) + { + bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type)); + IList matches = new ArrayList(); + foreach (string name in objects.Keys) + { + object instance = objects[name]; + if (instance is IFactoryObject && !isFactoryType) + { + if(includeFactoryObjects) + { + Type objectType = ((IFactoryObject) instance).ObjectType; + if (objectType != null && type.IsAssignableFrom(objectType)) + { + matches.Add(name); + } + } + } + else + { + if (type.IsInstanceOfType(instance)) + { + matches.Add(name); + } + } + } + return (string[]) ArrayList.Adapter(matches).ToArray(typeof(string)); + } + + /// + /// Tests whether this object factory contains an object definition for the + /// specified object name. + /// + /// The object name to query. + /// + /// True if an object defintion is contained within this object factory. + /// + public bool ContainsObjectDefinition(string name) + { + return objects.ContainsKey(name); + } + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + ///

+ /// This version of the + /// method matches all kinds of object definitions, be they singletons, prototypes, or + /// s. Typically, the results + /// of this method call will be the same as a call to + /// IListableObjectFactory.GetObjectsOfType(type,true,true) . + ///

+ ///
+ /// + /// The (class or interface) to match. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + public IDictionary GetObjectsOfType(Type type) + { + return GetObjectsOfType(type, true, true); + } + + /// + /// Return the object instances that match the given object + /// (including subclasses), judging from either object + /// definitions or the value of + /// in the case of + /// s. + /// + /// + /// The (class or interface) to match. + /// + /// + /// Whether to include prototype objects too or just singletons (also applies to + /// s). + /// + /// + /// Whether to include s too + /// or just normal objects. + /// + /// + /// A of the matching objects, + /// containing the object names as keys and the corresponding object instances + /// as values. + /// + /// + /// If the objects could not be created. + /// + public IDictionary GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects) + { + bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type)); + IDictionary matches = new Hashtable(); + foreach (string name in objects.Keys) + { + object instance = objects[name]; + if (instance is IFactoryObject && includeFactoryObjects) + { + IFactoryObject factory = (IFactoryObject) instance; + Type objectType = factory.ObjectType; + if ((objectType == null && factory.IsSingleton) || + ((factory.IsSingleton || includePrototypes) && + objectType != null && type.IsAssignableFrom(objectType))) + { + object createdObject = GetObject(name); + if (type.IsInstanceOfType(createdObject)) + { + matches[name] = createdObject; + } + } + } + else if (type.IsAssignableFrom(instance.GetType())) + { + if (isFactoryType) + { + matches[ObjectFactoryUtils.BuildFactoryObjectName(name)] = instance; + } + else + { + matches[name] = instance; + } + } + } + return matches; + } + + /// + /// Add a new singleton object. + /// + /// + /// The name to be associated with the object name. + /// + /// The singleton object. + public void AddObject(string name, object instance) + { + objects[name] = instance; + } + + /// + /// Injects dependencies into the supplied instance + /// using the named object definition. + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// This feature is not currently supported. + /// + /// + public object ConfigureObject(object target, string name) + { + throw new NotSupportedException(); + } + + /// + /// Injects dependencies into the supplied instance + /// using the supplied . + /// + /// + /// The object instance that is to be so configured. + /// + /// + /// The name of the object definition expressing the dependencies that are to + /// be injected into the supplied instance. + /// + /// + /// An object definition that should be used to configure object. + /// + /// + public object ConfigureObject(object target, string name, IObjectDefinition definition) + { + throw new NotSupportedException(); + } + + /// + /// Defines a method to release allocated unmanaged resources. + /// + public virtual void Dispose() + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/UnsatisfiedDependencyException.cs b/src/Spring/Spring.Core/Objects/Factory/UnsatisfiedDependencyException.cs index a32dcd70..adf9824f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/UnsatisfiedDependencyException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/UnsatisfiedDependencyException.cs @@ -1,160 +1,159 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Objects.Factory -{ - /// - /// Exception thrown when an object depends on other objects or simple properties - /// that were not specified in the object factory definition, although dependency - /// checking was enabled. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: UnsatisfiedDependencyException.cs,v 1.8 2006/04/09 07:18:49 markpollack Exp $ - [Serializable] - public class UnsatisfiedDependencyException : ObjectCreationException - { - /// - /// Creates a new instance of the UnsatisfiedDependencyException class. - /// - public UnsatisfiedDependencyException() - { - } - - /// - /// Creates a new instance of the UnsatisfiedDependencyException class. - /// - /// - /// A message about the exception. - /// - public UnsatisfiedDependencyException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the UnsatisfiedDependencyException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public UnsatisfiedDependencyException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the UnsatisfiedDependencyException class. - /// - /// - /// The description of the resource associated with the object. - /// - /// - /// The name of the object that has the unsatisfied dependency. - /// - /// - /// The constructor argument index at which the dependency is - /// unsatisfied. - /// - /// - /// The of the constructor argument at - /// which the dependency is unsatisfied. - /// - /// - /// A message about the exception. - /// - public UnsatisfiedDependencyException( - string resourceDescription, - string name, - int argumentIndex, - Type argumentType, - string message) - : base( - resourceDescription, - name, - string.Format( - "Unsatisfied dependency expressed through constructor argument with index {0} of type [{1}] : {2}", - argumentIndex, - argumentType, - message)) - { - } - - /// - /// Creates a new instance of the UnsatisfiedDependencyException class. - /// - /// - /// The description of the resource associated with the object. - /// - /// - /// The name of the object that has the unsatisfied dependency. - /// - /// - /// The name identifying the property on which the dependency is - /// unsatisfied. - /// - /// - /// A message about the exception. - /// - public UnsatisfiedDependencyException( - string resourceDescription, - string name, - string propertyName, - string message) - : base( - resourceDescription, - name, - string.Format( - "Unsatisfied dependency expressed through object property '{0}': {1}", - propertyName, - message)) - { - } - - /// - /// Creates a new instance of the UnsatisfiedDependencyException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected UnsatisfiedDependencyException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Objects.Factory +{ + /// + /// Exception thrown when an object depends on other objects or simple properties + /// that were not specified in the object factory definition, although dependency + /// checking was enabled. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + [Serializable] + public class UnsatisfiedDependencyException : ObjectCreationException + { + /// + /// Creates a new instance of the UnsatisfiedDependencyException class. + /// + public UnsatisfiedDependencyException() + { + } + + /// + /// Creates a new instance of the UnsatisfiedDependencyException class. + /// + /// + /// A message about the exception. + /// + public UnsatisfiedDependencyException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the UnsatisfiedDependencyException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public UnsatisfiedDependencyException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the UnsatisfiedDependencyException class. + /// + /// + /// The description of the resource associated with the object. + /// + /// + /// The name of the object that has the unsatisfied dependency. + /// + /// + /// The constructor argument index at which the dependency is + /// unsatisfied. + /// + /// + /// The of the constructor argument at + /// which the dependency is unsatisfied. + /// + /// + /// A message about the exception. + /// + public UnsatisfiedDependencyException( + string resourceDescription, + string name, + int argumentIndex, + Type argumentType, + string message) + : base( + resourceDescription, + name, + string.Format( + "Unsatisfied dependency expressed through constructor argument with index {0} of type [{1}] : {2}", + argumentIndex, + argumentType, + message)) + { + } + + /// + /// Creates a new instance of the UnsatisfiedDependencyException class. + /// + /// + /// The description of the resource associated with the object. + /// + /// + /// The name of the object that has the unsatisfied dependency. + /// + /// + /// The name identifying the property on which the dependency is + /// unsatisfied. + /// + /// + /// A message about the exception. + /// + public UnsatisfiedDependencyException( + string resourceDescription, + string name, + string propertyName, + string message) + : base( + resourceDescription, + name, + string.Format( + "Unsatisfied dependency expressed through object property '{0}': {1}", + propertyName, + message)) + { + } + + /// + /// Creates a new instance of the UnsatisfiedDependencyException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected UnsatisfiedDependencyException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractObjectDefinitionParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractObjectDefinitionParser.cs index 2d15e7d0..e40dad6f 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractObjectDefinitionParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractObjectDefinitionParser.cs @@ -1,212 +1,211 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports -using System.Xml; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Util; -#endregion - -namespace Spring.Objects.Factory.Xml -{ - - - /// - /// Abstract implementation providing - /// a number of convenience methods and a - /// template method - /// that subclasses must override to provide the actual parsing logic. - /// - /// - /// Use this implementation when you want - /// to parse some arbitrarily complex XML into one or more - /// ObjectDefinitions. If you just want to parse some - /// XML into a single IObjectDefinition, you may wish to consider - /// the simpler convenience extensions of this class, namely - /// and - /// - /// - /// Rob Harrop - /// Juergen Hoeller - /// Rick Evans - /// Mark Pollack (.NET) - /// $Id: AbstractObjectDefinitionParser.cs,v 1.4 2007/05/26 19:25:54 markpollack Exp $ - public abstract class AbstractObjectDefinitionParser : IObjectDefinitionParser - { - /// - /// Constant for the ID attribute - /// - public static readonly string ID_ATTRIBUTE = "id"; - - #region Properties - - /// - /// Gets a value indicating whether an ID should be generated instead of read - /// from the passed in XmlElement. - /// - /// Note that this flag is about always generating an ID; the parser - /// won't even check for an "id" attribute in this case. - /// - /// true if should generate id; otherwise, false. - protected virtual bool ShouldGenerateId - { - get { return false; } - } - - /// - /// Gets a value indicating whether an ID should be generated instead if the - /// passed in XmlElement does not specify an "id" attribute explicitly. - /// - /// Disabled by default; subclasses can override this to enable ID generation - /// as fallback: The parser will first check for an "id" attribute in this case, - /// only falling back to a generated ID if no value was specified. - /// - /// true if should generate id if no value was specified; otherwise, false. - /// - protected virtual bool ShouldGenerateIdAsFallback - { - get { return false; } - } - - #endregion - - #region IObjectDefinitionParser Members - - - /// - /// Parse the specified XmlElement and register the resulting - /// ObjectDefinitions with the IObjectDefinitionRegistry - /// embedded in the supplied - /// - /// The element to be parsed. - /// TThe object encapsulating the current state of the parsing process. - /// Provides access to a IObjectDefinitionRegistry - /// The primary object definition. - /// - ///

- /// This method is never invoked if the parser is namespace aware - /// and was called to process the root node. - ///

- ///
- public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - AbstractObjectDefinition definition = ParseInternal(element, parserContext); - - if (!parserContext.IsNested) - { - string id = null; - try - { - id = ResolveId(element, definition, parserContext); - if (!StringUtils.HasText(id)) - { - parserContext.ReaderContext.ReportException(element, "null", - "Id is required for element '" + element.LocalName + "' when used as a top-level tag", null); - } - ObjectDefinitionHolder holder = new ObjectDefinitionHolder(definition, id); - RegisterObjectDefinition(holder, parserContext.Registry); - } - catch (ObjectDefinitionStoreException ex) - { - parserContext.ReaderContext.ReportException(element, id, ex.Message); - return null; - } - } - return definition; - - - } - - #endregion - - #region Methods - - /// - /// Resolves the ID for the supplied . - /// - /// - /// When using generation, a name is generated automatically. - /// Otherwise, the ID is extracted from the "id" attribute, potentially with a - /// fallback to a generated id. - /// - /// The element that the object definition has been built from. - /// The object definition to be registered. - /// The the object encapsulating the current state of the parsing process; - /// provides access to a - /// the resolved id - /// - /// if no unique name could be generated for the given object definition - /// - protected virtual string ResolveId(XmlElement element, AbstractObjectDefinition definition, ParserContext parserContext) - { - - if (ShouldGenerateId) { - return parserContext.ReaderContext.GenerateObjectName(definition); - } - else { - string id = element.GetAttribute(ID_ATTRIBUTE); - if (!StringUtils.HasText(id) && ShouldGenerateIdAsFallback) { - id = parserContext.ReaderContext.GenerateObjectName(definition); - } - return id; - } - } - - /// - /// Registers the supplied with the supplied - /// . - /// - /// Subclasses can override this method to control whether or not the supplied - /// is actually even registered, or to - /// register even more objects. - /// - /// The default implementation registers the supplied - /// with the supplied only if the IsNested - /// parameter is false, because one typically does not want inner objects - /// to be registered as top level objects. - /// - /// - /// - /// The object definition to be registered. - /// The registry that the bean is to be registered with. - protected virtual void RegisterObjectDefinition(ObjectDefinitionHolder definition, IObjectDefinitionRegistry registry) - { - ObjectDefinitionReaderUtils.RegisterObjectDefinition(definition, registry); - } - - #endregion - - - #region Abstract Methods - - /// - /// Central template method to actually parse the supplied XmlElement - /// into one or more IObjectDefinitions. - /// - /// The element that is to be parsed into one or more s - /// The the object encapsulating the current state of the parsing process; - /// provides access to a - /// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement - protected abstract AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext); - - #endregion - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports +using System.Xml; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Util; +#endregion + +namespace Spring.Objects.Factory.Xml +{ + + + /// + /// Abstract implementation providing + /// a number of convenience methods and a + /// template method + /// that subclasses must override to provide the actual parsing logic. + /// + /// + /// Use this implementation when you want + /// to parse some arbitrarily complex XML into one or more + /// ObjectDefinitions. If you just want to parse some + /// XML into a single IObjectDefinition, you may wish to consider + /// the simpler convenience extensions of this class, namely + /// and + /// + /// + /// Rob Harrop + /// Juergen Hoeller + /// Rick Evans + /// Mark Pollack (.NET) + public abstract class AbstractObjectDefinitionParser : IObjectDefinitionParser + { + /// + /// Constant for the ID attribute + /// + public static readonly string ID_ATTRIBUTE = "id"; + + #region Properties + + /// + /// Gets a value indicating whether an ID should be generated instead of read + /// from the passed in XmlElement. + /// + /// Note that this flag is about always generating an ID; the parser + /// won't even check for an "id" attribute in this case. + /// + /// true if should generate id; otherwise, false. + protected virtual bool ShouldGenerateId + { + get { return false; } + } + + /// + /// Gets a value indicating whether an ID should be generated instead if the + /// passed in XmlElement does not specify an "id" attribute explicitly. + /// + /// Disabled by default; subclasses can override this to enable ID generation + /// as fallback: The parser will first check for an "id" attribute in this case, + /// only falling back to a generated ID if no value was specified. + /// + /// true if should generate id if no value was specified; otherwise, false. + /// + protected virtual bool ShouldGenerateIdAsFallback + { + get { return false; } + } + + #endregion + + #region IObjectDefinitionParser Members + + + /// + /// Parse the specified XmlElement and register the resulting + /// ObjectDefinitions with the IObjectDefinitionRegistry + /// embedded in the supplied + /// + /// The element to be parsed. + /// TThe object encapsulating the current state of the parsing process. + /// Provides access to a IObjectDefinitionRegistry + /// The primary object definition. + /// + ///

+ /// This method is never invoked if the parser is namespace aware + /// and was called to process the root node. + ///

+ ///
+ public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + AbstractObjectDefinition definition = ParseInternal(element, parserContext); + + if (!parserContext.IsNested) + { + string id = null; + try + { + id = ResolveId(element, definition, parserContext); + if (!StringUtils.HasText(id)) + { + parserContext.ReaderContext.ReportException(element, "null", + "Id is required for element '" + element.LocalName + "' when used as a top-level tag", null); + } + ObjectDefinitionHolder holder = new ObjectDefinitionHolder(definition, id); + RegisterObjectDefinition(holder, parserContext.Registry); + } + catch (ObjectDefinitionStoreException ex) + { + parserContext.ReaderContext.ReportException(element, id, ex.Message); + return null; + } + } + return definition; + + + } + + #endregion + + #region Methods + + /// + /// Resolves the ID for the supplied . + /// + /// + /// When using generation, a name is generated automatically. + /// Otherwise, the ID is extracted from the "id" attribute, potentially with a + /// fallback to a generated id. + /// + /// The element that the object definition has been built from. + /// The object definition to be registered. + /// The the object encapsulating the current state of the parsing process; + /// provides access to a + /// the resolved id + /// + /// if no unique name could be generated for the given object definition + /// + protected virtual string ResolveId(XmlElement element, AbstractObjectDefinition definition, ParserContext parserContext) + { + + if (ShouldGenerateId) { + return parserContext.ReaderContext.GenerateObjectName(definition); + } + else { + string id = element.GetAttribute(ID_ATTRIBUTE); + if (!StringUtils.HasText(id) && ShouldGenerateIdAsFallback) { + id = parserContext.ReaderContext.GenerateObjectName(definition); + } + return id; + } + } + + /// + /// Registers the supplied with the supplied + /// . + /// + /// Subclasses can override this method to control whether or not the supplied + /// is actually even registered, or to + /// register even more objects. + /// + /// The default implementation registers the supplied + /// with the supplied only if the IsNested + /// parameter is false, because one typically does not want inner objects + /// to be registered as top level objects. + /// + /// + /// + /// The object definition to be registered. + /// The registry that the bean is to be registered with. + protected virtual void RegisterObjectDefinition(ObjectDefinitionHolder definition, IObjectDefinitionRegistry registry) + { + ObjectDefinitionReaderUtils.RegisterObjectDefinition(definition, registry); + } + + #endregion + + + #region Abstract Methods + + /// + /// Central template method to actually parse the supplied XmlElement + /// into one or more IObjectDefinitions. + /// + /// The element that is to be parsed into one or more s + /// The the object encapsulating the current state of the parsing process; + /// provides access to a + /// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement + protected abstract AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext); + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSimpleObjectDefinitionParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSimpleObjectDefinitionParser.cs index 7e45a7d6..f6e9643d 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSimpleObjectDefinitionParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSimpleObjectDefinitionParser.cs @@ -1,37 +1,36 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Convenient base class for when there exists a one-to-one mapping - /// between attribute names on the element that is to be parsed and - /// the property names on the Type being configured. - /// - /// - /// - /// - /// Mark Pollack - /// $Id: AbstractSimpleObjectDefinitionParser.cs,v 1.1 2007/05/26 19:25:54 markpollack Exp $ - public class AbstractSimpleObjectDefinitionParser : AbstractSingleObjectDefinitionParser - { - - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Convenient base class for when there exists a one-to-one mapping + /// between attribute names on the element that is to be parsed and + /// the property names on the Type being configured. + /// + /// + /// + /// + /// Mark Pollack + public class AbstractSimpleObjectDefinitionParser : AbstractSingleObjectDefinitionParser + { + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSingleObjectDefinitionParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSingleObjectDefinitionParser.cs index 56fba856..c690bbd7 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSingleObjectDefinitionParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/AbstractSingleObjectDefinitionParser.cs @@ -1,143 +1,142 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Xml; -using Spring.Objects.Factory.Support; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Base Type for those implementations that - /// need to parse and define just a single IObjectDefinition. - /// - /// - /// Extend this parser Type when you want to create a single object definition - /// from an arbitrarily complex XML element. You may wish to consider extending - /// the when you want to create a - /// single Object definition from a relatively simple custom XML element. - /// The resulting ObjectDefinition will be automatically registered - /// with the ObjectDefinitionRegistry. Your job simply is to parse the - /// custom XML element into a single ObjectDefinition - /// - /// Rob Harrop - /// Juergen Hoeller - /// Rick Evans - /// Mark Pollack (.NET) - /// $Id: AbstractSingleObjectDefinitionParser.cs,v 1.3 2007/05/29 14:42:20 markpollack Exp $ - public class AbstractSingleObjectDefinitionParser : AbstractObjectDefinitionParser - { - #region Methods - - /// - /// Central template method to actually parse the supplied XmlElement - /// into one or more IObjectDefinitions. - /// - /// The element that is to be parsed into one or more s - /// The the object encapsulating the current state of the parsing process; - /// provides access to a - /// - /// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement - /// - protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext) - { - ObjectDefinitionBuilder builder; - Type objectType = GetObjectType(element); - if (objectType != null) - { - builder = - ObjectDefinitionBuilder.RootObjectDefinition(parserContext.ReaderContext.ObjectDefinitionFactory, - objectType); - } - else - { - throw new NotSupportedException("Need to refactor IObjectDefinitionFactory to not resolve object type names"); - } - if (parserContext.IsNested) - { - // Inner object definition must receive same singleton status as containing object. - builder.SetSingleton(parserContext.ContainingObjectDefinition.IsSingleton); - } - if (parserContext.IsDefaultLazyInit) - { - // Default-lazy-init applies to custom object definitions as well. - builder.SetLazyInit(true); - } - DoParse(element, parserContext, builder); - return builder.ObjectDefinition; - - } - - /// - /// Gets the type of the object corresponding to the supplied XmlElement. - /// - /// Note that, for application classes, it is generally preferable to override - /// GetObjectTypeName instad, in order to avoid a direct - /// dependence on the object implementation class. The ObjectDefinitionParser - /// and its IXmlObjectDefinitionParser (namespace parser) can be used within an - /// IDE add-in then, even if the application classses are not available in the add-ins - /// AppDomain. - /// - /// The element. - /// The Type of the class that is being defined via parsing the supplied - /// Element. - protected virtual Type GetObjectType(XmlElement element) - { - return null; - } - - /// - /// Gets the name of the object type name (FullName) corresponding to the supplied XmlElement. - /// - /// The element. - /// The type name of the object that is being defined via parsing the supplied - /// XmlElement. - protected virtual string GetObjectTypeName(XmlElement element) - { - return null; - } - - /// - /// Parse the supplied XmlElement and populate the supplied ObjectDefinitionBuilder as required. - /// - /// The default implementation delegates to the DoParse version without - /// ParameterContext argument. - /// The element. - /// The parser context. - /// The builder used to define the IObjectDefinition. - protected virtual void DoParse(XmlElement element, ParserContext parserContext, ObjectDefinitionBuilder builder) - { - DoParse(element, builder); - } - - /// - /// Parse the supplied XmlElement and populate the supplied ObjectDefinitionBuilder as required. - /// - /// The default implementation does nothing. - /// The element. - /// The builder used to define the IObjectDefinition. - protected virtual void DoParse(XmlElement element, ObjectDefinitionBuilder builder) - { - - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Xml; +using Spring.Objects.Factory.Support; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Base Type for those implementations that + /// need to parse and define just a single IObjectDefinition. + /// + /// + /// Extend this parser Type when you want to create a single object definition + /// from an arbitrarily complex XML element. You may wish to consider extending + /// the when you want to create a + /// single Object definition from a relatively simple custom XML element. + /// The resulting ObjectDefinition will be automatically registered + /// with the ObjectDefinitionRegistry. Your job simply is to parse the + /// custom XML element into a single ObjectDefinition + /// + /// Rob Harrop + /// Juergen Hoeller + /// Rick Evans + /// Mark Pollack (.NET) + public class AbstractSingleObjectDefinitionParser : AbstractObjectDefinitionParser + { + #region Methods + + /// + /// Central template method to actually parse the supplied XmlElement + /// into one or more IObjectDefinitions. + /// + /// The element that is to be parsed into one or more s + /// The the object encapsulating the current state of the parsing process; + /// provides access to a + /// + /// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement + /// + protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext) + { + ObjectDefinitionBuilder builder; + Type objectType = GetObjectType(element); + if (objectType != null) + { + builder = + ObjectDefinitionBuilder.RootObjectDefinition(parserContext.ReaderContext.ObjectDefinitionFactory, + objectType); + } + else + { + throw new NotSupportedException("Need to refactor IObjectDefinitionFactory to not resolve object type names"); + } + if (parserContext.IsNested) + { + // Inner object definition must receive same singleton status as containing object. + builder.SetSingleton(parserContext.ContainingObjectDefinition.IsSingleton); + } + if (parserContext.IsDefaultLazyInit) + { + // Default-lazy-init applies to custom object definitions as well. + builder.SetLazyInit(true); + } + DoParse(element, parserContext, builder); + return builder.ObjectDefinition; + + } + + /// + /// Gets the type of the object corresponding to the supplied XmlElement. + /// + /// Note that, for application classes, it is generally preferable to override + /// GetObjectTypeName instad, in order to avoid a direct + /// dependence on the object implementation class. The ObjectDefinitionParser + /// and its IXmlObjectDefinitionParser (namespace parser) can be used within an + /// IDE add-in then, even if the application classses are not available in the add-ins + /// AppDomain. + /// + /// The element. + /// The Type of the class that is being defined via parsing the supplied + /// Element. + protected virtual Type GetObjectType(XmlElement element) + { + return null; + } + + /// + /// Gets the name of the object type name (FullName) corresponding to the supplied XmlElement. + /// + /// The element. + /// The type name of the object that is being defined via parsing the supplied + /// XmlElement. + protected virtual string GetObjectTypeName(XmlElement element) + { + return null; + } + + /// + /// Parse the supplied XmlElement and populate the supplied ObjectDefinitionBuilder as required. + /// + /// The default implementation delegates to the DoParse version without + /// ParameterContext argument. + /// The element. + /// The parser context. + /// The builder used to define the IObjectDefinition. + protected virtual void DoParse(XmlElement element, ParserContext parserContext, ObjectDefinitionBuilder builder) + { + DoParse(element, builder); + } + + /// + /// Parse the supplied XmlElement and populate the supplied ObjectDefinitionBuilder as required. + /// + /// The default implementation does nothing. + /// The element. + /// The builder used to define the IObjectDefinition. + protected virtual void DoParse(XmlElement element, ObjectDefinitionBuilder builder) + { + + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/DefaultObjectDefinitionDocumentReader.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/DefaultObjectDefinitionDocumentReader.cs index 794f2837..ce2db6fd 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/DefaultObjectDefinitionDocumentReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/DefaultObjectDefinitionDocumentReader.cs @@ -1,341 +1,340 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.IO; -using System.Xml; -using Common.Logging; -using Spring.Core.IO; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// XML resource reader. - /// - /// - ///

- /// Navigates through an XML resource and invokes parsers registered - /// with the . - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: DefaultObjectDefinitionDocumentReader.cs,v 1.9 2007/08/27 14:49:43 oakinger Exp $ - public class DefaultObjectDefinitionDocumentReader : IObjectDefinitionDocumentReader - { - #region Constants - - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof(DefaultObjectDefinitionDocumentReader)); - - #endregion - - #region Fields - - private XmlReaderContext readerContext; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the DefaultObjectDefinitionDocumentReader class. - /// - public DefaultObjectDefinitionDocumentReader() - { - } - - #endregion - - #region Properties - - /// - /// Gets the reader context. - /// - /// The reader context. - public XmlReaderContext ReaderContext - { - get { return readerContext; } - } - - #endregion - - #region Methods - - /// - /// Read object definitions from the given DOM element, and register - /// them with the given object registry. - /// - /// The DOM element containing object definitions, usually the - /// root (document) element. - /// The current context of the reader. Includes - /// the resource being parsed - /// - /// The number of object definitions that were loaded. - /// - /// - /// In case of parsing errors. - /// - public void RegisterObjectDefinitions(XmlDocument doc, XmlReaderContext readerContext) - { - //int objectDefinitionCounter = 0; - - this.readerContext = readerContext; - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Loading object definitions."); - } - - #endregion - - XmlElement root = doc.DocumentElement; - - ObjectDefinitionParserHelper parserHelper = CreateHelper(readerContext, root); - - - PreProcessXml(root); - - ParseObjectDefinitions(root, parserHelper); - - PostProcessXml(root); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - "Found {0} <{1}> elements defining objects.", - readerContext.Registry.ObjectDefinitionCount, - ObjectDefinitionConstants.ObjectElement)); - } - - #endregion - } - - /// - /// Parses object definitions starting at the given - /// using the passed . - /// - /// The root element to start parsing from. - /// The instance to use. - protected virtual void ParseObjectDefinitions(XmlElement root, ObjectDefinitionParserHelper helper) - { - foreach (XmlNode node in root.ChildNodes) - { - if (node.NodeType == XmlNodeType.Element) - { - XmlElement element = (XmlElement) node; - INamespaceParser parser = GetNamespaceParser(element, helper); - ParserContext parserContext = new ParserContext(helper.ReaderContext, helper); - parser.ParseElement(element, parserContext); - } - } - } - - /// - /// Parses the default element. - /// - /// The element. - /// The helper. - private void ParseDefaultElement(XmlElement element, ObjectDefinitionParserHelper helper) - { - if (element.LocalName == ObjectDefinitionConstants.ImportElement) - { - ImportObjectDefinitionResource(element); - } - else if (element.LocalName == ObjectDefinitionConstants.AliasElement) - { - ParseAlias(element, ReaderContext.Registry); - } - else if (element.LocalName == ObjectDefinitionConstants.ObjectElement) - { - RegisterObjectDefinition(element, helper); - } - } - - /// - /// Loads external XML object definitions from the resource described by the supplied - /// . - /// - /// The XML element describing the resource. - /// - /// If the resource could not be imported. - /// - protected virtual void ImportObjectDefinitionResource(XmlElement resource) - { - string location = resource.GetAttribute(ObjectDefinitionConstants.ImportResourceAttribute); - try - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Attempting to import object definitions from '{0}'.", location)); - } - - #endregion - - IResource importResource = ReaderContext.Resource.CreateRelative(location); - ReaderContext.Reader.LoadObjectDefinitions(importResource); - } - catch (IOException ex) - { - ReaderContext.ReportException(resource, null, string.Format( - CultureInfo.InvariantCulture, - "Invalid relative resource location '{0}' to import object definitions from.", - location), ex); - } - } - - /// - /// Parses the given alias element, registering the alias with the registry. - /// - /// The alias element. - /// The registry. - protected virtual void ParseAlias(XmlElement aliasElement, IObjectDefinitionRegistry registry) - { - string name = aliasElement.GetAttribute(ObjectDefinitionConstants.NameAttribute); - string alias = aliasElement.GetAttribute(ObjectDefinitionConstants.AliasAttribute); - registry.RegisterAlias(name, alias); - } - - /// - /// Parse an object definition and register it with the object factory.. - /// - /// The element containing the object definition. - /// The helper. - /// - protected virtual void RegisterObjectDefinition(XmlElement element, ObjectDefinitionParserHelper helper) - { - ObjectDefinitionHolder holder = null; - try - { - INamespaceParser parser = GetNamespaceParser(element, helper); - - //holder = ParseObjectDefinition(element, parserContext); - //holder = helper.ParseObjectDefinitionElement(element); - if (holder == null) - { - return; - } - } - catch (Exception ex) - { - throw new ObjectDefinitionStoreException( - string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex); - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - CultureInfo.InvariantCulture, - "Registering object definition with id '{0}'.", holder.ObjectName)); - } - - #endregion - - ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, ReaderContext.Registry); - } - - /// - /// - /// Allow the XML to be extensible by processing any custom element types last, - /// after we finished processing the objct definitions. This method is a natural - /// extension point for any other custom post-processing of the XML. - /// - /// The default implementation is empty. Subclasses can override this method to - /// convert custom elements into standard Spring object definitions, for example. - /// Implementors have access to the parser's object definition reader and the - /// underlying XML resource, through the corresponding properties. - /// - /// - /// The root. - protected virtual void PostProcessXml(XmlElement root) - { - } - - /// - /// Allow the XML to be extensible by processing any custom element types first, - /// before we start to process the object definitions. - /// - /// This method is a natural - /// extension point for any other custom pre-processing of the XML. - ///

The default implementation is empty. Subclasses can override this method to - /// convert custom elements into standard Spring object definitions, for example. - /// Implementors have access to the parser's object definition reader and the - /// underlying XML resource, through the corresponding properties. - ///

- ///
- /// The root element of the XML document. - protected virtual void PreProcessXml(XmlElement root) - { - } - - /// - /// Creates an instance for the given and element. - /// - /// the to create the - /// the root to start reading from - /// a new instance - protected virtual ObjectDefinitionParserHelper CreateHelper(XmlReaderContext readerContext, XmlElement root) - { - ObjectDefinitionParserHelper helper = new ObjectDefinitionParserHelper(readerContext); - helper.InitDefaults(root); - return helper; - } - - private INamespaceParser GetNamespaceParser(XmlElement element, ObjectDefinitionParserHelper helper) - { - INamespaceParser parser = NamespaceParserRegistry.GetParser(element.NamespaceURI); - if (parser == null) - { - helper.ReaderContext.ReportException(element, null, GetNoParserForNamespaceMessage(element.NamespaceURI)); - } - return parser; - } - - private string GetNoParserForNamespaceMessage(string namespaceURI) - { - return "There is no parser registered for namespace '" + namespaceURI + "'"; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.IO; +using System.Xml; +using Common.Logging; +using Spring.Core.IO; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// XML resource reader. + /// + /// + ///

+ /// Navigates through an XML resource and invokes parsers registered + /// with the . + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public class DefaultObjectDefinitionDocumentReader : IObjectDefinitionDocumentReader + { + #region Constants + + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof(DefaultObjectDefinitionDocumentReader)); + + #endregion + + #region Fields + + private XmlReaderContext readerContext; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the DefaultObjectDefinitionDocumentReader class. + /// + public DefaultObjectDefinitionDocumentReader() + { + } + + #endregion + + #region Properties + + /// + /// Gets the reader context. + /// + /// The reader context. + public XmlReaderContext ReaderContext + { + get { return readerContext; } + } + + #endregion + + #region Methods + + /// + /// Read object definitions from the given DOM element, and register + /// them with the given object registry. + /// + /// The DOM element containing object definitions, usually the + /// root (document) element. + /// The current context of the reader. Includes + /// the resource being parsed + /// + /// The number of object definitions that were loaded. + /// + /// + /// In case of parsing errors. + /// + public void RegisterObjectDefinitions(XmlDocument doc, XmlReaderContext readerContext) + { + //int objectDefinitionCounter = 0; + + this.readerContext = readerContext; + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Loading object definitions."); + } + + #endregion + + XmlElement root = doc.DocumentElement; + + ObjectDefinitionParserHelper parserHelper = CreateHelper(readerContext, root); + + + PreProcessXml(root); + + ParseObjectDefinitions(root, parserHelper); + + PostProcessXml(root); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + "Found {0} <{1}> elements defining objects.", + readerContext.Registry.ObjectDefinitionCount, + ObjectDefinitionConstants.ObjectElement)); + } + + #endregion + } + + /// + /// Parses object definitions starting at the given + /// using the passed . + /// + /// The root element to start parsing from. + /// The instance to use. + protected virtual void ParseObjectDefinitions(XmlElement root, ObjectDefinitionParserHelper helper) + { + foreach (XmlNode node in root.ChildNodes) + { + if (node.NodeType == XmlNodeType.Element) + { + XmlElement element = (XmlElement) node; + INamespaceParser parser = GetNamespaceParser(element, helper); + ParserContext parserContext = new ParserContext(helper.ReaderContext, helper); + parser.ParseElement(element, parserContext); + } + } + } + + /// + /// Parses the default element. + /// + /// The element. + /// The helper. + private void ParseDefaultElement(XmlElement element, ObjectDefinitionParserHelper helper) + { + if (element.LocalName == ObjectDefinitionConstants.ImportElement) + { + ImportObjectDefinitionResource(element); + } + else if (element.LocalName == ObjectDefinitionConstants.AliasElement) + { + ParseAlias(element, ReaderContext.Registry); + } + else if (element.LocalName == ObjectDefinitionConstants.ObjectElement) + { + RegisterObjectDefinition(element, helper); + } + } + + /// + /// Loads external XML object definitions from the resource described by the supplied + /// . + /// + /// The XML element describing the resource. + /// + /// If the resource could not be imported. + /// + protected virtual void ImportObjectDefinitionResource(XmlElement resource) + { + string location = resource.GetAttribute(ObjectDefinitionConstants.ImportResourceAttribute); + try + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Attempting to import object definitions from '{0}'.", location)); + } + + #endregion + + IResource importResource = ReaderContext.Resource.CreateRelative(location); + ReaderContext.Reader.LoadObjectDefinitions(importResource); + } + catch (IOException ex) + { + ReaderContext.ReportException(resource, null, string.Format( + CultureInfo.InvariantCulture, + "Invalid relative resource location '{0}' to import object definitions from.", + location), ex); + } + } + + /// + /// Parses the given alias element, registering the alias with the registry. + /// + /// The alias element. + /// The registry. + protected virtual void ParseAlias(XmlElement aliasElement, IObjectDefinitionRegistry registry) + { + string name = aliasElement.GetAttribute(ObjectDefinitionConstants.NameAttribute); + string alias = aliasElement.GetAttribute(ObjectDefinitionConstants.AliasAttribute); + registry.RegisterAlias(name, alias); + } + + /// + /// Parse an object definition and register it with the object factory.. + /// + /// The element containing the object definition. + /// The helper. + /// + protected virtual void RegisterObjectDefinition(XmlElement element, ObjectDefinitionParserHelper helper) + { + ObjectDefinitionHolder holder = null; + try + { + INamespaceParser parser = GetNamespaceParser(element, helper); + + //holder = ParseObjectDefinition(element, parserContext); + //holder = helper.ParseObjectDefinitionElement(element); + if (holder == null) + { + return; + } + } + catch (Exception ex) + { + throw new ObjectDefinitionStoreException( + string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex); + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + CultureInfo.InvariantCulture, + "Registering object definition with id '{0}'.", holder.ObjectName)); + } + + #endregion + + ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, ReaderContext.Registry); + } + + /// + /// + /// Allow the XML to be extensible by processing any custom element types last, + /// after we finished processing the objct definitions. This method is a natural + /// extension point for any other custom post-processing of the XML. + /// + /// The default implementation is empty. Subclasses can override this method to + /// convert custom elements into standard Spring object definitions, for example. + /// Implementors have access to the parser's object definition reader and the + /// underlying XML resource, through the corresponding properties. + /// + /// + /// The root. + protected virtual void PostProcessXml(XmlElement root) + { + } + + /// + /// Allow the XML to be extensible by processing any custom element types first, + /// before we start to process the object definitions. + /// + /// This method is a natural + /// extension point for any other custom pre-processing of the XML. + ///

The default implementation is empty. Subclasses can override this method to + /// convert custom elements into standard Spring object definitions, for example. + /// Implementors have access to the parser's object definition reader and the + /// underlying XML resource, through the corresponding properties. + ///

+ ///
+ /// The root element of the XML document. + protected virtual void PreProcessXml(XmlElement root) + { + } + + /// + /// Creates an instance for the given and element. + /// + /// the to create the + /// the root to start reading from + /// a new instance + protected virtual ObjectDefinitionParserHelper CreateHelper(XmlReaderContext readerContext, XmlElement root) + { + ObjectDefinitionParserHelper helper = new ObjectDefinitionParserHelper(readerContext); + helper.InitDefaults(root); + return helper; + } + + private INamespaceParser GetNamespaceParser(XmlElement element, ObjectDefinitionParserHelper helper) + { + INamespaceParser parser = NamespaceParserRegistry.GetParser(element.NamespaceURI); + if (parser == null) + { + helper.ReaderContext.ReportException(element, null, GetNoParserForNamespaceMessage(element.NamespaceURI)); + } + return parser; + } + + private string GetNoParserForNamespaceMessage(string namespaceURI) + { + return "There is no parser registered for namespace '" + namespaceURI + "'"; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/DocumentDefaultsDefinition.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/DocumentDefaultsDefinition.cs index bfe2372c..12df0f32 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/DocumentDefaultsDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/DocumentDefaultsDefinition.cs @@ -1,66 +1,66 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Simple class that holds the defaults specified at the <objects> - /// level in a standard Spring XML object definition document: - /// default-lazy-init, default-autowire, etc. - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - public class DocumentDefaultsDefinition - { - private string autowire; - private string dependencyCheck; - private string lazyInit; - - /// - /// Gets or sets the autowire setting for the document that's currently parsed. - /// - /// The autowire. - public string Autowire - { - get { return autowire; } - set { autowire = value; } - } - - /// - /// Gets or sets the dependency-check setting for the document that's currently parsed - /// - /// The dependency check. - public string DependencyCheck - { - get { return dependencyCheck; } - set { dependencyCheck = value; } - } - - /// - /// Gets or sets the lazy-init flag for the document that's currently parsed. - /// - /// The lazy init. - public string LazyInit - { - get { return lazyInit; } - set { lazyInit = value; } - } - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Simple class that holds the defaults specified at the <objects> + /// level in a standard Spring XML object definition document: + /// default-lazy-init, default-autowire, etc. + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class DocumentDefaultsDefinition + { + private string autowire; + private string dependencyCheck; + private string lazyInit; + + /// + /// Gets or sets the autowire setting for the document that's currently parsed. + /// + /// The autowire. + public string Autowire + { + get { return autowire; } + set { autowire = value; } + } + + /// + /// Gets or sets the dependency-check setting for the document that's currently parsed + /// + /// The dependency check. + public string DependencyCheck + { + get { return dependencyCheck; } + set { dependencyCheck = value; } + } + + /// + /// Gets or sets the lazy-init flag for the document that's currently parsed. + /// + /// The lazy init. + public string LazyInit + { + get { return lazyInit; } + set { lazyInit = value; } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/INamespaceParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/INamespaceParser.cs index 478696d1..794e624a 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/INamespaceParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/INamespaceParser.cs @@ -1,100 +1,99 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Xml; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - - /// - /// Strategy interface for parsing XML object definitions. - /// - /// - ///

- /// Used by - /// for actually parsing a DOM document or - /// fragment. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// Sandu Turcan (.NET) - /// $Id: INamespaceParser.cs,v 1.1 2007/08/07 21:23:37 markpollack Exp $ - public interface INamespaceParser - { - - /// - /// Invoked by after construction but before any - /// elements have been parsed. - /// - void Init(); - - - /// - /// Parse the specified element and register any resulting - /// IObjectDefinitions with the IObjectDefinitionRegistry that is - /// embedded in the supplied ParserContext. - /// - /// - /// Implementations should return the primary IObjectDefinition - /// that results from the parse phase if they wish to used nested - /// inside (for example) a <property> tag. - /// Implementations may return null if they will not - /// be used in a nested scenario. - /// - /// - /// The element to be parsed into one or more IObjectDefinitions - /// The object encapsulating the current state of the parsing - /// process. - /// - /// The primary IObjectDefinition (can be null as explained above) - /// - IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext); - - - /// - /// Parse the specified XmlNode and decorate the supplied ObjectDefinitionHolder, - /// returning the decorated definition. - /// - /// The XmlNode may either be an XmlAttribute or an XmlElement, depending on - /// whether a custom attribute or element is being parsed. - /// Implementations may choose to return a completely new definition, - /// which will replace the original definition in the resulting IApplicationContext/IObjectFactory. - /// - /// The supplied ParserContext can be used to register any additional objects needed to support - /// the main definition. - /// - /// The source element or attribute that is to be parsed. - /// The current object definition. - /// The object encapsulating the current state of the parsing - /// process. - /// The decorated definition (to be registered in the IApplicationContext/IObjectFactory), - /// or simply the original object definition if no decoration is required. A null value is strickly - /// speaking invalid, but will leniently treated like the case where the original object definition - /// gets returned. - ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, ParserContext parserContext); - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Xml; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + + /// + /// Strategy interface for parsing XML object definitions. + /// + /// + ///

+ /// Used by + /// for actually parsing a DOM document or + /// fragment. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// Sandu Turcan (.NET) + public interface INamespaceParser + { + + /// + /// Invoked by after construction but before any + /// elements have been parsed. + /// + void Init(); + + + /// + /// Parse the specified element and register any resulting + /// IObjectDefinitions with the IObjectDefinitionRegistry that is + /// embedded in the supplied ParserContext. + /// + /// + /// Implementations should return the primary IObjectDefinition + /// that results from the parse phase if they wish to used nested + /// inside (for example) a <property> tag. + /// Implementations may return null if they will not + /// be used in a nested scenario. + /// + /// + /// The element to be parsed into one or more IObjectDefinitions + /// The object encapsulating the current state of the parsing + /// process. + /// + /// The primary IObjectDefinition (can be null as explained above) + /// + IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext); + + + /// + /// Parse the specified XmlNode and decorate the supplied ObjectDefinitionHolder, + /// returning the decorated definition. + /// + /// The XmlNode may either be an XmlAttribute or an XmlElement, depending on + /// whether a custom attribute or element is being parsed. + /// Implementations may choose to return a completely new definition, + /// which will replace the original definition in the resulting IApplicationContext/IObjectFactory. + /// + /// The supplied ParserContext can be used to register any additional objects needed to support + /// the main definition. + /// + /// The source element or attribute that is to be parsed. + /// The current object definition. + /// The object encapsulating the current state of the parsing + /// process. + /// The decorated definition (to be registered in the IApplicationContext/IObjectFactory), + /// or simply the original object definition if no decoration is required. A null value is strickly + /// speaking invalid, but will leniently treated like the case where the original object definition + /// gets returned. + ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, ParserContext parserContext); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionDocumentReader.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionDocumentReader.cs index c7b098ac..cc0f977b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionDocumentReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionDocumentReader.cs @@ -1,57 +1,57 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Xml; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// SPI for parsing an XML document that contains Spring object definitions. - /// Used by for actually parsing a DOM - /// document. - /// - /// Instantiated per document to parse: Implementations can hold state in - /// instance variables during the execution of the RegisterObjectDefinitions - /// method, for example global settings that are defined for all object definitions - /// in the document. - /// - /// Juergen Hoeller - /// Rob Harrop - /// Mark Pollack (.NET) - /// - public interface IObjectDefinitionDocumentReader - { - /// - /// Read object definitions from the given DOM element, and register - /// them with the given object registry. - /// - /// The DOM element containing object definitions, usually the - /// root (document) element. - /// The current context of the reader. Includes - /// the resource being parsed - /// - /// The number of object definitions that were loaded. - /// - /// - /// In case of parsing errors. - /// - void RegisterObjectDefinitions(XmlDocument doc, XmlReaderContext readerContext); - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Xml; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// SPI for parsing an XML document that contains Spring object definitions. + /// Used by for actually parsing a DOM + /// document. + /// + /// Instantiated per document to parse: Implementations can hold state in + /// instance variables during the execution of the RegisterObjectDefinitions + /// method, for example global settings that are defined for all object definitions + /// in the document. + /// + /// Juergen Hoeller + /// Rob Harrop + /// Mark Pollack (.NET) + /// + public interface IObjectDefinitionDocumentReader + { + /// + /// Read object definitions from the given DOM element, and register + /// them with the given object registry. + /// + /// The DOM element containing object definitions, usually the + /// root (document) element. + /// The current context of the reader. Includes + /// the resource being parsed + /// + /// The number of object definitions that were loaded. + /// + /// + /// In case of parsing errors. + /// + void RegisterObjectDefinitions(XmlDocument doc, XmlReaderContext readerContext); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionParser.cs index af799065..1ae08224 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/IObjectDefinitionParser.cs @@ -1,59 +1,58 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion -using System.Xml; -using Spring.Objects.Factory.Config; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Interface used to handle custom, top-level tags. - /// - /// Implementations are free to turn the metadata in the custom tag into as - /// many as required. - /// - /// Rob Harrop - /// Mark Pollack (.NET) - /// $Id: IObjectDefinitionParser.cs,v 1.3 2007/05/25 03:23:21 markpollack Exp $ - public interface IObjectDefinitionParser - { - /// - /// Parse the specified XmlElement and register the resulting - /// ObjectDefinitions with the IObjectDefinitionRegistry - /// embedded in the supplied - /// - /// - ///

- /// This method is never invoked if the parser is namespace aware - /// and was called to process the root node. - ///

- ///
- /// - /// The element to be parsed. - /// - /// - /// TThe object encapsulating the current state of the parsing process. - /// Provides access to a IObjectDefinitionRegistry - /// - /// - /// The primary object definition. - /// - IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion +using System.Xml; +using Spring.Objects.Factory.Config; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Interface used to handle custom, top-level tags. + /// + /// Implementations are free to turn the metadata in the custom tag into as + /// many as required. + /// + /// Rob Harrop + /// Mark Pollack (.NET) + public interface IObjectDefinitionParser + { + /// + /// Parse the specified XmlElement and register the resulting + /// ObjectDefinitions with the IObjectDefinitionRegistry + /// embedded in the supplied + /// + /// + ///

+ /// This method is never invoked if the parser is namespace aware + /// and was called to process the root node. + ///

+ ///
+ /// + /// The element to be parsed. + /// + /// + /// TThe object encapsulating the current state of the parsing process. + /// Provides access to a IObjectDefinitionRegistry + /// + /// + /// The primary object definition. + /// + IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext); + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserAttribute.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserAttribute.cs index d389175b..4243d72c 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserAttribute.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserAttribute.cs @@ -1,100 +1,99 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Attribute that should be used to specify the default namespace - /// and schema location for a custom namespace parser. - /// - /// - /// If - /// - /// Aleksandar Seovic - /// $Id: NamespaceParserAttribute.cs,v 1.1 2007/08/08 00:34:06 bbaia Exp $ - [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] - public class NamespaceParserAttribute : Attribute - { - private string ns; - private string schemaLocation; - private Type schemaLocationAssemblyHint; - - /// - /// Creates a new instance of . - /// - public NamespaceParserAttribute() - {} - - /// - /// Gets or sets the default namespace for the configuration parser. - /// - /// - /// The default namespace for the configuration parser. - /// - public string Namespace - { - get { return ns; } - set { ns = value; } - } - - /// - /// Gets or sets the default schema location for the configuration parser. - /// - /// - /// The default schema location for the configuration parser. - /// - /// - /// If the property is set, the will always resolve to an assembly-resource - /// and the set will be interpreted relative to this assembly. - /// - public string SchemaLocation - { - get - { - if (schemaLocationAssemblyHint != null) - { - return "assembly://" + schemaLocationAssemblyHint.Assembly.FullName + schemaLocation; - } - return schemaLocation; - } - set { schemaLocation = value; } - } - - /// - /// Gets or sets a type from the assembly containing the schema - /// - /// - /// If this property is set, the will always resolve to an assembly-resource - /// and the will be interpreted relative to this assembly. - /// - public Type SchemaLocationAssemblyHint - { - get { return schemaLocationAssemblyHint; } - set { schemaLocationAssemblyHint = value; } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Attribute that should be used to specify the default namespace + /// and schema location for a custom namespace parser. + /// + /// + /// If + /// + /// Aleksandar Seovic + [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] + public class NamespaceParserAttribute : Attribute + { + private string ns; + private string schemaLocation; + private Type schemaLocationAssemblyHint; + + /// + /// Creates a new instance of . + /// + public NamespaceParserAttribute() + {} + + /// + /// Gets or sets the default namespace for the configuration parser. + /// + /// + /// The default namespace for the configuration parser. + /// + public string Namespace + { + get { return ns; } + set { ns = value; } + } + + /// + /// Gets or sets the default schema location for the configuration parser. + /// + /// + /// The default schema location for the configuration parser. + /// + /// + /// If the property is set, the will always resolve to an assembly-resource + /// and the set will be interpreted relative to this assembly. + /// + public string SchemaLocation + { + get + { + if (schemaLocationAssemblyHint != null) + { + return "assembly://" + schemaLocationAssemblyHint.Assembly.FullName + schemaLocation; + } + return schemaLocation; + } + set { schemaLocation = value; } + } + + /// + /// Gets or sets a type from the assembly containing the schema + /// + /// + /// If this property is set, the will always resolve to an assembly-resource + /// and the will be interpreted relative to this assembly. + /// + public Type SchemaLocationAssemblyHint + { + get { return schemaLocationAssemblyHint; } + set { schemaLocationAssemblyHint = value; } + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs index 9716a8d0..d34fe0b1 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs @@ -1,287 +1,286 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Xml; -using System.Xml.Schema; -using Spring.Core; -using Spring.Core.IO; -using Spring.Core.TypeResolution; -using Spring.Util; -using Spring.Validation; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Provides a resolution mechanism for configuration parsers. - /// - /// - ///

- /// The uses this registry - /// class to find the parser handling a specific namespace. - ///

- ///
- /// Aleksandar Seovic - /// $Id: NamespaceParserRegistry.cs,v 1.7 2007/09/17 01:12:48 bbaia Exp $ - public class NamespaceParserRegistry - { - /// - /// Name of the .Net config section that contains definitions - /// for custom config parsers. - /// - private const string ConfigParsersSectionName = "spring/parsers"; - - #region Fields - - private static IDictionary parsers = new HybridDictionary(); - -#if !NET_2_0 - private static XmlSchemaCollection schemas = new XmlSchemaCollection(); -#else - private static XmlSchemaSet schemas = new XmlSchemaSet(); -#endif - - #endregion - - /// - /// Creates a new instance of the NamespaceParserRegistry class. - /// - static NamespaceParserRegistry() - { - lock (parsers.SyncRoot) - lock (schemas) - { - //TODO - externalize default list of parsers. - RegisterParser(new ObjectsNamespaceParser()); - //This is done simple as a means to avoid cyclic dependencies with Factory.Xml - //which implementations of parsers typically use. - RegisterParser(ObjectUtils.InstantiateType(typeof(NamespaceParserRegistry).Assembly, - "Spring.Validation.Config.ValidationNamespaceParser") as INamespaceParser); - - // register custom config parsers - ConfigurationUtils.GetSection(ConfigParsersSectionName); - } - } - - /// - /// Returns a parser for the given namespace. - /// - /// - /// The namespace for which to lookup the parser implementation. - /// - /// - /// A parser for a given , or - /// if no parser was found. - /// - public static INamespaceParser GetParser(string namespaceURI) - { - return (INamespaceParser) parsers[namespaceURI]; - } - - /// - /// Returns a schema collection containing validation schemas for all registered parsers. - /// - /// - /// A schema collection containing validation schemas for all registered parsers. - /// -#if !NET_2_0 - public static XmlSchemaCollection GetSchemas() -#else - public static XmlSchemaSet GetSchemas() -#endif - { - return schemas; - } - - /// - /// Pegisters parser, using default namespace and schema location - /// as defined by the . - /// - /// - /// The of the parser that will be activated - /// when an element in its default namespace is encountered. - /// - /// - /// If is . - /// - public static void RegisterParser(Type parserType) - { - RegisterParser(parserType, null, null); - } - - /// - /// Associates a parser with a namespace. - /// - /// - /// - /// Parsers registered with the same as that - /// of a parser that has previously been registered will overwrite the existing - /// parser. - /// - /// - /// - /// The of the parser that will be activated - /// when the attendant is - /// encountered. - /// - /// - /// The namespace with which to associate instance of the parser. - /// - /// - /// The location of the XML schema that should be used for validation - /// of the XML elements that belong to the specified namespace - /// (can be any valid Spring.NET resource URI). - /// - /// - /// If the is not a - /// that implements the - /// interface. - /// - /// - /// If is . - /// - public static void RegisterParser(Type parserType, string namespaceUri, string schemaLocation) - { - AssertUtils.ArgumentNotNull(parserType, "parserType"); - - if (!(typeof(INamespaceParser)).IsAssignableFrom(parserType)) - { - throw new ArgumentException(string.Format("The [{0}] Type must implement the IXmlObjectDefinitionParser interface.", - parserType.Name), "parserType"); - } - - RegisterParser((INamespaceParser) ObjectUtils.InstantiateType(parserType), namespaceUri, schemaLocation); - } - - /// - /// Pegisters parser, using default namespace and schema location - /// as defined by the . - /// - /// - /// The parser instance. - /// - /// - /// If is . - /// - public static void RegisterParser(INamespaceParser parser) - { - RegisterParser(parser, null, null); - } - - /// - /// Associates a parser with a namespace. - /// - /// - /// - /// Parsers registered with the same as that - /// of a parser that has previously been registered will overwrite the existing - /// parser. - /// - /// - /// - /// The namespace with which to associate instance of the parser. - /// - /// - /// The parser instance. - /// - /// - /// The location of the XML schema that should be used for validation - /// of the XML elements that belong to the specified namespace - /// (can be any valid Spring.NET resource URI). - /// - /// - /// If is , or if - /// is not specified and parser class - /// does not have default value defined using . - /// - public static void RegisterParser(INamespaceParser parser, string namespaceUri, string schemaLocation) - { - AssertUtils.ArgumentNotNull(parser, "parser"); - - // determine and use defaults for the namespace and schema location, if necessary - if (StringUtils.IsNullOrEmpty(namespaceUri) || StringUtils.IsNullOrEmpty(schemaLocation)) - { - NamespaceParserAttribute defaults = GetDefaults(parser); - if (defaults == null) - { - throw new ArgumentNullException( - "Either default or an explicit namespace value must be specified for a configuration parser."); - } - if (StringUtils.IsNullOrEmpty(namespaceUri)) - { - namespaceUri = defaults.Namespace; - } - if (StringUtils.IsNullOrEmpty(schemaLocation)) - { - schemaLocation = defaults.SchemaLocation; - } - } - - // initialize the parser - parser.Init(); - - // register parser - lock (parsers.SyncRoot) - lock (schemas) - { - parsers[namespaceUri] = parser; - if (StringUtils.HasText(schemaLocation) && !schemas.Contains(namespaceUri)) - { - IResourceLoader resourceLoader = new ConfigurableResourceLoader(); - IResource schema = resourceLoader.GetResource(schemaLocation); - try { - schemas.Add(namespaceUri, new XmlTextReader(schema.InputStream)); - } catch (Exception e) - { - throw new ArgumentException("Could not load schema from resource = " + schema, e); - } - - } - } - } - - /// - /// Returns default values for the parser namespace and schema location as - /// defined by the . - /// - /// - /// A parser instance. - /// - /// - /// A instance containing - /// default values for the parser namsepace and schema location - /// - private static NamespaceParserAttribute GetDefaults(INamespaceParser parser) - { - object[] attrs = parser.GetType().GetCustomAttributes(typeof(NamespaceParserAttribute), true); - if (attrs.Length > 0) - { - return (NamespaceParserAttribute)attrs[0]; - } - return null; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Xml; +using System.Xml.Schema; +using Spring.Core; +using Spring.Core.IO; +using Spring.Core.TypeResolution; +using Spring.Util; +using Spring.Validation; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Provides a resolution mechanism for configuration parsers. + /// + /// + ///

+ /// The uses this registry + /// class to find the parser handling a specific namespace. + ///

+ ///
+ /// Aleksandar Seovic + public class NamespaceParserRegistry + { + /// + /// Name of the .Net config section that contains definitions + /// for custom config parsers. + /// + private const string ConfigParsersSectionName = "spring/parsers"; + + #region Fields + + private static IDictionary parsers = new HybridDictionary(); + +#if !NET_2_0 + private static XmlSchemaCollection schemas = new XmlSchemaCollection(); +#else + private static XmlSchemaSet schemas = new XmlSchemaSet(); +#endif + + #endregion + + /// + /// Creates a new instance of the NamespaceParserRegistry class. + /// + static NamespaceParserRegistry() + { + lock (parsers.SyncRoot) + lock (schemas) + { + //TODO - externalize default list of parsers. + RegisterParser(new ObjectsNamespaceParser()); + //This is done simple as a means to avoid cyclic dependencies with Factory.Xml + //which implementations of parsers typically use. + RegisterParser(ObjectUtils.InstantiateType(typeof(NamespaceParserRegistry).Assembly, + "Spring.Validation.Config.ValidationNamespaceParser") as INamespaceParser); + + // register custom config parsers + ConfigurationUtils.GetSection(ConfigParsersSectionName); + } + } + + /// + /// Returns a parser for the given namespace. + /// + /// + /// The namespace for which to lookup the parser implementation. + /// + /// + /// A parser for a given , or + /// if no parser was found. + /// + public static INamespaceParser GetParser(string namespaceURI) + { + return (INamespaceParser) parsers[namespaceURI]; + } + + /// + /// Returns a schema collection containing validation schemas for all registered parsers. + /// + /// + /// A schema collection containing validation schemas for all registered parsers. + /// +#if !NET_2_0 + public static XmlSchemaCollection GetSchemas() +#else + public static XmlSchemaSet GetSchemas() +#endif + { + return schemas; + } + + /// + /// Pegisters parser, using default namespace and schema location + /// as defined by the . + /// + /// + /// The of the parser that will be activated + /// when an element in its default namespace is encountered. + /// + /// + /// If is . + /// + public static void RegisterParser(Type parserType) + { + RegisterParser(parserType, null, null); + } + + /// + /// Associates a parser with a namespace. + /// + /// + /// + /// Parsers registered with the same as that + /// of a parser that has previously been registered will overwrite the existing + /// parser. + /// + /// + /// + /// The of the parser that will be activated + /// when the attendant is + /// encountered. + /// + /// + /// The namespace with which to associate instance of the parser. + /// + /// + /// The location of the XML schema that should be used for validation + /// of the XML elements that belong to the specified namespace + /// (can be any valid Spring.NET resource URI). + /// + /// + /// If the is not a + /// that implements the + /// interface. + /// + /// + /// If is . + /// + public static void RegisterParser(Type parserType, string namespaceUri, string schemaLocation) + { + AssertUtils.ArgumentNotNull(parserType, "parserType"); + + if (!(typeof(INamespaceParser)).IsAssignableFrom(parserType)) + { + throw new ArgumentException(string.Format("The [{0}] Type must implement the IXmlObjectDefinitionParser interface.", + parserType.Name), "parserType"); + } + + RegisterParser((INamespaceParser) ObjectUtils.InstantiateType(parserType), namespaceUri, schemaLocation); + } + + /// + /// Pegisters parser, using default namespace and schema location + /// as defined by the . + /// + /// + /// The parser instance. + /// + /// + /// If is . + /// + public static void RegisterParser(INamespaceParser parser) + { + RegisterParser(parser, null, null); + } + + /// + /// Associates a parser with a namespace. + /// + /// + /// + /// Parsers registered with the same as that + /// of a parser that has previously been registered will overwrite the existing + /// parser. + /// + /// + /// + /// The namespace with which to associate instance of the parser. + /// + /// + /// The parser instance. + /// + /// + /// The location of the XML schema that should be used for validation + /// of the XML elements that belong to the specified namespace + /// (can be any valid Spring.NET resource URI). + /// + /// + /// If is , or if + /// is not specified and parser class + /// does not have default value defined using . + /// + public static void RegisterParser(INamespaceParser parser, string namespaceUri, string schemaLocation) + { + AssertUtils.ArgumentNotNull(parser, "parser"); + + // determine and use defaults for the namespace and schema location, if necessary + if (StringUtils.IsNullOrEmpty(namespaceUri) || StringUtils.IsNullOrEmpty(schemaLocation)) + { + NamespaceParserAttribute defaults = GetDefaults(parser); + if (defaults == null) + { + throw new ArgumentNullException( + "Either default or an explicit namespace value must be specified for a configuration parser."); + } + if (StringUtils.IsNullOrEmpty(namespaceUri)) + { + namespaceUri = defaults.Namespace; + } + if (StringUtils.IsNullOrEmpty(schemaLocation)) + { + schemaLocation = defaults.SchemaLocation; + } + } + + // initialize the parser + parser.Init(); + + // register parser + lock (parsers.SyncRoot) + lock (schemas) + { + parsers[namespaceUri] = parser; + if (StringUtils.HasText(schemaLocation) && !schemas.Contains(namespaceUri)) + { + IResourceLoader resourceLoader = new ConfigurableResourceLoader(); + IResource schema = resourceLoader.GetResource(schemaLocation); + try { + schemas.Add(namespaceUri, new XmlTextReader(schema.InputStream)); + } catch (Exception e) + { + throw new ArgumentException("Could not load schema from resource = " + schema, e); + } + + } + } + } + + /// + /// Returns default values for the parser namespace and schema location as + /// defined by the . + /// + /// + /// A parser instance. + /// + /// + /// A instance containing + /// default values for the parser namsepace and schema location + /// + private static NamespaceParserAttribute GetDefaults(INamespaceParser parser) + { + object[] attrs = parser.GetType().GetCustomAttributes(typeof(NamespaceParserAttribute), true); + if (attrs.Length > 0) + { + return (NamespaceParserAttribute)attrs[0]; + } + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserSupport.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserSupport.cs index 81aab2aa..e3ccee51 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserSupport.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserSupport.cs @@ -1,120 +1,119 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using System.Xml; -using Spring.Objects.Factory.Config; -using Spring.Util; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Support class for implementing custom namespace parsers. - /// - /// Parsing of individual elements is done via a ObjectDefintionParser. - /// Provides the RegisterObjectDefinitionParser for registering a ObjectDefintionParser - /// to handle a specific element. - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: NamespaceParserSupport.cs,v 1.9 2008/02/20 14:29:22 bbaia Exp $ - public abstract class NamespaceParserSupport : INamespaceParser - { - - private readonly IDictionary objectParsers = new Hashtable(); - - #region IXmlObjectDefinitionParser Members - - /// - /// Invoked by after construction but before any - /// elements have been parsed. - /// - public abstract void Init(); - - /// - /// Parses an element under the root node, typically - /// an object definition or import statement. - /// - /// - /// The element to be parsed. - /// - /// - /// The parser context. - /// - /// - /// The number of object defintions created from this element. - /// - public virtual IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - return FindParserForElement(element, parserContext).ParseElement(element, parserContext); - } - - - /// - /// Parse the specified XmlNode and decorate the supplied ObjectDefinitionHolder, - /// returning the decorated definition. - /// - /// The XmlNode may either be an XmlAttribute or an XmlElement, depending on - /// whether a custom attribute or element is being parsed. - /// Implementations may choose to return a completely new definition, - /// which will replace the original definition in the resulting IApplicationContext/IObjectFactory. - /// - /// The supplied ParserContext can be used to register any additional objects needed to support - /// the main definition. - /// - /// The source element or attribute that is to be parsed. - /// The current object definition. - /// The object encapsulating the current state of the parsing - /// process. - /// The decorated definition (to be registered in the IApplicationContext/IObjectFactory), - /// or simply the original object definition if no decoration is required. A null value is strickly - /// speaking invalid, but will leniently treated like the case where the original object definition - /// gets returned. - public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, - ParserContext parserContext) - { - return null; - } - - private IObjectDefinitionParser FindParserForElement(XmlElement element, ParserContext parserContext) - { - IObjectDefinitionParser parser = objectParsers[element.LocalName] as IObjectDefinitionParser; - if (parser == null) - { - parserContext.ReaderContext.ReportException(element, "unknown object name", "Cannot locate IObjectDefinitionParser for element [" - + element.LocalName + "]"); - } - return parser; - - } - - /// - /// Register the specified for the given - /// - protected virtual void RegisterObjectDefinitionParser(string elementName, IObjectDefinitionParser parser) - { - AssertUtils.ArgumentNotNull(elementName, "elementName"); - AssertUtils.ArgumentNotNull(parser, "parser"); - objectParsers[elementName] = parser; - } - - #endregion - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using System.Xml; +using Spring.Objects.Factory.Config; +using Spring.Util; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Support class for implementing custom namespace parsers. + /// + /// Parsing of individual elements is done via a ObjectDefintionParser. + /// Provides the RegisterObjectDefinitionParser for registering a ObjectDefintionParser + /// to handle a specific element. + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public abstract class NamespaceParserSupport : INamespaceParser + { + + private readonly IDictionary objectParsers = new Hashtable(); + + #region IXmlObjectDefinitionParser Members + + /// + /// Invoked by after construction but before any + /// elements have been parsed. + /// + public abstract void Init(); + + /// + /// Parses an element under the root node, typically + /// an object definition or import statement. + /// + /// + /// The element to be parsed. + /// + /// + /// The parser context. + /// + /// + /// The number of object defintions created from this element. + /// + public virtual IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + return FindParserForElement(element, parserContext).ParseElement(element, parserContext); + } + + + /// + /// Parse the specified XmlNode and decorate the supplied ObjectDefinitionHolder, + /// returning the decorated definition. + /// + /// The XmlNode may either be an XmlAttribute or an XmlElement, depending on + /// whether a custom attribute or element is being parsed. + /// Implementations may choose to return a completely new definition, + /// which will replace the original definition in the resulting IApplicationContext/IObjectFactory. + /// + /// The supplied ParserContext can be used to register any additional objects needed to support + /// the main definition. + /// + /// The source element or attribute that is to be parsed. + /// The current object definition. + /// The object encapsulating the current state of the parsing + /// process. + /// The decorated definition (to be registered in the IApplicationContext/IObjectFactory), + /// or simply the original object definition if no decoration is required. A null value is strickly + /// speaking invalid, but will leniently treated like the case where the original object definition + /// gets returned. + public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, + ParserContext parserContext) + { + return null; + } + + private IObjectDefinitionParser FindParserForElement(XmlElement element, ParserContext parserContext) + { + IObjectDefinitionParser parser = objectParsers[element.LocalName] as IObjectDefinitionParser; + if (parser == null) + { + parserContext.ReaderContext.ReportException(element, "unknown object name", "Cannot locate IObjectDefinitionParser for element [" + + element.LocalName + "]"); + } + return parser; + + } + + /// + /// Register the specified for the given + /// + protected virtual void RegisterObjectDefinitionParser(string elementName, IObjectDefinitionParser parser) + { + AssertUtils.ArgumentNotNull(elementName, "elementName"); + AssertUtils.ArgumentNotNull(parser, "parser"); + objectParsers[elementName] = parser; + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionConstants.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionConstants.cs index 4f7a2dc0..20855dc0 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionConstants.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionConstants.cs @@ -1,772 +1,771 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Constants defining the structure and values associated with the - /// Spring.NET XML object definition format. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ObjectDefinitionConstants.cs,v 1.8 2006/11/17 20:41:39 aseovic Exp $ - public sealed class ObjectDefinitionConstants - { - /// - /// Value of a boolean attribute that represents - /// . - /// - /// - ///

- /// Anything else represents . - ///

- ///
- public const string TrueValue = "true"; - - /// - /// Signifies that a default value is to be applied. - /// - public const string DefaultValue = "default"; - - /// - /// Defines an external XML object definition resource. - /// - public const string ImportElement = "import"; - - /// - /// Specifies the relative path to an external XML object definition - /// resource. - /// - public const string ImportResourceAttribute = "resource"; - - /// - /// Defines an alias for an object definition. - /// - public const string AliasElement = "alias"; - - /// - /// Specifies the alias of an object definition. - /// - public const string AliasAttribute = "alias"; - - /// - /// Specifies the default lazy initialization mode. - /// - public const string DefaultLazyInitAttribute = "default-lazy-init"; - - /// - /// Specifies the default dependency checking mode. - /// - public const string DefaultDependencyCheckAttribute - = "default-dependency-check"; - - /// - /// Specifies the default autowire mode. - /// - public const string DefaultAutowireAttribute = "default-autowire"; - - /// - /// Defines a single named object. - /// - public const string ObjectElement = "object"; - - /// - /// Element containing informative text describing the purpose of the - /// enclosing element. - /// - /// - ///

- /// Always optional. - ///

- ///

- /// Used primarily for user documentation of XML object definition - /// documents. - ///

- ///
- public const string DescriptionElement = "description"; - - /// - /// Specifies a . - /// - /// - ///

- /// Does not have to be fully assembly qualified, but it is recommended - /// that the names of one's objects are - /// specified explicitly. - ///

- ///
- public const string TypeAttribute = "type"; - - /// - /// The name or alias of the parent object definition that a child - /// object definition inherits from. - /// - public const string ParentAttribute = "parent"; - - /// - /// Objects can be identified by an id, to enable reference checking. - /// - /// - ///

- /// There are constraints on a valid XML id: if you want to reference - /// your object in .NET code using a name that's illegal as an XML id, - /// use the optional "name" attribute - /// (). - /// If neither given, the objects name is - /// used as id. - ///

- ///
- public const string IdAttribute = "id"; - - /// - /// Can be used to create one or more aliases illegal in an id. - /// - /// - ///

- /// Multiple aliases can be separated by any number of spaces, - /// semicolons, or commas - /// (). - ///

- ///

- /// Always optional. - ///

- ///
- public const string NameAttribute = "name"; - - /// - /// Is this object a "singleton" (one shared instance, which will - /// be returned by all calls to - /// with the id), or a - /// "prototype" (independent instance resulting from each call to - /// ). - /// - /// - ///

- /// Singletons are most commonly used, and are ideal for multi-threaded - /// service objects. - ///

- ///
- /// - public const string SingletonAttribute = "singleton"; - - /// - /// Controls object scope. Only applicable to ASP.NET web applications. - /// - /// - ///

- /// Scope can be defined as either application, session or request. It - /// defines when "singleton" instances are initialized, but has no - /// effect on prototype definitions. - ///

- ///
- public const string ScopeAttribute = "scope"; - - /// - /// The names of the objects that this object depends on being - /// initialized. - /// - /// - ///

- /// The object factory will guarantee that these objects - /// get initialized before this object definition. - ///

- /// - /// Dependencies are normally expressed through object properties or - /// constructor arguments. This property should just be necessary for - /// other kinds of dependencies such as statics (*ugh*) or database - /// preparation on startup. - /// - ///
- public const string DependsOnAttribute = "depends-on"; - - /// - /// Optional attribute for the name of the custom initialization method - /// to invoke after setting object properties. - /// - /// - ///

- /// The method must have no arguments. - ///

- ///
- public const string InitMethodAttribute = "init-method"; - - /// - /// Optional attribute for the name of the custom destroy method to - /// invoke on object factory shutdown. - /// - /// - ///

- /// Valid destroy methods have either of the following signatures... - /// - /// void MethodName() - /// void MethodName(bool force) - /// - ///

- /// - /// Only invoked on singleton objects! - /// - ///
- public const string DestroyMethodAttribute = "destroy-method"; - - /// - /// A constructor argument : the constructor-arg tag can have an - /// optional type attribute, to specify the exact type of the - /// constructor argument - /// - /// - ///

- /// Only needed to avoid ambiguities, e.g. in case of 2 single - /// argument constructors that can both be converted from a - /// . - ///

- ///
- public const string ConstructorArgElement = "constructor-arg"; - - /// - /// The constructor-arg tag can have an optional index attribute, - /// to specify the exact index in the constructor argument list. - /// - /// - ///

- /// Only needed to avoid ambiguities, e.g. in case of 2 arguments of - /// the same type. - ///

- ///
- public const string IndexAttribute = "index"; - - /// - /// The constructor-arg tag can have an optional named parameter - /// attribute, to specify a named parameter in the constructor - /// argument list. - /// - public const string ArgumentNameAttribute = "name"; - - /// - /// Is this object "abstract", i.e. not meant to be instantiated itself - /// but rather just serving as parent for concrete child object - /// definitions? - /// - /// - ///

- /// Default is . Specify - /// to tell the object factory to not try to instantiate that - /// particular object in any case. - ///

- ///
- public const string AbstractAttribute = "abstract"; - - /// - /// A property definition : object definitions can have zero or more - /// properties. - /// - /// - ///

- /// Spring.NET supports primitives, references to other objects in the - /// same or related factories, lists, dictionaries, and name value - /// collections. - ///

- ///
- public const string PropertyElement = "property"; - - /// - /// A reference to another managed object or static - /// . - /// - public const string RefElement = "ref"; - - /// - /// ID refs must specify a name of the target object. - /// - public const string IdRefElement = "idref"; - - /// - /// A reference to the name of another managed object in the same - /// context. - /// - public const string ObjectRefAttribute = "object"; - - /// - /// A reference to the name of another managed object in the same - /// context. - /// - /// - ///

- /// Local references, using the "local" attribute, have to use object - /// ids; they can be checked by a parser, thus should be preferred for - /// references within the same object factory XML file. - ///

- ///
- public const string LocalRefAttribute = "local"; - - /// - /// Alternative to type attribute for factory-method usage. - /// - /// - ///

- /// If this is specified, no type attribute should be used. This should - /// be set to the name of an object in the current or ancestor - /// factories that contains the relevant factory method. This allows - /// the factory itself to be configured using Dependency Injection, and - /// an instance (rather than static) method to be used. - ///

- ///
- public const string FactoryObjectAttribute = "factory-object"; - - /// - /// Optional attribute specifying the name of a factory method to use - /// to create this object. - /// - /// - ///

- /// Use constructor-arg elements to specify arguments to the factory - /// method, if it takes arguments. Autowiring does not apply to - /// factory methods. - ///

- ///

- /// If the "type" attribute is present, the factory method will be a - /// static method on the type specified by the "type" attribute on - /// this object definition. Often this will be the same type as that - /// of the constructed object - for example, when the factory method - /// is used as an alternative to a constructor. However, it may be on - /// a different type. In that case, the created object will *not* be - /// of the type specified in the "type" attribute. This is analogous - /// to behaviour. - ///

- ///

- /// If the "factory-object" attribute is present, the "type" attribute - /// is not used, and the factory method will be an instance method on - /// the object returned from a - /// - /// call with the specified object name. The factory object may be - /// defined as a singleton or a prototype. - ///

- ///

- /// The factory method can have any number of arguments. Use indexed - /// constructor-arg elements in conjunction with the factory-method - /// attribute. - ///

- ///

- /// Setter Injection can be used in conjunction with a factory method. - /// Method Injection cannot, as the factory method returns an instance, - /// which will be used when the container creates the object. - ///

- ///
- public const string FactoryMethodAttribute = "factory-method"; - - /// - /// A list can contain multiple inner object, ref, collection, or - /// value elements. - /// - /// - ///

- /// Lists are untyped, pending generics support, although references - /// will be strongly typed. - ///

- ///

- /// A list can also map to an array type. The necessary conversion is - /// automatically performed by the - /// . - ///

- ///
- public const string ListElement = "list"; - - /// - /// A set can contain multiple inner object, ref, collection, or value - /// elements. - /// - /// - ///

- /// Sets are untyped, pending generics support, although references - /// will be strongly typed. - ///

- ///
- public const string SetElement = "set"; - - /// - /// A Spring.NET map is a mapping from a string key to object (a .NET - /// ). - /// - /// - ///

- /// Dictionaries may be empty. - ///

- ///
- public const string DictionaryElement = "dictionary"; - - /// - /// A lookup key (for a dictionary or name / value collection). - /// - public const string KeyAttribute = "key"; - - /// - /// A lookup key (for a dictionary or name / value collection). - /// - public const string KeyElement = "key"; - - /// - /// Contains a string representation of a value. - /// - /// - ///

- /// This is used by name-value, ctor argument, and property elements. - ///

- ///
- public const string ValueAttribute = "value"; - - /// - /// Contains delimiters that should be used to split delimited string values. - /// - /// - ///

- /// This is used by name-value element. - ///

- ///
- public const string DelimitersAttribute = "delimiters"; - - /// - /// A reference to another objects. - /// - /// - ///

- /// Used as a convenience shortcut on property and constructor-arg - /// elements to refer to other objects. - ///

- ///
- public const string RefAttribute = "ref"; - - /// - /// Contains a string representation of an expression. - /// - /// - ///

- /// This is used by ctor argument and property elements. - ///

- ///
- public const string ExpressionAttribute = "expression"; - - /// - /// A map entry can be an inner object, ref, collection, or value. - /// - /// - ///

- /// The name of the property is given by the "key" attribute. - ///

- ///
- public const string EntryElement = "entry"; - - /// - /// Contains a string representation of a property value. - /// - /// - ///

- /// The property may be a string, or may be converted to the - /// required using the - /// - /// machinery. This makes it possible for application developers to - /// write custom - /// implementations that can convert strings to objects. - ///

- /// - /// This is recommended for simple objects only. Configure more complex - /// objects by setting properties to references to other objects. - /// - ///
- public const string ValueElement = "value"; - - /// - /// Contains a string representation of an expression. - /// - public const string ExpressionElement = "expression"; - - /// - /// Denotes value. - /// - /// - ///

- /// Necessary because an empty "value" tag will resolve to an empty - /// , which will not be resolved to - /// value unless a special - /// does so. - ///

- ///
- public const string NullElement = "null"; - - /// - /// 'name-values' elements differ from dictionary elements in that - /// values must be strings. - /// - /// - ///

- /// May be empty. - ///

- ///
- public const string NameValuesElement = "name-values"; - - /// - /// Element content is the string value of the property. - /// - /// - ///

- /// The "key" attribute is the name of the property. - ///

- ///
- public const string AddElement = "add"; - - /// - /// The lazy initialization mode for an individual object definition. - /// - public const string LazyInitAttribute = "lazy-init"; - - /// - /// The dependency checking mode for an individual object definition. - /// - public const string DependencyCheckAttribute = "dependency-check"; - - /// - /// Defines a subscription to one or more events published by one or - /// more event sources. - /// - public const string ListenerElement = "listener"; - - /// - /// The name of an event handling method. - /// - /// - ///

- /// Defaults to On${event}. - /// Note : this default will probably change before the first 1.0 - /// release. - ///

- ///
- public const string ListenerMethodAttribute = "method"; - - /// - /// The name of an event. - /// - public const string ListenerEventAttribute = "event"; - - /// - /// The autowiring mode for an individual object definition. - /// - public const string AutowireAttribute = "autowire"; - - /// - /// Shortcut alternative to specifying a key element in a - /// dictionary entry element with <ref object="..."/>. - /// - public const string DictionaryKeyRefShortcutAttribute = "key-ref"; - - /// - /// Shortcut alternative to specifying a value element in a - /// dictionary entry element with <ref object="..."/>. - /// - public const string DictionaryValueRefShortcutAttribute = "value-ref"; - - /// - /// The string of characters that delimit object names. - /// - public const string ObjectNameDelimiters = ",; "; - - /// - /// A lookup method causes the IoC container to override a given method and return - /// the object with the name given in the attendant object attribute. - /// - /// - ///

- /// This is a form of Method Injection. - ///

- ///

- /// It's particularly useful as an alternative to implementing the - /// interface, - /// in order to be able to make - /// - /// calls for non-singleton instances at runtime. In this case, Method Injection - /// is a less invasive alternative. - ///

- ///
- public const string LookupMethodElement = "lookup-method"; - - /// - /// The name of a lookup method. This method must take no arguments. - /// - public const string LookupMethodNameAttribute = "name"; - - /// - /// The name of the object in the IoC container that the lookup method - /// must resolve to. - /// - /// - ///

- /// Often this object will be a prototype, in which case the lookup method - /// will return a distinct instance on every invocation. This is useful - /// for single-threaded objects. - ///

- ///
- public const string LookupMethodObjectNameAttribute = "object"; - - /// - /// A replaced method causes the IoC container to override a given method - /// with an (arbitrary) implementation at runtime. - /// - /// - ///

- /// This (again) is a form of Method Injection. - ///

- ///
- public const string ReplacedMethodElement = "replaced-method"; - - /// - /// Name of the method whose implementation should be replaced by the - /// IoC container. - /// - /// - ///

- /// If this method is not overloaded, there's no need to use arg-type - /// subelements. - ///

- ///

- /// If this method is overloaded, arg-type subelements must be - /// used for all override definitions for the method. - ///

- ///
- public const string ReplacedMethodNameAttribute = "name"; - - /// - /// The object name of an implementation of the - /// interface. - /// - /// - ///

- /// This may be a singleton or prototype. If it's a prototype, a new - /// instance will be used for each method replacement. Singleton usage - /// is the norm. - ///

- ///
- public const string ReplacedMethodReplacerNameAttribute = "replacer"; - - /// - /// Subelement of replaced-method identifying an argument for a - /// replaced method in the event of method overloading. - /// - /// - public const string ReplacedMethodArgumentTypeElement = "arg-type"; - - /// - /// Specification of the of an overloaded method - /// argument as a . - /// - /// - ///

- /// For convenience, this may be a substring of the FQN. E.g. all the following would match - /// : - ///

- ///

- /// - /// - /// System.String - /// - /// - /// string - /// - /// - /// str - /// - /// - ///

- ///
- /// - public const string ReplacedMethodArgumentTypeMatchAttribute = "match"; - - /// - /// Check everything. - /// - public static readonly string DependencyCheckAllAttributeValue - = Enum.GetName(typeof (DependencyCheckingMode), DependencyCheckingMode.All); - - /// - /// Just check primitive (string, int, etc) values. - /// - public static readonly string DependencyCheckSimpleAttributeValue - = Enum.GetName(typeof (DependencyCheckingMode), DependencyCheckingMode.Simple); - - /// - /// Check object references. - /// - public static readonly string DependencyCheckObjectsAttributeValue - = Enum.GetName(typeof (DependencyCheckingMode), DependencyCheckingMode.Objects); - - /// - /// Autowire by name. - /// - public static readonly string AutowireByNameValue - = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.ByName); - - /// - /// Autowire by . - /// - public static readonly string AutowireByTypeValue - = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.ByType); - - /// - /// Autowiring by constructor. - /// - public static readonly string AutowireConstructorValue - = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.Constructor); - - /// - /// The autowiring strategy is to be determined by introspection - /// of the object's . - /// - public static readonly string AutowireAutoDetectValue - = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.AutoDetect); - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is a utility class, and as such has no publicly visible - /// constructors. - ///

- ///
- private ObjectDefinitionConstants() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Constants defining the structure and values associated with the + /// Spring.NET XML object definition format. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public sealed class ObjectDefinitionConstants + { + /// + /// Value of a boolean attribute that represents + /// . + /// + /// + ///

+ /// Anything else represents . + ///

+ ///
+ public const string TrueValue = "true"; + + /// + /// Signifies that a default value is to be applied. + /// + public const string DefaultValue = "default"; + + /// + /// Defines an external XML object definition resource. + /// + public const string ImportElement = "import"; + + /// + /// Specifies the relative path to an external XML object definition + /// resource. + /// + public const string ImportResourceAttribute = "resource"; + + /// + /// Defines an alias for an object definition. + /// + public const string AliasElement = "alias"; + + /// + /// Specifies the alias of an object definition. + /// + public const string AliasAttribute = "alias"; + + /// + /// Specifies the default lazy initialization mode. + /// + public const string DefaultLazyInitAttribute = "default-lazy-init"; + + /// + /// Specifies the default dependency checking mode. + /// + public const string DefaultDependencyCheckAttribute + = "default-dependency-check"; + + /// + /// Specifies the default autowire mode. + /// + public const string DefaultAutowireAttribute = "default-autowire"; + + /// + /// Defines a single named object. + /// + public const string ObjectElement = "object"; + + /// + /// Element containing informative text describing the purpose of the + /// enclosing element. + /// + /// + ///

+ /// Always optional. + ///

+ ///

+ /// Used primarily for user documentation of XML object definition + /// documents. + ///

+ ///
+ public const string DescriptionElement = "description"; + + /// + /// Specifies a . + /// + /// + ///

+ /// Does not have to be fully assembly qualified, but it is recommended + /// that the names of one's objects are + /// specified explicitly. + ///

+ ///
+ public const string TypeAttribute = "type"; + + /// + /// The name or alias of the parent object definition that a child + /// object definition inherits from. + /// + public const string ParentAttribute = "parent"; + + /// + /// Objects can be identified by an id, to enable reference checking. + /// + /// + ///

+ /// There are constraints on a valid XML id: if you want to reference + /// your object in .NET code using a name that's illegal as an XML id, + /// use the optional "name" attribute + /// (). + /// If neither given, the objects name is + /// used as id. + ///

+ ///
+ public const string IdAttribute = "id"; + + /// + /// Can be used to create one or more aliases illegal in an id. + /// + /// + ///

+ /// Multiple aliases can be separated by any number of spaces, + /// semicolons, or commas + /// (). + ///

+ ///

+ /// Always optional. + ///

+ ///
+ public const string NameAttribute = "name"; + + /// + /// Is this object a "singleton" (one shared instance, which will + /// be returned by all calls to + /// with the id), or a + /// "prototype" (independent instance resulting from each call to + /// ). + /// + /// + ///

+ /// Singletons are most commonly used, and are ideal for multi-threaded + /// service objects. + ///

+ ///
+ /// + public const string SingletonAttribute = "singleton"; + + /// + /// Controls object scope. Only applicable to ASP.NET web applications. + /// + /// + ///

+ /// Scope can be defined as either application, session or request. It + /// defines when "singleton" instances are initialized, but has no + /// effect on prototype definitions. + ///

+ ///
+ public const string ScopeAttribute = "scope"; + + /// + /// The names of the objects that this object depends on being + /// initialized. + /// + /// + ///

+ /// The object factory will guarantee that these objects + /// get initialized before this object definition. + ///

+ /// + /// Dependencies are normally expressed through object properties or + /// constructor arguments. This property should just be necessary for + /// other kinds of dependencies such as statics (*ugh*) or database + /// preparation on startup. + /// + ///
+ public const string DependsOnAttribute = "depends-on"; + + /// + /// Optional attribute for the name of the custom initialization method + /// to invoke after setting object properties. + /// + /// + ///

+ /// The method must have no arguments. + ///

+ ///
+ public const string InitMethodAttribute = "init-method"; + + /// + /// Optional attribute for the name of the custom destroy method to + /// invoke on object factory shutdown. + /// + /// + ///

+ /// Valid destroy methods have either of the following signatures... + /// + /// void MethodName() + /// void MethodName(bool force) + /// + ///

+ /// + /// Only invoked on singleton objects! + /// + ///
+ public const string DestroyMethodAttribute = "destroy-method"; + + /// + /// A constructor argument : the constructor-arg tag can have an + /// optional type attribute, to specify the exact type of the + /// constructor argument + /// + /// + ///

+ /// Only needed to avoid ambiguities, e.g. in case of 2 single + /// argument constructors that can both be converted from a + /// . + ///

+ ///
+ public const string ConstructorArgElement = "constructor-arg"; + + /// + /// The constructor-arg tag can have an optional index attribute, + /// to specify the exact index in the constructor argument list. + /// + /// + ///

+ /// Only needed to avoid ambiguities, e.g. in case of 2 arguments of + /// the same type. + ///

+ ///
+ public const string IndexAttribute = "index"; + + /// + /// The constructor-arg tag can have an optional named parameter + /// attribute, to specify a named parameter in the constructor + /// argument list. + /// + public const string ArgumentNameAttribute = "name"; + + /// + /// Is this object "abstract", i.e. not meant to be instantiated itself + /// but rather just serving as parent for concrete child object + /// definitions? + /// + /// + ///

+ /// Default is . Specify + /// to tell the object factory to not try to instantiate that + /// particular object in any case. + ///

+ ///
+ public const string AbstractAttribute = "abstract"; + + /// + /// A property definition : object definitions can have zero or more + /// properties. + /// + /// + ///

+ /// Spring.NET supports primitives, references to other objects in the + /// same or related factories, lists, dictionaries, and name value + /// collections. + ///

+ ///
+ public const string PropertyElement = "property"; + + /// + /// A reference to another managed object or static + /// . + /// + public const string RefElement = "ref"; + + /// + /// ID refs must specify a name of the target object. + /// + public const string IdRefElement = "idref"; + + /// + /// A reference to the name of another managed object in the same + /// context. + /// + public const string ObjectRefAttribute = "object"; + + /// + /// A reference to the name of another managed object in the same + /// context. + /// + /// + ///

+ /// Local references, using the "local" attribute, have to use object + /// ids; they can be checked by a parser, thus should be preferred for + /// references within the same object factory XML file. + ///

+ ///
+ public const string LocalRefAttribute = "local"; + + /// + /// Alternative to type attribute for factory-method usage. + /// + /// + ///

+ /// If this is specified, no type attribute should be used. This should + /// be set to the name of an object in the current or ancestor + /// factories that contains the relevant factory method. This allows + /// the factory itself to be configured using Dependency Injection, and + /// an instance (rather than static) method to be used. + ///

+ ///
+ public const string FactoryObjectAttribute = "factory-object"; + + /// + /// Optional attribute specifying the name of a factory method to use + /// to create this object. + /// + /// + ///

+ /// Use constructor-arg elements to specify arguments to the factory + /// method, if it takes arguments. Autowiring does not apply to + /// factory methods. + ///

+ ///

+ /// If the "type" attribute is present, the factory method will be a + /// static method on the type specified by the "type" attribute on + /// this object definition. Often this will be the same type as that + /// of the constructed object - for example, when the factory method + /// is used as an alternative to a constructor. However, it may be on + /// a different type. In that case, the created object will *not* be + /// of the type specified in the "type" attribute. This is analogous + /// to behaviour. + ///

+ ///

+ /// If the "factory-object" attribute is present, the "type" attribute + /// is not used, and the factory method will be an instance method on + /// the object returned from a + /// + /// call with the specified object name. The factory object may be + /// defined as a singleton or a prototype. + ///

+ ///

+ /// The factory method can have any number of arguments. Use indexed + /// constructor-arg elements in conjunction with the factory-method + /// attribute. + ///

+ ///

+ /// Setter Injection can be used in conjunction with a factory method. + /// Method Injection cannot, as the factory method returns an instance, + /// which will be used when the container creates the object. + ///

+ ///
+ public const string FactoryMethodAttribute = "factory-method"; + + /// + /// A list can contain multiple inner object, ref, collection, or + /// value elements. + /// + /// + ///

+ /// Lists are untyped, pending generics support, although references + /// will be strongly typed. + ///

+ ///

+ /// A list can also map to an array type. The necessary conversion is + /// automatically performed by the + /// . + ///

+ ///
+ public const string ListElement = "list"; + + /// + /// A set can contain multiple inner object, ref, collection, or value + /// elements. + /// + /// + ///

+ /// Sets are untyped, pending generics support, although references + /// will be strongly typed. + ///

+ ///
+ public const string SetElement = "set"; + + /// + /// A Spring.NET map is a mapping from a string key to object (a .NET + /// ). + /// + /// + ///

+ /// Dictionaries may be empty. + ///

+ ///
+ public const string DictionaryElement = "dictionary"; + + /// + /// A lookup key (for a dictionary or name / value collection). + /// + public const string KeyAttribute = "key"; + + /// + /// A lookup key (for a dictionary or name / value collection). + /// + public const string KeyElement = "key"; + + /// + /// Contains a string representation of a value. + /// + /// + ///

+ /// This is used by name-value, ctor argument, and property elements. + ///

+ ///
+ public const string ValueAttribute = "value"; + + /// + /// Contains delimiters that should be used to split delimited string values. + /// + /// + ///

+ /// This is used by name-value element. + ///

+ ///
+ public const string DelimitersAttribute = "delimiters"; + + /// + /// A reference to another objects. + /// + /// + ///

+ /// Used as a convenience shortcut on property and constructor-arg + /// elements to refer to other objects. + ///

+ ///
+ public const string RefAttribute = "ref"; + + /// + /// Contains a string representation of an expression. + /// + /// + ///

+ /// This is used by ctor argument and property elements. + ///

+ ///
+ public const string ExpressionAttribute = "expression"; + + /// + /// A map entry can be an inner object, ref, collection, or value. + /// + /// + ///

+ /// The name of the property is given by the "key" attribute. + ///

+ ///
+ public const string EntryElement = "entry"; + + /// + /// Contains a string representation of a property value. + /// + /// + ///

+ /// The property may be a string, or may be converted to the + /// required using the + /// + /// machinery. This makes it possible for application developers to + /// write custom + /// implementations that can convert strings to objects. + ///

+ /// + /// This is recommended for simple objects only. Configure more complex + /// objects by setting properties to references to other objects. + /// + ///
+ public const string ValueElement = "value"; + + /// + /// Contains a string representation of an expression. + /// + public const string ExpressionElement = "expression"; + + /// + /// Denotes value. + /// + /// + ///

+ /// Necessary because an empty "value" tag will resolve to an empty + /// , which will not be resolved to + /// value unless a special + /// does so. + ///

+ ///
+ public const string NullElement = "null"; + + /// + /// 'name-values' elements differ from dictionary elements in that + /// values must be strings. + /// + /// + ///

+ /// May be empty. + ///

+ ///
+ public const string NameValuesElement = "name-values"; + + /// + /// Element content is the string value of the property. + /// + /// + ///

+ /// The "key" attribute is the name of the property. + ///

+ ///
+ public const string AddElement = "add"; + + /// + /// The lazy initialization mode for an individual object definition. + /// + public const string LazyInitAttribute = "lazy-init"; + + /// + /// The dependency checking mode for an individual object definition. + /// + public const string DependencyCheckAttribute = "dependency-check"; + + /// + /// Defines a subscription to one or more events published by one or + /// more event sources. + /// + public const string ListenerElement = "listener"; + + /// + /// The name of an event handling method. + /// + /// + ///

+ /// Defaults to On${event}. + /// Note : this default will probably change before the first 1.0 + /// release. + ///

+ ///
+ public const string ListenerMethodAttribute = "method"; + + /// + /// The name of an event. + /// + public const string ListenerEventAttribute = "event"; + + /// + /// The autowiring mode for an individual object definition. + /// + public const string AutowireAttribute = "autowire"; + + /// + /// Shortcut alternative to specifying a key element in a + /// dictionary entry element with <ref object="..."/>. + /// + public const string DictionaryKeyRefShortcutAttribute = "key-ref"; + + /// + /// Shortcut alternative to specifying a value element in a + /// dictionary entry element with <ref object="..."/>. + /// + public const string DictionaryValueRefShortcutAttribute = "value-ref"; + + /// + /// The string of characters that delimit object names. + /// + public const string ObjectNameDelimiters = ",; "; + + /// + /// A lookup method causes the IoC container to override a given method and return + /// the object with the name given in the attendant object attribute. + /// + /// + ///

+ /// This is a form of Method Injection. + ///

+ ///

+ /// It's particularly useful as an alternative to implementing the + /// interface, + /// in order to be able to make + /// + /// calls for non-singleton instances at runtime. In this case, Method Injection + /// is a less invasive alternative. + ///

+ ///
+ public const string LookupMethodElement = "lookup-method"; + + /// + /// The name of a lookup method. This method must take no arguments. + /// + public const string LookupMethodNameAttribute = "name"; + + /// + /// The name of the object in the IoC container that the lookup method + /// must resolve to. + /// + /// + ///

+ /// Often this object will be a prototype, in which case the lookup method + /// will return a distinct instance on every invocation. This is useful + /// for single-threaded objects. + ///

+ ///
+ public const string LookupMethodObjectNameAttribute = "object"; + + /// + /// A replaced method causes the IoC container to override a given method + /// with an (arbitrary) implementation at runtime. + /// + /// + ///

+ /// This (again) is a form of Method Injection. + ///

+ ///
+ public const string ReplacedMethodElement = "replaced-method"; + + /// + /// Name of the method whose implementation should be replaced by the + /// IoC container. + /// + /// + ///

+ /// If this method is not overloaded, there's no need to use arg-type + /// subelements. + ///

+ ///

+ /// If this method is overloaded, arg-type subelements must be + /// used for all override definitions for the method. + ///

+ ///
+ public const string ReplacedMethodNameAttribute = "name"; + + /// + /// The object name of an implementation of the + /// interface. + /// + /// + ///

+ /// This may be a singleton or prototype. If it's a prototype, a new + /// instance will be used for each method replacement. Singleton usage + /// is the norm. + ///

+ ///
+ public const string ReplacedMethodReplacerNameAttribute = "replacer"; + + /// + /// Subelement of replaced-method identifying an argument for a + /// replaced method in the event of method overloading. + /// + /// + public const string ReplacedMethodArgumentTypeElement = "arg-type"; + + /// + /// Specification of the of an overloaded method + /// argument as a . + /// + /// + ///

+ /// For convenience, this may be a substring of the FQN. E.g. all the following would match + /// : + ///

+ ///

+ /// + /// + /// System.String + /// + /// + /// string + /// + /// + /// str + /// + /// + ///

+ ///
+ /// + public const string ReplacedMethodArgumentTypeMatchAttribute = "match"; + + /// + /// Check everything. + /// + public static readonly string DependencyCheckAllAttributeValue + = Enum.GetName(typeof (DependencyCheckingMode), DependencyCheckingMode.All); + + /// + /// Just check primitive (string, int, etc) values. + /// + public static readonly string DependencyCheckSimpleAttributeValue + = Enum.GetName(typeof (DependencyCheckingMode), DependencyCheckingMode.Simple); + + /// + /// Check object references. + /// + public static readonly string DependencyCheckObjectsAttributeValue + = Enum.GetName(typeof (DependencyCheckingMode), DependencyCheckingMode.Objects); + + /// + /// Autowire by name. + /// + public static readonly string AutowireByNameValue + = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.ByName); + + /// + /// Autowire by . + /// + public static readonly string AutowireByTypeValue + = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.ByType); + + /// + /// Autowiring by constructor. + /// + public static readonly string AutowireConstructorValue + = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.Constructor); + + /// + /// The autowiring strategy is to be determined by introspection + /// of the object's . + /// + public static readonly string AutowireAutoDetectValue + = Enum.GetName(typeof (AutoWiringMode), AutoWiringMode.AutoDetect); + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is a utility class, and as such has no publicly visible + /// constructors. + ///

+ ///
+ private ObjectDefinitionConstants() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionParserHelper.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionParserHelper.cs index 3696697f..6bcd951d 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionParserHelper.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectDefinitionParserHelper.cs @@ -1,210 +1,209 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Globalization; -using System.Xml; -using Common.Logging; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Util; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Sateful class used to parse XML object definitions. - /// - /// Not all parsing code has been refactored into this class. - /// Rob Harrop - /// Juergen Hoeller - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: ObjectDefinitionParserHelper.cs,v 1.7 2007/08/07 22:05:20 markpollack Exp $ - public class ObjectDefinitionParserHelper - { - - #region Fields - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof(ObjectDefinitionParserHelper)); - - private DocumentDefaultsDefinition defaults; - - private XmlReaderContext readerContext; - - #endregion - - /// - /// Initializes a new instance of the class. - /// - /// The reader context. - public ObjectDefinitionParserHelper(XmlReaderContext readerContext) - { - AssertUtils.ArgumentNotNull(readerContext, "readerContext"); - this.readerContext = readerContext; - } - - /// - /// Gets the defaults definition object, or null if the - /// default have not yet been initialized. - /// - /// The defaults. - public DocumentDefaultsDefinition Defaults - { - get { return defaults; } - } - - - /// - /// Gets the reader context. - /// - /// The reader context. - public XmlReaderContext ReaderContext - { - get { return readerContext; } - } - - /// - /// Initialize the default lazy-init, dependency check, and autowire settings. - /// - /// The root element - public void InitDefaults(XmlElement root) - { - DocumentDefaultsDefinition ddd = new DocumentDefaultsDefinition(); - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Loading object definitions..."); - } - - #endregion - - ddd.LazyInit = root.GetAttribute(ObjectDefinitionConstants.DefaultLazyInitAttribute); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - "Default lazy init '{0}'.", - ddd.LazyInit)); - } - - #endregion - - ddd.DependencyCheck = root.GetAttribute(ObjectDefinitionConstants.DefaultDependencyCheckAttribute); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - "Default dependency check '{0}'.", - ddd.DependencyCheck)); - } - - #endregion - - ddd.Autowire = root.GetAttribute(ObjectDefinitionConstants.DefaultAutowireAttribute); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - "Default autowire '{0}'.", - ddd.Autowire)); - } - - #endregion - - defaults = ddd; - } - - - /// - /// Determines whether the Spring object namespace is equal to the the specified namespace URI. - /// - /// The namespace URI. - /// - /// true if is the default Spring namespace; otherwise, false. - /// - public bool IsDefaultNamespace(string namespaceUri) - { - return - (!StringUtils.HasLength(namespaceUri) || ObjectsNamespaceParser.Namespace.Equals(namespaceUri)); - } - - - /// - /// Decorates the object definition if required. - /// - /// The element. - /// The holder. - /// - public ObjectDefinitionHolder DecorateObjectDefinitionIfRequired(XmlElement element, ObjectDefinitionHolder holder) - { - - //TODO decoration processing. - return holder; - } - - - /// - /// Determines whether the string represents a 'true' boolean value. - /// - /// The value. - /// - /// true if is 'true' string value; otherwise, false. - /// - public bool IsTrueStringValue(string value) - { - return ObjectDefinitionConstants.TrueValue.Equals(value.ToLower(CultureInfo.CurrentCulture)); - } - - /// - /// Convenience method to create a builder for a root object definition. - /// - /// Name of the object type. - /// A builder for a root object definition. - public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(string objectTypeName) - { - return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectTypeName); - } - - /// - /// Convenience method to create a builder for a root object definition. - /// - /// Type of the object. - /// a builder for a root object definition - public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(Type objectType) - { - return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectType); - } - - - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Globalization; +using System.Xml; +using Common.Logging; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Util; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Sateful class used to parse XML object definitions. + /// + /// Not all parsing code has been refactored into this class. + /// Rob Harrop + /// Juergen Hoeller + /// Rod Johnson + /// Mark Pollack (.NET) + public class ObjectDefinitionParserHelper + { + + #region Fields + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof(ObjectDefinitionParserHelper)); + + private DocumentDefaultsDefinition defaults; + + private XmlReaderContext readerContext; + + #endregion + + /// + /// Initializes a new instance of the class. + /// + /// The reader context. + public ObjectDefinitionParserHelper(XmlReaderContext readerContext) + { + AssertUtils.ArgumentNotNull(readerContext, "readerContext"); + this.readerContext = readerContext; + } + + /// + /// Gets the defaults definition object, or null if the + /// default have not yet been initialized. + /// + /// The defaults. + public DocumentDefaultsDefinition Defaults + { + get { return defaults; } + } + + + /// + /// Gets the reader context. + /// + /// The reader context. + public XmlReaderContext ReaderContext + { + get { return readerContext; } + } + + /// + /// Initialize the default lazy-init, dependency check, and autowire settings. + /// + /// The root element + public void InitDefaults(XmlElement root) + { + DocumentDefaultsDefinition ddd = new DocumentDefaultsDefinition(); + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Loading object definitions..."); + } + + #endregion + + ddd.LazyInit = root.GetAttribute(ObjectDefinitionConstants.DefaultLazyInitAttribute); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + "Default lazy init '{0}'.", + ddd.LazyInit)); + } + + #endregion + + ddd.DependencyCheck = root.GetAttribute(ObjectDefinitionConstants.DefaultDependencyCheckAttribute); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + "Default dependency check '{0}'.", + ddd.DependencyCheck)); + } + + #endregion + + ddd.Autowire = root.GetAttribute(ObjectDefinitionConstants.DefaultAutowireAttribute); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + "Default autowire '{0}'.", + ddd.Autowire)); + } + + #endregion + + defaults = ddd; + } + + + /// + /// Determines whether the Spring object namespace is equal to the the specified namespace URI. + /// + /// The namespace URI. + /// + /// true if is the default Spring namespace; otherwise, false. + /// + public bool IsDefaultNamespace(string namespaceUri) + { + return + (!StringUtils.HasLength(namespaceUri) || ObjectsNamespaceParser.Namespace.Equals(namespaceUri)); + } + + + /// + /// Decorates the object definition if required. + /// + /// The element. + /// The holder. + /// + public ObjectDefinitionHolder DecorateObjectDefinitionIfRequired(XmlElement element, ObjectDefinitionHolder holder) + { + + //TODO decoration processing. + return holder; + } + + + /// + /// Determines whether the string represents a 'true' boolean value. + /// + /// The value. + /// + /// true if is 'true' string value; otherwise, false. + /// + public bool IsTrueStringValue(string value) + { + return ObjectDefinitionConstants.TrueValue.Equals(value.ToLower(CultureInfo.CurrentCulture)); + } + + /// + /// Convenience method to create a builder for a root object definition. + /// + /// Name of the object type. + /// A builder for a root object definition. + public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(string objectTypeName) + { + return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectTypeName); + } + + /// + /// Convenience method to create a builder for a root object definition. + /// + /// Type of the object. + /// a builder for a root object definition + public ObjectDefinitionBuilder CreateRootObjectDefinitionBuilder(Type objectType) + { + return ObjectDefinitionBuilder.RootObjectDefinition(this.readerContext.ObjectDefinitionFactory, objectType); + } + + + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectFactorySectionHandler.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectFactorySectionHandler.cs index 47cf97c1..ab0c3f37 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectFactorySectionHandler.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectFactorySectionHandler.cs @@ -1,92 +1,91 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Configuration; -using System.Xml; - -using Spring.Core.IO; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Creates an instance - /// populated with the object definitions supplied in the configuration - /// section. - /// - /// - ///

- /// Applications will typically want to use an - /// , and instantiate it - /// via the use of the - /// class (which is similar in functionality to this class). This class is - /// provided for those times when only an - /// is required. - ///

- /// Creates an instance of the class XmlObjectFactory - ///
- /// - ///

- /// - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: ObjectFactorySectionHandler.cs,v 1.3 2007/08/08 17:47:13 bbaia Exp $ - public class ObjectFactorySectionHandler : IConfigurationSectionHandler - { - /// - /// Creates a new instance of the - /// class. - /// - public ObjectFactorySectionHandler() - {} - - /// - /// Creates a - /// instance populated with the object definitions supplied in the - /// configuration section. - /// - /// - /// The configuration settings in a corresponding parent configuration - /// section. - /// - /// - /// The configuration context when called from the ASP.NET - /// configuration system. Otherwise, this parameter is reserved and - /// is . - /// - /// - /// The for the section. - /// - /// - /// A instance - /// populated with the object definitions supplied in the configuration - /// section. - /// - public object Create( - object parent, object configContext, XmlNode section) - { - return new XmlObjectFactory(new ConfigSectionResource(section as XmlElement), true); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Configuration; +using System.Xml; + +using Spring.Core.IO; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Creates an instance + /// populated with the object definitions supplied in the configuration + /// section. + /// + /// + ///

+ /// Applications will typically want to use an + /// , and instantiate it + /// via the use of the + /// class (which is similar in functionality to this class). This class is + /// provided for those times when only an + /// is required. + ///

+ /// Creates an instance of the class XmlObjectFactory + ///
+ /// + ///

+ /// + ///

+ ///
+ /// Mark Pollack (.NET) + public class ObjectFactorySectionHandler : IConfigurationSectionHandler + { + /// + /// Creates a new instance of the + /// class. + /// + public ObjectFactorySectionHandler() + {} + + /// + /// Creates a + /// instance populated with the object definitions supplied in the + /// configuration section. + /// + /// + /// The configuration settings in a corresponding parent configuration + /// section. + /// + /// + /// The configuration context when called from the ASP.NET + /// configuration system. Otherwise, this parameter is reserved and + /// is . + /// + /// + /// The for the section. + /// + /// + /// A instance + /// populated with the object definitions supplied in the configuration + /// section. + /// + public object Create( + object parent, object configContext, XmlNode section) + { + return new XmlObjectFactory(new ConfigSectionResource(section as XmlElement), true); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs index 221da168..f2442102 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs @@ -1,1421 +1,1420 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Globalization; -using System.IO; -using System.Text; -using System.Xml; - -using Common.Logging; - -using Spring.Collections; -using Spring.Core; -using Spring.Core.IO; -using Spring.Core.TypeResolution; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Default implementation of the - /// interface. - /// - /// - ///

- /// Parses object definitions according to the standard Spring.NET schema. - ///

- ///

- /// This schema is typically located at - /// http://www.springframework.net/xsd/spring-objects.xsd. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ObjectsNamespaceParser.cs,v 1.7 2007/11/26 14:15:54 bbaia Exp $ - [ - NamespaceParser( - Namespace = "http://www.springframework.net", - SchemaLocationAssemblyHint = typeof(ObjectsNamespaceParser), - SchemaLocation = "/Spring.Objects.Factory.Xml/spring-objects-1.1.xsd" - ) - ] - public class ObjectsNamespaceParser : INamespaceParser - { - /// - /// The namespace URI for the standard Spring.NET object definition schema. - /// - public const string Namespace = "http://www.springframework.net"; - - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof(ObjectsNamespaceParser)); - - #region IXmlObjectDefinitionParser Members - - /// - /// Invoked by after construction but before any - /// elements have been parsed. - /// - /// This is a NoOp - public void Init() - { - - } - - #endregion - - - /// - /// Parse the specified element and register any resulting - /// IObjectDefinitions with the IObjectDefinitionRegistry that is - /// embedded in the supplied ParserContext. - /// - /// The element to be parsed into one or more IObjectDefinitions - /// The object encapsulating the current state of the parsing - /// process. - /// - /// The primary IObjectDefinition (can be null as explained above) - /// - /// - /// Implementations should return the primary IObjectDefinition - /// that results from the parse phase if they wish to used nested - /// inside (for example) a <property> tag. - /// Implementations may return null if they will not - /// be used in a nested scenario. - /// - /// - public virtual IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - - if (element.LocalName == ObjectDefinitionConstants.ImportElement) - { - ImportObjectDefinitionResource(element, parserContext); - } - else if (element.LocalName == ObjectDefinitionConstants.AliasElement) - { - ParseAlias(element, parserContext.ReaderContext.Registry); - } - else if (element.LocalName == ObjectDefinitionConstants.ObjectElement) - { - RegisterObjectDefinition(element, parserContext); - } - - return null; - } - - - /// - /// Parse the specified XmlNode and decorate the supplied ObjectDefinitionHolder, - /// returning the decorated definition. - /// - /// The XmlNode may either be an XmlAttribute or an XmlElement, depending on - /// whether a custom attribute or element is being parsed. - /// Implementations may choose to return a completely new definition, - /// which will replace the original definition in the resulting IApplicationContext/IObjectFactory. - /// - /// The supplied ParserContext can be used to register any additional objects needed to support - /// the main definition. - /// - /// The source element or attribute that is to be parsed. - /// The current object definition. - /// The object encapsulating the current state of the parsing - /// process. - /// The decorated definition (to be registered in the IApplicationContext/IObjectFactory), - /// or simply the original object definition if no decoration is required. A null value is strickly - /// speaking invalid, but will leniently treated like the case where the original object definition - /// gets returned. - public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, - ParserContext parserContext) - { - return null; - } - - private void ParseAlias(XmlElement aliasElement, IObjectDefinitionRegistry registry) - { - string name = aliasElement.GetAttribute(ObjectDefinitionConstants.NameAttribute); - string alias = aliasElement.GetAttribute(ObjectDefinitionConstants.AliasAttribute); - registry.RegisterAlias(name, alias); - } - - - - - /// - /// Loads external XML object definitions from the resource described by the supplied - /// . - /// - /// The XML element describing the resource. - /// The parser context. - /// - /// If the resource could not be imported. - /// - protected virtual void ImportObjectDefinitionResource(XmlElement resource, ParserContext parserContext) - { - string location = resource.GetAttribute(ObjectDefinitionConstants.ImportResourceAttribute); - try - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Attempting to import object definitions from '{0}'.", location)); - } - - #endregion - - IResource importResource = parserContext.ReaderContext.Resource.CreateRelative(location); - parserContext.ReaderContext.Reader.LoadObjectDefinitions(importResource); - } - catch (IOException ex) - { - parserContext.ReaderContext.ReportException(resource, null, string.Format( - CultureInfo.InvariantCulture, - "Invalid relative resource location '{0}' to import object definitions from.", - location), ex); - } - } - - - /// Parses an event listener definition. - /// - /// The name associated with the object that the event handler is being defined on. - /// - /// The events being populated. - /// - /// The element containing the event listener definition. - /// - /// - /// The namespace-aware parser. - /// - protected virtual void ParseEventListenerDefinition( - string name, EventValues events, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - // get an appropriate IEventHandlerValue instance based upon the - // attribute values of the listener element... - IEventHandlerValue myHandler = ObjectDefinitionReaderUtils.CreateEventHandlerValue( - element.GetAttribute(ObjectDefinitionConstants.ListenerMethodAttribute), - element.GetAttribute(ObjectDefinitionConstants.ListenerEventAttribute)); - - // and then get the source of the event (another managed object instance - // or a Type reference (i.e. a static event exposed on a class)... - XmlElement sourceElement = this.SelectSingleNode(element, ObjectDefinitionConstants.RefElement) as XmlElement; - - XmlAttribute sourceAtt = sourceElement.Attributes[0]; - if (StringUtils.IsNullOrEmpty(sourceAtt.Value)) - { - parserHelper.ReaderContext.ReportFatalException(sourceElement, string.Format( - CultureInfo.InvariantCulture, - "The single attribute of the <{0}/> element cannot be empty. Specify the " + - "object id (alias) or the full, assembly qualified Type name that is the " + - "source of the event.", - ObjectDefinitionConstants.RefElement)); - return; - } - switch (sourceAtt.LocalName) - { - case ObjectDefinitionConstants.LocalRefAttribute: - case ObjectDefinitionConstants.ObjectRefAttribute: - // we're wiring up to an event exposed on another managed object (instance) - RuntimeObjectReference ror = new RuntimeObjectReference(sourceAtt.Value); - myHandler.Source = ror; - break; - case ObjectDefinitionConstants.TypeAttribute: - // we're wiring up to a static event exposed on a Type (class) - myHandler.Source = parserHelper.ReaderContext.Reader.Domain == null ? - (object) sourceAtt.Value : - (object)TypeResolutionUtils.ResolveType(sourceAtt.Value); - break; - } - events.AddHandler(myHandler); - } - - - - /// - /// Parse an object definition and register it with the object factory.. - /// - /// The element containing the object definition. - /// The parser context. - /// - protected void RegisterObjectDefinition(XmlElement element, ParserContext parserContext) - { - ObjectDefinitionHolder holder = null; - try - { - holder = ParseObjectDefinition(element, parserContext); - if (holder == null) - { - return; - } - } - catch (Exception ex) - { - throw new ObjectDefinitionStoreException(string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex); - } - - - holder = parserContext.ParserHelper.DecorateObjectDefinitionIfRequired(element, holder); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - CultureInfo.InvariantCulture, - "Registering object definition with id '{0}'.", holder.ObjectName)); - } - - #endregion - - ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.ReaderContext.Registry); - } - - - /// - /// Parse a standard object definition into a - /// , - /// including object name and aliases. - /// - /// The element containing the object definition. - /// The parser context. - /// - /// The object (definition) wrapped within an - /// - /// instance. - /// - /// - ///

- /// Object elements specify their canonical name via the "id" attribute - /// and their aliases as a delimited "name" attribute. - ///

- ///

- /// If no "id" is specified, uses the first name in the "name" attribute - /// as the canonical name, registering all others as aliases. - ///

- ///
- protected ObjectDefinitionHolder ParseObjectDefinition(XmlElement element, ParserContext parserContext) - { - string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); - string name = element.GetAttribute(ObjectDefinitionConstants.NameAttribute); - ArrayList aliases = new ArrayList(); - if (StringUtils.HasText(name)) - { - aliases.AddRange(GetObjectNames(name)); - } - // if we ain't got an id, check if object is page definition or assign any existing (first) alias... - if (StringUtils.IsNullOrEmpty(id)) - { - id = CalculateId(element, aliases); - } - - - IConfigurableObjectDefinition definition = ParseObjectDefinition(element, id, parserContext.ParserHelper); - if (StringUtils.IsNullOrEmpty(id)) - { - id = ObjectDefinitionReaderUtils.GenerateObjectName(definition, parserContext.Registry); - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - "Neither XML '{0}' nor '{1}' specified - using object " + - "class name [{2}] as the id.", - id, ObjectDefinitionConstants.IdAttribute, ObjectDefinitionConstants.NameAttribute)); - } - - #endregion - } - string[] aliasesArray = (string[]) aliases.ToArray(typeof(string)); - return new ObjectDefinitionHolder(definition, id, aliasesArray); - } - - /// - /// Calculates an id for an object definition. - /// - /// - ///

- /// Called when an object definition has not been explicitly defined - /// with an id. - ///

- ///
- /// - /// The element containing the object definition. - /// - /// - /// The list of names defined for the object; may be - /// or even empty. - /// - /// - /// A calculated object definition id. - /// - protected virtual string CalculateId(XmlElement element, ArrayList aliases) - { - string id = null; - if (aliases.Count > 0) - { - string firstAlias = aliases[0] as string; - aliases.RemoveAt(0); - id = firstAlias; - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - StringBuilder buffer = new StringBuilder(); - foreach (string alias in aliases) - { - buffer.Append(alias).Append(","); - } - log.Debug(string.Format("No XML 'id' specified - using '{0}' as the id and '{1}' as aliases.", - id, buffer.ToString())); - } - - #endregion - - return id; - } - - /// - /// Parse a standard object definition. - /// - /// The element containing the object definition. - /// The id of the object definition. - /// parsing state holder - /// The object (definition). - protected virtual IConfigurableObjectDefinition ParseObjectDefinition( - XmlElement element, string id, ObjectDefinitionParserHelper parserHelper) - { - string typeName = null; - try - { - if (element.HasAttribute(ObjectDefinitionConstants.TypeAttribute)) - { - typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - if (StringUtils.IsNullOrEmpty(typeName)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, id, - "The 'type' attribute does not need to be present, but if it is it must not be empty: got '" + typeName + "'."); - } - } - string parent = element.GetAttribute(ObjectDefinitionConstants.ParentAttribute); - - - AbstractObjectDefinition od - = parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, parent, parserHelper.ReaderContext.Reader.Domain); - - - MutablePropertyValues pvs = GetPropertyValueSubElements(id, element, parserHelper); - ConstructorArgumentValues arguments - = GetConstructorArgSubElements(id, element, parserHelper); - EventValues events = GetEventHandlerSubElements(id, element, parserHelper); - MethodOverrides methodOverrides = GetMethodOverrideSubElements(id, element, parserHelper); - - bool isPage = StringUtils.HasText(typeName) && typeName!= null && typeName.ToLower().EndsWith(".aspx"); - if (!isPage) - { - od.ConstructorArgumentValues = arguments; - } - - od.PropertyValues = pvs; - od.MethodOverrides = methodOverrides; - od.EventHandlerValues = events; - if (element.HasAttribute(ObjectDefinitionConstants.DependsOnAttribute)) - { - string dependsOn = element.GetAttribute(ObjectDefinitionConstants.DependsOnAttribute); - od.DependsOn = GetObjectNames(dependsOn); - } - od.FactoryMethodName = element.GetAttribute(ObjectDefinitionConstants.FactoryMethodAttribute); - od.FactoryObjectName = element.GetAttribute(ObjectDefinitionConstants.FactoryObjectAttribute); - string dependencyCheck = element.GetAttribute(ObjectDefinitionConstants.DependencyCheckAttribute); - if (ObjectDefinitionConstants.DefaultValue.Equals(dependencyCheck)) - { - dependencyCheck = parserHelper.Defaults.DependencyCheck; - } - od.DependencyCheck = GetDependencyCheck(dependencyCheck); - string autowire = element.GetAttribute(ObjectDefinitionConstants.AutowireAttribute); - if (ObjectDefinitionConstants.DefaultValue.Equals(autowire)) - { - autowire = parserHelper.Defaults.Autowire; - } - od.AutowireMode = GetAutowireMode(autowire); - string initMethodName = element.GetAttribute(ObjectDefinitionConstants.InitMethodAttribute); - if (StringUtils.HasText(initMethodName)) - { - od.InitMethodName = initMethodName; - } - string destroyMethodName = element.GetAttribute(ObjectDefinitionConstants.DestroyMethodAttribute); - if (StringUtils.HasText(destroyMethodName)) - { - od.DestroyMethodName = destroyMethodName; - } - if (element.HasAttribute(ObjectDefinitionConstants.SingletonAttribute)) - { - od.IsSingleton = IsTrueStringValue(element.GetAttribute(ObjectDefinitionConstants.SingletonAttribute).ToLower(CultureInfo.CurrentCulture)); - } - string lazyInit = element.GetAttribute(ObjectDefinitionConstants.LazyInitAttribute); - if (ObjectDefinitionConstants.DefaultValue.Equals(lazyInit) && od.IsSingleton) - { - // just apply default to singletons, as lazy-init has no meaning for prototypes... - lazyInit = parserHelper.Defaults.LazyInit; - } - od.IsLazyInit = IsTrueStringValue(lazyInit); - - // try to get the line info - string resourceDescription = parserHelper.ReaderContext.Resource.Description; - if (StringUtils.HasText(resourceDescription)) - { - int line = ConfigurationUtils.GetLineNumber(element); - if (line > 0) - { - resourceDescription += " line " + line; - } - } - od.ResourceDescription = resourceDescription; - - string isAbstract = element.GetAttribute(ObjectDefinitionConstants.AbstractAttribute); - if (StringUtils.HasText(isAbstract)) - { - od.IsAbstract = IsTrueStringValue(isAbstract); - } - return od; - } - catch (TypeLoadException ex) - { - parserHelper.ReaderContext.ReportException( - element, - id, - string.Format( - "Object class [{0}] not found.", - typeName), - ex); - } - catch (ApplicationException ex) - { - parserHelper.ReaderContext.ReportException(element, id, string.Empty, ex); - } - return null; - } - - /// - /// Parse method override argument subelements of the given object element. - /// - protected MethodOverrides GetMethodOverrideSubElements( - string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - MethodOverrides overrides = new MethodOverrides(); - foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.LookupMethodElement)) - { - ParseLookupMethodElement(name, overrides, (XmlElement) node, parserHelper); - } - foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ReplacedMethodElement)) - { - ParseReplacedMethodElement(name, overrides, (XmlElement) node, parserHelper); - } - return overrides; - } - - /// - /// Parse element and add parsed element to - /// - protected void ParseLookupMethodElement( - string name, MethodOverrides overrides, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string methodName = element.GetAttribute(ObjectDefinitionConstants.LookupMethodNameAttribute); - string targetObjectName = element.GetAttribute(ObjectDefinitionConstants.LookupMethodObjectNameAttribute); - if (StringUtils.IsNullOrEmpty(methodName)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("The '{0}' attribute is required for the '{1}' element.", - ObjectDefinitionConstants.LookupMethodNameAttribute, ObjectDefinitionConstants.LookupMethodElement)); - } - if (StringUtils.IsNullOrEmpty(targetObjectName)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("The '{0}' attribute is required for the '{1}' element.", - ObjectDefinitionConstants.LookupMethodObjectNameAttribute, ObjectDefinitionConstants.LookupMethodElement)); - } - overrides.Add(new LookupMethodOverride(methodName, targetObjectName)); - } - - /// - /// Parse element and add parsed element to - /// - protected void ParseReplacedMethodElement( - string name, MethodOverrides overrides, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string methodName = element.GetAttribute(ObjectDefinitionConstants.ReplacedMethodNameAttribute); - string targetReplacerObjectName = element.GetAttribute(ObjectDefinitionConstants.ReplacedMethodReplacerNameAttribute); - if (StringUtils.IsNullOrEmpty(methodName)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("The '{0}' attribute is required for the '{1}' element.", - ObjectDefinitionConstants.ReplacedMethodNameAttribute, ObjectDefinitionConstants.ReplacedMethodElement)); - } - if (StringUtils.IsNullOrEmpty(targetReplacerObjectName)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("The '{0}' attribute is required for the '{1}' element.", - ObjectDefinitionConstants.ReplacedMethodReplacerNameAttribute, ObjectDefinitionConstants.ReplacedMethodElement)); - } - ReplacedMethodOverride theOverride = new ReplacedMethodOverride(methodName, targetReplacerObjectName); - foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ReplacedMethodArgumentTypeElement)) - { - XmlElement argElement = (XmlElement) node; - string match = argElement.GetAttribute(ObjectDefinitionConstants.ReplacedMethodArgumentTypeMatchAttribute); - if (StringUtils.IsNullOrEmpty(match)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("The '{0}' attribute is required for the '{1}' element.", - ObjectDefinitionConstants.ReplacedMethodArgumentTypeMatchAttribute, ObjectDefinitionConstants.ReplacedMethodArgumentTypeElement)); - } - theOverride.AddTypeIdentifier(match); - } - overrides.Add(theOverride); - } - - /// - /// Parse constructor argument subelements of the given object element. - /// - protected ConstructorArgumentValues GetConstructorArgSubElements( - string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - ConstructorArgumentValues arguments = new ConstructorArgumentValues(); - foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ConstructorArgElement)) - { - ParseConstructorArgElement(name, arguments, (XmlElement) node, parserHelper); - } - return arguments; - } - - /// - /// Parse event handler subelements of the given object element. - /// - protected EventValues GetEventHandlerSubElements( - string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - EventValues events = new EventValues(); - foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ListenerElement)) - { - ParseEventListenerDefinition(name, events, (XmlElement) node, parserHelper); - } - return events; - } - - /// - /// Parse property value subelements of the given object element. - /// - /// - /// The name of the object (definition) associated with the property element (s) - /// - /// - /// The element containing the top level object definition. - /// - /// - /// The namespace-aware parser. - /// - /// - /// The property (s) associated with the object (definition). - /// - protected virtual MutablePropertyValues GetPropertyValueSubElements( - string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - MutablePropertyValues properties = new MutablePropertyValues(); - foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.PropertyElement)) - { - ParsePropertyElement(name, properties, (XmlElement) node, parserHelper); - } - return properties; - } - - /// - /// Parse a constructor-arg element. - /// - /// - /// The name of the object (definition) associated with the ctor arg. - /// - /// - /// The list of constructor args associated with the object (definition). - /// - /// - /// The name of the element containing the ctor arg definition. - /// - /// - /// The namespace-aware parser. - /// - protected virtual void ParseConstructorArgElement( - string name, ConstructorArgumentValues arguments, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - object val = GetPropertyValue(element, name, parserHelper); - string indexAttr = element.GetAttribute(ObjectDefinitionConstants.IndexAttribute); - string typeAttr = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - string nameAttr = element.GetAttribute(ObjectDefinitionConstants.ArgumentNameAttribute); - - // only one of the 'index' or 'name' attributes can be present - if (StringUtils.HasText(indexAttr) - && StringUtils.HasText(nameAttr)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - "Only one of the 'index' or 'name' attributes can be present per constructor argument."); - } - if (StringUtils.HasText(indexAttr)) - { - try - { - int index = int.Parse(indexAttr, CultureInfo.CurrentCulture); - if (index < 0) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - "'index' cannot be lower than 0"); - } - if (StringUtils.HasText(typeAttr)) - { - arguments.AddIndexedArgumentValue(index, val, typeAttr); - } - else - { - arguments.AddIndexedArgumentValue(index, val); - } - } - catch (FormatException) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - "Attribute 'index' of tag 'constructor-arg' must be an integer value."); - } - } - else if (StringUtils.HasText(nameAttr)) - { - if (StringUtils.HasText(typeAttr)) - { - if (log.IsWarnEnabled) - { - log.Warn("The 'type' attribute is redundant when the 'name' attribute has been used on a constructor argument element."); - } - } - arguments.AddNamedArgumentValue(nameAttr, val); - } - else - { - if (StringUtils.HasText(typeAttr)) - { - arguments.AddGenericArgumentValue(val, typeAttr); - } - else - { - arguments.AddGenericArgumentValue(val); - } - } - } - - /// - /// Parse a property element. - /// - /// - /// The name of the object (definition) associated with the property. - /// - /// - /// The list of properties associated with the object (definition). - /// - /// - /// The name of the element containing the property definition. - /// - /// - /// The namespace-aware parser. - /// - protected void ParsePropertyElement( - string name, MutablePropertyValues properties, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string propertyName = element.GetAttribute(ObjectDefinitionConstants.NameAttribute); - if (StringUtils.IsNullOrEmpty(propertyName)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, - name, - "The 'property' element must have a 'name' attribute"); - } - object val = GetPropertyValue(element, name, parserHelper); - properties.Add(new PropertyValue(propertyName, val)); - } - - /// - /// Get the value of a property element (may be a list). - /// - ///

- /// Please note that even though this method is named GetPropertyValue, - /// it is called by both the property and constructor argument element - /// handlers. - ///

- ///
- /// The property element. - /// - /// The name of the object associated with the property. - /// - /// - /// The namespace-aware parser. - /// - protected virtual object GetPropertyValue( - XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) - { - XmlAttribute inlineValueAtt = element.Attributes[ObjectDefinitionConstants.ValueAttribute]; - if (inlineValueAtt != null) - { - return inlineValueAtt.Value; - } - XmlAttribute inlineRefAtt = element.Attributes[ObjectDefinitionConstants.RefAttribute]; - if (inlineRefAtt != null) - { - return new RuntimeObjectReference(inlineRefAtt.Value); - } - XmlAttribute inlineExpressionAtt = element.Attributes[ObjectDefinitionConstants.ExpressionAttribute]; - if (inlineExpressionAtt != null) - { - return new ExpressionHolder(inlineExpressionAtt.Value); - } - - // should only have one element child: value, ref, collection... - XmlNodeList nodes = element.ChildNodes; - XmlElement valueRefOrCollectionElement = null; - for (int i = 0; i < nodes.Count; ++i) - { - XmlElement candidateEle = nodes.Item(i) as XmlElement; - if (candidateEle != null) - { - if (ObjectDefinitionConstants.DescriptionElement.Equals(candidateEle.Name)) - { - // keep going: we don't use this value for now... - } - else - { - // child element is what we're looking for... - valueRefOrCollectionElement = candidateEle; - } - } - } - if (valueRefOrCollectionElement == null) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, - name, - "The '' element must have a subelement such as 'value' or 'ref'."); - } - return ParsePropertySubElement(valueRefOrCollectionElement, name, parserHelper); - } - - /// - /// Parse a value, ref or collection subelement of a property element. - /// - /// - /// Subelement of property element; we don't know which yet. - /// - /// - /// The name of the object (definition) associated with the top level property. - /// - /// - /// The namespace-aware parser. - /// - protected virtual object ParsePropertySubElement( - XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) - { - if (element.Name.Equals(ObjectDefinitionConstants.ObjectElement)) - { - return ParseObjectDefinition(element, "(inner object definition)", parserHelper); - } - else if (element.Name.Equals(ObjectDefinitionConstants.RefElement)) - { - return GetReference(element, parserHelper, name); - } - else if (element.Name.Equals(ObjectDefinitionConstants.IdRefElement)) - { - return GetObjectReference(element, parserHelper, name); - } - else if (element.Name.Equals(ObjectDefinitionConstants.ListElement)) - { - return GetList(element, name, parserHelper); - } - else if (element.Name.Equals(ObjectDefinitionConstants.SetElement)) - { - return GetSet(element, name, parserHelper); - } - else if (element.Name.Equals(ObjectDefinitionConstants.DictionaryElement)) - { - return GetDictionary(element, name, parserHelper); - } - else if (element.Name.Equals(ObjectDefinitionConstants.NameValuesElement)) - { - return GetNameValues(element, name); - } - else if (element.Name.Equals(ObjectDefinitionConstants.ValueElement)) - { - return GetValue(element, name); - } - else if (element.Name.Equals(ObjectDefinitionConstants.ExpressionElement)) - { - return GetExpression(element, name, parserHelper); - } - else if (element.Name.Equals(ObjectDefinitionConstants.NullElement)) - { - // it's a distinguished null value... - return null; - } - else - { - // it may match another Parser - INamespaceParser otherParser = GetParser(element.NamespaceURI); - if (otherParser != null) - { - // The other parser uses nestings tags and thus returns the definition - // of the parsed object. - return otherParser.ParseElement(element, new ParserContext(parserHelper.ReaderContext, parserHelper)); - } - } - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, - name, - "Unknown subelement of : <" + element.Name + ">"); - } - - private static INamespaceParser GetParser(string nspace) - { - // finds the configuration parser for the given namespace - try - { - return NamespaceParserRegistry.GetParser(nspace); - } - catch (Exception) - { - // The parser for the given namespace is not found - return null; - } - } - - private static object GetObjectReference(XmlElement element, ObjectDefinitionParserHelper parserHelper, string name) - { - // a generic reference to any name of any object - string objectRef = element.GetAttribute(ObjectDefinitionConstants.ObjectRefAttribute); - if (StringUtils.IsNullOrEmpty(objectRef)) - { - // a reference to the id of another object in the same XML file - objectRef = element.GetAttribute(ObjectDefinitionConstants.LocalRefAttribute); - if (StringUtils.IsNullOrEmpty(objectRef)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, - name, - "Either 'object' or 'local' is required for an idref"); - } - } - return objectRef; - } - - private object GetReference(XmlElement element, ObjectDefinitionParserHelper parserHelper, string name) - { - // is it a generic reference to any name of any object? - string objectRef = element.GetAttribute(ObjectDefinitionConstants.ObjectRefAttribute); - if (StringUtils.IsNullOrEmpty(objectRef)) - { - // is it a reference to the id of another object in the same XML file? - objectRef = element.GetAttribute(ObjectDefinitionConstants.LocalRefAttribute); - if (StringUtils.IsNullOrEmpty(objectRef)) - { - // is it a reference to the id of another object in a parent context? - objectRef = element.GetAttribute(ObjectDefinitionConstants.ParentAttribute); - if (StringUtils.IsNullOrEmpty(objectRef)) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, - name, - "Either 'object' or 'local' is required for a reference"); - } - return new RuntimeObjectReference(objectRef, true); - } - } - return new RuntimeObjectReference(objectRef); - } - - private object GetValue(XmlElement element, string name) - { - string valueType = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - if (StringUtils.IsNullOrEmpty(valueType)) - { - return GetTextValue(element, name); - } - else - { - Type resolvedValueType = TypeResolutionUtils.ResolveType(valueType); - if (resolvedValueType == typeof(string)) - { - return GetTextValue(element, name); - } - else - { - return new TypedStringValue(GetTextValue(element, name), resolvedValueType); - } - } - } - - private object GetExpression(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) - { - string expression = element.GetAttribute(ObjectDefinitionConstants.ValueAttribute); - ExpressionHolder holder = new ExpressionHolder(expression); - holder.Properties = GetPropertyValueSubElements(name, element, parserHelper); - return holder; - } - - /// - /// Gets a list definition. - /// - /// - /// The element describing the list definition. - /// - /// - /// The name of the object (definition) associated with the list definition. - /// - /// - /// The namespace-aware parser. - /// - /// The list definition. - protected virtual IList GetList(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) - { - ManagedList list = new ManagedList(); - - string elementTypeName = element.GetAttribute("element-type"); - if (StringUtils.HasText(elementTypeName)) - { - list.ElementTypeName = elementTypeName; - } - - foreach (XmlNode node in element.ChildNodes) - { - XmlElement ele = node as XmlElement; - if (ele != null) - { - list.Add(ParsePropertySubElement(ele, name, parserHelper)); - } - } - return list; - } - - /// - /// Gets a set definition. - /// - /// - /// The element describing the set definition. - /// - /// - /// The name of the object (definition) associated with the set definition. - /// - /// - /// The namespace-aware parser. - /// - /// The set definition. - protected Set GetSet(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) - { - ManagedSet theSet = new ManagedSet(); - string elementTypeName = element.GetAttribute("element-type"); - if (StringUtils.HasText(elementTypeName)) - { - theSet.ElementTypeName = elementTypeName; - } - foreach (XmlNode node in element.ChildNodes) - { - XmlElement ele = node as XmlElement; - if (ele != null) - { - object sub = ParsePropertySubElement(ele, name, parserHelper); - theSet.Add(sub); - } - } - return theSet; - } - - /// - /// Gets a dictionary definition. - /// - /// - /// The element describing the dictionary definition. - /// - /// - /// The name of the object (definition) associated with the dictionary definition. - /// - /// - /// The namespace-aware parser. - /// - /// The dictionary definition. - protected IDictionary GetDictionary(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) - { - ManagedDictionary dictionary = new ManagedDictionary(); - string keyTypeName = element.GetAttribute("key-type"); - string valueTypeName = element.GetAttribute("value-type"); - if (StringUtils.HasText(keyTypeName)) - { - dictionary.KeyTypeName = keyTypeName; - } - if (StringUtils.HasText(valueTypeName)) - { - dictionary.ValueTypeName = valueTypeName; - } - - XmlNodeList entryElements = SelectNodes(element, ObjectDefinitionConstants.EntryElement); - foreach (XmlElement entryEle in entryElements) - { - #region Key - - object key = null; - - XmlAttribute keyAtt = entryEle.Attributes[ObjectDefinitionConstants.KeyAttribute]; - if (keyAtt != null) - { - key = keyAtt.Value; - } - else - { - // ok, we're not using the 'key' attribute; lets check for the ref shortcut... - XmlAttribute keyRefAtt = entryEle.Attributes[ObjectDefinitionConstants.DictionaryKeyRefShortcutAttribute]; - if (keyRefAtt != null) - { - key = new RuntimeObjectReference(keyRefAtt.Value); - } - else - { - // so check for the 'key' element... - XmlNode keyNode = SelectSingleNode(entryEle, ObjectDefinitionConstants.KeyElement); - if (keyNode == null) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("One of either the '{0}' element, or the the '{1}' or '{2}' attributes " + - "is required for the <{3}/> element.", - ObjectDefinitionConstants.KeyElement, - ObjectDefinitionConstants.KeyAttribute, - ObjectDefinitionConstants.DictionaryKeyRefShortcutAttribute, - ObjectDefinitionConstants.EntryElement)); - } - XmlElement keyElement = (XmlElement) keyNode; - XmlNodeList keyNodes = keyElement.GetElementsByTagName("*"); - if (keyNodes == null || keyNodes.Count == 0) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("Malformed <{0}/> element... the value of the key must be " + - "specified as a child value-style element.", - ObjectDefinitionConstants.KeyElement)); - } - key = ParsePropertySubElement((XmlElement) keyNodes.Item(0), name, parserHelper); - } - } - - #endregion - - #region Value - - XmlAttribute inlineValueAtt = entryEle.Attributes[ObjectDefinitionConstants.ValueAttribute]; - if (inlineValueAtt != null) - { - // ok, we're using the value attribute shortcut... - dictionary[key] = inlineValueAtt.Value; - } - else if (entryEle.Attributes[ObjectDefinitionConstants.DictionaryValueRefShortcutAttribute] != null) - { - // ok, we're using the value-ref attribute shortcut... - XmlAttribute inlineValueRefAtt = entryEle.Attributes[ObjectDefinitionConstants.DictionaryValueRefShortcutAttribute]; - RuntimeObjectReference ror = new RuntimeObjectReference(inlineValueRefAtt.Value); - dictionary[key] = ror; - } - else if (entryEle.Attributes[ObjectDefinitionConstants.ExpressionAttribute] != null) - { - // ok, we're using the expression attribute shortcut... - XmlAttribute inlineExpressionAtt = entryEle.Attributes[ObjectDefinitionConstants.ExpressionAttribute]; - ExpressionHolder expHolder = new ExpressionHolder(inlineExpressionAtt.Value); - dictionary[key] = expHolder; - } - else - { - XmlNode keyNode = SelectSingleNode(entryEle, ObjectDefinitionConstants.KeyElement); - if (keyNode != null) - { - entryEle.RemoveChild(keyNode); - } - // ok, we're using the original full-on value element... - XmlNodeList valueElements = entryEle.GetElementsByTagName("*"); - if (valueElements == null || valueElements.Count == 0) - { - throw new ObjectDefinitionStoreException( - parserHelper.ReaderContext.Resource, name, - string.Format("One of either the '{0}' or '{1}' attributes, or a value-style element " + - "is required for the <{2}/> element.", - ObjectDefinitionConstants.ValueAttribute, ObjectDefinitionConstants.DictionaryValueRefShortcutAttribute, ObjectDefinitionConstants.EntryElement)); - } - dictionary[key] = ParsePropertySubElement((XmlElement)valueElements.Item(0), name, parserHelper); - } - - #endregion - } - return dictionary; - } - - /// - /// Selects sub-elements with a given - /// name. - /// - /// - ///

- /// Uses a namespace manager if necessary. - ///

- ///
- /// - /// The element to be searched in. - /// - /// - /// The name of the child nodes to look for. - /// - /// - /// The child s of the supplied - /// with the supplied - /// . - /// - protected XmlNodeList SelectNodes(XmlElement element, string childElementName) - { - XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable()); - nsManager.AddNamespace(GetNamespacePrefix(element), element.NamespaceURI); - return element.SelectNodes(GetNamespacePrefix(element) + ":" + childElementName, nsManager); - } - - /// - /// Selects a single sub-element with a given - /// name. - /// - /// - ///

- /// Uses a namespace manager if necessary. - ///

- ///
- /// - /// The element to be searched in. - /// - /// - /// The name of the child node to look for. - /// - /// - /// The first child of the supplied - /// with the supplied - /// . - /// - protected XmlNode SelectSingleNode(XmlElement element, string childElementName) - { - XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable()); - nsManager.AddNamespace(GetNamespacePrefix(element), element.NamespaceURI); - return element.SelectSingleNode(GetNamespacePrefix(element) + ":" + childElementName, nsManager); - } - - /// - /// Gets a name value collection mapping definition. - /// - /// - /// The element describing the name value collection mapping definition. - /// - /// - /// The name of the object (definition) associated with the - /// name value collection mapping definition. - /// - /// The name value collection definition. - protected NameValueCollection GetNameValues(XmlElement element, string name) - { - NameValueCollection nvc = new NameValueCollection(); - XmlNodeList addElements = element.GetElementsByTagName(ObjectDefinitionConstants.AddElement); - foreach (XmlElement addElement in addElements) - { - string key = addElement.GetAttribute(ObjectDefinitionConstants.KeyAttribute); - string value = addElement.GetAttribute(ObjectDefinitionConstants.ValueAttribute); - string delimiters = addElement.GetAttribute(ObjectDefinitionConstants.DelimitersAttribute); - - if (StringUtils.HasText(delimiters)) - { - string[] values = value.Split(delimiters.ToCharArray()); - foreach (string v in values) - { - nvc.Add(key, v); - } - } - else - { - nvc[key] = value; - } - } - return nvc; - } - - /// - /// Returns the text of the supplied , - /// or the empty string value if said is empty. - /// - /// - ///

- /// If the supplied is , - /// then the empty string value will be returned. - ///

- ///
- protected string GetTextValue(XmlElement element, string name) - { - if (element == null || StringUtils.IsNullOrEmpty(element.InnerText)) - { - return String.Empty; - } - return element.InnerText; - } - - /// - /// Strips the dependency check value out of the supplied string. - /// - /// - ///

- /// If the supplied is an invalid dependency - /// checking mode, the invalid value will be logged and this method will - /// return the value. - /// No exception will be raised. - ///

- ///
- /// - /// The string containing the dependency check value. - /// - /// The dependency check value. - /// - protected DependencyCheckingMode GetDependencyCheck(string value) - { - DependencyCheckingMode code = DependencyCheckingMode.None; - if (StringUtils.HasText(value)) - { - try - { - code = (DependencyCheckingMode) Enum.Parse( - typeof(DependencyCheckingMode), value, true); - } - catch (ArgumentException ex) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format("Error while parsing dependency checking mode : '{0}' is an invalid value.", - value), ex); - } - - #endregion - } - } - return code; - } - - /// - /// Strips the autowiring mode out of the supplied string. - /// - /// - ///

- /// If the supplied is an invalid autowiring mode, - /// the invalid value will be logged and this method will return the - /// value. No exception will be raised. - ///

- ///
- /// - /// The string containing the autowiring mode definition. - /// - /// The autowiring mode. - /// - protected AutoWiringMode GetAutowireMode(string value) - { - AutoWiringMode mode = AutoWiringMode.No; - if (StringUtils.HasText(value)) - { - try - { - mode = (AutoWiringMode) Enum.Parse( - typeof(AutoWiringMode), value, true); - } - catch (ArgumentException ex) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format("Error while parsing autowire mode : '{0}' is an invalid value.", - value), ex); - } - - #endregion - } - } - return mode; - } - - /// - /// Given a string containing delimited object names, returns - /// a string array split on the object name delimeter. - /// - /// - /// The string containing delimited object names. - /// - /// - /// A string array split on the object name delimeter. - /// - /// - private string[] GetObjectNames(string value) - { - return StringUtils.Split( - value, ObjectDefinitionConstants.ObjectNameDelimiters, true, true); - } - - private static bool IsTrueStringValue(string value) - { - return ObjectDefinitionConstants.TrueValue.Equals(value); - } - - private string GetNamespacePrefix(XmlElement element) - { - return StringUtils.HasText(element.Prefix) ? element.Prefix : "spring"; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Globalization; +using System.IO; +using System.Text; +using System.Xml; + +using Common.Logging; + +using Spring.Collections; +using Spring.Core; +using Spring.Core.IO; +using Spring.Core.TypeResolution; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Default implementation of the + /// interface. + /// + /// + ///

+ /// Parses object definitions according to the standard Spring.NET schema. + ///

+ ///

+ /// This schema is typically located at + /// http://www.springframework.net/xsd/spring-objects.xsd. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + [ + NamespaceParser( + Namespace = "http://www.springframework.net", + SchemaLocationAssemblyHint = typeof(ObjectsNamespaceParser), + SchemaLocation = "/Spring.Objects.Factory.Xml/spring-objects-1.1.xsd" + ) + ] + public class ObjectsNamespaceParser : INamespaceParser + { + /// + /// The namespace URI for the standard Spring.NET object definition schema. + /// + public const string Namespace = "http://www.springframework.net"; + + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof(ObjectsNamespaceParser)); + + #region IXmlObjectDefinitionParser Members + + /// + /// Invoked by after construction but before any + /// elements have been parsed. + /// + /// This is a NoOp + public void Init() + { + + } + + #endregion + + + /// + /// Parse the specified element and register any resulting + /// IObjectDefinitions with the IObjectDefinitionRegistry that is + /// embedded in the supplied ParserContext. + /// + /// The element to be parsed into one or more IObjectDefinitions + /// The object encapsulating the current state of the parsing + /// process. + /// + /// The primary IObjectDefinition (can be null as explained above) + /// + /// + /// Implementations should return the primary IObjectDefinition + /// that results from the parse phase if they wish to used nested + /// inside (for example) a <property> tag. + /// Implementations may return null if they will not + /// be used in a nested scenario. + /// + /// + public virtual IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + + if (element.LocalName == ObjectDefinitionConstants.ImportElement) + { + ImportObjectDefinitionResource(element, parserContext); + } + else if (element.LocalName == ObjectDefinitionConstants.AliasElement) + { + ParseAlias(element, parserContext.ReaderContext.Registry); + } + else if (element.LocalName == ObjectDefinitionConstants.ObjectElement) + { + RegisterObjectDefinition(element, parserContext); + } + + return null; + } + + + /// + /// Parse the specified XmlNode and decorate the supplied ObjectDefinitionHolder, + /// returning the decorated definition. + /// + /// The XmlNode may either be an XmlAttribute or an XmlElement, depending on + /// whether a custom attribute or element is being parsed. + /// Implementations may choose to return a completely new definition, + /// which will replace the original definition in the resulting IApplicationContext/IObjectFactory. + /// + /// The supplied ParserContext can be used to register any additional objects needed to support + /// the main definition. + /// + /// The source element or attribute that is to be parsed. + /// The current object definition. + /// The object encapsulating the current state of the parsing + /// process. + /// The decorated definition (to be registered in the IApplicationContext/IObjectFactory), + /// or simply the original object definition if no decoration is required. A null value is strickly + /// speaking invalid, but will leniently treated like the case where the original object definition + /// gets returned. + public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, + ParserContext parserContext) + { + return null; + } + + private void ParseAlias(XmlElement aliasElement, IObjectDefinitionRegistry registry) + { + string name = aliasElement.GetAttribute(ObjectDefinitionConstants.NameAttribute); + string alias = aliasElement.GetAttribute(ObjectDefinitionConstants.AliasAttribute); + registry.RegisterAlias(name, alias); + } + + + + + /// + /// Loads external XML object definitions from the resource described by the supplied + /// . + /// + /// The XML element describing the resource. + /// The parser context. + /// + /// If the resource could not be imported. + /// + protected virtual void ImportObjectDefinitionResource(XmlElement resource, ParserContext parserContext) + { + string location = resource.GetAttribute(ObjectDefinitionConstants.ImportResourceAttribute); + try + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Attempting to import object definitions from '{0}'.", location)); + } + + #endregion + + IResource importResource = parserContext.ReaderContext.Resource.CreateRelative(location); + parserContext.ReaderContext.Reader.LoadObjectDefinitions(importResource); + } + catch (IOException ex) + { + parserContext.ReaderContext.ReportException(resource, null, string.Format( + CultureInfo.InvariantCulture, + "Invalid relative resource location '{0}' to import object definitions from.", + location), ex); + } + } + + + /// Parses an event listener definition. + /// + /// The name associated with the object that the event handler is being defined on. + /// + /// The events being populated. + /// + /// The element containing the event listener definition. + /// + /// + /// The namespace-aware parser. + /// + protected virtual void ParseEventListenerDefinition( + string name, EventValues events, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + // get an appropriate IEventHandlerValue instance based upon the + // attribute values of the listener element... + IEventHandlerValue myHandler = ObjectDefinitionReaderUtils.CreateEventHandlerValue( + element.GetAttribute(ObjectDefinitionConstants.ListenerMethodAttribute), + element.GetAttribute(ObjectDefinitionConstants.ListenerEventAttribute)); + + // and then get the source of the event (another managed object instance + // or a Type reference (i.e. a static event exposed on a class)... + XmlElement sourceElement = this.SelectSingleNode(element, ObjectDefinitionConstants.RefElement) as XmlElement; + + XmlAttribute sourceAtt = sourceElement.Attributes[0]; + if (StringUtils.IsNullOrEmpty(sourceAtt.Value)) + { + parserHelper.ReaderContext.ReportFatalException(sourceElement, string.Format( + CultureInfo.InvariantCulture, + "The single attribute of the <{0}/> element cannot be empty. Specify the " + + "object id (alias) or the full, assembly qualified Type name that is the " + + "source of the event.", + ObjectDefinitionConstants.RefElement)); + return; + } + switch (sourceAtt.LocalName) + { + case ObjectDefinitionConstants.LocalRefAttribute: + case ObjectDefinitionConstants.ObjectRefAttribute: + // we're wiring up to an event exposed on another managed object (instance) + RuntimeObjectReference ror = new RuntimeObjectReference(sourceAtt.Value); + myHandler.Source = ror; + break; + case ObjectDefinitionConstants.TypeAttribute: + // we're wiring up to a static event exposed on a Type (class) + myHandler.Source = parserHelper.ReaderContext.Reader.Domain == null ? + (object) sourceAtt.Value : + (object)TypeResolutionUtils.ResolveType(sourceAtt.Value); + break; + } + events.AddHandler(myHandler); + } + + + + /// + /// Parse an object definition and register it with the object factory.. + /// + /// The element containing the object definition. + /// The parser context. + /// + protected void RegisterObjectDefinition(XmlElement element, ParserContext parserContext) + { + ObjectDefinitionHolder holder = null; + try + { + holder = ParseObjectDefinition(element, parserContext); + if (holder == null) + { + return; + } + } + catch (Exception ex) + { + throw new ObjectDefinitionStoreException(string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex); + } + + + holder = parserContext.ParserHelper.DecorateObjectDefinitionIfRequired(element, holder); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + CultureInfo.InvariantCulture, + "Registering object definition with id '{0}'.", holder.ObjectName)); + } + + #endregion + + ObjectDefinitionReaderUtils.RegisterObjectDefinition(holder, parserContext.ReaderContext.Registry); + } + + + /// + /// Parse a standard object definition into a + /// , + /// including object name and aliases. + /// + /// The element containing the object definition. + /// The parser context. + /// + /// The object (definition) wrapped within an + /// + /// instance. + /// + /// + ///

+ /// Object elements specify their canonical name via the "id" attribute + /// and their aliases as a delimited "name" attribute. + ///

+ ///

+ /// If no "id" is specified, uses the first name in the "name" attribute + /// as the canonical name, registering all others as aliases. + ///

+ ///
+ protected ObjectDefinitionHolder ParseObjectDefinition(XmlElement element, ParserContext parserContext) + { + string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); + string name = element.GetAttribute(ObjectDefinitionConstants.NameAttribute); + ArrayList aliases = new ArrayList(); + if (StringUtils.HasText(name)) + { + aliases.AddRange(GetObjectNames(name)); + } + // if we ain't got an id, check if object is page definition or assign any existing (first) alias... + if (StringUtils.IsNullOrEmpty(id)) + { + id = CalculateId(element, aliases); + } + + + IConfigurableObjectDefinition definition = ParseObjectDefinition(element, id, parserContext.ParserHelper); + if (StringUtils.IsNullOrEmpty(id)) + { + id = ObjectDefinitionReaderUtils.GenerateObjectName(definition, parserContext.Registry); + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + "Neither XML '{0}' nor '{1}' specified - using object " + + "class name [{2}] as the id.", + id, ObjectDefinitionConstants.IdAttribute, ObjectDefinitionConstants.NameAttribute)); + } + + #endregion + } + string[] aliasesArray = (string[]) aliases.ToArray(typeof(string)); + return new ObjectDefinitionHolder(definition, id, aliasesArray); + } + + /// + /// Calculates an id for an object definition. + /// + /// + ///

+ /// Called when an object definition has not been explicitly defined + /// with an id. + ///

+ ///
+ /// + /// The element containing the object definition. + /// + /// + /// The list of names defined for the object; may be + /// or even empty. + /// + /// + /// A calculated object definition id. + /// + protected virtual string CalculateId(XmlElement element, ArrayList aliases) + { + string id = null; + if (aliases.Count > 0) + { + string firstAlias = aliases[0] as string; + aliases.RemoveAt(0); + id = firstAlias; + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + StringBuilder buffer = new StringBuilder(); + foreach (string alias in aliases) + { + buffer.Append(alias).Append(","); + } + log.Debug(string.Format("No XML 'id' specified - using '{0}' as the id and '{1}' as aliases.", + id, buffer.ToString())); + } + + #endregion + + return id; + } + + /// + /// Parse a standard object definition. + /// + /// The element containing the object definition. + /// The id of the object definition. + /// parsing state holder + /// The object (definition). + protected virtual IConfigurableObjectDefinition ParseObjectDefinition( + XmlElement element, string id, ObjectDefinitionParserHelper parserHelper) + { + string typeName = null; + try + { + if (element.HasAttribute(ObjectDefinitionConstants.TypeAttribute)) + { + typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + if (StringUtils.IsNullOrEmpty(typeName)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, id, + "The 'type' attribute does not need to be present, but if it is it must not be empty: got '" + typeName + "'."); + } + } + string parent = element.GetAttribute(ObjectDefinitionConstants.ParentAttribute); + + + AbstractObjectDefinition od + = parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, parent, parserHelper.ReaderContext.Reader.Domain); + + + MutablePropertyValues pvs = GetPropertyValueSubElements(id, element, parserHelper); + ConstructorArgumentValues arguments + = GetConstructorArgSubElements(id, element, parserHelper); + EventValues events = GetEventHandlerSubElements(id, element, parserHelper); + MethodOverrides methodOverrides = GetMethodOverrideSubElements(id, element, parserHelper); + + bool isPage = StringUtils.HasText(typeName) && typeName!= null && typeName.ToLower().EndsWith(".aspx"); + if (!isPage) + { + od.ConstructorArgumentValues = arguments; + } + + od.PropertyValues = pvs; + od.MethodOverrides = methodOverrides; + od.EventHandlerValues = events; + if (element.HasAttribute(ObjectDefinitionConstants.DependsOnAttribute)) + { + string dependsOn = element.GetAttribute(ObjectDefinitionConstants.DependsOnAttribute); + od.DependsOn = GetObjectNames(dependsOn); + } + od.FactoryMethodName = element.GetAttribute(ObjectDefinitionConstants.FactoryMethodAttribute); + od.FactoryObjectName = element.GetAttribute(ObjectDefinitionConstants.FactoryObjectAttribute); + string dependencyCheck = element.GetAttribute(ObjectDefinitionConstants.DependencyCheckAttribute); + if (ObjectDefinitionConstants.DefaultValue.Equals(dependencyCheck)) + { + dependencyCheck = parserHelper.Defaults.DependencyCheck; + } + od.DependencyCheck = GetDependencyCheck(dependencyCheck); + string autowire = element.GetAttribute(ObjectDefinitionConstants.AutowireAttribute); + if (ObjectDefinitionConstants.DefaultValue.Equals(autowire)) + { + autowire = parserHelper.Defaults.Autowire; + } + od.AutowireMode = GetAutowireMode(autowire); + string initMethodName = element.GetAttribute(ObjectDefinitionConstants.InitMethodAttribute); + if (StringUtils.HasText(initMethodName)) + { + od.InitMethodName = initMethodName; + } + string destroyMethodName = element.GetAttribute(ObjectDefinitionConstants.DestroyMethodAttribute); + if (StringUtils.HasText(destroyMethodName)) + { + od.DestroyMethodName = destroyMethodName; + } + if (element.HasAttribute(ObjectDefinitionConstants.SingletonAttribute)) + { + od.IsSingleton = IsTrueStringValue(element.GetAttribute(ObjectDefinitionConstants.SingletonAttribute).ToLower(CultureInfo.CurrentCulture)); + } + string lazyInit = element.GetAttribute(ObjectDefinitionConstants.LazyInitAttribute); + if (ObjectDefinitionConstants.DefaultValue.Equals(lazyInit) && od.IsSingleton) + { + // just apply default to singletons, as lazy-init has no meaning for prototypes... + lazyInit = parserHelper.Defaults.LazyInit; + } + od.IsLazyInit = IsTrueStringValue(lazyInit); + + // try to get the line info + string resourceDescription = parserHelper.ReaderContext.Resource.Description; + if (StringUtils.HasText(resourceDescription)) + { + int line = ConfigurationUtils.GetLineNumber(element); + if (line > 0) + { + resourceDescription += " line " + line; + } + } + od.ResourceDescription = resourceDescription; + + string isAbstract = element.GetAttribute(ObjectDefinitionConstants.AbstractAttribute); + if (StringUtils.HasText(isAbstract)) + { + od.IsAbstract = IsTrueStringValue(isAbstract); + } + return od; + } + catch (TypeLoadException ex) + { + parserHelper.ReaderContext.ReportException( + element, + id, + string.Format( + "Object class [{0}] not found.", + typeName), + ex); + } + catch (ApplicationException ex) + { + parserHelper.ReaderContext.ReportException(element, id, string.Empty, ex); + } + return null; + } + + /// + /// Parse method override argument subelements of the given object element. + /// + protected MethodOverrides GetMethodOverrideSubElements( + string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + MethodOverrides overrides = new MethodOverrides(); + foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.LookupMethodElement)) + { + ParseLookupMethodElement(name, overrides, (XmlElement) node, parserHelper); + } + foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ReplacedMethodElement)) + { + ParseReplacedMethodElement(name, overrides, (XmlElement) node, parserHelper); + } + return overrides; + } + + /// + /// Parse element and add parsed element to + /// + protected void ParseLookupMethodElement( + string name, MethodOverrides overrides, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string methodName = element.GetAttribute(ObjectDefinitionConstants.LookupMethodNameAttribute); + string targetObjectName = element.GetAttribute(ObjectDefinitionConstants.LookupMethodObjectNameAttribute); + if (StringUtils.IsNullOrEmpty(methodName)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("The '{0}' attribute is required for the '{1}' element.", + ObjectDefinitionConstants.LookupMethodNameAttribute, ObjectDefinitionConstants.LookupMethodElement)); + } + if (StringUtils.IsNullOrEmpty(targetObjectName)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("The '{0}' attribute is required for the '{1}' element.", + ObjectDefinitionConstants.LookupMethodObjectNameAttribute, ObjectDefinitionConstants.LookupMethodElement)); + } + overrides.Add(new LookupMethodOverride(methodName, targetObjectName)); + } + + /// + /// Parse element and add parsed element to + /// + protected void ParseReplacedMethodElement( + string name, MethodOverrides overrides, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string methodName = element.GetAttribute(ObjectDefinitionConstants.ReplacedMethodNameAttribute); + string targetReplacerObjectName = element.GetAttribute(ObjectDefinitionConstants.ReplacedMethodReplacerNameAttribute); + if (StringUtils.IsNullOrEmpty(methodName)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("The '{0}' attribute is required for the '{1}' element.", + ObjectDefinitionConstants.ReplacedMethodNameAttribute, ObjectDefinitionConstants.ReplacedMethodElement)); + } + if (StringUtils.IsNullOrEmpty(targetReplacerObjectName)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("The '{0}' attribute is required for the '{1}' element.", + ObjectDefinitionConstants.ReplacedMethodReplacerNameAttribute, ObjectDefinitionConstants.ReplacedMethodElement)); + } + ReplacedMethodOverride theOverride = new ReplacedMethodOverride(methodName, targetReplacerObjectName); + foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ReplacedMethodArgumentTypeElement)) + { + XmlElement argElement = (XmlElement) node; + string match = argElement.GetAttribute(ObjectDefinitionConstants.ReplacedMethodArgumentTypeMatchAttribute); + if (StringUtils.IsNullOrEmpty(match)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("The '{0}' attribute is required for the '{1}' element.", + ObjectDefinitionConstants.ReplacedMethodArgumentTypeMatchAttribute, ObjectDefinitionConstants.ReplacedMethodArgumentTypeElement)); + } + theOverride.AddTypeIdentifier(match); + } + overrides.Add(theOverride); + } + + /// + /// Parse constructor argument subelements of the given object element. + /// + protected ConstructorArgumentValues GetConstructorArgSubElements( + string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + ConstructorArgumentValues arguments = new ConstructorArgumentValues(); + foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ConstructorArgElement)) + { + ParseConstructorArgElement(name, arguments, (XmlElement) node, parserHelper); + } + return arguments; + } + + /// + /// Parse event handler subelements of the given object element. + /// + protected EventValues GetEventHandlerSubElements( + string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + EventValues events = new EventValues(); + foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ListenerElement)) + { + ParseEventListenerDefinition(name, events, (XmlElement) node, parserHelper); + } + return events; + } + + /// + /// Parse property value subelements of the given object element. + /// + /// + /// The name of the object (definition) associated with the property element (s) + /// + /// + /// The element containing the top level object definition. + /// + /// + /// The namespace-aware parser. + /// + /// + /// The property (s) associated with the object (definition). + /// + protected virtual MutablePropertyValues GetPropertyValueSubElements( + string name, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + MutablePropertyValues properties = new MutablePropertyValues(); + foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.PropertyElement)) + { + ParsePropertyElement(name, properties, (XmlElement) node, parserHelper); + } + return properties; + } + + /// + /// Parse a constructor-arg element. + /// + /// + /// The name of the object (definition) associated with the ctor arg. + /// + /// + /// The list of constructor args associated with the object (definition). + /// + /// + /// The name of the element containing the ctor arg definition. + /// + /// + /// The namespace-aware parser. + /// + protected virtual void ParseConstructorArgElement( + string name, ConstructorArgumentValues arguments, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + object val = GetPropertyValue(element, name, parserHelper); + string indexAttr = element.GetAttribute(ObjectDefinitionConstants.IndexAttribute); + string typeAttr = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + string nameAttr = element.GetAttribute(ObjectDefinitionConstants.ArgumentNameAttribute); + + // only one of the 'index' or 'name' attributes can be present + if (StringUtils.HasText(indexAttr) + && StringUtils.HasText(nameAttr)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + "Only one of the 'index' or 'name' attributes can be present per constructor argument."); + } + if (StringUtils.HasText(indexAttr)) + { + try + { + int index = int.Parse(indexAttr, CultureInfo.CurrentCulture); + if (index < 0) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + "'index' cannot be lower than 0"); + } + if (StringUtils.HasText(typeAttr)) + { + arguments.AddIndexedArgumentValue(index, val, typeAttr); + } + else + { + arguments.AddIndexedArgumentValue(index, val); + } + } + catch (FormatException) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + "Attribute 'index' of tag 'constructor-arg' must be an integer value."); + } + } + else if (StringUtils.HasText(nameAttr)) + { + if (StringUtils.HasText(typeAttr)) + { + if (log.IsWarnEnabled) + { + log.Warn("The 'type' attribute is redundant when the 'name' attribute has been used on a constructor argument element."); + } + } + arguments.AddNamedArgumentValue(nameAttr, val); + } + else + { + if (StringUtils.HasText(typeAttr)) + { + arguments.AddGenericArgumentValue(val, typeAttr); + } + else + { + arguments.AddGenericArgumentValue(val); + } + } + } + + /// + /// Parse a property element. + /// + /// + /// The name of the object (definition) associated with the property. + /// + /// + /// The list of properties associated with the object (definition). + /// + /// + /// The name of the element containing the property definition. + /// + /// + /// The namespace-aware parser. + /// + protected void ParsePropertyElement( + string name, MutablePropertyValues properties, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string propertyName = element.GetAttribute(ObjectDefinitionConstants.NameAttribute); + if (StringUtils.IsNullOrEmpty(propertyName)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, + name, + "The 'property' element must have a 'name' attribute"); + } + object val = GetPropertyValue(element, name, parserHelper); + properties.Add(new PropertyValue(propertyName, val)); + } + + /// + /// Get the value of a property element (may be a list). + /// + ///

+ /// Please note that even though this method is named GetPropertyValue, + /// it is called by both the property and constructor argument element + /// handlers. + ///

+ ///
+ /// The property element. + /// + /// The name of the object associated with the property. + /// + /// + /// The namespace-aware parser. + /// + protected virtual object GetPropertyValue( + XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) + { + XmlAttribute inlineValueAtt = element.Attributes[ObjectDefinitionConstants.ValueAttribute]; + if (inlineValueAtt != null) + { + return inlineValueAtt.Value; + } + XmlAttribute inlineRefAtt = element.Attributes[ObjectDefinitionConstants.RefAttribute]; + if (inlineRefAtt != null) + { + return new RuntimeObjectReference(inlineRefAtt.Value); + } + XmlAttribute inlineExpressionAtt = element.Attributes[ObjectDefinitionConstants.ExpressionAttribute]; + if (inlineExpressionAtt != null) + { + return new ExpressionHolder(inlineExpressionAtt.Value); + } + + // should only have one element child: value, ref, collection... + XmlNodeList nodes = element.ChildNodes; + XmlElement valueRefOrCollectionElement = null; + for (int i = 0; i < nodes.Count; ++i) + { + XmlElement candidateEle = nodes.Item(i) as XmlElement; + if (candidateEle != null) + { + if (ObjectDefinitionConstants.DescriptionElement.Equals(candidateEle.Name)) + { + // keep going: we don't use this value for now... + } + else + { + // child element is what we're looking for... + valueRefOrCollectionElement = candidateEle; + } + } + } + if (valueRefOrCollectionElement == null) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, + name, + "The '' element must have a subelement such as 'value' or 'ref'."); + } + return ParsePropertySubElement(valueRefOrCollectionElement, name, parserHelper); + } + + /// + /// Parse a value, ref or collection subelement of a property element. + /// + /// + /// Subelement of property element; we don't know which yet. + /// + /// + /// The name of the object (definition) associated with the top level property. + /// + /// + /// The namespace-aware parser. + /// + protected virtual object ParsePropertySubElement( + XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) + { + if (element.Name.Equals(ObjectDefinitionConstants.ObjectElement)) + { + return ParseObjectDefinition(element, "(inner object definition)", parserHelper); + } + else if (element.Name.Equals(ObjectDefinitionConstants.RefElement)) + { + return GetReference(element, parserHelper, name); + } + else if (element.Name.Equals(ObjectDefinitionConstants.IdRefElement)) + { + return GetObjectReference(element, parserHelper, name); + } + else if (element.Name.Equals(ObjectDefinitionConstants.ListElement)) + { + return GetList(element, name, parserHelper); + } + else if (element.Name.Equals(ObjectDefinitionConstants.SetElement)) + { + return GetSet(element, name, parserHelper); + } + else if (element.Name.Equals(ObjectDefinitionConstants.DictionaryElement)) + { + return GetDictionary(element, name, parserHelper); + } + else if (element.Name.Equals(ObjectDefinitionConstants.NameValuesElement)) + { + return GetNameValues(element, name); + } + else if (element.Name.Equals(ObjectDefinitionConstants.ValueElement)) + { + return GetValue(element, name); + } + else if (element.Name.Equals(ObjectDefinitionConstants.ExpressionElement)) + { + return GetExpression(element, name, parserHelper); + } + else if (element.Name.Equals(ObjectDefinitionConstants.NullElement)) + { + // it's a distinguished null value... + return null; + } + else + { + // it may match another Parser + INamespaceParser otherParser = GetParser(element.NamespaceURI); + if (otherParser != null) + { + // The other parser uses nestings tags and thus returns the definition + // of the parsed object. + return otherParser.ParseElement(element, new ParserContext(parserHelper.ReaderContext, parserHelper)); + } + } + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, + name, + "Unknown subelement of : <" + element.Name + ">"); + } + + private static INamespaceParser GetParser(string nspace) + { + // finds the configuration parser for the given namespace + try + { + return NamespaceParserRegistry.GetParser(nspace); + } + catch (Exception) + { + // The parser for the given namespace is not found + return null; + } + } + + private static object GetObjectReference(XmlElement element, ObjectDefinitionParserHelper parserHelper, string name) + { + // a generic reference to any name of any object + string objectRef = element.GetAttribute(ObjectDefinitionConstants.ObjectRefAttribute); + if (StringUtils.IsNullOrEmpty(objectRef)) + { + // a reference to the id of another object in the same XML file + objectRef = element.GetAttribute(ObjectDefinitionConstants.LocalRefAttribute); + if (StringUtils.IsNullOrEmpty(objectRef)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, + name, + "Either 'object' or 'local' is required for an idref"); + } + } + return objectRef; + } + + private object GetReference(XmlElement element, ObjectDefinitionParserHelper parserHelper, string name) + { + // is it a generic reference to any name of any object? + string objectRef = element.GetAttribute(ObjectDefinitionConstants.ObjectRefAttribute); + if (StringUtils.IsNullOrEmpty(objectRef)) + { + // is it a reference to the id of another object in the same XML file? + objectRef = element.GetAttribute(ObjectDefinitionConstants.LocalRefAttribute); + if (StringUtils.IsNullOrEmpty(objectRef)) + { + // is it a reference to the id of another object in a parent context? + objectRef = element.GetAttribute(ObjectDefinitionConstants.ParentAttribute); + if (StringUtils.IsNullOrEmpty(objectRef)) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, + name, + "Either 'object' or 'local' is required for a reference"); + } + return new RuntimeObjectReference(objectRef, true); + } + } + return new RuntimeObjectReference(objectRef); + } + + private object GetValue(XmlElement element, string name) + { + string valueType = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + if (StringUtils.IsNullOrEmpty(valueType)) + { + return GetTextValue(element, name); + } + else + { + Type resolvedValueType = TypeResolutionUtils.ResolveType(valueType); + if (resolvedValueType == typeof(string)) + { + return GetTextValue(element, name); + } + else + { + return new TypedStringValue(GetTextValue(element, name), resolvedValueType); + } + } + } + + private object GetExpression(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) + { + string expression = element.GetAttribute(ObjectDefinitionConstants.ValueAttribute); + ExpressionHolder holder = new ExpressionHolder(expression); + holder.Properties = GetPropertyValueSubElements(name, element, parserHelper); + return holder; + } + + /// + /// Gets a list definition. + /// + /// + /// The element describing the list definition. + /// + /// + /// The name of the object (definition) associated with the list definition. + /// + /// + /// The namespace-aware parser. + /// + /// The list definition. + protected virtual IList GetList(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) + { + ManagedList list = new ManagedList(); + + string elementTypeName = element.GetAttribute("element-type"); + if (StringUtils.HasText(elementTypeName)) + { + list.ElementTypeName = elementTypeName; + } + + foreach (XmlNode node in element.ChildNodes) + { + XmlElement ele = node as XmlElement; + if (ele != null) + { + list.Add(ParsePropertySubElement(ele, name, parserHelper)); + } + } + return list; + } + + /// + /// Gets a set definition. + /// + /// + /// The element describing the set definition. + /// + /// + /// The name of the object (definition) associated with the set definition. + /// + /// + /// The namespace-aware parser. + /// + /// The set definition. + protected Set GetSet(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) + { + ManagedSet theSet = new ManagedSet(); + string elementTypeName = element.GetAttribute("element-type"); + if (StringUtils.HasText(elementTypeName)) + { + theSet.ElementTypeName = elementTypeName; + } + foreach (XmlNode node in element.ChildNodes) + { + XmlElement ele = node as XmlElement; + if (ele != null) + { + object sub = ParsePropertySubElement(ele, name, parserHelper); + theSet.Add(sub); + } + } + return theSet; + } + + /// + /// Gets a dictionary definition. + /// + /// + /// The element describing the dictionary definition. + /// + /// + /// The name of the object (definition) associated with the dictionary definition. + /// + /// + /// The namespace-aware parser. + /// + /// The dictionary definition. + protected IDictionary GetDictionary(XmlElement element, string name, ObjectDefinitionParserHelper parserHelper) + { + ManagedDictionary dictionary = new ManagedDictionary(); + string keyTypeName = element.GetAttribute("key-type"); + string valueTypeName = element.GetAttribute("value-type"); + if (StringUtils.HasText(keyTypeName)) + { + dictionary.KeyTypeName = keyTypeName; + } + if (StringUtils.HasText(valueTypeName)) + { + dictionary.ValueTypeName = valueTypeName; + } + + XmlNodeList entryElements = SelectNodes(element, ObjectDefinitionConstants.EntryElement); + foreach (XmlElement entryEle in entryElements) + { + #region Key + + object key = null; + + XmlAttribute keyAtt = entryEle.Attributes[ObjectDefinitionConstants.KeyAttribute]; + if (keyAtt != null) + { + key = keyAtt.Value; + } + else + { + // ok, we're not using the 'key' attribute; lets check for the ref shortcut... + XmlAttribute keyRefAtt = entryEle.Attributes[ObjectDefinitionConstants.DictionaryKeyRefShortcutAttribute]; + if (keyRefAtt != null) + { + key = new RuntimeObjectReference(keyRefAtt.Value); + } + else + { + // so check for the 'key' element... + XmlNode keyNode = SelectSingleNode(entryEle, ObjectDefinitionConstants.KeyElement); + if (keyNode == null) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("One of either the '{0}' element, or the the '{1}' or '{2}' attributes " + + "is required for the <{3}/> element.", + ObjectDefinitionConstants.KeyElement, + ObjectDefinitionConstants.KeyAttribute, + ObjectDefinitionConstants.DictionaryKeyRefShortcutAttribute, + ObjectDefinitionConstants.EntryElement)); + } + XmlElement keyElement = (XmlElement) keyNode; + XmlNodeList keyNodes = keyElement.GetElementsByTagName("*"); + if (keyNodes == null || keyNodes.Count == 0) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("Malformed <{0}/> element... the value of the key must be " + + "specified as a child value-style element.", + ObjectDefinitionConstants.KeyElement)); + } + key = ParsePropertySubElement((XmlElement) keyNodes.Item(0), name, parserHelper); + } + } + + #endregion + + #region Value + + XmlAttribute inlineValueAtt = entryEle.Attributes[ObjectDefinitionConstants.ValueAttribute]; + if (inlineValueAtt != null) + { + // ok, we're using the value attribute shortcut... + dictionary[key] = inlineValueAtt.Value; + } + else if (entryEle.Attributes[ObjectDefinitionConstants.DictionaryValueRefShortcutAttribute] != null) + { + // ok, we're using the value-ref attribute shortcut... + XmlAttribute inlineValueRefAtt = entryEle.Attributes[ObjectDefinitionConstants.DictionaryValueRefShortcutAttribute]; + RuntimeObjectReference ror = new RuntimeObjectReference(inlineValueRefAtt.Value); + dictionary[key] = ror; + } + else if (entryEle.Attributes[ObjectDefinitionConstants.ExpressionAttribute] != null) + { + // ok, we're using the expression attribute shortcut... + XmlAttribute inlineExpressionAtt = entryEle.Attributes[ObjectDefinitionConstants.ExpressionAttribute]; + ExpressionHolder expHolder = new ExpressionHolder(inlineExpressionAtt.Value); + dictionary[key] = expHolder; + } + else + { + XmlNode keyNode = SelectSingleNode(entryEle, ObjectDefinitionConstants.KeyElement); + if (keyNode != null) + { + entryEle.RemoveChild(keyNode); + } + // ok, we're using the original full-on value element... + XmlNodeList valueElements = entryEle.GetElementsByTagName("*"); + if (valueElements == null || valueElements.Count == 0) + { + throw new ObjectDefinitionStoreException( + parserHelper.ReaderContext.Resource, name, + string.Format("One of either the '{0}' or '{1}' attributes, or a value-style element " + + "is required for the <{2}/> element.", + ObjectDefinitionConstants.ValueAttribute, ObjectDefinitionConstants.DictionaryValueRefShortcutAttribute, ObjectDefinitionConstants.EntryElement)); + } + dictionary[key] = ParsePropertySubElement((XmlElement)valueElements.Item(0), name, parserHelper); + } + + #endregion + } + return dictionary; + } + + /// + /// Selects sub-elements with a given + /// name. + /// + /// + ///

+ /// Uses a namespace manager if necessary. + ///

+ ///
+ /// + /// The element to be searched in. + /// + /// + /// The name of the child nodes to look for. + /// + /// + /// The child s of the supplied + /// with the supplied + /// . + /// + protected XmlNodeList SelectNodes(XmlElement element, string childElementName) + { + XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable()); + nsManager.AddNamespace(GetNamespacePrefix(element), element.NamespaceURI); + return element.SelectNodes(GetNamespacePrefix(element) + ":" + childElementName, nsManager); + } + + /// + /// Selects a single sub-element with a given + /// name. + /// + /// + ///

+ /// Uses a namespace manager if necessary. + ///

+ ///
+ /// + /// The element to be searched in. + /// + /// + /// The name of the child node to look for. + /// + /// + /// The first child of the supplied + /// with the supplied + /// . + /// + protected XmlNode SelectSingleNode(XmlElement element, string childElementName) + { + XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable()); + nsManager.AddNamespace(GetNamespacePrefix(element), element.NamespaceURI); + return element.SelectSingleNode(GetNamespacePrefix(element) + ":" + childElementName, nsManager); + } + + /// + /// Gets a name value collection mapping definition. + /// + /// + /// The element describing the name value collection mapping definition. + /// + /// + /// The name of the object (definition) associated with the + /// name value collection mapping definition. + /// + /// The name value collection definition. + protected NameValueCollection GetNameValues(XmlElement element, string name) + { + NameValueCollection nvc = new NameValueCollection(); + XmlNodeList addElements = element.GetElementsByTagName(ObjectDefinitionConstants.AddElement); + foreach (XmlElement addElement in addElements) + { + string key = addElement.GetAttribute(ObjectDefinitionConstants.KeyAttribute); + string value = addElement.GetAttribute(ObjectDefinitionConstants.ValueAttribute); + string delimiters = addElement.GetAttribute(ObjectDefinitionConstants.DelimitersAttribute); + + if (StringUtils.HasText(delimiters)) + { + string[] values = value.Split(delimiters.ToCharArray()); + foreach (string v in values) + { + nvc.Add(key, v); + } + } + else + { + nvc[key] = value; + } + } + return nvc; + } + + /// + /// Returns the text of the supplied , + /// or the empty string value if said is empty. + /// + /// + ///

+ /// If the supplied is , + /// then the empty string value will be returned. + ///

+ ///
+ protected string GetTextValue(XmlElement element, string name) + { + if (element == null || StringUtils.IsNullOrEmpty(element.InnerText)) + { + return String.Empty; + } + return element.InnerText; + } + + /// + /// Strips the dependency check value out of the supplied string. + /// + /// + ///

+ /// If the supplied is an invalid dependency + /// checking mode, the invalid value will be logged and this method will + /// return the value. + /// No exception will be raised. + ///

+ ///
+ /// + /// The string containing the dependency check value. + /// + /// The dependency check value. + /// + protected DependencyCheckingMode GetDependencyCheck(string value) + { + DependencyCheckingMode code = DependencyCheckingMode.None; + if (StringUtils.HasText(value)) + { + try + { + code = (DependencyCheckingMode) Enum.Parse( + typeof(DependencyCheckingMode), value, true); + } + catch (ArgumentException ex) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format("Error while parsing dependency checking mode : '{0}' is an invalid value.", + value), ex); + } + + #endregion + } + } + return code; + } + + /// + /// Strips the autowiring mode out of the supplied string. + /// + /// + ///

+ /// If the supplied is an invalid autowiring mode, + /// the invalid value will be logged and this method will return the + /// value. No exception will be raised. + ///

+ ///
+ /// + /// The string containing the autowiring mode definition. + /// + /// The autowiring mode. + /// + protected AutoWiringMode GetAutowireMode(string value) + { + AutoWiringMode mode = AutoWiringMode.No; + if (StringUtils.HasText(value)) + { + try + { + mode = (AutoWiringMode) Enum.Parse( + typeof(AutoWiringMode), value, true); + } + catch (ArgumentException ex) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format("Error while parsing autowire mode : '{0}' is an invalid value.", + value), ex); + } + + #endregion + } + } + return mode; + } + + /// + /// Given a string containing delimited object names, returns + /// a string array split on the object name delimeter. + /// + /// + /// The string containing delimited object names. + /// + /// + /// A string array split on the object name delimeter. + /// + /// + private string[] GetObjectNames(string value) + { + return StringUtils.Split( + value, ObjectDefinitionConstants.ObjectNameDelimiters, true, true); + } + + private static bool IsTrueStringValue(string value) + { + return ObjectDefinitionConstants.TrueValue.Equals(value); + } + + private string GetNamespacePrefix(XmlElement element) + { + return StringUtils.HasText(element.Prefix) ? element.Prefix : "spring"; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/ParserContext.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/ParserContext.cs index ed05a8a7..99f1c890 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/ParserContext.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/ParserContext.cs @@ -1,128 +1,128 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Context that gets passed along an object definition parsing process, encapsulating - /// all relevant configuraiton as well as state. - /// - public class ParserContext - { - private XmlReaderContext readerContext; - - private ObjectDefinitionParserHelper parserHelper; - - private IObjectDefinition containingObjectDefinition; - - private Stack containingComponents = new Stack(); - - - /// - /// Initializes a new instance of the class. - /// - /// The reader context. - /// The parser helper. - public ParserContext(XmlReaderContext readerContext, ObjectDefinitionParserHelper parserHelper) - { - this.readerContext = readerContext; - this.parserHelper = parserHelper; - } - - - /// - /// Initializes a new instance of the class. - /// - /// The reader context. - /// The parser helper. - /// The containing object definition. - public ParserContext(XmlReaderContext readerContext, ObjectDefinitionParserHelper parserHelper, IObjectDefinition containingObjectDefinition) - { - this.readerContext = readerContext; - this.parserHelper = parserHelper; - this.containingObjectDefinition = containingObjectDefinition; - } - - - /// - /// Gets the reader context. - /// - /// The reader context. - public XmlReaderContext ReaderContext - { - get { return readerContext; } - } - - /// - /// Gets the registry. - /// - /// The registry. - public IObjectDefinitionRegistry Registry - { - get { return readerContext.Registry; } - } - - - /// - /// Gets the parser helper. - /// - /// The parser helper. - public ObjectDefinitionParserHelper ParserHelper - { - get { return parserHelper; } - } - - - /// - /// Gets the containing object definition. - /// - /// The containing object definition. - public IObjectDefinition ContainingObjectDefinition - { - get { return containingObjectDefinition; } - } - - /// - /// Gets a value indicating whether this instance is nested. - /// - /// true if this instance is nested; otherwise, false. - public bool IsNested - { - get { return containingObjectDefinition != null; } - } - - /// - /// Gets a value indicating whether this instance is default lazy init. - /// - /// - /// true if this instance is default lazy init; otherwise, false. - /// - public bool IsDefaultLazyInit - { - get { return ObjectDefinitionConstants.TrueValue.Equals(ParserHelper.Defaults.LazyInit); } - } - - - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Context that gets passed along an object definition parsing process, encapsulating + /// all relevant configuraiton as well as state. + /// + public class ParserContext + { + private XmlReaderContext readerContext; + + private ObjectDefinitionParserHelper parserHelper; + + private IObjectDefinition containingObjectDefinition; + + private Stack containingComponents = new Stack(); + + + /// + /// Initializes a new instance of the class. + /// + /// The reader context. + /// The parser helper. + public ParserContext(XmlReaderContext readerContext, ObjectDefinitionParserHelper parserHelper) + { + this.readerContext = readerContext; + this.parserHelper = parserHelper; + } + + + /// + /// Initializes a new instance of the class. + /// + /// The reader context. + /// The parser helper. + /// The containing object definition. + public ParserContext(XmlReaderContext readerContext, ObjectDefinitionParserHelper parserHelper, IObjectDefinition containingObjectDefinition) + { + this.readerContext = readerContext; + this.parserHelper = parserHelper; + this.containingObjectDefinition = containingObjectDefinition; + } + + + /// + /// Gets the reader context. + /// + /// The reader context. + public XmlReaderContext ReaderContext + { + get { return readerContext; } + } + + /// + /// Gets the registry. + /// + /// The registry. + public IObjectDefinitionRegistry Registry + { + get { return readerContext.Registry; } + } + + + /// + /// Gets the parser helper. + /// + /// The parser helper. + public ObjectDefinitionParserHelper ParserHelper + { + get { return parserHelper; } + } + + + /// + /// Gets the containing object definition. + /// + /// The containing object definition. + public IObjectDefinition ContainingObjectDefinition + { + get { return containingObjectDefinition; } + } + + /// + /// Gets a value indicating whether this instance is nested. + /// + /// true if this instance is nested; otherwise, false. + public bool IsNested + { + get { return containingObjectDefinition != null; } + } + + /// + /// Gets a value indicating whether this instance is default lazy init. + /// + /// + /// true if this instance is default lazy init; otherwise, false. + /// + public bool IsDefaultLazyInit + { + get { return ObjectDefinitionConstants.TrueValue.Equals(ParserHelper.Defaults.LazyInit); } + } + + + } +} diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionReader.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionReader.cs index b2bd456f..d10f124b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionReader.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionReader.cs @@ -1,329 +1,328 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.IO; -using System.Xml; -using System.Xml.Schema; -using Spring.Core.IO; -using Spring.Objects.Factory.Support; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Object definition reader for Spring's default XML object definition format. - /// - /// - ///

- /// Typically applied to a - /// instance. - ///

- ///

- /// This class registers each object definition with the given object factory superclass, - /// and relies on the latter's implementation of the - /// interface. - ///

- ///

- /// It supports singletons, prototypes, and references to either of these kinds of object. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: XmlObjectDefinitionReader.cs,v 1.33 2008/02/04 22:44:03 markpollack Exp $ - public class XmlObjectDefinitionReader : AbstractObjectDefinitionReader - { - #region Fields - - [NonSerialized] - private XmlResolver resolver; - - private Type documentReaderType = typeof (DefaultObjectDefinitionDocumentReader); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// instance that this reader works on. - /// - public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry) - : this(registry, new XmlUrlResolver()) - {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// instance that this reader works on. - /// - /// - /// The to be used for parsing. - /// - public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry, XmlResolver resolver) : base(registry) - { - Resolver = resolver; - } - - #endregion - - #region Properties - - /// - /// The to be used for parsing. - /// - public XmlResolver Resolver - { - get { return resolver; } - set { resolver = value; } - } - - - /// - /// Sets the IObjectDefinitionDocumentReader implementation to use, responsible for - /// the actual reading of the XML object definition document.stype of the document reader. - /// - /// The type of the document reader. - public Type DocumentReaderType - { - set - { - if (value == null || !typeof(IObjectDefinitionDocumentReader).IsAssignableFrom(value)) - { - throw new ArgumentException( - "DocumentReaderType must be an implementation of the IObjectDefinitionReader interface."); - } - documentReaderType = value; - } - } - - #endregion - - #region Methods - - /// - /// Load object definitions from the supplied XML . - /// - /// - /// The XML resource for the object definitions that are to be loaded. - /// - /// - /// The number of object definitions that were loaded. - /// - /// - /// In the case of loading or parsing errors. - /// - public override int LoadObjectDefinitions(IResource resource) - { - if (resource == null) - { - throw new ObjectDefinitionStoreException - ("Resource cannot be null: expected an XML resource."); - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Loading XML object definitions from " + resource); - } - - #endregion - - try - { - Stream stream = resource.InputStream; - if (stream == null) - { - throw new ObjectDefinitionStoreException( - "InputStream is null from Resource = [" + resource + "]"); - } - try - { - return DoLoadObjectDefinitions(stream, resource); - } - finally - { - #region Close stream - try - { - stream.Close(); - } - catch (IOException ex) - { - #region Instrumentation - - if (log.IsWarnEnabled) - { - log.Warn("Could not close stream.", ex); - } - - #endregion - } - #endregion - } - } - catch (IOException ex) - { - throw new ObjectDefinitionStoreException( - "IOException parsing XML document from " + resource.Description, ex); - } - - } - - /// - /// Actually load object definitions from the specified XML file. - /// - /// The input stream to read from. - /// The resource for the XML data. - /// - protected virtual int DoLoadObjectDefinitions(Stream stream, IResource resource) - { - try - { - XmlReader reader = null; - - if (SystemUtils.MonoRuntime) - { - reader = XmlUtils.CreateReader(stream); - } - else - { - reader = - XmlUtils.CreateValidatingReader(stream, Resolver, NamespaceParserRegistry.GetSchemas(), - new ValidationEventHandler(HandleValidation)); - } - - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Using the following XmlReader implementation : " + reader.GetType()); - } - - #endregion - - XmlDocument doc = new XmlDocument(); - doc.Load(reader); - return RegisterObjectDefinitions(doc, resource); - } - catch (XmlException ex) - { - throw new XmlObjectDefinitionStoreException(resource.Description, - "Line " + ex.LineNumber + " in XML document from " + - resource + " is invalid. " + ex.Message, ex); - } - catch (Exception ex) - { - throw new ObjectDefinitionStoreException("Unexpected exception parsing XML document from " + resource.Description + "Inner exception message= " + ex.Message, ex); - } - } - - /// - /// Validation callback for a validating XML reader. - /// - /// The source of the event. - /// Any data pertinent to the event. - private void HandleValidation(object sender, ValidationEventArgs args) - { - if (args.Severity == XmlSeverityType.Error) - { -#if !NET_1_0 - throw new XmlException(args.Message, args.Exception, args.Exception.LineNumber, args.Exception.LinePosition); -#else - throw new XmlException(args.Message, args.Exception); -#endif - } - else - { - #region Instrumentation - - if (log.IsWarnEnabled) - { - log.Warn( - "Ignored XML validation warning: " + args.Message, - args.Exception); - } - - #endregion - } - } - - /// - /// Register the object definitions contained in the given DOM document. - /// - /// The DOM document. - /// - /// The original resource from where the - /// was read. - /// - /// - /// The number of object definitions that were registered. - /// - /// - /// In case of parsing errors. - /// - public int RegisterObjectDefinitions( - XmlDocument doc, IResource resource) - { - IObjectDefinitionDocumentReader documentReader = CreateObjectDefinitionDocumentReader(); - - //TODO make void return and get object count from registry. - int countBefore = Registry.ObjectDefinitionCount; - documentReader.RegisterObjectDefinitions(doc, CreateReaderContext(resource)); - return Registry.ObjectDefinitionCount - countBefore; - } - - /// - /// Creates the to use for actually - /// reading object definitions from an XML document. - /// - /// Default implementation instantiates the specified 'documentReaderType'. - /// - protected virtual IObjectDefinitionDocumentReader CreateObjectDefinitionDocumentReader() - { - return (IObjectDefinitionDocumentReader) ObjectUtils.InstantiateType(documentReaderType); - } - - /// - /// Creates the to be passed along - /// during the object definition reading process. - /// - /// The underlying that is currently processed. - /// A new - protected virtual XmlReaderContext CreateReaderContext(IResource resource) - { - return new XmlReaderContext(resource, this); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.IO; +using System.Xml; +using System.Xml.Schema; +using Spring.Core.IO; +using Spring.Objects.Factory.Support; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Object definition reader for Spring's default XML object definition format. + /// + /// + ///

+ /// Typically applied to a + /// instance. + ///

+ ///

+ /// This class registers each object definition with the given object factory superclass, + /// and relies on the latter's implementation of the + /// interface. + ///

+ ///

+ /// It supports singletons, prototypes, and references to either of these kinds of object. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + public class XmlObjectDefinitionReader : AbstractObjectDefinitionReader + { + #region Fields + + [NonSerialized] + private XmlResolver resolver; + + private Type documentReaderType = typeof (DefaultObjectDefinitionDocumentReader); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// instance that this reader works on. + /// + public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry) + : this(registry, new XmlUrlResolver()) + {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// instance that this reader works on. + /// + /// + /// The to be used for parsing. + /// + public XmlObjectDefinitionReader(IObjectDefinitionRegistry registry, XmlResolver resolver) : base(registry) + { + Resolver = resolver; + } + + #endregion + + #region Properties + + /// + /// The to be used for parsing. + /// + public XmlResolver Resolver + { + get { return resolver; } + set { resolver = value; } + } + + + /// + /// Sets the IObjectDefinitionDocumentReader implementation to use, responsible for + /// the actual reading of the XML object definition document.stype of the document reader. + /// + /// The type of the document reader. + public Type DocumentReaderType + { + set + { + if (value == null || !typeof(IObjectDefinitionDocumentReader).IsAssignableFrom(value)) + { + throw new ArgumentException( + "DocumentReaderType must be an implementation of the IObjectDefinitionReader interface."); + } + documentReaderType = value; + } + } + + #endregion + + #region Methods + + /// + /// Load object definitions from the supplied XML . + /// + /// + /// The XML resource for the object definitions that are to be loaded. + /// + /// + /// The number of object definitions that were loaded. + /// + /// + /// In the case of loading or parsing errors. + /// + public override int LoadObjectDefinitions(IResource resource) + { + if (resource == null) + { + throw new ObjectDefinitionStoreException + ("Resource cannot be null: expected an XML resource."); + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Loading XML object definitions from " + resource); + } + + #endregion + + try + { + Stream stream = resource.InputStream; + if (stream == null) + { + throw new ObjectDefinitionStoreException( + "InputStream is null from Resource = [" + resource + "]"); + } + try + { + return DoLoadObjectDefinitions(stream, resource); + } + finally + { + #region Close stream + try + { + stream.Close(); + } + catch (IOException ex) + { + #region Instrumentation + + if (log.IsWarnEnabled) + { + log.Warn("Could not close stream.", ex); + } + + #endregion + } + #endregion + } + } + catch (IOException ex) + { + throw new ObjectDefinitionStoreException( + "IOException parsing XML document from " + resource.Description, ex); + } + + } + + /// + /// Actually load object definitions from the specified XML file. + /// + /// The input stream to read from. + /// The resource for the XML data. + /// + protected virtual int DoLoadObjectDefinitions(Stream stream, IResource resource) + { + try + { + XmlReader reader = null; + + if (SystemUtils.MonoRuntime) + { + reader = XmlUtils.CreateReader(stream); + } + else + { + reader = + XmlUtils.CreateValidatingReader(stream, Resolver, NamespaceParserRegistry.GetSchemas(), + new ValidationEventHandler(HandleValidation)); + } + + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Using the following XmlReader implementation : " + reader.GetType()); + } + + #endregion + + XmlDocument doc = new XmlDocument(); + doc.Load(reader); + return RegisterObjectDefinitions(doc, resource); + } + catch (XmlException ex) + { + throw new XmlObjectDefinitionStoreException(resource.Description, + "Line " + ex.LineNumber + " in XML document from " + + resource + " is invalid. " + ex.Message, ex); + } + catch (Exception ex) + { + throw new ObjectDefinitionStoreException("Unexpected exception parsing XML document from " + resource.Description + "Inner exception message= " + ex.Message, ex); + } + } + + /// + /// Validation callback for a validating XML reader. + /// + /// The source of the event. + /// Any data pertinent to the event. + private void HandleValidation(object sender, ValidationEventArgs args) + { + if (args.Severity == XmlSeverityType.Error) + { +#if !NET_1_0 + throw new XmlException(args.Message, args.Exception, args.Exception.LineNumber, args.Exception.LinePosition); +#else + throw new XmlException(args.Message, args.Exception); +#endif + } + else + { + #region Instrumentation + + if (log.IsWarnEnabled) + { + log.Warn( + "Ignored XML validation warning: " + args.Message, + args.Exception); + } + + #endregion + } + } + + /// + /// Register the object definitions contained in the given DOM document. + /// + /// The DOM document. + /// + /// The original resource from where the + /// was read. + /// + /// + /// The number of object definitions that were registered. + /// + /// + /// In case of parsing errors. + /// + public int RegisterObjectDefinitions( + XmlDocument doc, IResource resource) + { + IObjectDefinitionDocumentReader documentReader = CreateObjectDefinitionDocumentReader(); + + //TODO make void return and get object count from registry. + int countBefore = Registry.ObjectDefinitionCount; + documentReader.RegisterObjectDefinitions(doc, CreateReaderContext(resource)); + return Registry.ObjectDefinitionCount - countBefore; + } + + /// + /// Creates the to use for actually + /// reading object definitions from an XML document. + /// + /// Default implementation instantiates the specified 'documentReaderType'. + /// + protected virtual IObjectDefinitionDocumentReader CreateObjectDefinitionDocumentReader() + { + return (IObjectDefinitionDocumentReader) ObjectUtils.InstantiateType(documentReaderType); + } + + /// + /// Creates the to be passed along + /// during the object definition reading process. + /// + /// The underlying that is currently processed. + /// A new + protected virtual XmlReaderContext CreateReaderContext(IResource resource) + { + return new XmlReaderContext(resource, this); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionStoreException.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionStoreException.cs index 26b92f36..0afbcf4e 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionStoreException.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectDefinitionStoreException.cs @@ -1,121 +1,121 @@ - - -using System; -using System.Runtime.Serialization; -using System.Xml; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// XML-specific ObjectDefinitionStoreException subclass that wraps a XmlException, which - /// contains information about the error location. - /// - [Serializable] - public class XmlObjectDefinitionStoreException : ObjectDefinitionStoreException - { - - #region Required for Standards Compliance - /// - /// Initializes a new instance of the class. - /// - public XmlObjectDefinitionStoreException() - { - } - - /// - /// Creates a new instance of the XmlObjectDefinitionStoreException class. - /// - /// - /// A message about the exception. - /// - public XmlObjectDefinitionStoreException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the XmlObjectDefinitionStoreException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public XmlObjectDefinitionStoreException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the XmlObjectDefinitionStoreException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected XmlObjectDefinitionStoreException( - SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - #endregion - - /// - /// Initializes a new instance of the class. - /// - /// The description of the resource that the object definition came from - /// The detail message (used as exception message as-is). - /// The XmlException root cause. - public XmlObjectDefinitionStoreException(string resourceDescription, string msg, XmlException cause) - : base(resourceDescription, msg, cause) - { - - } - - /// - /// Gets the line number in the XML resource that failed. - /// - /// The line number if available (in case of a XmlException); -1 else. - public int LineNumber - { - get - { - XmlException cause = InnerException as XmlException; - if (cause != null) - { - return (cause.LineNumber); - } - else - { - return -1; - } - } - } - - /// - /// Gets the line position in the XML resource that failed. - /// - /// The line position if available (in case of a XmlException); -1 else. - public int LinePosition - { - get - { - XmlException cause = InnerException as XmlException; - if (cause != null) - { - return (cause.LinePosition); - } - else - { - return -1; - } - } - } - } + + +using System; +using System.Runtime.Serialization; +using System.Xml; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// XML-specific ObjectDefinitionStoreException subclass that wraps a XmlException, which + /// contains information about the error location. + /// + [Serializable] + public class XmlObjectDefinitionStoreException : ObjectDefinitionStoreException + { + + #region Required for Standards Compliance + /// + /// Initializes a new instance of the class. + /// + public XmlObjectDefinitionStoreException() + { + } + + /// + /// Creates a new instance of the XmlObjectDefinitionStoreException class. + /// + /// + /// A message about the exception. + /// + public XmlObjectDefinitionStoreException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the XmlObjectDefinitionStoreException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public XmlObjectDefinitionStoreException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the XmlObjectDefinitionStoreException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected XmlObjectDefinitionStoreException( + SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #endregion + + /// + /// Initializes a new instance of the class. + /// + /// The description of the resource that the object definition came from + /// The detail message (used as exception message as-is). + /// The XmlException root cause. + public XmlObjectDefinitionStoreException(string resourceDescription, string msg, XmlException cause) + : base(resourceDescription, msg, cause) + { + + } + + /// + /// Gets the line number in the XML resource that failed. + /// + /// The line number if available (in case of a XmlException); -1 else. + public int LineNumber + { + get + { + XmlException cause = InnerException as XmlException; + if (cause != null) + { + return (cause.LineNumber); + } + else + { + return -1; + } + } + } + + /// + /// Gets the line position in the XML resource that failed. + /// + /// The line position if available (in case of a XmlException); -1 else. + public int LinePosition + { + get + { + XmlException cause = InnerException as XmlException; + if (cause != null) + { + return (cause.LinePosition); + } + else + { + return -1; + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectFactory.cs index b2f25884..e918463b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlObjectFactory.cs @@ -1,150 +1,149 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Core.IO; -using Spring.Objects.Factory.Support; - -#endregion - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Convenience extension of - /// - /// that reads object definitions from an XML document or element. - /// - /// - ///

- /// Delegates to - /// - /// underneath; effectively equivalent to using a - /// for a - /// . - ///

- /// - /// objects doesn't need to be the root element of - /// the XML document: this class will parse all object definition elements in the - /// XML stream. - /// - ///

- /// This class registers each object definition with the - /// - /// superclass, and relies on the latter's implementation of the - /// interface. It supports - /// singletons, prototypes and references to either of these kinds of object. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: XmlObjectFactory.cs,v 1.13 2007/08/08 17:47:13 bbaia Exp $ - /// - [Serializable] - public class XmlObjectFactory : DefaultListableObjectFactory - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the class, - /// with the given resource, which must be parsable using DOM. - /// - /// - /// The XML resource to load object definitions from. - /// - /// - /// In the case of loading or parsing errors. - /// - public XmlObjectFactory(IResource resource) : this(resource, true, null) - { - } - - /// - /// Creates a new instance of the class, - /// with the given resource, which must be parsable using DOM. - /// - /// - /// The XML resource to load object definitions from. - /// - /// Flag specifying whether to make this object factory case sensitive or not. - /// - /// In the case of loading or parsing errors. - /// - public XmlObjectFactory(IResource resource, bool caseSensitive) : this(resource, caseSensitive, null) - { - } - - /// - /// Creates a new instance of the class, - /// with the given resource, which must be parsable using DOM, and the - /// given parent factory. - /// - /// - /// The XML resource to load object definitions from. - /// - /// The parent object factory (may be ). - /// - /// In the case of loading or parsing errors. - /// - public XmlObjectFactory( - IResource resource, IObjectFactory parentFactory) - : this(resource, true, parentFactory) - {} - - /// - /// Creates a new instance of the class, - /// with the given resource, which must be parsable using DOM, and the - /// given parent factory. - /// - /// - /// The XML resource to load object definitions from. - /// - /// Flag specifying whether to make this object factory case sensitive or not. - /// The parent object factory (may be ). - /// - /// In the case of loading or parsing errors. - /// - public XmlObjectFactory( - IResource resource, bool caseSensitive, IObjectFactory parentFactory) - : base(caseSensitive, parentFactory) - { - ObjectDefinitionReader.LoadObjectDefinitions(resource); - } - - #endregion - - #region Properties - - /// - /// Gets object definition reader to use. - /// - protected virtual IObjectDefinitionReader ObjectDefinitionReader - { - get - { - return new XmlObjectDefinitionReader(this); - } - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Core.IO; +using Spring.Objects.Factory.Support; + +#endregion + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Convenience extension of + /// + /// that reads object definitions from an XML document or element. + /// + /// + ///

+ /// Delegates to + /// + /// underneath; effectively equivalent to using a + /// for a + /// . + ///

+ /// + /// objects doesn't need to be the root element of + /// the XML document: this class will parse all object definition elements in the + /// XML stream. + /// + ///

+ /// This class registers each object definition with the + /// + /// superclass, and relies on the latter's implementation of the + /// interface. It supports + /// singletons, prototypes and references to either of these kinds of object. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + /// + [Serializable] + public class XmlObjectFactory : DefaultListableObjectFactory + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the class, + /// with the given resource, which must be parsable using DOM. + /// + /// + /// The XML resource to load object definitions from. + /// + /// + /// In the case of loading or parsing errors. + /// + public XmlObjectFactory(IResource resource) : this(resource, true, null) + { + } + + /// + /// Creates a new instance of the class, + /// with the given resource, which must be parsable using DOM. + /// + /// + /// The XML resource to load object definitions from. + /// + /// Flag specifying whether to make this object factory case sensitive or not. + /// + /// In the case of loading or parsing errors. + /// + public XmlObjectFactory(IResource resource, bool caseSensitive) : this(resource, caseSensitive, null) + { + } + + /// + /// Creates a new instance of the class, + /// with the given resource, which must be parsable using DOM, and the + /// given parent factory. + /// + /// + /// The XML resource to load object definitions from. + /// + /// The parent object factory (may be ). + /// + /// In the case of loading or parsing errors. + /// + public XmlObjectFactory( + IResource resource, IObjectFactory parentFactory) + : this(resource, true, parentFactory) + {} + + /// + /// Creates a new instance of the class, + /// with the given resource, which must be parsable using DOM, and the + /// given parent factory. + /// + /// + /// The XML resource to load object definitions from. + /// + /// Flag specifying whether to make this object factory case sensitive or not. + /// The parent object factory (may be ). + /// + /// In the case of loading or parsing errors. + /// + public XmlObjectFactory( + IResource resource, bool caseSensitive, IObjectFactory parentFactory) + : base(caseSensitive, parentFactory) + { + ObjectDefinitionReader.LoadObjectDefinitions(resource); + } + + #endregion + + #region Properties + + /// + /// Gets object definition reader to use. + /// + protected virtual IObjectDefinitionReader ObjectDefinitionReader + { + get + { + return new XmlObjectDefinitionReader(this); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlReaderContext.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlReaderContext.cs index 2cc7a2a0..27abf435 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/XmlReaderContext.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/XmlReaderContext.cs @@ -1,239 +1,238 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Xml; -using Spring.Core.IO; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Parsing; -using Spring.Objects.Factory.Support; -using Spring.Util; - -namespace Spring.Objects.Factory.Xml -{ - /// - /// Extension of specific to use with an - /// XmlObjectDefinitionReader. - /// - /// In future will contain access to IXmlParserRegistry - /// $Id: XmlReaderContext.cs,v 1.6 2007/08/27 13:57:43 oakinger Exp $ - public class XmlReaderContext : ReaderContext - { - - //TODO: Should have a ref to NamespaceParserRegistry, i.e. NamespaceHandlerResolver here.... - - private IObjectDefinitionReader reader; - - private IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory(); - - /// - /// The maximum length of any XML fragment displayed in the error message - /// reporting. - /// - /// - ///

- /// Hopefully this will display enough context so that a user - /// can pinpoint the cause of the error. - ///

- ///
- private const int MaxXmlErrorFragmentLength = 255; - - /// - /// Initializes a new instance of the class. - /// - /// The resource. - /// The reader. - public XmlReaderContext(IResource resource, IObjectDefinitionReader reader) : base(resource) - { - this.reader = reader; - - } - - - /// - /// Gets the reader. - /// - /// The reader. - public IObjectDefinitionReader Reader - { - get { return reader; } - } - - /// - /// Gets the resource loader. - /// - /// The resource loader. - public IResourceLoader ResourceLoader - { - get { return reader.ResourceLoader; } - } - - /// - /// Gets the registry. - /// - /// The registry. - public IObjectDefinitionRegistry Registry - { - get - { - return reader.Registry; - } - } - - - /// - /// Gets or sets the object definition factory. - /// - /// The object definition factory. - public IObjectDefinitionFactory ObjectDefinitionFactory - { - get { return objectDefinitionFactory; } - set { objectDefinitionFactory = value; } - } - - - - /// - /// Generates the name of the object. - /// - /// The object definition. - /// the generated object name - public string GenerateObjectName(IObjectDefinition objectDefinition) - { - return reader.ObjectNameGenerator.GenerateObjectName(objectDefinition, Registry); - } - - /// - /// Registers the name of the with generated. - /// - /// The object definition. - /// the generated object name - public string RegisterWithGeneratedName(IObjectDefinition objectDefinition) - { - string generatedName = GenerateObjectName(objectDefinition); - Registry.RegisterObjectDefinition(generatedName, objectDefinition); - return generatedName; - } - - /// - /// Reports a parse error by loading a - /// with helpful contextual - /// information and throwing said exception. - /// - /// - ///

- /// Derived classes can of course override this method in order to implement - /// validators capable of displaying a full list of errors found in the - /// definition. - ///

- ///
- /// - /// The node that triggered the parse error. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// A message about the exception. - /// - /// - /// Always throws an instance of this exception class, that will - /// contain helpful contextual infomation about the parse error. - /// - /// - public void ReportException(XmlNode node, string name, string message) - { - ReportException(node, name, message, null); - } - - /// - /// Reports a parse error by loading a - /// with helpful contextual - /// information and throwing said exception. - /// - /// - ///

- /// Derived classes can of course override this method in order to implement - /// validators capable of displaying a full list of errors found in the - /// definition. - ///

- ///
- /// - /// The node that triggered the parse error. - /// - /// - /// The name of the object that triggered the exception. - /// - /// - /// A message about the error. - /// - /// - /// The root cause of the parse error (if any - may be ). - /// - /// - /// Always throws an instance of this exception class, that will - /// contain helpful contextual infomation about the parse error. - /// - public virtual void ReportException( - XmlNode node, string name, string message, Exception cause) - { - string xmlFragment; - - if (node is XmlAttribute) - { - xmlFragment = ((XmlAttribute)node).OwnerElement.OuterXml; - } - else - { - xmlFragment = node.OuterXml; - } - if (xmlFragment.Length > MaxXmlErrorFragmentLength) - { - xmlFragment = xmlFragment.Substring(0, MaxXmlErrorFragmentLength) + "..."; - } - - string resourceDescription = Resource.Description; - int line = ConfigurationUtils.GetLineNumber(node); - if (line > 0) - { - string atLine = " at line " + line; - resourceDescription += atLine; - } - throw new ObjectDefinitionStoreException( - resourceDescription, name, message + Environment.NewLine + xmlFragment, cause); - } - - /// - /// This method can be overwritten in order to implement validators - /// capable of displaying a full list of errors found in the definition. - /// - /// - /// The node that triggered the parse error. - /// - /// - /// A message about the exception. - /// - public virtual void ReportFatalException(XmlNode node, string message) - { - throw new FatalObjectException(message); - } - - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Xml; +using Spring.Core.IO; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Parsing; +using Spring.Objects.Factory.Support; +using Spring.Util; + +namespace Spring.Objects.Factory.Xml +{ + /// + /// Extension of specific to use with an + /// XmlObjectDefinitionReader. + /// + /// In future will contain access to IXmlParserRegistry + public class XmlReaderContext : ReaderContext + { + + //TODO: Should have a ref to NamespaceParserRegistry, i.e. NamespaceHandlerResolver here.... + + private IObjectDefinitionReader reader; + + private IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory(); + + /// + /// The maximum length of any XML fragment displayed in the error message + /// reporting. + /// + /// + ///

+ /// Hopefully this will display enough context so that a user + /// can pinpoint the cause of the error. + ///

+ ///
+ private const int MaxXmlErrorFragmentLength = 255; + + /// + /// Initializes a new instance of the class. + /// + /// The resource. + /// The reader. + public XmlReaderContext(IResource resource, IObjectDefinitionReader reader) : base(resource) + { + this.reader = reader; + + } + + + /// + /// Gets the reader. + /// + /// The reader. + public IObjectDefinitionReader Reader + { + get { return reader; } + } + + /// + /// Gets the resource loader. + /// + /// The resource loader. + public IResourceLoader ResourceLoader + { + get { return reader.ResourceLoader; } + } + + /// + /// Gets the registry. + /// + /// The registry. + public IObjectDefinitionRegistry Registry + { + get + { + return reader.Registry; + } + } + + + /// + /// Gets or sets the object definition factory. + /// + /// The object definition factory. + public IObjectDefinitionFactory ObjectDefinitionFactory + { + get { return objectDefinitionFactory; } + set { objectDefinitionFactory = value; } + } + + + + /// + /// Generates the name of the object. + /// + /// The object definition. + /// the generated object name + public string GenerateObjectName(IObjectDefinition objectDefinition) + { + return reader.ObjectNameGenerator.GenerateObjectName(objectDefinition, Registry); + } + + /// + /// Registers the name of the with generated. + /// + /// The object definition. + /// the generated object name + public string RegisterWithGeneratedName(IObjectDefinition objectDefinition) + { + string generatedName = GenerateObjectName(objectDefinition); + Registry.RegisterObjectDefinition(generatedName, objectDefinition); + return generatedName; + } + + /// + /// Reports a parse error by loading a + /// with helpful contextual + /// information and throwing said exception. + /// + /// + ///

+ /// Derived classes can of course override this method in order to implement + /// validators capable of displaying a full list of errors found in the + /// definition. + ///

+ ///
+ /// + /// The node that triggered the parse error. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// A message about the exception. + /// + /// + /// Always throws an instance of this exception class, that will + /// contain helpful contextual infomation about the parse error. + /// + /// + public void ReportException(XmlNode node, string name, string message) + { + ReportException(node, name, message, null); + } + + /// + /// Reports a parse error by loading a + /// with helpful contextual + /// information and throwing said exception. + /// + /// + ///

+ /// Derived classes can of course override this method in order to implement + /// validators capable of displaying a full list of errors found in the + /// definition. + ///

+ ///
+ /// + /// The node that triggered the parse error. + /// + /// + /// The name of the object that triggered the exception. + /// + /// + /// A message about the error. + /// + /// + /// The root cause of the parse error (if any - may be ). + /// + /// + /// Always throws an instance of this exception class, that will + /// contain helpful contextual infomation about the parse error. + /// + public virtual void ReportException( + XmlNode node, string name, string message, Exception cause) + { + string xmlFragment; + + if (node is XmlAttribute) + { + xmlFragment = ((XmlAttribute)node).OwnerElement.OuterXml; + } + else + { + xmlFragment = node.OuterXml; + } + if (xmlFragment.Length > MaxXmlErrorFragmentLength) + { + xmlFragment = xmlFragment.Substring(0, MaxXmlErrorFragmentLength) + "..."; + } + + string resourceDescription = Resource.Description; + int line = ConfigurationUtils.GetLineNumber(node); + if (line > 0) + { + string atLine = " at line " + line; + resourceDescription += atLine; + } + throw new ObjectDefinitionStoreException( + resourceDescription, name, message + Environment.NewLine + xmlFragment, cause); + } + + /// + /// This method can be overwritten in order to implement validators + /// capable of displaying a full list of errors found in the definition. + /// + /// + /// The node that triggered the parse error. + /// + /// + /// A message about the exception. + /// + public virtual void ReportFatalException(XmlNode node, string message) + { + throw new FatalObjectException(message); + } + + } +} diff --git a/src/Spring/Spring.Core/Objects/FatalObjectException.cs b/src/Spring/Spring.Core/Objects/FatalObjectException.cs index d2b51009..c18ea47c 100644 --- a/src/Spring/Spring.Core/Objects/FatalObjectException.cs +++ b/src/Spring/Spring.Core/Objects/FatalObjectException.cs @@ -1,91 +1,89 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Objects -{ - /// - /// Thrown on an unrecoverable problem encountered in the - /// objects namespace or sub-namespaces, e.g. bad class or field. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: FatalObjectException.cs,v 1.7 2006/04/09 07:18:49 markpollack Exp $ - /// - [Serializable] - public class FatalObjectException : ObjectsException - { - /// - /// Creates a new instance of the FatalObjectException class. - /// - public FatalObjectException() - { - } - - /// - /// Creates a new instance of the FatalObjectException class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - public FatalObjectException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the FatalObjectException class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public FatalObjectException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the FatalObjectException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected FatalObjectException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Objects +{ + /// + /// Thrown on an unrecoverable problem encountered in the + /// objects namespace or sub-namespaces, e.g. bad class or field. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class FatalObjectException : ObjectsException + { + /// + /// Creates a new instance of the FatalObjectException class. + /// + public FatalObjectException() + { + } + + /// + /// Creates a new instance of the FatalObjectException class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + public FatalObjectException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the FatalObjectException class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public FatalObjectException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the FatalObjectException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected FatalObjectException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/IEventHandlerValue.cs b/src/Spring/Spring.Core/Objects/IEventHandlerValue.cs index 7b1ff97e..e1be1648 100644 --- a/src/Spring/Spring.Core/Objects/IEventHandlerValue.cs +++ b/src/Spring/Spring.Core/Objects/IEventHandlerValue.cs @@ -1,72 +1,71 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - - -namespace Spring.Objects -{ - /// - /// Describes an event handler. - /// - /// Rick Evans - /// $Id: IEventHandlerValue.cs,v 1.6 2006/04/09 07:18:49 markpollack Exp $ - public interface IEventHandlerValue - { - /// - /// The source of the event. - /// - object Source - { - get; - set; - } - - /// - /// The name of the method that is going to handle the event. - /// - string MethodName - { - get; - set; - } - - /// - /// The name of the event that is being wired up. - /// - string EventName - { - get; - set; - } - - /// - /// Wires up the specified handler to the named event on the - /// supplied event source. - /// - /// - /// The object (an object instance, a , etc) - /// exposing the named event. - /// - /// - /// The handler for the event (an object instance, a - /// , etc). - /// - void Wire (object source, object handler); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + + +namespace Spring.Objects +{ + /// + /// Describes an event handler. + /// + /// Rick Evans + public interface IEventHandlerValue + { + /// + /// The source of the event. + /// + object Source + { + get; + set; + } + + /// + /// The name of the method that is going to handle the event. + /// + string MethodName + { + get; + set; + } + + /// + /// The name of the event that is being wired up. + /// + string EventName + { + get; + set; + } + + /// + /// Wires up the specified handler to the named event on the + /// supplied event source. + /// + /// + /// The object (an object instance, a , etc) + /// exposing the named event. + /// + /// + /// The handler for the event (an object instance, a + /// , etc). + /// + void Wire (object source, object handler); + } +} diff --git a/src/Spring/Spring.Core/Objects/IObjectWrapper.cs b/src/Spring/Spring.Core/Objects/IObjectWrapper.cs index 3081fc97..816b6992 100644 --- a/src/Spring/Spring.Core/Objects/IObjectWrapper.cs +++ b/src/Spring/Spring.Core/Objects/IObjectWrapper.cs @@ -1,208 +1,206 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Core; - -#endregion - -namespace Spring.Objects -{ - /// - /// The central interface of Spring.NET's low-level object infrastructure. - /// - /// - ///

- /// Typically not directly used by application code but rather implicitly - /// via an . - ///

- ///

- /// Implementing classes have the ability to get and set property values - /// (individually or in bulk), get property descriptors and query the - /// readability and writability of properties. - ///

- ///

- /// This interface supports nested properties enabling the setting - /// of properties on subproperties to an unlimited depth. - ///

- ///

- /// If a property update causes an exception, a - /// will be thrown. Bulk - /// updates continue after exceptions are encountered, throwing an exception - /// wrapping all exceptions encountered during the update. - ///

- ///

- /// implementations can be used - /// repeatedly, with their "target" or wrapped object changed. - ///

- ///
- /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: IObjectWrapper.cs,v 1.15 2007/07/31 21:43:52 markpollack Exp $ - /// - public interface IObjectWrapper - { - /// - /// The object wrapped by the wrapper (cannot be ). - /// - /// - ///

- /// Implementations are required to allow the type of the wrapped - /// object to change. - ///

- ///
- /// The object wrapped by this wrapper. - object WrappedInstance { get; set; } - - /// - /// Convenience method to return the - /// of the wrapped object. - /// - /// The of the wrapped object. - Type WrappedType { get; } - - /// Get the value of a property. - /// - /// The name of the property to get the value of. May be nested. - /// - /// The value of the property. - /// - /// if the property isn't readable, or if the getting the value throws - /// an exception. - /// - object GetPropertyValue(string theProperty); - - /// - /// Get the for a particular - /// property. - /// - /// - /// The property to be retrieved. - /// - /// - /// The for the particular - /// property. - /// - PropertyInfo GetPropertyInfo(string theProperty); - - /// - /// Get the for a particular property. - /// - /// - /// The property the of which is to be retrieved. - /// - /// - /// The for a particular property.. - /// - Type GetPropertyType(string theProperty); - - /// - /// Get all of the instances for - /// all of the properties of the wrapped object. - /// - /// - /// An array of instances. - /// - PropertyInfo[] GetPropertyInfos(); - - /// - /// Set a property value. - /// - /// - ///

- /// This is the preferred way to update an individual property. - ///

- ///
- /// The new property value. - void SetPropertyValue(PropertyValue propertyValue); - - /// - /// Set a property value. - /// - /// - ///

- /// This method is provided for convenience only. The - /// - /// method is more powerful. - ///

- ///
- /// - /// The name of the property to set value of. - /// - /// The new property value. - void SetPropertyValue(string theProperty, object propertyValue); - - /// Set a number of property values in bulk. - /// - ///

- /// This is the preferred way to perform a bulk update. - ///

- ///

- /// Note that performing a bulk update differs from performing a single update, - /// in that an implementation of this class will continue to update properties - /// if a recoverable error (such as a vetoed property change or a type - /// mismatch, but not an invalid property name or the like) is - /// encountered, throwing a - /// containing - /// all the individual errors. This exception can be examined later to see all - /// binding errors. Properties that were successfully updated stay changed. - ///

- ///

- /// Does not allow the setting of unknown fields. Equivalent to - /// - /// with an argument of false for the second parameter. - ///

- ///
- /// - /// The collection of instances to - /// set on the wrapped object. - /// - void SetPropertyValues(IPropertyValues values); - - /// - /// Set a number of property values in bulk with full control over behavior. - /// - /// - ///

- /// Note that performing a bulk update differs from performing a single update, - /// in that an implementation of this class will continue to update properties - /// if a recoverable error (such as a vetoed property change or a type - /// mismatch, but not an invalid property name or the like) is - /// encountered, throwing a - /// containing - /// all the individual errors. This exception can be examined later to see all - /// binding errors. Properties that were successfully updated stay changed. - ///

- ///

Does not allow the setting of unknown fields. - ///

- ///
- /// - /// The to set on the target object - /// - /// - /// Should we ignore unknown values (not found in the object!?) - /// - void SetPropertyValues(IPropertyValues values, bool ignoreUnknown); - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Core; + +#endregion + +namespace Spring.Objects +{ + /// + /// The central interface of Spring.NET's low-level object infrastructure. + /// + /// + ///

+ /// Typically not directly used by application code but rather implicitly + /// via an . + ///

+ ///

+ /// Implementing classes have the ability to get and set property values + /// (individually or in bulk), get property descriptors and query the + /// readability and writability of properties. + ///

+ ///

+ /// This interface supports nested properties enabling the setting + /// of properties on subproperties to an unlimited depth. + ///

+ ///

+ /// If a property update causes an exception, a + /// will be thrown. Bulk + /// updates continue after exceptions are encountered, throwing an exception + /// wrapping all exceptions encountered during the update. + ///

+ ///

+ /// implementations can be used + /// repeatedly, with their "target" or wrapped object changed. + ///

+ ///
+ /// Rod Johnson + /// Mark Pollack (.NET) + public interface IObjectWrapper + { + /// + /// The object wrapped by the wrapper (cannot be ). + /// + /// + ///

+ /// Implementations are required to allow the type of the wrapped + /// object to change. + ///

+ ///
+ /// The object wrapped by this wrapper. + object WrappedInstance { get; set; } + + /// + /// Convenience method to return the + /// of the wrapped object. + /// + /// The of the wrapped object. + Type WrappedType { get; } + + /// Get the value of a property. + /// + /// The name of the property to get the value of. May be nested. + /// + /// The value of the property. + /// + /// if the property isn't readable, or if the getting the value throws + /// an exception. + /// + object GetPropertyValue(string theProperty); + + /// + /// Get the for a particular + /// property. + /// + /// + /// The property to be retrieved. + /// + /// + /// The for the particular + /// property. + /// + PropertyInfo GetPropertyInfo(string theProperty); + + /// + /// Get the for a particular property. + /// + /// + /// The property the of which is to be retrieved. + /// + /// + /// The for a particular property.. + /// + Type GetPropertyType(string theProperty); + + /// + /// Get all of the instances for + /// all of the properties of the wrapped object. + /// + /// + /// An array of instances. + /// + PropertyInfo[] GetPropertyInfos(); + + /// + /// Set a property value. + /// + /// + ///

+ /// This is the preferred way to update an individual property. + ///

+ ///
+ /// The new property value. + void SetPropertyValue(PropertyValue propertyValue); + + /// + /// Set a property value. + /// + /// + ///

+ /// This method is provided for convenience only. The + /// + /// method is more powerful. + ///

+ ///
+ /// + /// The name of the property to set value of. + /// + /// The new property value. + void SetPropertyValue(string theProperty, object propertyValue); + + /// Set a number of property values in bulk. + /// + ///

+ /// This is the preferred way to perform a bulk update. + ///

+ ///

+ /// Note that performing a bulk update differs from performing a single update, + /// in that an implementation of this class will continue to update properties + /// if a recoverable error (such as a vetoed property change or a type + /// mismatch, but not an invalid property name or the like) is + /// encountered, throwing a + /// containing + /// all the individual errors. This exception can be examined later to see all + /// binding errors. Properties that were successfully updated stay changed. + ///

+ ///

+ /// Does not allow the setting of unknown fields. Equivalent to + /// + /// with an argument of false for the second parameter. + ///

+ ///
+ /// + /// The collection of instances to + /// set on the wrapped object. + /// + void SetPropertyValues(IPropertyValues values); + + /// + /// Set a number of property values in bulk with full control over behavior. + /// + /// + ///

+ /// Note that performing a bulk update differs from performing a single update, + /// in that an implementation of this class will continue to update properties + /// if a recoverable error (such as a vetoed property change or a type + /// mismatch, but not an invalid property name or the like) is + /// encountered, throwing a + /// containing + /// all the individual errors. This exception can be examined later to see all + /// binding errors. Properties that were successfully updated stay changed. + ///

+ ///

Does not allow the setting of unknown fields. + ///

+ ///
+ /// + /// The to set on the target object + /// + /// + /// Should we ignore unknown values (not found in the object!?) + /// + void SetPropertyValues(IPropertyValues values, bool ignoreUnknown); + + } +} diff --git a/src/Spring/Spring.Core/Objects/IPropertyValues.cs b/src/Spring/Spring.Core/Objects/IPropertyValues.cs index da6e032b..daa693e4 100644 --- a/src/Spring/Spring.Core/Objects/IPropertyValues.cs +++ b/src/Spring/Spring.Core/Objects/IPropertyValues.cs @@ -1,90 +1,89 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; - -#endregion - -namespace Spring.Objects -{ - /// - /// A collection style container for - /// instances. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: IPropertyValues.cs,v 1.7 2006/04/09 07:18:49 markpollack Exp $ - public interface IPropertyValues : IEnumerable - { - /// - /// Return an array of the objects - /// held in this object. - /// - /// An array of the objects held - /// in this object. - /// - PropertyValue [] PropertyValues - { - get; - } - - /// - /// Return the instance with the - /// given name. - /// - /// The name to search for. - /// the , or null if a - /// the with the supplied - /// did not exist in this collection. - /// - PropertyValue GetPropertyValue(string propertyName); - - /// - /// Is there a instance for this - /// property name? - /// - /// The name to search for. - /// - /// True if there is a instance for - /// the supplied . - /// - bool Contains(string propertyName); - - /// - /// Return the difference (changes, additions, but not removals) of - /// property values between the supplied argument and the values - /// contained in the collection. - /// - /// - ///

- /// Subclasses should also override Equals. - ///

- ///
- /// The old property values. - /// - /// An containing any changes, or - /// an empty instance if there were - /// no changes. - /// - IPropertyValues ChangesSince (IPropertyValues old); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; + +#endregion + +namespace Spring.Objects +{ + /// + /// A collection style container for + /// instances. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + public interface IPropertyValues : IEnumerable + { + /// + /// Return an array of the objects + /// held in this object. + /// + /// An array of the objects held + /// in this object. + /// + PropertyValue [] PropertyValues + { + get; + } + + /// + /// Return the instance with the + /// given name. + /// + /// The name to search for. + /// the , or null if a + /// the with the supplied + /// did not exist in this collection. + /// + PropertyValue GetPropertyValue(string propertyName); + + /// + /// Is there a instance for this + /// property name? + /// + /// The name to search for. + /// + /// True if there is a instance for + /// the supplied . + /// + bool Contains(string propertyName); + + /// + /// Return the difference (changes, additions, but not removals) of + /// property values between the supplied argument and the values + /// contained in the collection. + /// + /// + ///

+ /// Subclasses should also override Equals. + ///

+ ///
+ /// The old property values. + /// + /// An containing any changes, or + /// an empty instance if there were + /// no changes. + /// + IPropertyValues ChangesSince (IPropertyValues old); + } +} diff --git a/src/Spring/Spring.Core/Objects/MutablePropertyValues.cs b/src/Spring/Spring.Core/Objects/MutablePropertyValues.cs index 296813f7..df757c77 100644 --- a/src/Spring/Spring.Core/Objects/MutablePropertyValues.cs +++ b/src/Spring/Spring.Core/Objects/MutablePropertyValues.cs @@ -1,348 +1,347 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Text; -using Spring.Util; - -#endregion - -namespace Spring.Objects -{ - /// - /// Default implementation of the - /// interface. - /// - /// - ///

- /// Allows simple manipulation of properties, and provides constructors to - /// support deep copy and construction from a number of collection types such as - /// and - /// . - ///

- ///
- /// Rod Johnson - /// Mark Pollack (.NET) - /// Rick Evans (.NET) - /// $Id: MutablePropertyValues.cs,v 1.15 2007/03/16 04:01:29 aseovic Exp $ - [Serializable] - public class MutablePropertyValues : IPropertyValues - { - #region Fields - - /// - /// The list of objects. - /// - private IList propertyValuesList = new ArrayList(); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// The returned instance is initially empty... - /// s can be added with the various - /// overloaded , - /// , - /// , - /// and - /// methods. - ///

- ///
- /// - /// - public MutablePropertyValues () - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Deep copy constructor. Guarantees - /// references are independent, although it can't deep copy objects currently - /// referenced by individual objects. - ///

- ///
- public MutablePropertyValues (IPropertyValues other) - { - if (other != null) - { - AddAll (other.PropertyValues); - } - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The with property values - /// keyed by property name, which must be a . - /// - public MutablePropertyValues (IDictionary map) - { - AddAll (map); - } - - #endregion - - #region Properties - - /// - /// Property to retrieve the array of property values. - /// - public PropertyValue[] PropertyValues - { - get { return (PropertyValue[]) ArrayList.Adapter (propertyValuesList).ToArray (typeof (PropertyValue)); } - } - - #endregion - - #region Methods - - /// - /// Overloaded version of Add that takes a property name and a property value. - /// - /// - /// The name of the property. - /// - /// - /// The value of the property. - /// - public void Add (string propertyName, object propertyValue) - { - Add (new PropertyValue (propertyName, propertyValue)); - } - - /// - /// Add the supplied object, - /// replacing any existing one for the respective property. - /// - /// - /// The object to add. - /// - public void Add (PropertyValue pv) - { - for (int i = 0; i < propertyValuesList.Count; ++i) - { - PropertyValue currentPv = (PropertyValue) propertyValuesList [i]; - if (currentPv.Name.Equals (pv.Name)) - { - propertyValuesList[i] = pv; - return ; - } - } - propertyValuesList.Add (pv); - } - - /// - /// Add all property values from the given - /// . - /// - /// - /// The map of property values, the keys of which must be - /// s. - /// - public void AddAll (IDictionary map) - { - if (map != null) - { - foreach (string key in map.Keys) - { - Add (new PropertyValue (key, map [key])); - } - } - } - - /// - /// Add all property values from the given - /// . - /// - /// - /// The list of s to be added. - /// - public void AddAll (IList values) - { - if (values != null) - { - foreach (PropertyValue value in values) - { - Add (value); - } - } - } - - /// - /// Remove the given , if contained. - /// - /// - /// The to remove. - /// - public void Remove (PropertyValue pv) - { - propertyValuesList.Remove (pv); - } - - /// - /// Removes the named , if contained. - /// - /// - /// The name of the property. - /// - public void Remove (string propertyName) - { - Remove (GetPropertyValue (propertyName)); - } - - /// - /// Modify a object held in this object. Indexed from 0. - /// - public void SetPropertyValueAt (PropertyValue pv, int i) - { - propertyValuesList [i] = pv; - } - - /// - /// Return the property value given the name. - /// - /// - /// The property name is checked in a case-insensitive fashion. - /// - /// - /// The name of the property. - /// - /// - /// The property value. - /// - public PropertyValue GetPropertyValue (string propertyName) - { - string propertyNameLowered = propertyName.ToLower (CultureInfo.CurrentCulture); - foreach (PropertyValue pv in propertyValuesList) - { - if (pv.Name.ToLower(CultureInfo.CurrentCulture).Equals (propertyNameLowered)) - { - return pv; - } - } - return null; - } - - /// - /// Does the container of properties contain one of this name. - /// - /// The name of the property to search for. - /// - /// True if the property is contained in this collection, false otherwise. - /// - public bool Contains (string propertyName) - { - return GetPropertyValue (propertyName) != null; - } - - /// - /// Return the difference (changes, additions, but not removals) of - /// property values between the supplied argument and the values - /// contained in the collection. - /// - /// Another property values collection. - /// - /// The collection of property values that are different than the supplied one. - /// - public IPropertyValues ChangesSince (IPropertyValues old) - { - MutablePropertyValues changes = new MutablePropertyValues (); - if (old == this) - { - return changes; - } - // for each property value in this (the newer set) - foreach (PropertyValue newProperty in propertyValuesList) - { - PropertyValue oldProperty = old.GetPropertyValue (newProperty.Name); - if (oldProperty == null) - { - // if there wasn't an old one, add it - changes.Add (newProperty); - } - else if (!oldProperty.Equals (newProperty)) - { - // it's changed - changes.Add (newProperty); - } - } - return changes; - } - - /// - /// Returns an that can iterate - /// through a collection. - /// - /// - ///

- /// The returned is the - /// exposed by the - /// - /// property. - ///

- ///
- /// - /// An that can iterate through a - /// collection. - /// - public IEnumerator GetEnumerator () - { - return PropertyValues.GetEnumerator (); - } - - // CLOVER:OFF - - /// - /// Convert the object to a string representation. - /// - /// - /// A string representation of the object. - /// - public override string ToString () - { - PropertyValue[] pvs = PropertyValues; - StringBuilder sb - = new StringBuilder ( - "MutablePropertyValues: length=").Append (pvs.Length).Append ("; "); - sb.Append (StringUtils.ArrayToDelimitedString (pvs, ",")); - return sb.ToString (); - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Text; +using Spring.Util; + +#endregion + +namespace Spring.Objects +{ + /// + /// Default implementation of the + /// interface. + /// + /// + ///

+ /// Allows simple manipulation of properties, and provides constructors to + /// support deep copy and construction from a number of collection types such as + /// and + /// . + ///

+ ///
+ /// Rod Johnson + /// Mark Pollack (.NET) + /// Rick Evans (.NET) + [Serializable] + public class MutablePropertyValues : IPropertyValues + { + #region Fields + + /// + /// The list of objects. + /// + private IList propertyValuesList = new ArrayList(); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// The returned instance is initially empty... + /// s can be added with the various + /// overloaded , + /// , + /// , + /// and + /// methods. + ///

+ ///
+ /// + /// + public MutablePropertyValues () + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Deep copy constructor. Guarantees + /// references are independent, although it can't deep copy objects currently + /// referenced by individual objects. + ///

+ ///
+ public MutablePropertyValues (IPropertyValues other) + { + if (other != null) + { + AddAll (other.PropertyValues); + } + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The with property values + /// keyed by property name, which must be a . + /// + public MutablePropertyValues (IDictionary map) + { + AddAll (map); + } + + #endregion + + #region Properties + + /// + /// Property to retrieve the array of property values. + /// + public PropertyValue[] PropertyValues + { + get { return (PropertyValue[]) ArrayList.Adapter (propertyValuesList).ToArray (typeof (PropertyValue)); } + } + + #endregion + + #region Methods + + /// + /// Overloaded version of Add that takes a property name and a property value. + /// + /// + /// The name of the property. + /// + /// + /// The value of the property. + /// + public void Add (string propertyName, object propertyValue) + { + Add (new PropertyValue (propertyName, propertyValue)); + } + + /// + /// Add the supplied object, + /// replacing any existing one for the respective property. + /// + /// + /// The object to add. + /// + public void Add (PropertyValue pv) + { + for (int i = 0; i < propertyValuesList.Count; ++i) + { + PropertyValue currentPv = (PropertyValue) propertyValuesList [i]; + if (currentPv.Name.Equals (pv.Name)) + { + propertyValuesList[i] = pv; + return ; + } + } + propertyValuesList.Add (pv); + } + + /// + /// Add all property values from the given + /// . + /// + /// + /// The map of property values, the keys of which must be + /// s. + /// + public void AddAll (IDictionary map) + { + if (map != null) + { + foreach (string key in map.Keys) + { + Add (new PropertyValue (key, map [key])); + } + } + } + + /// + /// Add all property values from the given + /// . + /// + /// + /// The list of s to be added. + /// + public void AddAll (IList values) + { + if (values != null) + { + foreach (PropertyValue value in values) + { + Add (value); + } + } + } + + /// + /// Remove the given , if contained. + /// + /// + /// The to remove. + /// + public void Remove (PropertyValue pv) + { + propertyValuesList.Remove (pv); + } + + /// + /// Removes the named , if contained. + /// + /// + /// The name of the property. + /// + public void Remove (string propertyName) + { + Remove (GetPropertyValue (propertyName)); + } + + /// + /// Modify a object held in this object. Indexed from 0. + /// + public void SetPropertyValueAt (PropertyValue pv, int i) + { + propertyValuesList [i] = pv; + } + + /// + /// Return the property value given the name. + /// + /// + /// The property name is checked in a case-insensitive fashion. + /// + /// + /// The name of the property. + /// + /// + /// The property value. + /// + public PropertyValue GetPropertyValue (string propertyName) + { + string propertyNameLowered = propertyName.ToLower (CultureInfo.CurrentCulture); + foreach (PropertyValue pv in propertyValuesList) + { + if (pv.Name.ToLower(CultureInfo.CurrentCulture).Equals (propertyNameLowered)) + { + return pv; + } + } + return null; + } + + /// + /// Does the container of properties contain one of this name. + /// + /// The name of the property to search for. + /// + /// True if the property is contained in this collection, false otherwise. + /// + public bool Contains (string propertyName) + { + return GetPropertyValue (propertyName) != null; + } + + /// + /// Return the difference (changes, additions, but not removals) of + /// property values between the supplied argument and the values + /// contained in the collection. + /// + /// Another property values collection. + /// + /// The collection of property values that are different than the supplied one. + /// + public IPropertyValues ChangesSince (IPropertyValues old) + { + MutablePropertyValues changes = new MutablePropertyValues (); + if (old == this) + { + return changes; + } + // for each property value in this (the newer set) + foreach (PropertyValue newProperty in propertyValuesList) + { + PropertyValue oldProperty = old.GetPropertyValue (newProperty.Name); + if (oldProperty == null) + { + // if there wasn't an old one, add it + changes.Add (newProperty); + } + else if (!oldProperty.Equals (newProperty)) + { + // it's changed + changes.Add (newProperty); + } + } + return changes; + } + + /// + /// Returns an that can iterate + /// through a collection. + /// + /// + ///

+ /// The returned is the + /// exposed by the + /// + /// property. + ///

+ ///
+ /// + /// An that can iterate through a + /// collection. + /// + public IEnumerator GetEnumerator () + { + return PropertyValues.GetEnumerator (); + } + + // CLOVER:OFF + + /// + /// Convert the object to a string representation. + /// + /// + /// A string representation of the object. + /// + public override string ToString () + { + PropertyValue[] pvs = PropertyValues; + StringBuilder sb + = new StringBuilder ( + "MutablePropertyValues: length=").Append (pvs.Length).Append ("; "); + sb.Append (StringUtils.ArrayToDelimitedString (pvs, ",")); + return sb.ToString (); + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/ObjectWrapper.cs b/src/Spring/Spring.Core/Objects/ObjectWrapper.cs index 53409a96..efac9e76 100644 --- a/src/Spring/Spring.Core/Objects/ObjectWrapper.cs +++ b/src/Spring/Spring.Core/Objects/ObjectWrapper.cs @@ -1,547 +1,546 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.ComponentModel; -using System.Reflection; -using System.Text; - -using antlr; -using Common.Logging; -using Spring.Core; -using Spring.Expressions; -using Spring.Util; -using StringUtils=Spring.Util.StringUtils; - -#endregion - -namespace Spring.Objects -{ - /// - /// Default implementation of the - /// interface that should be sufficient for all normal uses. - /// - /// - ///

- /// will convert - /// and array - /// values to the corresponding target arrays, if necessary. Custom - /// s that deal with - /// s or arrays can be written against a - /// comma delimited as - /// arrays are converted in such a format if the array itself is not assignable. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Jean-Pierre Pawlak - /// Mark Pollack (.NET) - /// Aleksandar Seovic(.NET) - /// $Id: ObjectWrapper.cs,v 1.72 2007/07/31 08:18:20 markpollack Exp $ - [Serializable] - public class ObjectWrapper : IObjectWrapper - { - private ILog Log = LogManager.GetLogger(typeof(ObjectWrapper)); - - #region Fields - - /// The wrapped object. - private object wrappedObject; - - /// - /// The ILog instance for this class. We'll create a lot of these objects, - /// so we don't want a new instance every time. - /// - private static readonly ILog log = LogManager.GetLogger(typeof(ObjectWrapper)); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// The wrapped target instance will need to be set afterwards. - ///

- ///
- /// - public ObjectWrapper() - {} - - /// - /// Creates a new instance of the class. - /// - /// - /// The object wrapped by this . - /// - /// - /// If the supplied is . - /// - public ObjectWrapper(object instance) - { - WrappedInstance = instance; - } - - /// - /// Creates a new instance of the class, - /// instantiating a new instance of the specified and using - /// it as the . - /// - /// - ///

- /// Please note that the passed as the - /// argument must have a no-argument constructor. - /// If it does not, an exception will be thrown when this class attempts - /// to instantiate the supplied using it's - /// (non-existent) constructor. - ///

- ///
- /// - /// The to instantiate and wrap. - /// - /// - /// If the is , or if the - /// invocation of the s default (no-arg) constructor - /// fails (due to invalid arguments, insufficient permissions, etc). - /// - public ObjectWrapper(Type type) : this(true) - { - try - { - WrappedInstance = ObjectUtils.InstantiateType(type); - } catch (FatalReflectionException e) - { - throw new FatalObjectException(e.Message, e); - } - } - - #endregion - - #region Properties - - /// - /// The object wrapped by this . - /// - /// - /// If the object cannot be changed; or an attempt is made to set the - /// value of this property to . - /// - public object WrappedInstance - { - get { return wrappedObject; } - set - { - if (value == null) - { - throw new FatalObjectException("Wraped instance cannot be null."); - } - this.wrappedObject = value; - } - } - - /// - /// Convenience method to return the of the wrapped object. - /// - /// - ///

- /// Do not use this (convenience) method prior to setting the - /// property. - ///

- ///
- /// - /// The of the wrapped object. - /// - /// - /// If the property - /// is . - /// - public Type WrappedType - { - get { return WrappedInstance.GetType(); } - } - - #endregion - - #region Methods - - /// Gets the value of a property. - /// - /// The name of the property to get the value of. - /// - /// The value of the property. - /// - /// If there is no such property, if the property isn't readable, or - /// if getting the property value throws an exception. - /// - public virtual object GetPropertyValue(string propertyName) - { - try - { - IExpression propertyExpression = GetPropertyExpression(propertyName); - return GetPropertyValue(propertyExpression); - } - catch (RecognitionException e) - { - throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); - } - catch (TokenStreamRecognitionException e) - { - throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); - } - } - - /// Gets the value of a property. - /// - /// The property expression that should be used to retrieve the property value. - /// - /// The value of the property. - /// - /// If there is no such property, if the property isn't readable, or - /// if getting the property value throws an exception. - /// - public virtual object GetPropertyValue(IExpression propertyExpression) - { - return propertyExpression.GetValue(this.wrappedObject); - } - - /// - /// Sets a property value. - /// - /// - ///

- /// This method is provided for convenience only. The - /// - /// method is more powerful. - ///

- ///
- /// - /// The name of the property to set value of. - /// - /// The new value. - public virtual void SetPropertyValue(string propertyName, object val) - { - try - { - IExpression propertyExpression = GetPropertyExpression(propertyName); - SetPropertyValue(propertyExpression, val); - } - catch (RecognitionException e) - { - throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); - } - catch (TokenStreamRecognitionException e) - { - throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); - } - } - - /// - /// Sets a property value. - /// - /// - /// The property expression that should be used to set the property value. - /// - /// The new value. - public virtual void SetPropertyValue(IExpression propertyExpression, object val) - { - propertyExpression.SetValue(this.wrappedObject, val); - } - - /// - /// Sets a property value. - /// - /// - ///

- /// This is the preferred way to update an individual property. - ///

- ///
- /// - /// The object containing new property value. - /// - public virtual void SetPropertyValue(PropertyValue pv) - { - SetPropertyValue(pv.Expression, pv.Value); - } - - /// Set a number of property values in bulk. - /// - ///

- /// Does not allow unknown fields. Equivalent to - /// - /// with and for - /// arguments. - ///

- ///
- /// - /// The to set on the target - /// object. - /// - /// - /// If an error is encountered while setting a property. - /// - /// - /// On a mismatch while setting a property, insufficient permissions, etc. - /// - /// - public virtual void SetPropertyValues(IPropertyValues pvs) - { - SetPropertyValues(pvs, false); - } - - /// - /// Perform a bulk update with full control over behavior. - /// - /// - ///

- /// This method may throw a reflection-based exception, if there is a critical - /// failure such as no matching field... less serious exceptions will be accumulated - /// and thrown as a single . - ///

- ///
- /// - /// The s to set on the target object. - /// - /// - /// Should we ignore unknown values (not found in the object!?). - /// - /// - /// If an error is encountered while setting a property (only thrown if the - /// parameter is set to ). - /// - /// - /// On a mismatch while setting a property, insufficient permissions, etc. - /// - /// - public virtual void SetPropertyValues(IPropertyValues propertyValues, bool ignoreUnknown) - { - ArrayList propertyAccessExceptions = new ArrayList(); - foreach (PropertyValue pv in propertyValues) - { - try - { - SetPropertyValue(pv); - } - catch (NotWritablePropertyException ex) - { - if (!ignoreUnknown) - { - Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); - throw; - } - } - catch (InvalidPropertyException ex) - { - if (!ignoreUnknown) - { - Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); - throw; - } - } - catch (TypeMismatchException ex) // otherwise, just ignore it and continue... - { - Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); - propertyAccessExceptions.Add(ex); - } - catch (MethodInvocationException ex) - { - Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); - propertyAccessExceptions.Add(ex); - } - catch (Exception ex) - { - Log.Error(string.Format("Failed setting property '{0}' on instance of type '{1}'", pv.Name, this.WrappedType.FullName), ex); - throw; - } - } - - // if we encountered individual exceptions, throw the composite exception... - if (propertyAccessExceptions.Count > 0) - { - throw new PropertyAccessExceptionsException(this, - (PropertyAccessException[]) propertyAccessExceptions.ToArray(typeof(PropertyAccessException))); - } - } - - /// - /// Returns PropertyInfo for the specified property - /// - /// The name of the property to search for. - /// The for the specified property. - /// If cannot be determined. - public PropertyInfo GetPropertyInfo(string propertyName) - { - return (PropertyInfo) this.GetPropertyOrFieldInfo(propertyName); - } - - /// - /// Get the for a particular property. - /// - /// - /// The property the of which is to be retrieved. - /// - /// - /// The for a particular property.. - /// - public Type GetPropertyType(string propertyName) - { - MemberInfo memberInfo = this.GetPropertyOrFieldInfo(propertyName); - switch(memberInfo.MemberType) - { - case MemberTypes.Property: - return ((PropertyInfo) memberInfo).PropertyType; - case MemberTypes.Field: - return ((FieldInfo) memberInfo).FieldType; - default: - throw new FatalObjectException("'" + propertyName + "' is not a valid property expression."); - } - } - - /// - /// Returns MemberInfo for the specified property or field - /// - /// The name of the property or field to search for. - /// The or for the specified property or field. - /// If does not resolve to a property or field. - private MemberInfo GetPropertyOrFieldInfo(string propertyOrFieldName) - { - if(StringUtils.IsNullOrEmpty(propertyOrFieldName)) - { - throw new FatalObjectException("Can't find property or field info for null or zero length property name."); - } - - try - { - IExpression propertyExpression = GetPropertyExpression(propertyOrFieldName); - if(propertyExpression is PropertyOrFieldNode) - { - return ((PropertyOrFieldNode)propertyExpression).GetMemberInfo(this.wrappedObject); - } - else if(propertyExpression is IndexerNode) - { - return ((IndexerNode)propertyExpression).GetPropertyInfo(this.wrappedObject, null); - } - else if(propertyExpression is Expression) - { - return ((Expression)propertyExpression).GetPropertyInfo(this.wrappedObject, null); - } - else - { - throw new FatalObjectException("'" + propertyOrFieldName + "' is not a valid property or field expression."); - } - } - catch(RecognitionException e) - { - throw new FatalObjectException("Failed to parse property or field name '" + propertyOrFieldName + "'.", e); - } - catch(TokenStreamRecognitionException e) - { - throw new FatalObjectException("Failed to parse property or field name '" + propertyOrFieldName + "'.", e); - } - } - - - /// - /// Get the properties of the wrapped object. - /// - /// - /// An array of s. - /// - public PropertyInfo[] GetPropertyInfos() - { - return WrappedType.GetProperties(); - } - - /// - /// Return the collection of property descriptors. - /// - public PropertyDescriptorCollection PropertyDescriptors - { - get { return TypeDescriptor.GetProperties(WrappedInstance); } - } - - /// - /// This method is expensive! Only call for diagnostics and debugging reasons, - /// not in production. - /// - /// - /// A string describing the state of this object. - /// - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - try - { - sb.Append("ObjectWrapper: wrapping class ["); - sb.Append(WrappedType.FullName); - sb.Append("]; "); - foreach (PropertyDescriptor p in PropertyDescriptors) - { - object val = GetPropertyValue(p.Name); - string valStr = (val != null) ? val.ToString() : "null"; - sb.Append(p.Name).Append("={").Append(valStr).Append("}"); - } - } - catch (Exception ex) - { - sb.Append("Exception encountered: ").Append(ex.ToString()); - } - return sb.ToString(); - } - - #endregion - - #region Helper methods - - /// - /// Attempts to parse property expression first and falls back to full expression - /// if that fails. Performance optimization. - /// - /// Property expression to parse. - /// Parsed proeprty expression. - internal static IExpression GetPropertyExpression(string propertyName) - { - IExpression propertyExpression = null; - if (propertyName.IndexOfAny(new char[] { '.', '[', '(', ' ', '{' }) < 0) - { - try - { - propertyExpression = Expression.ParseProperty(propertyName); - } - catch (Exception) - { - propertyExpression = Expression.ParsePrimary(propertyName); - } - } - else - { - propertyExpression = Expression.ParsePrimary(propertyName); - } - - return propertyExpression; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using System.Text; + +using antlr; +using Common.Logging; +using Spring.Core; +using Spring.Expressions; +using Spring.Util; +using StringUtils=Spring.Util.StringUtils; + +#endregion + +namespace Spring.Objects +{ + /// + /// Default implementation of the + /// interface that should be sufficient for all normal uses. + /// + /// + ///

+ /// will convert + /// and array + /// values to the corresponding target arrays, if necessary. Custom + /// s that deal with + /// s or arrays can be written against a + /// comma delimited as + /// arrays are converted in such a format if the array itself is not assignable. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Jean-Pierre Pawlak + /// Mark Pollack (.NET) + /// Aleksandar Seovic(.NET) + [Serializable] + public class ObjectWrapper : IObjectWrapper + { + private ILog Log = LogManager.GetLogger(typeof(ObjectWrapper)); + + #region Fields + + /// The wrapped object. + private object wrappedObject; + + /// + /// The ILog instance for this class. We'll create a lot of these objects, + /// so we don't want a new instance every time. + /// + private static readonly ILog log = LogManager.GetLogger(typeof(ObjectWrapper)); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// The wrapped target instance will need to be set afterwards. + ///

+ ///
+ /// + public ObjectWrapper() + {} + + /// + /// Creates a new instance of the class. + /// + /// + /// The object wrapped by this . + /// + /// + /// If the supplied is . + /// + public ObjectWrapper(object instance) + { + WrappedInstance = instance; + } + + /// + /// Creates a new instance of the class, + /// instantiating a new instance of the specified and using + /// it as the . + /// + /// + ///

+ /// Please note that the passed as the + /// argument must have a no-argument constructor. + /// If it does not, an exception will be thrown when this class attempts + /// to instantiate the supplied using it's + /// (non-existent) constructor. + ///

+ ///
+ /// + /// The to instantiate and wrap. + /// + /// + /// If the is , or if the + /// invocation of the s default (no-arg) constructor + /// fails (due to invalid arguments, insufficient permissions, etc). + /// + public ObjectWrapper(Type type) : this(true) + { + try + { + WrappedInstance = ObjectUtils.InstantiateType(type); + } catch (FatalReflectionException e) + { + throw new FatalObjectException(e.Message, e); + } + } + + #endregion + + #region Properties + + /// + /// The object wrapped by this . + /// + /// + /// If the object cannot be changed; or an attempt is made to set the + /// value of this property to . + /// + public object WrappedInstance + { + get { return wrappedObject; } + set + { + if (value == null) + { + throw new FatalObjectException("Wraped instance cannot be null."); + } + this.wrappedObject = value; + } + } + + /// + /// Convenience method to return the of the wrapped object. + /// + /// + ///

+ /// Do not use this (convenience) method prior to setting the + /// property. + ///

+ ///
+ /// + /// The of the wrapped object. + /// + /// + /// If the property + /// is . + /// + public Type WrappedType + { + get { return WrappedInstance.GetType(); } + } + + #endregion + + #region Methods + + /// Gets the value of a property. + /// + /// The name of the property to get the value of. + /// + /// The value of the property. + /// + /// If there is no such property, if the property isn't readable, or + /// if getting the property value throws an exception. + /// + public virtual object GetPropertyValue(string propertyName) + { + try + { + IExpression propertyExpression = GetPropertyExpression(propertyName); + return GetPropertyValue(propertyExpression); + } + catch (RecognitionException e) + { + throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); + } + catch (TokenStreamRecognitionException e) + { + throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); + } + } + + /// Gets the value of a property. + /// + /// The property expression that should be used to retrieve the property value. + /// + /// The value of the property. + /// + /// If there is no such property, if the property isn't readable, or + /// if getting the property value throws an exception. + /// + public virtual object GetPropertyValue(IExpression propertyExpression) + { + return propertyExpression.GetValue(this.wrappedObject); + } + + /// + /// Sets a property value. + /// + /// + ///

+ /// This method is provided for convenience only. The + /// + /// method is more powerful. + ///

+ ///
+ /// + /// The name of the property to set value of. + /// + /// The new value. + public virtual void SetPropertyValue(string propertyName, object val) + { + try + { + IExpression propertyExpression = GetPropertyExpression(propertyName); + SetPropertyValue(propertyExpression, val); + } + catch (RecognitionException e) + { + throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); + } + catch (TokenStreamRecognitionException e) + { + throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); + } + } + + /// + /// Sets a property value. + /// + /// + /// The property expression that should be used to set the property value. + /// + /// The new value. + public virtual void SetPropertyValue(IExpression propertyExpression, object val) + { + propertyExpression.SetValue(this.wrappedObject, val); + } + + /// + /// Sets a property value. + /// + /// + ///

+ /// This is the preferred way to update an individual property. + ///

+ ///
+ /// + /// The object containing new property value. + /// + public virtual void SetPropertyValue(PropertyValue pv) + { + SetPropertyValue(pv.Expression, pv.Value); + } + + /// Set a number of property values in bulk. + /// + ///

+ /// Does not allow unknown fields. Equivalent to + /// + /// with and for + /// arguments. + ///

+ ///
+ /// + /// The to set on the target + /// object. + /// + /// + /// If an error is encountered while setting a property. + /// + /// + /// On a mismatch while setting a property, insufficient permissions, etc. + /// + /// + public virtual void SetPropertyValues(IPropertyValues pvs) + { + SetPropertyValues(pvs, false); + } + + /// + /// Perform a bulk update with full control over behavior. + /// + /// + ///

+ /// This method may throw a reflection-based exception, if there is a critical + /// failure such as no matching field... less serious exceptions will be accumulated + /// and thrown as a single . + ///

+ ///
+ /// + /// The s to set on the target object. + /// + /// + /// Should we ignore unknown values (not found in the object!?). + /// + /// + /// If an error is encountered while setting a property (only thrown if the + /// parameter is set to ). + /// + /// + /// On a mismatch while setting a property, insufficient permissions, etc. + /// + /// + public virtual void SetPropertyValues(IPropertyValues propertyValues, bool ignoreUnknown) + { + ArrayList propertyAccessExceptions = new ArrayList(); + foreach (PropertyValue pv in propertyValues) + { + try + { + SetPropertyValue(pv); + } + catch (NotWritablePropertyException ex) + { + if (!ignoreUnknown) + { + Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); + throw; + } + } + catch (InvalidPropertyException ex) + { + if (!ignoreUnknown) + { + Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); + throw; + } + } + catch (TypeMismatchException ex) // otherwise, just ignore it and continue... + { + Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); + propertyAccessExceptions.Add(ex); + } + catch (MethodInvocationException ex) + { + Log.Error(string.Format("Failed setting property '{0}'", pv.Name), ex); + propertyAccessExceptions.Add(ex); + } + catch (Exception ex) + { + Log.Error(string.Format("Failed setting property '{0}' on instance of type '{1}'", pv.Name, this.WrappedType.FullName), ex); + throw; + } + } + + // if we encountered individual exceptions, throw the composite exception... + if (propertyAccessExceptions.Count > 0) + { + throw new PropertyAccessExceptionsException(this, + (PropertyAccessException[]) propertyAccessExceptions.ToArray(typeof(PropertyAccessException))); + } + } + + /// + /// Returns PropertyInfo for the specified property + /// + /// The name of the property to search for. + /// The for the specified property. + /// If cannot be determined. + public PropertyInfo GetPropertyInfo(string propertyName) + { + return (PropertyInfo) this.GetPropertyOrFieldInfo(propertyName); + } + + /// + /// Get the for a particular property. + /// + /// + /// The property the of which is to be retrieved. + /// + /// + /// The for a particular property.. + /// + public Type GetPropertyType(string propertyName) + { + MemberInfo memberInfo = this.GetPropertyOrFieldInfo(propertyName); + switch(memberInfo.MemberType) + { + case MemberTypes.Property: + return ((PropertyInfo) memberInfo).PropertyType; + case MemberTypes.Field: + return ((FieldInfo) memberInfo).FieldType; + default: + throw new FatalObjectException("'" + propertyName + "' is not a valid property expression."); + } + } + + /// + /// Returns MemberInfo for the specified property or field + /// + /// The name of the property or field to search for. + /// The or for the specified property or field. + /// If does not resolve to a property or field. + private MemberInfo GetPropertyOrFieldInfo(string propertyOrFieldName) + { + if(StringUtils.IsNullOrEmpty(propertyOrFieldName)) + { + throw new FatalObjectException("Can't find property or field info for null or zero length property name."); + } + + try + { + IExpression propertyExpression = GetPropertyExpression(propertyOrFieldName); + if(propertyExpression is PropertyOrFieldNode) + { + return ((PropertyOrFieldNode)propertyExpression).GetMemberInfo(this.wrappedObject); + } + else if(propertyExpression is IndexerNode) + { + return ((IndexerNode)propertyExpression).GetPropertyInfo(this.wrappedObject, null); + } + else if(propertyExpression is Expression) + { + return ((Expression)propertyExpression).GetPropertyInfo(this.wrappedObject, null); + } + else + { + throw new FatalObjectException("'" + propertyOrFieldName + "' is not a valid property or field expression."); + } + } + catch(RecognitionException e) + { + throw new FatalObjectException("Failed to parse property or field name '" + propertyOrFieldName + "'.", e); + } + catch(TokenStreamRecognitionException e) + { + throw new FatalObjectException("Failed to parse property or field name '" + propertyOrFieldName + "'.", e); + } + } + + + /// + /// Get the properties of the wrapped object. + /// + /// + /// An array of s. + /// + public PropertyInfo[] GetPropertyInfos() + { + return WrappedType.GetProperties(); + } + + /// + /// Return the collection of property descriptors. + /// + public PropertyDescriptorCollection PropertyDescriptors + { + get { return TypeDescriptor.GetProperties(WrappedInstance); } + } + + /// + /// This method is expensive! Only call for diagnostics and debugging reasons, + /// not in production. + /// + /// + /// A string describing the state of this object. + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + try + { + sb.Append("ObjectWrapper: wrapping class ["); + sb.Append(WrappedType.FullName); + sb.Append("]; "); + foreach (PropertyDescriptor p in PropertyDescriptors) + { + object val = GetPropertyValue(p.Name); + string valStr = (val != null) ? val.ToString() : "null"; + sb.Append(p.Name).Append("={").Append(valStr).Append("}"); + } + } + catch (Exception ex) + { + sb.Append("Exception encountered: ").Append(ex.ToString()); + } + return sb.ToString(); + } + + #endregion + + #region Helper methods + + /// + /// Attempts to parse property expression first and falls back to full expression + /// if that fails. Performance optimization. + /// + /// Property expression to parse. + /// Parsed proeprty expression. + internal static IExpression GetPropertyExpression(string propertyName) + { + IExpression propertyExpression = null; + if (propertyName.IndexOfAny(new char[] { '.', '[', '(', ' ', '{' }) < 0) + { + try + { + propertyExpression = Expression.ParseProperty(propertyName); + } + catch (Exception) + { + propertyExpression = Expression.ParsePrimary(propertyName); + } + } + else + { + propertyExpression = Expression.ParsePrimary(propertyName); + } + + return propertyExpression; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/ObjectsException.cs b/src/Spring/Spring.Core/Objects/ObjectsException.cs index 0e490690..b6b38592 100644 --- a/src/Spring/Spring.Core/Objects/ObjectsException.cs +++ b/src/Spring/Spring.Core/Objects/ObjectsException.cs @@ -1,89 +1,87 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Objects -{ - /// - /// Superclass for all exceptions thrown in the Objects namespace and sub-namespaces. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: ObjectsException.cs,v 1.8 2006/04/09 07:18:49 markpollack Exp $ - /// - [Serializable] - public class ObjectsException : ApplicationException - { - #region Constructor (s) / Destructor - /// Creates a new instance of the ObjectsException class. - public ObjectsException() - { - } - - /// - /// Creates a new instance of the ObjectsException class. with the specified message. - /// - /// - /// A message about the exception. - /// - public ObjectsException (string message) : base(message) - { - } - - /// - /// Creates a new instance of the ObjectsException class with the specified message - /// and root cause. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ObjectsException (string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectsException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectsException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Objects +{ + /// + /// Superclass for all exceptions thrown in the Objects namespace and sub-namespaces. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class ObjectsException : ApplicationException + { + #region Constructor (s) / Destructor + /// Creates a new instance of the ObjectsException class. + public ObjectsException() + { + } + + /// + /// Creates a new instance of the ObjectsException class. with the specified message. + /// + /// + /// A message about the exception. + /// + public ObjectsException (string message) : base(message) + { + } + + /// + /// Creates a new instance of the ObjectsException class with the specified message + /// and root cause. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ObjectsException (string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectsException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectsException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/PropertyAccessExceptionsException.cs b/src/Spring/Spring.Core/Objects/PropertyAccessExceptionsException.cs index 6de65983..3ee15e9f 100644 --- a/src/Spring/Spring.Core/Objects/PropertyAccessExceptionsException.cs +++ b/src/Spring/Spring.Core/Objects/PropertyAccessExceptionsException.cs @@ -1,259 +1,258 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; -using Spring.Core; - -#endregion - -namespace Spring.Objects -{ - /// - /// Combined exception, composed of individual binding - /// s. - /// - /// - ///

- /// An object of this class is created at the beginning of the binding - /// process, and errors added to it as necessary. - ///

- ///

- /// The binding process continues when it encounters application-level - /// s, applying those changes - /// that can be applied and storing rejected changes in an instance of this class. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: PropertyAccessExceptionsException.cs,v 1.15 2007/07/31 00:26:30 markpollack Exp $ - [Serializable] - public class PropertyAccessExceptionsException : ObjectsException - { - #region Constants - - private static PropertyAccessException[] EmptyPropertyAccessExceptions - = new PropertyAccessException[] {}; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the PropertyAccessExceptionsException class. - /// - public PropertyAccessExceptionsException() - { - } - - /// - /// Creates a new instance of the PropertyAccessExceptionsException class. - /// - /// - /// A message about the exception. - /// - public PropertyAccessExceptionsException(string message) - : base(message) - { - } - - /// - /// Creates a new instance of the PropertyAccessExceptionsException class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public PropertyAccessExceptionsException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Create new empty PropertyAccessExceptionsException. - /// We'll add errors to it as we attempt to bind properties. - /// - public PropertyAccessExceptionsException( - IObjectWrapper objectWrapper, - PropertyAccessException[] propertyAccessExceptions) - : base(string.Empty) - { - _objectWrapper = objectWrapper; - _propertyAccessExceptions - = propertyAccessExceptions == null ? - EmptyPropertyAccessExceptions : - propertyAccessExceptions; - } - - /// - /// Creates a new instance of the PropertyAccessExceptionsException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected PropertyAccessExceptionsException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - #endregion - - /// - /// Return the that generated - /// this exception. - /// - public IObjectWrapper ObjectWrapper - { - get { return _objectWrapper; } - } - - /// - /// Return the object we're binding to. - /// - public object BindObject - { - get { return ObjectWrapper.WrappedInstance; } - } - - /// - /// If this returns zero (0), no errors were encountered during binding. - /// - public int ExceptionCount - { - get { return PropertyAccessExceptions.Length; } - } - - /// - /// Return an array of the s - /// stored in this object. - /// - /// - ///

- /// Will return the empty array (not ) if there were no errors. - ///

- ///
- public virtual PropertyAccessException[] PropertyAccessExceptions - { - get { return _propertyAccessExceptions; } - } - - /// - /// Describe the group of exceptions. - /// - public override string Message - { - get - { - StringBuilder sb = new StringBuilder(); - sb.Append("PropertyAccessExceptionsException (") - .Append(ExceptionCount) - .Append(" errors)") - .Append("; nested PropertyAccessExceptions are: \n"); - for (int i = 0; i < PropertyAccessExceptions.Length; ++i) - { - PropertyAccessException pae = PropertyAccessExceptions[i]; - sb.Append("["); - sb.Append(pae.GetType().FullName); - sb.Append(": "); - sb.Append(pae.Message); - if (pae.InnerException != null) - { - sb.Append(", Inner Exception: "); - sb.Append(pae.InnerException.ToString()); - } - sb.Append(']'); - if (i < PropertyAccessExceptions.Length - 1) - { - sb.Append(", "); - } - } - return sb.ToString(); - } - } - - /// - /// Populates a with - /// the data needed to serialize the target object. - /// - /// - /// The to populate - /// with data. - /// - /// - /// The destination (see ) - /// for this serialization. - /// - [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] - public override void GetObjectData( - SerializationInfo info, StreamingContext context) - { - // TODO serialize me - base.GetObjectData(info, context); - } - - /// - /// The IObjectWrapper wrapping the target object at the root of the exception. - /// - private IObjectWrapper _objectWrapper; - - /// The list of PropertyAccessException objects. - private PropertyAccessException[] _propertyAccessExceptions - = EmptyPropertyAccessExceptions; - - /// - /// Return the - /// for the supplied , or - /// if there isn't one. - /// - public PropertyAccessException GetPropertyAccessException( - string propertyName) - { - foreach (PropertyAccessException pae in PropertyAccessExceptions) - { - if (propertyName.Equals(pae.PropertyChangeArgs.PropertyName)) - { - return pae; - } - } - return null; - } - - /// - /// Describe the number of exceptions contained in this container class. - /// - /// A description of the instance contents. - public override string ToString() - { - return Message; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Text; +using Spring.Core; + +#endregion + +namespace Spring.Objects +{ + /// + /// Combined exception, composed of individual binding + /// s. + /// + /// + ///

+ /// An object of this class is created at the beginning of the binding + /// process, and errors added to it as necessary. + ///

+ ///

+ /// The binding process continues when it encounters application-level + /// s, applying those changes + /// that can be applied and storing rejected changes in an instance of this class. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Mark Pollack (.NET) + [Serializable] + public class PropertyAccessExceptionsException : ObjectsException + { + #region Constants + + private static PropertyAccessException[] EmptyPropertyAccessExceptions + = new PropertyAccessException[] {}; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the PropertyAccessExceptionsException class. + /// + public PropertyAccessExceptionsException() + { + } + + /// + /// Creates a new instance of the PropertyAccessExceptionsException class. + /// + /// + /// A message about the exception. + /// + public PropertyAccessExceptionsException(string message) + : base(message) + { + } + + /// + /// Creates a new instance of the PropertyAccessExceptionsException class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public PropertyAccessExceptionsException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Create new empty PropertyAccessExceptionsException. + /// We'll add errors to it as we attempt to bind properties. + /// + public PropertyAccessExceptionsException( + IObjectWrapper objectWrapper, + PropertyAccessException[] propertyAccessExceptions) + : base(string.Empty) + { + _objectWrapper = objectWrapper; + _propertyAccessExceptions + = propertyAccessExceptions == null ? + EmptyPropertyAccessExceptions : + propertyAccessExceptions; + } + + /// + /// Creates a new instance of the PropertyAccessExceptionsException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected PropertyAccessExceptionsException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #endregion + + /// + /// Return the that generated + /// this exception. + /// + public IObjectWrapper ObjectWrapper + { + get { return _objectWrapper; } + } + + /// + /// Return the object we're binding to. + /// + public object BindObject + { + get { return ObjectWrapper.WrappedInstance; } + } + + /// + /// If this returns zero (0), no errors were encountered during binding. + /// + public int ExceptionCount + { + get { return PropertyAccessExceptions.Length; } + } + + /// + /// Return an array of the s + /// stored in this object. + /// + /// + ///

+ /// Will return the empty array (not ) if there were no errors. + ///

+ ///
+ public virtual PropertyAccessException[] PropertyAccessExceptions + { + get { return _propertyAccessExceptions; } + } + + /// + /// Describe the group of exceptions. + /// + public override string Message + { + get + { + StringBuilder sb = new StringBuilder(); + sb.Append("PropertyAccessExceptionsException (") + .Append(ExceptionCount) + .Append(" errors)") + .Append("; nested PropertyAccessExceptions are: \n"); + for (int i = 0; i < PropertyAccessExceptions.Length; ++i) + { + PropertyAccessException pae = PropertyAccessExceptions[i]; + sb.Append("["); + sb.Append(pae.GetType().FullName); + sb.Append(": "); + sb.Append(pae.Message); + if (pae.InnerException != null) + { + sb.Append(", Inner Exception: "); + sb.Append(pae.InnerException.ToString()); + } + sb.Append(']'); + if (i < PropertyAccessExceptions.Length - 1) + { + sb.Append(", "); + } + } + return sb.ToString(); + } + } + + /// + /// Populates a with + /// the data needed to serialize the target object. + /// + /// + /// The to populate + /// with data. + /// + /// + /// The destination (see ) + /// for this serialization. + /// + [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)] + public override void GetObjectData( + SerializationInfo info, StreamingContext context) + { + // TODO serialize me + base.GetObjectData(info, context); + } + + /// + /// The IObjectWrapper wrapping the target object at the root of the exception. + /// + private IObjectWrapper _objectWrapper; + + /// The list of PropertyAccessException objects. + private PropertyAccessException[] _propertyAccessExceptions + = EmptyPropertyAccessExceptions; + + /// + /// Return the + /// for the supplied , or + /// if there isn't one. + /// + public PropertyAccessException GetPropertyAccessException( + string propertyName) + { + foreach (PropertyAccessException pae in PropertyAccessExceptions) + { + if (propertyName.Equals(pae.PropertyChangeArgs.PropertyName)) + { + return pae; + } + } + return null; + } + + /// + /// Describe the number of exceptions contained in this container class. + /// + /// A description of the instance contents. + public override string ToString() + { + return Message; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/PropertyValue.cs b/src/Spring/Spring.Core/Objects/PropertyValue.cs index 4d013d34..104bc60d 100644 --- a/src/Spring/Spring.Core/Objects/PropertyValue.cs +++ b/src/Spring/Spring.Core/Objects/PropertyValue.cs @@ -1,199 +1,198 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; - -using antlr; -using Spring.Core; -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Objects -{ - /// - /// Holds information and value for an individual property. - /// - /// - ///

- /// Using an object here, rather than just storing all properties in a - /// map keyed by property name, allows for more flexibility, and the - /// ability to handle indexed properties in a special way if necessary. - ///

- ///

- /// Note that the value doesn't need to be the final required - /// : an - /// implementation must - /// handle any necessary conversion, as this object doesn't know anything - /// about the objects it will be applied to. - ///

- ///
- /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: PropertyValue.cs,v 1.15 2007/07/31 00:08:42 markpollack Exp $ - [Serializable] - public class PropertyValue - { - private string propertyName; - private IExpression propertyExpression; - private object propertyValue; - - /// - /// Creates a new instance of the - /// class. - /// - /// The name of the property. - /// - /// The value of the property (possibly before type conversion). - /// - /// - /// If the supplied is or - /// contains only whitespace character(s). - /// - public PropertyValue(string name, object val) - { - AssertUtils.ArgumentHasText(name, "name"); - - propertyName = name; - propertyValue = val; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The name of the property. - /// - /// The value of the property (possibly before type conversion). - /// - /// Pre-parsed property name. - /// - /// If the supplied or - /// is , or if the name contains only whitespace characters. - /// - public PropertyValue(string name, object val, IExpression expression) - { - AssertUtils.ArgumentHasText(name, "name"); - - propertyName = name; - propertyExpression = expression; - propertyValue = val; - } - - /// The name of the property. - /// The name of the property. - public string Name - { - get { return propertyName; } - } - - /// - /// Parsed property expression. - /// - public IExpression Expression - { - get - { - if (propertyExpression == null) - { - try - { - propertyExpression = ObjectWrapper.GetPropertyExpression(propertyName); - } - catch (RecognitionException e) - { - throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); - } - catch (TokenStreamRecognitionException e) - { - throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); - } - } - return propertyExpression; - } - } - - /// - /// Return the value of the property. - /// - /// - ///

- /// Note that type conversion will not have occurred here. - /// It is the responsibility of the - /// implementation to - /// perform type conversion. - ///

- ///
- /// The (possibly unresolved) value of the property. - public object Value - { - get { return propertyValue; } - } - - /// - /// Print a string representation of the property. - /// - /// A string representation of the property. - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "PropertyValue: name='{0}'; value=[{1}].", propertyName, propertyValue); - } - - /// - /// Determines whether the supplied - /// is equal to the current . - /// - /// The other instance. - /// - /// if they are equal in content. - /// - public override bool Equals(object other) - { - if (this == other) - { - return true; - } - if (!(other is PropertyValue)) - { - return false; - } - PropertyValue otherPv = (PropertyValue) other; - return - (propertyName.Equals(otherPv.propertyName) - && ((propertyValue == null && otherPv.propertyValue == null) || propertyValue.Equals(otherPv.propertyValue))); - } - - /// - /// Serves as a hash function for a particular type, suitable for use - /// in hashing algorithms and data structures like a hash table. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return propertyName.GetHashCode() * 29 + (propertyValue != null ? propertyValue.GetHashCode() : 0); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; + +using antlr; +using Spring.Core; +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Objects +{ + /// + /// Holds information and value for an individual property. + /// + /// + ///

+ /// Using an object here, rather than just storing all properties in a + /// map keyed by property name, allows for more flexibility, and the + /// ability to handle indexed properties in a special way if necessary. + ///

+ ///

+ /// Note that the value doesn't need to be the final required + /// : an + /// implementation must + /// handle any necessary conversion, as this object doesn't know anything + /// about the objects it will be applied to. + ///

+ ///
+ /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class PropertyValue + { + private string propertyName; + private IExpression propertyExpression; + private object propertyValue; + + /// + /// Creates a new instance of the + /// class. + /// + /// The name of the property. + /// + /// The value of the property (possibly before type conversion). + /// + /// + /// If the supplied is or + /// contains only whitespace character(s). + /// + public PropertyValue(string name, object val) + { + AssertUtils.ArgumentHasText(name, "name"); + + propertyName = name; + propertyValue = val; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The name of the property. + /// + /// The value of the property (possibly before type conversion). + /// + /// Pre-parsed property name. + /// + /// If the supplied or + /// is , or if the name contains only whitespace characters. + /// + public PropertyValue(string name, object val, IExpression expression) + { + AssertUtils.ArgumentHasText(name, "name"); + + propertyName = name; + propertyExpression = expression; + propertyValue = val; + } + + /// The name of the property. + /// The name of the property. + public string Name + { + get { return propertyName; } + } + + /// + /// Parsed property expression. + /// + public IExpression Expression + { + get + { + if (propertyExpression == null) + { + try + { + propertyExpression = ObjectWrapper.GetPropertyExpression(propertyName); + } + catch (RecognitionException e) + { + throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); + } + catch (TokenStreamRecognitionException e) + { + throw new InvalidPropertyException("Failed to parse property name '" + propertyName + "'.", e); + } + } + return propertyExpression; + } + } + + /// + /// Return the value of the property. + /// + /// + ///

+ /// Note that type conversion will not have occurred here. + /// It is the responsibility of the + /// implementation to + /// perform type conversion. + ///

+ ///
+ /// The (possibly unresolved) value of the property. + public object Value + { + get { return propertyValue; } + } + + /// + /// Print a string representation of the property. + /// + /// A string representation of the property. + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "PropertyValue: name='{0}'; value=[{1}].", propertyName, propertyValue); + } + + /// + /// Determines whether the supplied + /// is equal to the current . + /// + /// The other instance. + /// + /// if they are equal in content. + /// + public override bool Equals(object other) + { + if (this == other) + { + return true; + } + if (!(other is PropertyValue)) + { + return false; + } + PropertyValue otherPv = (PropertyValue) other; + return + (propertyName.Equals(otherPv.propertyName) + && ((propertyValue == null && otherPv.propertyValue == null) || propertyValue.Equals(otherPv.propertyValue))); + } + + /// + /// Serves as a hash function for a particular type, suitable for use + /// in hashing algorithms and data structures like a hash table. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return propertyName.GetHashCode() * 29 + (propertyValue != null ? propertyValue.GetHashCode() : 0); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/AbstractEventHandlerValue.cs b/src/Spring/Spring.Core/Objects/Support/AbstractEventHandlerValue.cs index feb03e9a..bbe1ba87 100644 --- a/src/Spring/Spring.Core/Objects/Support/AbstractEventHandlerValue.cs +++ b/src/Spring/Spring.Core/Objects/Support/AbstractEventHandlerValue.cs @@ -1,153 +1,152 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Globalization; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Base class implementation for classes that describe an event handler. - /// - /// Rick Evans - /// $Id: AbstractEventHandlerValue.cs,v 1.7 2006/04/09 07:19:00 markpollack Exp $ - public abstract class AbstractEventHandlerValue : IEventHandlerValue - { - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractEventHandlerValue() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object (possibly unresolved) that is exposing the event. - /// - /// - /// The name of the method on the handler that is going to handle the event. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractEventHandlerValue (object source, string methodName) - { - _source = source; - _methodName = methodName; - } - #endregion - - #region Properties - /// - /// The source of the event (may be unresolved, as in the case - /// of a - /// value). - /// - public virtual object Source - { - get - { - return _source; - } - set - { - _source = value; - } - } - - /// - /// The name of the method that is going to handle the event. - /// - public virtual string MethodName - { - get - { - return _methodName; - } - set - { - _methodName = StringUtils.HasText (value) ? value.Trim () : string.Empty; - } - } - - /// - /// The name of the event that is being wired up. - /// - public virtual string EventName - { - get - { - return _eventName; - } - set - { - _eventName = StringUtils.HasText (value) ? value.Trim () : string.Empty; - } - } - #endregion - - #region Methods - /// - /// Wires up the specified handler to the named event on the - /// supplied event source. - /// - /// - /// The object (an object instance, a , etc) - /// exposing the named event. - /// - /// - /// The handler for the event (an object instance, a - /// , etc). - /// - public abstract void Wire (object source, object handler); - - /// - /// Returns a stringified representation of this object. - /// - /// A stringified representation of this object. - public override string ToString() - { - return string.Format ( - CultureInfo.InvariantCulture, - "{0} [Source = '{1}', Method = '{2}']", GetType ().FullName, Source, MethodName); - } - #endregion - - #region Fields - private object _source; - private string _methodName; - private string _eventName; - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Globalization; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Base class implementation for classes that describe an event handler. + /// + /// Rick Evans + public abstract class AbstractEventHandlerValue : IEventHandlerValue + { + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractEventHandlerValue() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object (possibly unresolved) that is exposing the event. + /// + /// + /// The name of the method on the handler that is going to handle the event. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractEventHandlerValue (object source, string methodName) + { + _source = source; + _methodName = methodName; + } + #endregion + + #region Properties + /// + /// The source of the event (may be unresolved, as in the case + /// of a + /// value). + /// + public virtual object Source + { + get + { + return _source; + } + set + { + _source = value; + } + } + + /// + /// The name of the method that is going to handle the event. + /// + public virtual string MethodName + { + get + { + return _methodName; + } + set + { + _methodName = StringUtils.HasText (value) ? value.Trim () : string.Empty; + } + } + + /// + /// The name of the event that is being wired up. + /// + public virtual string EventName + { + get + { + return _eventName; + } + set + { + _eventName = StringUtils.HasText (value) ? value.Trim () : string.Empty; + } + } + #endregion + + #region Methods + /// + /// Wires up the specified handler to the named event on the + /// supplied event source. + /// + /// + /// The object (an object instance, a , etc) + /// exposing the named event. + /// + /// + /// The handler for the event (an object instance, a + /// , etc). + /// + public abstract void Wire (object source, object handler); + + /// + /// Returns a stringified representation of this object. + /// + /// A stringified representation of this object. + public override string ToString() + { + return string.Format ( + CultureInfo.InvariantCulture, + "{0} [Source = '{1}', Method = '{2}']", GetType ().FullName, Source, MethodName); + } + #endregion + + #region Fields + private object _source; + private string _methodName; + private string _eventName; + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Support/AbstractWiringEventHandlerValue.cs b/src/Spring/Spring.Core/Objects/Support/AbstractWiringEventHandlerValue.cs index 8a9c7146..4467ed1c 100644 --- a/src/Spring/Spring.Core/Objects/Support/AbstractWiringEventHandlerValue.cs +++ b/src/Spring/Spring.Core/Objects/Support/AbstractWiringEventHandlerValue.cs @@ -1,159 +1,158 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Base class for all - /// implemenations that actually perform event wiring. - /// - /// Rick Evans - /// $Id: AbstractWiringEventHandlerValue.cs,v 1.8 2006/04/09 07:19:00 markpollack Exp $ - public abstract class AbstractWiringEventHandlerValue : AbstractEventHandlerValue - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractWiringEventHandlerValue() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object (possibly unresolved) that is exposing the event. - /// - /// - /// The name of the method on the handler that is going to handle the event. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractWiringEventHandlerValue(object source, string methodName) - : base(source, methodName) - { - } - - #endregion - - #region Methods - - /// - /// Wires up the specified handler to the named event on the - /// supplied event source. - /// - /// - /// The object (an object instance, a , etc) - /// exposing the named event. - /// - /// - /// The handler for the event (an object instance, a - /// , etc). - /// - public override void Wire(object source, object handler) - { - Type sourceType = ReflectionUtils.TypeOfOrType(source); - EventInfo eventInfo = sourceType.GetEvent(EventName); - Delegate callback = GetHandler(handler, eventInfo); - eventInfo.AddEventHandler(source, callback); - } - - /// - /// Gets the event handler. - /// - /// - /// The instance that is registering for the event notification. - /// - /// - /// Event metadata about the event. - /// - /// - /// The event handler. - /// - protected abstract Delegate GetHandler(object instance, EventInfo info); - - /// - /// Resolves the method metadata that describes the method that is to be used - /// as the argument to a delegate constructor. - /// - /// - /// The exposing the method. - /// - /// - /// The of the delegate (e.g. System.EventHandler). - /// - /// - /// The custom binding flags to use when searching for the method. - /// - /// The method metadata. - /// - /// If the method could not be found. - /// - protected virtual MethodInfo ResolveHandlerMethod( - Type handlerType, Type delegateType, BindingFlags flags) - { - MethodInfo method = handlerType.GetMethod( - MethodName, - flags, - Type.DefaultBinder, - CallingConventions.Standard, - // cache this? for EventHandler types, we're always gonna get the same parameters - new DelegateInfo(delegateType).GetParameterTypes(), - null); - - #region Sanity Check - - if (method == null) - { - throw new FatalObjectException(string.Format( - CultureInfo.InvariantCulture, - "The '{0}' method could not be found on this object [{1}]", - MethodName, handlerType)); - } - - #endregion - - return method; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Base class for all + /// implemenations that actually perform event wiring. + /// + /// Rick Evans + public abstract class AbstractWiringEventHandlerValue : AbstractEventHandlerValue + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractWiringEventHandlerValue() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object (possibly unresolved) that is exposing the event. + /// + /// + /// The name of the method on the handler that is going to handle the event. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractWiringEventHandlerValue(object source, string methodName) + : base(source, methodName) + { + } + + #endregion + + #region Methods + + /// + /// Wires up the specified handler to the named event on the + /// supplied event source. + /// + /// + /// The object (an object instance, a , etc) + /// exposing the named event. + /// + /// + /// The handler for the event (an object instance, a + /// , etc). + /// + public override void Wire(object source, object handler) + { + Type sourceType = ReflectionUtils.TypeOfOrType(source); + EventInfo eventInfo = sourceType.GetEvent(EventName); + Delegate callback = GetHandler(handler, eventInfo); + eventInfo.AddEventHandler(source, callback); + } + + /// + /// Gets the event handler. + /// + /// + /// The instance that is registering for the event notification. + /// + /// + /// Event metadata about the event. + /// + /// + /// The event handler. + /// + protected abstract Delegate GetHandler(object instance, EventInfo info); + + /// + /// Resolves the method metadata that describes the method that is to be used + /// as the argument to a delegate constructor. + /// + /// + /// The exposing the method. + /// + /// + /// The of the delegate (e.g. System.EventHandler). + /// + /// + /// The custom binding flags to use when searching for the method. + /// + /// The method metadata. + /// + /// If the method could not be found. + /// + protected virtual MethodInfo ResolveHandlerMethod( + Type handlerType, Type delegateType, BindingFlags flags) + { + MethodInfo method = handlerType.GetMethod( + MethodName, + flags, + Type.DefaultBinder, + CallingConventions.Standard, + // cache this? for EventHandler types, we're always gonna get the same parameters + new DelegateInfo(delegateType).GetParameterTypes(), + null); + + #region Sanity Check + + if (method == null) + { + throw new FatalObjectException(string.Format( + CultureInfo.InvariantCulture, + "The '{0}' method could not be found on this object [{1}]", + MethodName, handlerType)); + } + + #endregion + + return method; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/ArgumentConvertingMethodInvoker.cs b/src/Spring/Spring.Core/Objects/Support/ArgumentConvertingMethodInvoker.cs index 4e7ab959..c525789e 100644 --- a/src/Spring/Spring.Core/Objects/Support/ArgumentConvertingMethodInvoker.cs +++ b/src/Spring/Spring.Core/Objects/Support/ArgumentConvertingMethodInvoker.cs @@ -1,120 +1,119 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; - -using Spring.Core; -using Spring.Core.TypeConversion; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Specialisation of the class that tries - /// to convert the given arguments for the actual target method via an - /// appropriate implementation. - /// - /// Juergen Hoeller - /// Rick Evans - /// $Id: ArgumentConvertingMethodInvoker.cs,v 1.10 2007/07/31 18:17:08 bbaia Exp $ - /// - public class ArgumentConvertingMethodInvoker : MethodInvoker - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public ArgumentConvertingMethodInvoker() - { - } - - #endregion - - #region Properties - - private ObjectWrapper Wrapper - { - get { return _wrapper; } - } - - #endregion - - #region Methods - - /// - /// Prepare the specified method. - /// - /// - ///

- /// The method can be invoked any number of times afterwards. - ///

- ///
- /// - /// If all required properties are not set. - /// - /// - /// If the specified method could not be found. - /// - public override void Prepare() - { - base.Prepare(); - // try to convert the arguments for the chosen method - Type[] requiredTypes = ReflectionUtils.GetParameterTypes(GetPreparedMethod()); - object[] arguments = PreparedArguments; - object[] convertedArguments = new object[arguments.Length]; - for (int i = 0; i < arguments.Length; ++i) - { - convertedArguments[i] = TypeConversionUtils.ConvertValueIfNecessary(requiredTypes[i], arguments[i], null); - } - PreparedArguments = convertedArguments; - } - - /// - /// Register the given custom - /// for all properties of the given . - /// - /// - /// The of property. - /// - /// - /// The to register. - /// - public virtual void RegisterCustomConverter( - Type requiredType, TypeConverter typeConverter) - { - TypeConverterRegistry.RegisterConverter(requiredType, typeConverter); - } - - #endregion - - #region Fields - - private readonly ObjectWrapper _wrapper = new ObjectWrapper(); - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; + +using Spring.Core; +using Spring.Core.TypeConversion; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Specialisation of the class that tries + /// to convert the given arguments for the actual target method via an + /// appropriate implementation. + /// + /// Juergen Hoeller + /// Rick Evans + /// + public class ArgumentConvertingMethodInvoker : MethodInvoker + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public ArgumentConvertingMethodInvoker() + { + } + + #endregion + + #region Properties + + private ObjectWrapper Wrapper + { + get { return _wrapper; } + } + + #endregion + + #region Methods + + /// + /// Prepare the specified method. + /// + /// + ///

+ /// The method can be invoked any number of times afterwards. + ///

+ ///
+ /// + /// If all required properties are not set. + /// + /// + /// If the specified method could not be found. + /// + public override void Prepare() + { + base.Prepare(); + // try to convert the arguments for the chosen method + Type[] requiredTypes = ReflectionUtils.GetParameterTypes(GetPreparedMethod()); + object[] arguments = PreparedArguments; + object[] convertedArguments = new object[arguments.Length]; + for (int i = 0; i < arguments.Length; ++i) + { + convertedArguments[i] = TypeConversionUtils.ConvertValueIfNecessary(requiredTypes[i], arguments[i], null); + } + PreparedArguments = convertedArguments; + } + + /// + /// Register the given custom + /// for all properties of the given . + /// + /// + /// The of property. + /// + /// + /// The to register. + /// + public virtual void RegisterCustomConverter( + Type requiredType, TypeConverter typeConverter) + { + TypeConverterRegistry.RegisterConverter(requiredType, typeConverter); + } + + #endregion + + #region Fields + + private readonly ObjectWrapper _wrapper = new ObjectWrapper(); + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/AutoWiringEventHandlerValue.cs b/src/Spring/Spring.Core/Objects/Support/AutoWiringEventHandlerValue.cs index 20df3c63..739e24e6 100644 --- a/src/Spring/Spring.Core/Objects/Support/AutoWiringEventHandlerValue.cs +++ b/src/Spring/Spring.Core/Objects/Support/AutoWiringEventHandlerValue.cs @@ -1,321 +1,320 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; -using Common.Logging; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Describes an implementation - /// that autowires events to handler methods. - /// - /// Rick Evans - /// $Id: AutoWiringEventHandlerValue.cs,v 1.11 2006/11/13 07:04:41 markpollack Exp $ - public class AutoWiringEventHandlerValue : AbstractEventHandlerValue - { - #region Constants - - private const string EventNamePlaceHolder = "${event}"; - - private const string DefaultMethodPrefix = "On"; - - private const string DefaultMethodName = DefaultMethodPrefix + EventNamePlaceHolder; - - private static readonly ILog log - = LogManager.GetLogger(typeof (AutoWiringEventHandlerValue)); - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public AutoWiringEventHandlerValue() - { - MethodName = DefaultMethodName; - } - - #endregion - - #region Properties - - /// - /// The name of the method that is going to handle the event. - /// - public override string MethodName - { - get { return base.MethodName; } - set { base.MethodName = StringUtils.HasText(value) ? value.Trim() : DefaultMethodName; } - } - - #endregion - - #region Methods - - /// - /// Wires up the specified handler to the named event on the supplied event source. - /// - /// - /// The object (an object instance, a , etc) - /// exposing the named event. - /// - /// - /// The handler for the event (an object instance, a , - /// etc). - /// - public override void Wire(object source, object handler) - { - AssertUtils.ArgumentNotNull(source, "source"); - AssertUtils.ArgumentNotNull(handler, "handler"); - // simply delegate so that after wiring, state is wiped clean... - AutoWirer wirer = new AutoWirer(source, EventName, handler, MethodName); - wirer.Wire(); - } - - #endregion - - #region Inner Class : AutoWirer - - /// - /// Performs the matching up of handler methods to one or more source events. - /// - /// - ///

- /// This class merely marshals the matching of handler methods to the events exposed - /// by an event source, and then delegates to a concrete - /// implementation (such as - /// or - /// ) to do the heavy lifting of - /// actually wiring a handler method to an event. - ///

- ///

- /// Note : the order in which handler's are wired up to events is non-deterministic. - ///

- ///
- private sealed class AutoWirer - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object exposing the event (s) being wired up. - /// - /// - /// The name of the event that is being wired up. - /// - /// - /// The object exposing the method (s) being wired to the event. - /// - /// - /// The name of the method that is going to handle the event. - /// - public AutoWirer( - object source, string eventName, object handler, string methodName) - { - Source = source; - EventName = eventName; - Handler = handler; - MethodName = methodName; - } - - #endregion - - #region Methods - - /// - /// Wires up events on the source to methods exposed on the handler. - /// - public void Wire() - { - Type sourceType = ReflectionUtils.TypeOfOrType(Source); - // create the criteria for the event search... - ICriteria criteria = new RegularExpressionEventNameCriteria(EventName); - // and grab the events that satisfy the criteria... - BindingFlags eventFlags = BindingFlags.Instance | BindingFlags.Static - | BindingFlags.Public; - MemberInfo[] events = sourceType.FindMembers( - MemberTypes.Event, - eventFlags, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - criteria); - // and for each event that satisfied the criteria... - foreach (EventInfo evt in events) - { - WireEvent(evt); - } - } - - /// - /// Wires up the supplied event to any handler methods that match the event - /// signature. - /// - /// The event being wired up. - private void WireEvent(EventInfo theEvent) - { - // grab some info (such as the delegate's method signature) about the event - DelegateInfo eventDelegate = new DelegateInfo(theEvent); - // if the method name needs to be customised on a per event basis, do so - string customMethodName = GetMethodNameCustomisedForEvent(theEvent.Name); - - // create the criteria for the handler method search... - ComposedCriteria methodCriteria = new ComposedCriteria(); - // a candidate handlers method name must match the custom method name - methodCriteria.Add(new RegularExpressionMethodNameCriteria(customMethodName)); - // the return Type of a candidate handlers method must be the same as the return type of the event - methodCriteria.Add(new MethodReturnTypeCriteria(eventDelegate.GetReturnType())); - // a candidate handlers method parameters must match the event's parameters - methodCriteria.Add(new MethodParametersCriteria(eventDelegate.GetParameterTypes())); - - // and grab the methods that satisfy the criteria... - BindingFlags methodFlags = BindingFlags.Instance | BindingFlags.Static - | BindingFlags.NonPublic | BindingFlags.Public; - MemberInfo[] methods = HandlerType.FindMembers( - MemberTypes.Method, - methodFlags, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - methodCriteria); - - // and for each method that satisfied the criteria... - foreach (MethodInfo method in methods) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format( - CultureInfo.InvariantCulture, - "Wiring up this method '{0}' to this event '{1}'", - method.Name, - theEvent.Name)); - } - - #endregion - - IEventHandlerValue myHandler = method.IsStatic ? - (IEventHandlerValue) new StaticEventHandlerValue() : - (IEventHandlerValue) new InstanceEventHandlerValue(); - myHandler.EventName = theEvent.Name; - myHandler.MethodName = method.Name; - myHandler.Wire(Source, Handler); - } - } - - /// - /// Only replaces the first occurrence of the placeholder. - /// - /// The event whose name is going to be used. - /// - /// The method name customised for the name of the supplied event. - /// - private string GetMethodNameCustomisedForEvent(string eventName) - { - string methodName = MethodName; - if (MethodName.IndexOf(EventNamePlaceHolder) >= 0) - { - methodName = MethodName.Replace(EventNamePlaceHolder, eventName); - } - return methodName; - } - - #endregion - - #region Properties - - /// - /// The object exposing the event (s) being wired up. - /// - private object Source - { - get { return _source; } - set { _source = value; } - } - - /// - /// The object exposing the method (s) being wired to an event source. - /// - private object Handler - { - get { return _handler; } - set { _handler = value; } - } - - /// - /// The of the object that is handling any events. - /// - private Type HandlerType - { - get - { - if (_handlerType == null) - { - _handlerType = ReflectionUtils.TypeOfOrType(Handler); - } - return _handlerType; - } - } - - /// - /// The name of the method that is going to handle the event. - /// - private string MethodName - { - get { return _methodName; } - set { _methodName = value; } - } - - /// - /// The name of the event that is being wired up. - /// - private string EventName - { - get { return _eventName; } - set { _eventName = value; } - } - - #endregion - - #region Fields - - private object _source; - private object _handler; - private string _methodName; - private string _eventName; - private Type _handlerType; - - #endregion - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; +using Common.Logging; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Describes an implementation + /// that autowires events to handler methods. + /// + /// Rick Evans + public class AutoWiringEventHandlerValue : AbstractEventHandlerValue + { + #region Constants + + private const string EventNamePlaceHolder = "${event}"; + + private const string DefaultMethodPrefix = "On"; + + private const string DefaultMethodName = DefaultMethodPrefix + EventNamePlaceHolder; + + private static readonly ILog log + = LogManager.GetLogger(typeof (AutoWiringEventHandlerValue)); + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public AutoWiringEventHandlerValue() + { + MethodName = DefaultMethodName; + } + + #endregion + + #region Properties + + /// + /// The name of the method that is going to handle the event. + /// + public override string MethodName + { + get { return base.MethodName; } + set { base.MethodName = StringUtils.HasText(value) ? value.Trim() : DefaultMethodName; } + } + + #endregion + + #region Methods + + /// + /// Wires up the specified handler to the named event on the supplied event source. + /// + /// + /// The object (an object instance, a , etc) + /// exposing the named event. + /// + /// + /// The handler for the event (an object instance, a , + /// etc). + /// + public override void Wire(object source, object handler) + { + AssertUtils.ArgumentNotNull(source, "source"); + AssertUtils.ArgumentNotNull(handler, "handler"); + // simply delegate so that after wiring, state is wiped clean... + AutoWirer wirer = new AutoWirer(source, EventName, handler, MethodName); + wirer.Wire(); + } + + #endregion + + #region Inner Class : AutoWirer + + /// + /// Performs the matching up of handler methods to one or more source events. + /// + /// + ///

+ /// This class merely marshals the matching of handler methods to the events exposed + /// by an event source, and then delegates to a concrete + /// implementation (such as + /// or + /// ) to do the heavy lifting of + /// actually wiring a handler method to an event. + ///

+ ///

+ /// Note : the order in which handler's are wired up to events is non-deterministic. + ///

+ ///
+ private sealed class AutoWirer + { + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object exposing the event (s) being wired up. + /// + /// + /// The name of the event that is being wired up. + /// + /// + /// The object exposing the method (s) being wired to the event. + /// + /// + /// The name of the method that is going to handle the event. + /// + public AutoWirer( + object source, string eventName, object handler, string methodName) + { + Source = source; + EventName = eventName; + Handler = handler; + MethodName = methodName; + } + + #endregion + + #region Methods + + /// + /// Wires up events on the source to methods exposed on the handler. + /// + public void Wire() + { + Type sourceType = ReflectionUtils.TypeOfOrType(Source); + // create the criteria for the event search... + ICriteria criteria = new RegularExpressionEventNameCriteria(EventName); + // and grab the events that satisfy the criteria... + BindingFlags eventFlags = BindingFlags.Instance | BindingFlags.Static + | BindingFlags.Public; + MemberInfo[] events = sourceType.FindMembers( + MemberTypes.Event, + eventFlags, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + criteria); + // and for each event that satisfied the criteria... + foreach (EventInfo evt in events) + { + WireEvent(evt); + } + } + + /// + /// Wires up the supplied event to any handler methods that match the event + /// signature. + /// + /// The event being wired up. + private void WireEvent(EventInfo theEvent) + { + // grab some info (such as the delegate's method signature) about the event + DelegateInfo eventDelegate = new DelegateInfo(theEvent); + // if the method name needs to be customised on a per event basis, do so + string customMethodName = GetMethodNameCustomisedForEvent(theEvent.Name); + + // create the criteria for the handler method search... + ComposedCriteria methodCriteria = new ComposedCriteria(); + // a candidate handlers method name must match the custom method name + methodCriteria.Add(new RegularExpressionMethodNameCriteria(customMethodName)); + // the return Type of a candidate handlers method must be the same as the return type of the event + methodCriteria.Add(new MethodReturnTypeCriteria(eventDelegate.GetReturnType())); + // a candidate handlers method parameters must match the event's parameters + methodCriteria.Add(new MethodParametersCriteria(eventDelegate.GetParameterTypes())); + + // and grab the methods that satisfy the criteria... + BindingFlags methodFlags = BindingFlags.Instance | BindingFlags.Static + | BindingFlags.NonPublic | BindingFlags.Public; + MemberInfo[] methods = HandlerType.FindMembers( + MemberTypes.Method, + methodFlags, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + methodCriteria); + + // and for each method that satisfied the criteria... + foreach (MethodInfo method in methods) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug(string.Format( + CultureInfo.InvariantCulture, + "Wiring up this method '{0}' to this event '{1}'", + method.Name, + theEvent.Name)); + } + + #endregion + + IEventHandlerValue myHandler = method.IsStatic ? + (IEventHandlerValue) new StaticEventHandlerValue() : + (IEventHandlerValue) new InstanceEventHandlerValue(); + myHandler.EventName = theEvent.Name; + myHandler.MethodName = method.Name; + myHandler.Wire(Source, Handler); + } + } + + /// + /// Only replaces the first occurrence of the placeholder. + /// + /// The event whose name is going to be used. + /// + /// The method name customised for the name of the supplied event. + /// + private string GetMethodNameCustomisedForEvent(string eventName) + { + string methodName = MethodName; + if (MethodName.IndexOf(EventNamePlaceHolder) >= 0) + { + methodName = MethodName.Replace(EventNamePlaceHolder, eventName); + } + return methodName; + } + + #endregion + + #region Properties + + /// + /// The object exposing the event (s) being wired up. + /// + private object Source + { + get { return _source; } + set { _source = value; } + } + + /// + /// The object exposing the method (s) being wired to an event source. + /// + private object Handler + { + get { return _handler; } + set { _handler = value; } + } + + /// + /// The of the object that is handling any events. + /// + private Type HandlerType + { + get + { + if (_handlerType == null) + { + _handlerType = ReflectionUtils.TypeOfOrType(Handler); + } + return _handlerType; + } + } + + /// + /// The name of the method that is going to handle the event. + /// + private string MethodName + { + get { return _methodName; } + set { _methodName = value; } + } + + /// + /// The name of the event that is being wired up. + /// + private string EventName + { + get { return _eventName; } + set { _eventName = value; } + } + + #endregion + + #region Fields + + private object _source; + private object _handler; + private string _methodName; + private string _eventName; + private Type _handlerType; + + #endregion + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/ISortDefinition.cs b/src/Spring/Spring.Core/Objects/Support/ISortDefinition.cs index c996cbba..04b31b4d 100644 --- a/src/Spring/Spring.Core/Objects/Support/ISortDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Support/ISortDefinition.cs @@ -1,66 +1,66 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Definition for sorting object instances by a property. - /// - /// Juergen Hoeller - /// Simon White (.NET) - public interface ISortDefinition - { - /// - /// The name of the property to sort by. - /// - string Property - { - get; - } - - /// - /// Whether upper and lower case in string values should be ignored. - /// - /// - /// True if the sorting should be performed in a case-insensitive fashion. - /// - bool IgnoreCase - { - get; - } - - /// - /// If the sorting should be ascending or descending. - /// - /// - /// True if the sorting should be in the ascending order. - /// - bool Ascending - { - get; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Definition for sorting object instances by a property. + /// + /// Juergen Hoeller + /// Simon White (.NET) + public interface ISortDefinition + { + /// + /// The name of the property to sort by. + /// + string Property + { + get; + } + + /// + /// Whether upper and lower case in string values should be ignored. + /// + /// + /// True if the sorting should be performed in a case-insensitive fashion. + /// + bool IgnoreCase + { + get; + } + + /// + /// If the sorting should be ascending or descending. + /// + /// + /// True if the sorting should be in the ascending order. + /// + bool Ascending + { + get; + } + } +} diff --git a/src/Spring/Spring.Core/Objects/Support/InstanceEventHandlerValue.cs b/src/Spring/Spring.Core/Objects/Support/InstanceEventHandlerValue.cs index 869bf081..1256a69d 100644 --- a/src/Spring/Spring.Core/Objects/Support/InstanceEventHandlerValue.cs +++ b/src/Spring/Spring.Core/Objects/Support/InstanceEventHandlerValue.cs @@ -1,116 +1,115 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Describes an event handler for an object instance. - /// - /// Rick Evans - /// $Id: InstanceEventHandlerValue.cs,v 1.7 2006/04/09 07:19:00 markpollack Exp $ - public class InstanceEventHandlerValue : AbstractWiringEventHandlerValue - { - #region Constants - - private static readonly BindingFlags InstanceMethodFlags = - BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.IgnoreCase | BindingFlags.Static; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public InstanceEventHandlerValue() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object (possibly unresolved) that is exposing the event. - /// - /// - /// The name of the method on the handler that is going to handle the event. - /// - public InstanceEventHandlerValue(object source, string methodName) - : base(source, methodName) - { - } - - #endregion - - #region Methods - - /// - /// Gets the event handler. - /// - /// - /// The instance that is registering for the event notification. - /// - /// - /// Event metadata about the event. - /// - /// - /// The event handler. - /// - protected override Delegate GetHandler(object instance, EventInfo info) - { - MethodInfo methodMeta = ResolveHandlerMethod( - ReflectionUtils.TypeOfOrType(instance), - info.EventHandlerType, - InstanceEventHandlerValue.InstanceMethodFlags); - Delegate callback = null; - if (methodMeta.IsStatic) - { - // case insensitive binding to a static method on an (irrelevant) instance - callback = Delegate.CreateDelegate( - info.EventHandlerType, - methodMeta); - } - else - { - // case insensitive binding to an instance method on an instance - callback = - Delegate.CreateDelegate( - info.EventHandlerType, - instance, - MethodName, - true); - } - return callback; - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Describes an event handler for an object instance. + /// + /// Rick Evans + public class InstanceEventHandlerValue : AbstractWiringEventHandlerValue + { + #region Constants + + private static readonly BindingFlags InstanceMethodFlags = + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.IgnoreCase | BindingFlags.Static; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public InstanceEventHandlerValue() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object (possibly unresolved) that is exposing the event. + /// + /// + /// The name of the method on the handler that is going to handle the event. + /// + public InstanceEventHandlerValue(object source, string methodName) + : base(source, methodName) + { + } + + #endregion + + #region Methods + + /// + /// Gets the event handler. + /// + /// + /// The instance that is registering for the event notification. + /// + /// + /// Event metadata about the event. + /// + /// + /// The event handler. + /// + protected override Delegate GetHandler(object instance, EventInfo info) + { + MethodInfo methodMeta = ResolveHandlerMethod( + ReflectionUtils.TypeOfOrType(instance), + info.EventHandlerType, + InstanceEventHandlerValue.InstanceMethodFlags); + Delegate callback = null; + if (methodMeta.IsStatic) + { + // case insensitive binding to a static method on an (irrelevant) instance + callback = Delegate.CreateDelegate( + info.EventHandlerType, + methodMeta); + } + else + { + // case insensitive binding to an instance method on an instance + callback = + Delegate.CreateDelegate( + info.EventHandlerType, + instance, + MethodName, + true); + } + return callback; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/MethodInvoker.cs b/src/Spring/Spring.Core/Objects/Support/MethodInvoker.cs index e35523ed..41cc3550 100644 --- a/src/Spring/Spring.Core/Objects/Support/MethodInvoker.cs +++ b/src/Spring/Spring.Core/Objects/Support/MethodInvoker.cs @@ -1,555 +1,554 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Reflection; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Objects; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Helper class allowing one to declaratively specify a method call for later invocation. - /// - /// - ///

- /// Typically not used directly but via its subclasses such as - /// . - ///

- ///

- /// Usage: specify either the and - /// or the - /// and - /// properties respectively, and - /// (optionally) any arguments to the method. Then call the - /// method to prepare the invoker. - /// Once prepared, the invoker can be invoked any number of times. - ///

- ///
- /// - ///

- /// The following example uses the class to invoke the - /// ToString() method on the Foo class using a mixture of both named and unnamed - /// arguments. - ///

- /// - /// public class Foo - /// { - /// public string ToString(string name, int age, string address) - /// { - /// return string.Format("{0}, {1} years old, {2}", name, age, address); - /// } - /// - /// public static void Main() - /// { - /// Foo foo = new Foo(); - /// MethodInvoker invoker = new MethodInvoker(); - /// invoker.Arguments = new object [] {"Kaneda", "18 Kaosu Gardens, Nakatani Drive, Okinanawa"}; - /// invoker.AddNamedArgument("age", 29); - /// invoker.Prepare(); - /// // at this point, the arguments that will be passed to the method invocation - /// // will have been resolved into the following ordered array : {"Kaneda", 29, "18 Kaosu Gardens, Nakatani Drive, Okinanawa"} - /// string details = (string) invoker.Invoke(); - /// Console.WriteLine (details); - /// // will print out 'Kaneda, 29 years old, 18 Kaosu Gardens, Nakatani Drive, Okinanawa' - /// } - /// } - /// - ///
- /// Colin Sampaleanu - /// Juergen Hoeller - /// Simon White (.NET) - /// $Id: MethodInvoker.cs,v 1.7 2007/08/04 01:05:15 bbaia Exp $ - public class MethodInvoker - { - #region Fields - - /// - /// The value returned from the invocation of a method that returns void. - /// - public static readonly Missing Void = Missing.Value; - - private Type _targetType; - private object _targetObject; - private string _targetMethod; - private object[] _arguments; - private IDictionary _namedArguments; - private object[] _preparedArguments; - - /// - /// The method that will be invoked. - /// - private MethodInfo _methodObject; - - /// - /// The used to search for - /// the method to be invoked. - /// - private const BindingFlags MethodSearchingFlags = - BindingFlags.Instance | - BindingFlags.Static | - BindingFlags.Public | - BindingFlags.NonPublic | - BindingFlags.IgnoreCase; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the class. - /// - public MethodInvoker() - { - Arguments = new object[] {}; - NamedArguments = new Hashtable(); - PreparedArguments = new object[] {}; - } - - #endregion - - #region Properties - - /// - /// The target on which to call the target method. - /// - /// - ///

- /// Only necessary when the target method is ; - /// else, a target object needs to be specified. - ///

- ///
- public Type TargetType - { - get { return _targetType; } - set { this._targetType = value; } - } - - /// - /// The target object on which to call the target method. - /// - /// - ///

- /// Only necessary when the target method is not ; - /// else, a target class is sufficient. - ///

- ///
- public object TargetObject - { - get { return _targetObject; } - set { this._targetObject = value; } - } - - /// - /// The name of the method to be invoked. - /// - /// - ///

- /// Refers to either a method - /// or a non- method, depending on - /// whether or not a target object has been set. - ///

- ///
- /// - public string TargetMethod - { - get { return _targetMethod; } - set { this._targetMethod = value; } - } - - /// - /// Arguments for the method invocation. - /// - /// - ///

- /// Ordering is significant... the order of the arguments in this - /// property must match the ordering of the various parameters on the target - /// method. There does however exist a small possibility for confusion when - /// the arguments in this property are supplied in addition to one or more named - /// arguments. In this case, each named argument is slotted into the index position - /// corresponding to the named argument... once once all named arguments have been - /// resolved, the arguments in this property are slotted into any remaining (empty) - /// slots in the method parameter list (see the example in the overview of the - /// class if this is not clear). - ///

- ///

- /// If this property is not set, or the value passed to the setter invocation - /// is or a zero-length array, a method with no (un-named) arguments is assumed. - ///

- ///
- /// - public object[] Arguments - { - get { return _arguments; } - set - { - if (value != null) - { - this._arguments = value; - } - else - { - this._arguments = new object[] {}; - } - } - } - - /// - /// The resolved arguments for the method invocation. - /// - /// - /// - /// This property is not set until the target method has been resolved via a call to the - /// method). It is a combination of the - /// named and plain vanilla arguments properties, and it is this object array that - /// will actually be passed to the invocation of the target method. - /// - ///

- /// Setting the value of this property to results in basically clearing out any - /// previously prepared arguments... another call to the - /// method will then be required to prepare the arguments again (or the prepared arguments - /// can be set explicitly if so desired). - ///

- ///
- /// - /// - protected object[] PreparedArguments - { - get { return _preparedArguments; } - set - { - if (value != null) - { - this._preparedArguments = value; - } - else - { - this._preparedArguments = new object[] {}; - } - } - } - - /// - /// Named arguments for the method invocation. - /// - /// - ///

- /// The keys of this dictionary are the () names of the - /// method arguments, and the () values are the actual - /// argument values themselves. - ///

- ///

- /// If this property is not set, or the value passed to the setter invocation - /// is a reference, a method with no named arguments is assumed. - ///

- ///
- /// - public IDictionary NamedArguments - { - get { return _namedArguments; } - set - { - if (value != null) - { - this._namedArguments = value; - } - else - { - this._namedArguments.Clear(); - } - } - } - - #endregion - - #region Methods - - /// - /// Prepare the specified method. - /// - /// - ///

- /// The method can be invoked any number of times afterwards. - ///

- ///
- /// - /// If all required properties are not set, or a matching argument could not be found - /// for a named argument (typically down to a typo). - /// - /// - /// If the specified method could not be found. - /// - public virtual void Prepare() - { - if (_targetMethod == null) - { - throw new ArgumentException("The 'TargetMethod' property is required."); - } - if (_targetType == null && _targetObject == null) - { - throw new ArgumentException("One of either the 'TargetType' or 'TargetObject' properties is required."); - } - _methodObject = FindTheMethodToInvoke(); - if (TargetObject == null && !_methodObject.IsStatic) - { - throw new ArgumentException( - "The target method cannot be an instance method without a corresponding target instance on which to invoke it."); - } - PrepareArguments(); - } - - private void PrepareArguments() - { - _preparedArguments = new object[ArgumentCount]; - // ok, lets prepare any named arguments first... - if (NamedArguments.Count > 0) - { - // lets slot in all of the named arguments first... - ParameterInfo[] parameters = _methodObject.GetParameters(); - // lets figure out the index og each of the method parameters... - IDictionary argumentNamesToIndexes = new Hashtable(); - for (int i = 0; i < parameters.Length; ++i) - { - ParameterInfo parameter = parameters[i]; - argumentNamesToIndexes[parameter.Name.ToLower(CultureInfo.InvariantCulture)] = i; - } - int THE_ARGUMENT_IS_PREPARED = -12; - foreach (DictionaryEntry namedArgument in NamedArguments) - { - string argumentName = ((string) namedArgument.Key).ToLower(CultureInfo.InvariantCulture); - object argumentValue = namedArgument.Value; - if (!argumentNamesToIndexes.Contains(argumentName)) - { - // whoa (Nelly); the named argument does not exist on the method... - throw new ArgumentException(string.Format( - CultureInfo.InvariantCulture, - "The named argument '{0}' could not be found on the '{1}' method of class [{2}].", - argumentName, _methodObject.Name, _methodObject.DeclaringType.FullName)); - - } - // look up the index of where in the prepared args array we're gonna stick the named argument value - int namedArgumentsIndex = (int) argumentNamesToIndexes[argumentName]; - PreparedArguments[namedArgumentsIndex] = argumentValue; - // we've prepped this index position, so mark it as so... - argumentNamesToIndexes[argumentName] = THE_ARGUMENT_IS_PREPARED; - } - // and then fill in any remaining blanks with the plain vanilla arguments... - int plainVanillaIndex = 0; - int[] sortedIndexes = (int[]) new ArrayList(argumentNamesToIndexes.Values).ToArray(typeof (int)); - Array.Sort(sortedIndexes); - foreach (int argumentIndex in sortedIndexes) - { - // have we previously prepped a named argument at this index position? - if (argumentIndex == THE_ARGUMENT_IS_PREPARED) - { - continue; - } - // lets stick a plain vanilla argument in at this index position (in the order that they have been supplied)... - PreparedArguments[argumentIndex] = Arguments[plainVanillaIndex++]; - } - } - else - { - PreparedArguments = Arguments; - } - } - - /// - /// Searches for and returns the method that is to be invoked. - /// - /// - /// The return value of this method call will subsequently be returned from the - /// . - /// - /// The method that is to be invoked. - /// - /// If no method could be found. - /// - /// - /// If more than one method was found. - /// - protected virtual MethodInfo FindTheMethodToInvoke() - { - MethodInfo theMethod = null; - Type targetType = (TargetObject != null) ? TargetObject.GetType() : TargetType; -#if NET_2_0 - GenericArgumentsHolder genericInfo = new GenericArgumentsHolder(TargetMethod); -#endif - // if we don't have any named arguments, we can try to get the exact method first... - if (NamedArguments.Count == 0) - { - ComposedCriteria searchCriteria = new ComposedCriteria(); -#if NET_2_0 - searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); - searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); - searchCriteria.Add(new MethodGenericArgumentsCountCriteria( - genericInfo.GetGenericArguments().Length)); -#else - searchCriteria.Add(new MethodNameMatchCriteria(TargetMethod)); - searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); -#endif - searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetTypes(Arguments))); - - MemberInfo[] matchingMethods = targetType.FindMembers( - MemberTypes.Method, - MethodSearchingFlags, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - searchCriteria); - - if (matchingMethods != null && matchingMethods.Length == 1) - { - theMethod = matchingMethods[0] as MethodInfo; - } - } - if (theMethod == null) - { - // search for a method with a matching signature... - ComposedCriteria searchCriteria = new ComposedCriteria(); -#if NET_2_0 - searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); - searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); - searchCriteria.Add(new MethodGenericArgumentsCountCriteria( - genericInfo.GetGenericArguments().Length)); -#else - searchCriteria.Add(new MethodNameMatchCriteria(TargetMethod)); - searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); -#endif - MemberInfo[] matchingMethods = targetType.FindMembers( - MemberTypes.Method, - MethodSearchingFlags, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - searchCriteria); - - if (matchingMethods == null - || matchingMethods.Length == 0) - { - throw new MissingMethodException(targetType.Name, TargetMethod); - } - if (matchingMethods.Length > 1) - { - throw new ArgumentException(string.Format( - CultureInfo.InvariantCulture, - "Unable to determine which exact method to call; found '{0}' matches.", - matchingMethods.Length)); - } - theMethod = matchingMethods[0] as MethodInfo; - } -#if NET_2_0 - if (genericInfo.ContainsGenericArguments) - { - string[] unresolvedGenericArgs = genericInfo.GetGenericArguments(); - Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; - for (int j = 0; j < unresolvedGenericArgs.Length; j++) - { - genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); - } - theMethod = theMethod.MakeGenericMethod(genericArgs); - } -#endif - return theMethod; - } - - /// - /// Adds the named argument to this instances mapping of argument names to argument values. - /// - /// - /// The name of an argument on the method that is to be invoked. - /// - /// - /// The value of the named argument on the method that is to be invoked. - /// - public void AddNamedArgument(string argumentName, object argument) - { - if (NamedArguments.Contains(argumentName)) - { - NamedArguments.Remove(argumentName); - } - NamedArguments.Add(argumentName, argument); - } - - private int ArgumentCount - { - get { return Arguments.Length + NamedArguments.Count; } - } - - /// - /// Returns the prepared object that - /// will be invoked. - /// - /// - ///

- /// A possible use case is to determine the return of the method. - ///

- ///
- /// - /// The prepared object that - /// will be invoked. - /// - public MethodInfo GetPreparedMethod() - { - return this._methodObject; - } - - /// - /// Invoke the specified method. - /// - /// - ///

- /// The invoker needs to have been prepared beforehand (via a call to the - /// method). - ///

- ///
- /// - /// The object returned by the method invocation, or - /// if the method returns void. - /// - /// - /// If at least one of the arguments passed to this - /// was incompatible with the signature of the invoked method. - /// - public virtual object Invoke() - { - object result = null; - try - { - result = this._methodObject.Invoke(TargetObject, PreparedArguments); - } - catch (ArgumentException ex) - { - throw new MethodInvocationException( - string.Format(CultureInfo.InvariantCulture, - "At least one of the arguments passed to this {0} was " + - "incompatible with the signature of the invoked method.", GetType().Name), ex); - } - return (result == null ? Void : result); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Reflection; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Objects; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Helper class allowing one to declaratively specify a method call for later invocation. + /// + /// + ///

+ /// Typically not used directly but via its subclasses such as + /// . + ///

+ ///

+ /// Usage: specify either the and + /// or the + /// and + /// properties respectively, and + /// (optionally) any arguments to the method. Then call the + /// method to prepare the invoker. + /// Once prepared, the invoker can be invoked any number of times. + ///

+ ///
+ /// + ///

+ /// The following example uses the class to invoke the + /// ToString() method on the Foo class using a mixture of both named and unnamed + /// arguments. + ///

+ /// + /// public class Foo + /// { + /// public string ToString(string name, int age, string address) + /// { + /// return string.Format("{0}, {1} years old, {2}", name, age, address); + /// } + /// + /// public static void Main() + /// { + /// Foo foo = new Foo(); + /// MethodInvoker invoker = new MethodInvoker(); + /// invoker.Arguments = new object [] {"Kaneda", "18 Kaosu Gardens, Nakatani Drive, Okinanawa"}; + /// invoker.AddNamedArgument("age", 29); + /// invoker.Prepare(); + /// // at this point, the arguments that will be passed to the method invocation + /// // will have been resolved into the following ordered array : {"Kaneda", 29, "18 Kaosu Gardens, Nakatani Drive, Okinanawa"} + /// string details = (string) invoker.Invoke(); + /// Console.WriteLine (details); + /// // will print out 'Kaneda, 29 years old, 18 Kaosu Gardens, Nakatani Drive, Okinanawa' + /// } + /// } + /// + ///
+ /// Colin Sampaleanu + /// Juergen Hoeller + /// Simon White (.NET) + public class MethodInvoker + { + #region Fields + + /// + /// The value returned from the invocation of a method that returns void. + /// + public static readonly Missing Void = Missing.Value; + + private Type _targetType; + private object _targetObject; + private string _targetMethod; + private object[] _arguments; + private IDictionary _namedArguments; + private object[] _preparedArguments; + + /// + /// The method that will be invoked. + /// + private MethodInfo _methodObject; + + /// + /// The used to search for + /// the method to be invoked. + /// + private const BindingFlags MethodSearchingFlags = + BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.Public | + BindingFlags.NonPublic | + BindingFlags.IgnoreCase; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the class. + /// + public MethodInvoker() + { + Arguments = new object[] {}; + NamedArguments = new Hashtable(); + PreparedArguments = new object[] {}; + } + + #endregion + + #region Properties + + /// + /// The target on which to call the target method. + /// + /// + ///

+ /// Only necessary when the target method is ; + /// else, a target object needs to be specified. + ///

+ ///
+ public Type TargetType + { + get { return _targetType; } + set { this._targetType = value; } + } + + /// + /// The target object on which to call the target method. + /// + /// + ///

+ /// Only necessary when the target method is not ; + /// else, a target class is sufficient. + ///

+ ///
+ public object TargetObject + { + get { return _targetObject; } + set { this._targetObject = value; } + } + + /// + /// The name of the method to be invoked. + /// + /// + ///

+ /// Refers to either a method + /// or a non- method, depending on + /// whether or not a target object has been set. + ///

+ ///
+ /// + public string TargetMethod + { + get { return _targetMethod; } + set { this._targetMethod = value; } + } + + /// + /// Arguments for the method invocation. + /// + /// + ///

+ /// Ordering is significant... the order of the arguments in this + /// property must match the ordering of the various parameters on the target + /// method. There does however exist a small possibility for confusion when + /// the arguments in this property are supplied in addition to one or more named + /// arguments. In this case, each named argument is slotted into the index position + /// corresponding to the named argument... once once all named arguments have been + /// resolved, the arguments in this property are slotted into any remaining (empty) + /// slots in the method parameter list (see the example in the overview of the + /// class if this is not clear). + ///

+ ///

+ /// If this property is not set, or the value passed to the setter invocation + /// is or a zero-length array, a method with no (un-named) arguments is assumed. + ///

+ ///
+ /// + public object[] Arguments + { + get { return _arguments; } + set + { + if (value != null) + { + this._arguments = value; + } + else + { + this._arguments = new object[] {}; + } + } + } + + /// + /// The resolved arguments for the method invocation. + /// + /// + /// + /// This property is not set until the target method has been resolved via a call to the + /// method). It is a combination of the + /// named and plain vanilla arguments properties, and it is this object array that + /// will actually be passed to the invocation of the target method. + /// + ///

+ /// Setting the value of this property to results in basically clearing out any + /// previously prepared arguments... another call to the + /// method will then be required to prepare the arguments again (or the prepared arguments + /// can be set explicitly if so desired). + ///

+ ///
+ /// + /// + protected object[] PreparedArguments + { + get { return _preparedArguments; } + set + { + if (value != null) + { + this._preparedArguments = value; + } + else + { + this._preparedArguments = new object[] {}; + } + } + } + + /// + /// Named arguments for the method invocation. + /// + /// + ///

+ /// The keys of this dictionary are the () names of the + /// method arguments, and the () values are the actual + /// argument values themselves. + ///

+ ///

+ /// If this property is not set, or the value passed to the setter invocation + /// is a reference, a method with no named arguments is assumed. + ///

+ ///
+ /// + public IDictionary NamedArguments + { + get { return _namedArguments; } + set + { + if (value != null) + { + this._namedArguments = value; + } + else + { + this._namedArguments.Clear(); + } + } + } + + #endregion + + #region Methods + + /// + /// Prepare the specified method. + /// + /// + ///

+ /// The method can be invoked any number of times afterwards. + ///

+ ///
+ /// + /// If all required properties are not set, or a matching argument could not be found + /// for a named argument (typically down to a typo). + /// + /// + /// If the specified method could not be found. + /// + public virtual void Prepare() + { + if (_targetMethod == null) + { + throw new ArgumentException("The 'TargetMethod' property is required."); + } + if (_targetType == null && _targetObject == null) + { + throw new ArgumentException("One of either the 'TargetType' or 'TargetObject' properties is required."); + } + _methodObject = FindTheMethodToInvoke(); + if (TargetObject == null && !_methodObject.IsStatic) + { + throw new ArgumentException( + "The target method cannot be an instance method without a corresponding target instance on which to invoke it."); + } + PrepareArguments(); + } + + private void PrepareArguments() + { + _preparedArguments = new object[ArgumentCount]; + // ok, lets prepare any named arguments first... + if (NamedArguments.Count > 0) + { + // lets slot in all of the named arguments first... + ParameterInfo[] parameters = _methodObject.GetParameters(); + // lets figure out the index og each of the method parameters... + IDictionary argumentNamesToIndexes = new Hashtable(); + for (int i = 0; i < parameters.Length; ++i) + { + ParameterInfo parameter = parameters[i]; + argumentNamesToIndexes[parameter.Name.ToLower(CultureInfo.InvariantCulture)] = i; + } + int THE_ARGUMENT_IS_PREPARED = -12; + foreach (DictionaryEntry namedArgument in NamedArguments) + { + string argumentName = ((string) namedArgument.Key).ToLower(CultureInfo.InvariantCulture); + object argumentValue = namedArgument.Value; + if (!argumentNamesToIndexes.Contains(argumentName)) + { + // whoa (Nelly); the named argument does not exist on the method... + throw new ArgumentException(string.Format( + CultureInfo.InvariantCulture, + "The named argument '{0}' could not be found on the '{1}' method of class [{2}].", + argumentName, _methodObject.Name, _methodObject.DeclaringType.FullName)); + + } + // look up the index of where in the prepared args array we're gonna stick the named argument value + int namedArgumentsIndex = (int) argumentNamesToIndexes[argumentName]; + PreparedArguments[namedArgumentsIndex] = argumentValue; + // we've prepped this index position, so mark it as so... + argumentNamesToIndexes[argumentName] = THE_ARGUMENT_IS_PREPARED; + } + // and then fill in any remaining blanks with the plain vanilla arguments... + int plainVanillaIndex = 0; + int[] sortedIndexes = (int[]) new ArrayList(argumentNamesToIndexes.Values).ToArray(typeof (int)); + Array.Sort(sortedIndexes); + foreach (int argumentIndex in sortedIndexes) + { + // have we previously prepped a named argument at this index position? + if (argumentIndex == THE_ARGUMENT_IS_PREPARED) + { + continue; + } + // lets stick a plain vanilla argument in at this index position (in the order that they have been supplied)... + PreparedArguments[argumentIndex] = Arguments[plainVanillaIndex++]; + } + } + else + { + PreparedArguments = Arguments; + } + } + + /// + /// Searches for and returns the method that is to be invoked. + /// + /// + /// The return value of this method call will subsequently be returned from the + /// . + /// + /// The method that is to be invoked. + /// + /// If no method could be found. + /// + /// + /// If more than one method was found. + /// + protected virtual MethodInfo FindTheMethodToInvoke() + { + MethodInfo theMethod = null; + Type targetType = (TargetObject != null) ? TargetObject.GetType() : TargetType; +#if NET_2_0 + GenericArgumentsHolder genericInfo = new GenericArgumentsHolder(TargetMethod); +#endif + // if we don't have any named arguments, we can try to get the exact method first... + if (NamedArguments.Count == 0) + { + ComposedCriteria searchCriteria = new ComposedCriteria(); +#if NET_2_0 + searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); + searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); + searchCriteria.Add(new MethodGenericArgumentsCountCriteria( + genericInfo.GetGenericArguments().Length)); +#else + searchCriteria.Add(new MethodNameMatchCriteria(TargetMethod)); + searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); +#endif + searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetTypes(Arguments))); + + MemberInfo[] matchingMethods = targetType.FindMembers( + MemberTypes.Method, + MethodSearchingFlags, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + searchCriteria); + + if (matchingMethods != null && matchingMethods.Length == 1) + { + theMethod = matchingMethods[0] as MethodInfo; + } + } + if (theMethod == null) + { + // search for a method with a matching signature... + ComposedCriteria searchCriteria = new ComposedCriteria(); +#if NET_2_0 + searchCriteria.Add(new MethodNameMatchCriteria(genericInfo.GenericMethodName)); + searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); + searchCriteria.Add(new MethodGenericArgumentsCountCriteria( + genericInfo.GetGenericArguments().Length)); +#else + searchCriteria.Add(new MethodNameMatchCriteria(TargetMethod)); + searchCriteria.Add(new MethodParametersCountCriteria(ArgumentCount)); +#endif + MemberInfo[] matchingMethods = targetType.FindMembers( + MemberTypes.Method, + MethodSearchingFlags, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + searchCriteria); + + if (matchingMethods == null + || matchingMethods.Length == 0) + { + throw new MissingMethodException(targetType.Name, TargetMethod); + } + if (matchingMethods.Length > 1) + { + throw new ArgumentException(string.Format( + CultureInfo.InvariantCulture, + "Unable to determine which exact method to call; found '{0}' matches.", + matchingMethods.Length)); + } + theMethod = matchingMethods[0] as MethodInfo; + } +#if NET_2_0 + if (genericInfo.ContainsGenericArguments) + { + string[] unresolvedGenericArgs = genericInfo.GetGenericArguments(); + Type[] genericArgs = new Type[unresolvedGenericArgs.Length]; + for (int j = 0; j < unresolvedGenericArgs.Length; j++) + { + genericArgs[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); + } + theMethod = theMethod.MakeGenericMethod(genericArgs); + } +#endif + return theMethod; + } + + /// + /// Adds the named argument to this instances mapping of argument names to argument values. + /// + /// + /// The name of an argument on the method that is to be invoked. + /// + /// + /// The value of the named argument on the method that is to be invoked. + /// + public void AddNamedArgument(string argumentName, object argument) + { + if (NamedArguments.Contains(argumentName)) + { + NamedArguments.Remove(argumentName); + } + NamedArguments.Add(argumentName, argument); + } + + private int ArgumentCount + { + get { return Arguments.Length + NamedArguments.Count; } + } + + /// + /// Returns the prepared object that + /// will be invoked. + /// + /// + ///

+ /// A possible use case is to determine the return of the method. + ///

+ ///
+ /// + /// The prepared object that + /// will be invoked. + /// + public MethodInfo GetPreparedMethod() + { + return this._methodObject; + } + + /// + /// Invoke the specified method. + /// + /// + ///

+ /// The invoker needs to have been prepared beforehand (via a call to the + /// method). + ///

+ ///
+ /// + /// The object returned by the method invocation, or + /// if the method returns void. + /// + /// + /// If at least one of the arguments passed to this + /// was incompatible with the signature of the invoked method. + /// + public virtual object Invoke() + { + object result = null; + try + { + result = this._methodObject.Invoke(TargetObject, PreparedArguments); + } + catch (ArgumentException ex) + { + throw new MethodInvocationException( + string.Format(CultureInfo.InvariantCulture, + "At least one of the arguments passed to this {0} was " + + "incompatible with the signature of the invoked method.", GetType().Name), ex); + } + return (result == null ? Void : result); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/MutableSortDefinition.cs b/src/Spring/Spring.Core/Objects/Support/MutableSortDefinition.cs index 452b3db3..41b49601 100644 --- a/src/Spring/Spring.Core/Objects/Support/MutableSortDefinition.cs +++ b/src/Spring/Spring.Core/Objects/Support/MutableSortDefinition.cs @@ -1,217 +1,217 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Mutable implementation of the - /// interface that - /// supports toggling the ascending value on setting the same property again. - /// - /// Juergen Hoeller - /// Jean-Pierre Pawlak - /// Simon White (.NET) - [Serializable] - public class MutableSortDefinition : ISortDefinition - { - private string _property = string.Empty; - private bool _ignoreCase = true; - private bool _ascending = true; - private bool _toggleAscendingOnProperty = false; - - #region Properties - private bool ToggleAscendingOnProperty - { - get - { - return _toggleAscendingOnProperty; - } - set - { - this._toggleAscendingOnProperty = value; - } - } - #endregion - - #region ISortDefinition Properties - /// - /// The name of the property to sort by. - /// - public string Property - { - get - { - return _property; - } - set - { - if (!StringUtils.HasText (value)) - { - _property = string.Empty; - } - else - { - // implicit toggling of ascending? - if (ToggleAscendingOnProperty) - { - if (value.Equals(_property)) - { - _ascending = !_ascending; - } - } - _property = value; - } - } - } - - /// - /// Whether upper and lower case in string values should be ignored. - /// - /// - /// True if the sorting should be performed in a case-insensitive fashion. - /// - public bool IgnoreCase - { - get - { - return _ignoreCase; - } - } - - /// - /// If the sorting should be ascending or descending. - /// - /// - /// True if the sorting should be in the ascending order. - /// - public bool Ascending - { - get - { - return _ascending; - } - } - #endregion - - #region Constructors - /// - /// Creates a new instance of the - /// class. - /// - public MutableSortDefinition () - { - } - - /// - /// Creates a new instance of the - /// class using - /// the specified . - /// - /// - /// The to use - /// as a source for initial property values. - /// - public MutableSortDefinition (ISortDefinition source) - { - this._property = source.Property; - this._ignoreCase = source.IgnoreCase; - this._ascending = source.Ascending; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the property to sort by. - /// - /// - /// Whether upper and lower case in string values should be ignored. - /// - /// - /// Whether or not the sorting should be ascending or descending. - /// - public MutableSortDefinition(string name, bool ignoreCase, bool ascending) - { - this._property = name; - this._ignoreCase = ignoreCase; - this._ascending = ascending; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// Whether or not the - /// - /// property should be toggled if the same name is set on the - /// - /// property. - /// - public MutableSortDefinition (bool toggleAscendingOnSameProperty) - { - this.ToggleAscendingOnProperty = toggleAscendingOnSameProperty; - } - #endregion - - #region Methods - /// - /// Overrides the default method - /// - /// - /// The object to test against this instance for equality. - /// - /// - /// True if the supplied is equal to this instance. - /// - public override bool Equals(object obj) - { - if (!(obj is ISortDefinition)) - { - return false; - } - ISortDefinition sd = (ISortDefinition) obj; - return (this.Property.Equals(sd.Property) && - this.Ascending == sd.Ascending && this.IgnoreCase == sd.IgnoreCase); - } - - /// - /// Overrides the default method. - /// - /// The hashcode for this instance. - public override int GetHashCode() - { - int result = 0; - result = this.Property.GetHashCode(); - result = 29 * result + (this.IgnoreCase ? 1 : 0); - result = 29 * result + (this.Ascending ? 1 : 0); - return result; - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Mutable implementation of the + /// interface that + /// supports toggling the ascending value on setting the same property again. + /// + /// Juergen Hoeller + /// Jean-Pierre Pawlak + /// Simon White (.NET) + [Serializable] + public class MutableSortDefinition : ISortDefinition + { + private string _property = string.Empty; + private bool _ignoreCase = true; + private bool _ascending = true; + private bool _toggleAscendingOnProperty = false; + + #region Properties + private bool ToggleAscendingOnProperty + { + get + { + return _toggleAscendingOnProperty; + } + set + { + this._toggleAscendingOnProperty = value; + } + } + #endregion + + #region ISortDefinition Properties + /// + /// The name of the property to sort by. + /// + public string Property + { + get + { + return _property; + } + set + { + if (!StringUtils.HasText (value)) + { + _property = string.Empty; + } + else + { + // implicit toggling of ascending? + if (ToggleAscendingOnProperty) + { + if (value.Equals(_property)) + { + _ascending = !_ascending; + } + } + _property = value; + } + } + } + + /// + /// Whether upper and lower case in string values should be ignored. + /// + /// + /// True if the sorting should be performed in a case-insensitive fashion. + /// + public bool IgnoreCase + { + get + { + return _ignoreCase; + } + } + + /// + /// If the sorting should be ascending or descending. + /// + /// + /// True if the sorting should be in the ascending order. + /// + public bool Ascending + { + get + { + return _ascending; + } + } + #endregion + + #region Constructors + /// + /// Creates a new instance of the + /// class. + /// + public MutableSortDefinition () + { + } + + /// + /// Creates a new instance of the + /// class using + /// the specified . + /// + /// + /// The to use + /// as a source for initial property values. + /// + public MutableSortDefinition (ISortDefinition source) + { + this._property = source.Property; + this._ignoreCase = source.IgnoreCase; + this._ascending = source.Ascending; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the property to sort by. + /// + /// + /// Whether upper and lower case in string values should be ignored. + /// + /// + /// Whether or not the sorting should be ascending or descending. + /// + public MutableSortDefinition(string name, bool ignoreCase, bool ascending) + { + this._property = name; + this._ignoreCase = ignoreCase; + this._ascending = ascending; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// Whether or not the + /// + /// property should be toggled if the same name is set on the + /// + /// property. + /// + public MutableSortDefinition (bool toggleAscendingOnSameProperty) + { + this.ToggleAscendingOnProperty = toggleAscendingOnSameProperty; + } + #endregion + + #region Methods + /// + /// Overrides the default method + /// + /// + /// The object to test against this instance for equality. + /// + /// + /// True if the supplied is equal to this instance. + /// + public override bool Equals(object obj) + { + if (!(obj is ISortDefinition)) + { + return false; + } + ISortDefinition sd = (ISortDefinition) obj; + return (this.Property.Equals(sd.Property) && + this.Ascending == sd.Ascending && this.IgnoreCase == sd.IgnoreCase); + } + + /// + /// Overrides the default method. + /// + /// The hashcode for this instance. + public override int GetHashCode() + { + int result = 0; + result = this.Property.GetHashCode(); + result = 29 * result + (this.IgnoreCase ? 1 : 0); + result = 29 * result + (this.Ascending ? 1 : 0); + return result; + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Objects/Support/PropertyComparator.cs b/src/Spring/Spring.Core/Objects/Support/PropertyComparator.cs index 69f12f27..880f8b12 100644 --- a/src/Spring/Spring.Core/Objects/Support/PropertyComparator.cs +++ b/src/Spring/Spring.Core/Objects/Support/PropertyComparator.cs @@ -1,198 +1,197 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using Common.Logging; -using Spring.Core; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Performs a comparison of two objects, using the specified object property via - /// an . - /// - /// Juergen Hoeller - /// Jean-Pierre Pawlak - /// Simon White (.NET) - /// $Id: PropertyComparator.cs,v 1.12 2007/07/31 00:09:03 markpollack Exp $ - public class PropertyComparator : IComparer - { - private static readonly ILog logger - = LogManager.GetLogger(typeof (PropertyComparator)); - - private ISortDefinition sortDefinition; - private readonly IDictionary cachedObjectWrappers = new Hashtable(); - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The to use for any - /// sorting. - /// - /// - /// If the supplied is . - /// - public PropertyComparator(ISortDefinition definition) - { - AssertUtils.ArgumentNotNull(definition, "definition"); - this.sortDefinition = definition; - } - - /// - /// Gets the to - /// use for any sorting. - /// - /// - /// The to use for - /// any sorting. - /// - public ISortDefinition SortDefinition - { - get { return this.sortDefinition; } - } - - /// - /// Compares two objects and returns a value indicating whether one is less - /// than, equal to or greater than the other. - /// - /// The first object to compare. - /// The second object to compare. - /// - public virtual int Compare(object o1, object o2) - { - object v1 = GetPropertyValue(o1); - object v2 = GetPropertyValue(o2); - if (this.sortDefinition.IgnoreCase - && (v1 is string) - && (v2 is string)) - { - v1 = ((string) v1).ToLower(CultureInfo.CurrentCulture); - v2 = ((string) v2).ToLower(CultureInfo.CurrentCulture); - } - int result = 0; - try - { - if (v1 != null) - { - if (v2 != null) - { - result = ((IComparable) v1).CompareTo(v2); - } - else - { - result = -1; - } - } - else - { - if (v2 != null) - { - result = 1; - } - else - { - result = 0; - } - } - } - catch (Exception ex) - { - #region Instrumentation - - if (logger.IsWarnEnabled) - { - logger.Warn("Could not sort objects [" + o1 + "] and [" + o2 + "]", - ex); - } - - #endregion - - return 0; - } - return (this.sortDefinition.Ascending ? result : -result); - } - - /// - /// Get the 's property - /// value for the given object. - /// - /// The object to get the property value for. - /// The property value. - private object GetPropertyValue(object obj) - { - object propertyValue = null; - if (obj != null) - { - IObjectWrapper ow = (IObjectWrapper) this.cachedObjectWrappers[obj]; - if (ow == null) - { - ow = new ObjectWrapper(obj); - this.cachedObjectWrappers.Add(obj, ow); - } - try - { - propertyValue = ow.GetPropertyValue(this.sortDefinition.Property); - } - catch (InvalidPropertyException ex) - { - // the property doesn't exist in the first place, so let exception through... - throw ex; - } - catch (ObjectsException ex) - { - // if a nested property cannot be read, simply return null... - if (logger.IsDebugEnabled) - { - logger.Debug("Could not access property - treating as null for sorting.", ex); - } - } - } - return propertyValue; - } - - /// - /// Sort the given according to the - /// given sort definition. - /// - /// - /// The to be sorted. - /// - /// The parameters to sort by. - /// - /// In the case of a missing property name. - /// - /// - /// If the supplied is . - /// - public static void Sort(IList source, ISortDefinition sortDefinition) - { - ArrayList.Adapter(source).Sort(new PropertyComparator(sortDefinition)); - } - } +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using Common.Logging; +using Spring.Core; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Performs a comparison of two objects, using the specified object property via + /// an . + /// + /// Juergen Hoeller + /// Jean-Pierre Pawlak + /// Simon White (.NET) + public class PropertyComparator : IComparer + { + private static readonly ILog logger + = LogManager.GetLogger(typeof (PropertyComparator)); + + private ISortDefinition sortDefinition; + private readonly IDictionary cachedObjectWrappers = new Hashtable(); + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The to use for any + /// sorting. + /// + /// + /// If the supplied is . + /// + public PropertyComparator(ISortDefinition definition) + { + AssertUtils.ArgumentNotNull(definition, "definition"); + this.sortDefinition = definition; + } + + /// + /// Gets the to + /// use for any sorting. + /// + /// + /// The to use for + /// any sorting. + /// + public ISortDefinition SortDefinition + { + get { return this.sortDefinition; } + } + + /// + /// Compares two objects and returns a value indicating whether one is less + /// than, equal to or greater than the other. + /// + /// The first object to compare. + /// The second object to compare. + /// + public virtual int Compare(object o1, object o2) + { + object v1 = GetPropertyValue(o1); + object v2 = GetPropertyValue(o2); + if (this.sortDefinition.IgnoreCase + && (v1 is string) + && (v2 is string)) + { + v1 = ((string) v1).ToLower(CultureInfo.CurrentCulture); + v2 = ((string) v2).ToLower(CultureInfo.CurrentCulture); + } + int result = 0; + try + { + if (v1 != null) + { + if (v2 != null) + { + result = ((IComparable) v1).CompareTo(v2); + } + else + { + result = -1; + } + } + else + { + if (v2 != null) + { + result = 1; + } + else + { + result = 0; + } + } + } + catch (Exception ex) + { + #region Instrumentation + + if (logger.IsWarnEnabled) + { + logger.Warn("Could not sort objects [" + o1 + "] and [" + o2 + "]", + ex); + } + + #endregion + + return 0; + } + return (this.sortDefinition.Ascending ? result : -result); + } + + /// + /// Get the 's property + /// value for the given object. + /// + /// The object to get the property value for. + /// The property value. + private object GetPropertyValue(object obj) + { + object propertyValue = null; + if (obj != null) + { + IObjectWrapper ow = (IObjectWrapper) this.cachedObjectWrappers[obj]; + if (ow == null) + { + ow = new ObjectWrapper(obj); + this.cachedObjectWrappers.Add(obj, ow); + } + try + { + propertyValue = ow.GetPropertyValue(this.sortDefinition.Property); + } + catch (InvalidPropertyException ex) + { + // the property doesn't exist in the first place, so let exception through... + throw ex; + } + catch (ObjectsException ex) + { + // if a nested property cannot be read, simply return null... + if (logger.IsDebugEnabled) + { + logger.Debug("Could not access property - treating as null for sorting.", ex); + } + } + } + return propertyValue; + } + + /// + /// Sort the given according to the + /// given sort definition. + /// + /// + /// The to be sorted. + /// + /// The parameters to sort by. + /// + /// In the case of a missing property name. + /// + /// + /// If the supplied is . + /// + public static void Sort(IList source, ISortDefinition sortDefinition) + { + ArrayList.Adapter(source).Sort(new PropertyComparator(sortDefinition)); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Support/StaticEventHandlerValue.cs b/src/Spring/Spring.Core/Objects/Support/StaticEventHandlerValue.cs index 3c85ab6d..8457bf55 100644 --- a/src/Spring/Spring.Core/Objects/Support/StaticEventHandlerValue.cs +++ b/src/Spring/Spring.Core/Objects/Support/StaticEventHandlerValue.cs @@ -1,98 +1,97 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; - -#endregion - -namespace Spring.Objects.Support -{ - /// - /// Describes an event handler for a static class method. - /// - /// Rick Evans - /// $Id: StaticEventHandlerValue.cs,v 1.5 2006/04/09 07:19:00 markpollack Exp $ - public class StaticEventHandlerValue : AbstractWiringEventHandlerValue - { - #region Constants - private static readonly BindingFlags StaticMethodFlags = - BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.IgnoreCase; - #endregion - - #region Constructor (s) / Destructor - /// - /// Creates a new instance of the - /// class. - /// - public StaticEventHandlerValue () - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The object (possibly unresolved) that is exposing the event. - /// - /// - /// The name of the method on the handler that is going to handle the event. - /// - public StaticEventHandlerValue (object source, string methodName) - : base (source, methodName) {} - #endregion - - #region Methods - /// - /// Gets the event handler. - /// - /// - /// The instance that is registering for the event notification. - /// - /// - /// Event metadata about the event. - /// - /// - /// The event handler. - /// - protected override Delegate GetHandler(object instance, EventInfo info) - { - Type type = instance as Type; - if (type == null) - { - throw new FatalObjectException (string.Format ( - CultureInfo.InvariantCulture, - "Only 'System.Type' instances can be wired by instances of " + - "the StaticEventHandlerValue class; got '{0}'", instance)); - } - MethodInfo method = ResolveHandlerMethod ( - type, - info.EventHandlerType, - StaticEventHandlerValue.StaticMethodFlags); - return Delegate.CreateDelegate (info.EventHandlerType, method); - } - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; + +#endregion + +namespace Spring.Objects.Support +{ + /// + /// Describes an event handler for a static class method. + /// + /// Rick Evans + public class StaticEventHandlerValue : AbstractWiringEventHandlerValue + { + #region Constants + private static readonly BindingFlags StaticMethodFlags = + BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.IgnoreCase; + #endregion + + #region Constructor (s) / Destructor + /// + /// Creates a new instance of the + /// class. + /// + public StaticEventHandlerValue () + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The object (possibly unresolved) that is exposing the event. + /// + /// + /// The name of the method on the handler that is going to handle the event. + /// + public StaticEventHandlerValue (object source, string methodName) + : base (source, methodName) {} + #endregion + + #region Methods + /// + /// Gets the event handler. + /// + /// + /// The instance that is registering for the event notification. + /// + /// + /// Event metadata about the event. + /// + /// + /// The event handler. + /// + protected override Delegate GetHandler(object instance, EventInfo info) + { + Type type = instance as Type; + if (type == null) + { + throw new FatalObjectException (string.Format ( + CultureInfo.InvariantCulture, + "Only 'System.Type' instances can be wired by instances of " + + "the StaticEventHandlerValue class; got '{0}'", instance)); + } + MethodInfo method = ResolveHandlerMethod ( + type, + info.EventHandlerType, + StaticEventHandlerValue.StaticMethodFlags); + return Delegate.CreateDelegate (info.EventHandlerType, method); + } + #endregion + } +} diff --git a/src/Spring/Spring.Core/Pool/IObjectPool.cs b/src/Spring/Spring.Core/Pool/IObjectPool.cs index 07ccc58c..05e8de03 100644 --- a/src/Spring/Spring.Core/Pool/IObjectPool.cs +++ b/src/Spring/Spring.Core/Pool/IObjectPool.cs @@ -1,150 +1,149 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -using System; - -namespace Spring.Pool -{ - /// - /// A simple pooling interface for managing and monitoring a pool - /// of objects. - /// - /// - ///

- /// Based on the Jakarta Commons Pool API. - ///

- ///
- /// Federico Spinazzi - /// $Id: IObjectPool.cs,v 1.5 2005/08/13 18:04:54 springboy Exp $ - /// - public interface IObjectPool - { - /// - /// Obtain an instance from the pool. - /// - /// - ///

- /// By contract, clients must return the borrowed - /// instance using - /// or a related method as defined in an implementation or - /// sub-interface. - ///

- ///
- /// An instance from the pool. - /// - /// In case the pool is unusable. - /// - /// - object BorrowObject(); - - /// - /// Return an instance to the pool. - /// - /// - ///

- /// By contract, the object must have been obtained using - /// - /// or a related method as defined in an implementation or sub-interface. - ///

- ///
- /// The instance to be returned to the pool. - /// - void ReturnObject(object target); - - /// - /// Create an object using the factory set by - /// the property - /// or other implementation dependent mechanism - /// and place it into the pool. - /// - /// - ///

- /// This is an optional operation. AddObject is useful for "pre-loading" a - /// pool with idle objects. - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - void AddObject(); - - /// - /// Close the pool and free any resources associated with it. - /// - void Close(); - - /// - /// Clear objects sitting idle in the pool, releasing any - /// associated resources. - /// - /// - ///

- /// This is an optional operation. - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - void Clear(); - - /// - /// Gets the number of instances currently borrowed from the pool. - /// - /// - ///

- /// This is an optional operation. - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - int NumActive { get; } - - /// - /// Gets the number of instances currently idle in the pool. - /// - /// - ///

- /// This is an optional operation. - ///

- ///

- /// This may be considered an approximation of the number of objects - /// that can be borrowed without creating any new instances. - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - int NumIdle { get; } - - /// - /// Set the factory used to create new instances. - /// - /// - ///

- /// This is an optional operation. - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - IPoolableObjectFactory PoolableObjectFactory { set; } - } -} +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +using System; + +namespace Spring.Pool +{ + /// + /// A simple pooling interface for managing and monitoring a pool + /// of objects. + /// + /// + ///

+ /// Based on the Jakarta Commons Pool API. + ///

+ ///
+ /// Federico Spinazzi + /// + public interface IObjectPool + { + /// + /// Obtain an instance from the pool. + /// + /// + ///

+ /// By contract, clients must return the borrowed + /// instance using + /// or a related method as defined in an implementation or + /// sub-interface. + ///

+ ///
+ /// An instance from the pool. + /// + /// In case the pool is unusable. + /// + /// + object BorrowObject(); + + /// + /// Return an instance to the pool. + /// + /// + ///

+ /// By contract, the object must have been obtained using + /// + /// or a related method as defined in an implementation or sub-interface. + ///

+ ///
+ /// The instance to be returned to the pool. + /// + void ReturnObject(object target); + + /// + /// Create an object using the factory set by + /// the property + /// or other implementation dependent mechanism + /// and place it into the pool. + /// + /// + ///

+ /// This is an optional operation. AddObject is useful for "pre-loading" a + /// pool with idle objects. + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + void AddObject(); + + /// + /// Close the pool and free any resources associated with it. + /// + void Close(); + + /// + /// Clear objects sitting idle in the pool, releasing any + /// associated resources. + /// + /// + ///

+ /// This is an optional operation. + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + void Clear(); + + /// + /// Gets the number of instances currently borrowed from the pool. + /// + /// + ///

+ /// This is an optional operation. + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + int NumActive { get; } + + /// + /// Gets the number of instances currently idle in the pool. + /// + /// + ///

+ /// This is an optional operation. + ///

+ ///

+ /// This may be considered an approximation of the number of objects + /// that can be borrowed without creating any new instances. + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + int NumIdle { get; } + + /// + /// Set the factory used to create new instances. + /// + /// + ///

+ /// This is an optional operation. + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + IPoolableObjectFactory PoolableObjectFactory { set; } + } +} diff --git a/src/Spring/Spring.Core/Pool/IPoolableObjectFactory.cs b/src/Spring/Spring.Core/Pool/IPoolableObjectFactory.cs index 500e1605..69423735 100644 --- a/src/Spring/Spring.Core/Pool/IPoolableObjectFactory.cs +++ b/src/Spring/Spring.Core/Pool/IPoolableObjectFactory.cs @@ -1,125 +1,124 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -namespace Spring.Pool -{ - /// - /// Defines lifecycle methods for objects that are to be used in an - /// implementation. - /// - /// - ///

- /// The following methods summarize the contract between an - /// and an - /// an . - ///

- /// - /// - /// - /// is called whenever a new instance is needed. - /// - /// - /// - /// is invoked on every instance before it is returned from - /// the pool. - /// - /// - /// - /// is invoked on every instance when it is returned to the pool. - /// - /// - /// - /// is invoked on every instance when it is being dropped from the - /// pool (see - /// - /// - /// - ///

- /// Based on the Jakarta Commons Pool API. - ///

- ///
- /// Federico Spinazzi - /// $Id: IPoolableObjectFactory.cs,v 1.5 2005/11/18 17:29:32 gcaprio Exp $ - /// - public interface IPoolableObjectFactory - { - /// - /// Creates an instance that can be returned by the pool. - /// - /// - /// An instance that can be returned by the pool. - /// - object MakeObject(); - - /// - /// Destroys an instance no longer needed by the pool. - /// - /// - ///

- /// Invoked on every instance when it is being "dropped" - /// from the pool (whether due to the return value from a call to the - /// - /// method, or for reasons specific to the pool implementation.) - ///

- ///
- /// The instance to be destroyed. - void DestroyObject(object obj); - - /// - /// Ensures that the instance is safe to be returned by the pool. - /// Returns false if this object should be destroyed. - /// - /// - ///

- /// Invoked in an implementation-specific fashion to determine if an - /// instance is still valid to be returned by the pool. - /// It will only be invoked on an "activated" instance. - ///

- ///
- /// The instance to validate. - /// - /// if this object is not valid and - /// should be dropped from the pool, otherwise . - /// - bool ValidateObject(object obj); - - /// - /// Reinitialize an instance to be returned by the pool. - /// - /// - ///

- /// Invoked on every instance before it is returned from the pool. - ///

- ///
- /// The instance to be activated. - void ActivateObject(object obj); - - /// - /// Uninitialize an instance to be returned to the pool. - /// - /// - ///

- /// Invoked on every instance when it is returned to the pool. - ///

- ///
- /// The instance returned to the pool. - void PassivateObject(object obj); - } +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +namespace Spring.Pool +{ + /// + /// Defines lifecycle methods for objects that are to be used in an + /// implementation. + /// + /// + ///

+ /// The following methods summarize the contract between an + /// and an + /// an . + ///

+ /// + /// + /// + /// is called whenever a new instance is needed. + /// + /// + /// + /// is invoked on every instance before it is returned from + /// the pool. + /// + /// + /// + /// is invoked on every instance when it is returned to the pool. + /// + /// + /// + /// is invoked on every instance when it is being dropped from the + /// pool (see + /// + /// + /// + ///

+ /// Based on the Jakarta Commons Pool API. + ///

+ ///
+ /// Federico Spinazzi + /// + public interface IPoolableObjectFactory + { + /// + /// Creates an instance that can be returned by the pool. + /// + /// + /// An instance that can be returned by the pool. + /// + object MakeObject(); + + /// + /// Destroys an instance no longer needed by the pool. + /// + /// + ///

+ /// Invoked on every instance when it is being "dropped" + /// from the pool (whether due to the return value from a call to the + /// + /// method, or for reasons specific to the pool implementation.) + ///

+ ///
+ /// The instance to be destroyed. + void DestroyObject(object obj); + + /// + /// Ensures that the instance is safe to be returned by the pool. + /// Returns false if this object should be destroyed. + /// + /// + ///

+ /// Invoked in an implementation-specific fashion to determine if an + /// instance is still valid to be returned by the pool. + /// It will only be invoked on an "activated" instance. + ///

+ ///
+ /// The instance to validate. + /// + /// if this object is not valid and + /// should be dropped from the pool, otherwise . + /// + bool ValidateObject(object obj); + + /// + /// Reinitialize an instance to be returned by the pool. + /// + /// + ///

+ /// Invoked on every instance before it is returned from the pool. + ///

+ ///
+ /// The instance to be activated. + void ActivateObject(object obj); + + /// + /// Uninitialize an instance to be returned to the pool. + /// + /// + ///

+ /// Invoked on every instance when it is returned to the pool. + ///

+ ///
+ /// The instance returned to the pool. + void PassivateObject(object obj); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Pool/PoolException.cs b/src/Spring/Spring.Core/Pool/PoolException.cs index 8d6c3467..9c1020da 100644 --- a/src/Spring/Spring.Core/Pool/PoolException.cs +++ b/src/Spring/Spring.Core/Pool/PoolException.cs @@ -1,81 +1,80 @@ -#region License -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Pool -{ - /// - /// Base class for all pooling exceptions. - /// - /// Federico Spinazzi - /// $Id: PoolException.cs,v 1.4 2005/08/07 04:59:47 markpollack Exp $ - [Serializable] - public class PoolException : Exception - { - /// - /// Creates a new instance of the - /// class. - /// - public PoolException () - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public PoolException (string message) : base (message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public PoolException (string message, Exception innerException) : base (message, innerException) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected PoolException (SerializationInfo info, StreamingContext context) : base (info, context) - { - } - } +#region License +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Pool +{ + /// + /// Base class for all pooling exceptions. + /// + /// Federico Spinazzi + [Serializable] + public class PoolException : Exception + { + /// + /// Creates a new instance of the + /// class. + /// + public PoolException () + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public PoolException (string message) : base (message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public PoolException (string message, Exception innerException) : base (message, innerException) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected PoolException (SerializationInfo info, StreamingContext context) : base (info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Pool/Support/SimplePool.cs b/src/Spring/Spring.Core/Pool/Support/SimplePool.cs index 34175bd9..b280086a 100644 --- a/src/Spring/Spring.Core/Pool/Support/SimplePool.cs +++ b/src/Spring/Spring.Core/Pool/Support/SimplePool.cs @@ -1,294 +1,293 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Util; -using Spring.Threading; - -#endregion - -namespace Spring.Pool.Support -{ - /// - /// A simple pool implementation - /// - /// - ///

- /// Based on the implementation found in Concurrent Programming in Java, - /// 2nd ed., by Doug Lea. - ///

- ///
- /// Doug Lea - /// Federico Spinazzi - /// Mark Pollack - /// $Id: SimplePool.cs,v 1.4 2006/09/15 19:06:07 markpollack Exp $ - public class SimplePool : IObjectPool - { - private readonly IPoolableObjectFactory factory; - private bool closed; - private IList free = new ArrayList(); - private IList busy = new ArrayList(); // linear search !! - - /// - /// Set of permits - /// - internal readonly Semaphore available; - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The factory used to instantiate and manage the lifecycle of pooled objects. - /// - /// The initial size of the pool. - /// - /// If the supplied is . - /// - /// - /// If the supplied is less than or equal to zero. - /// - public SimplePool(IPoolableObjectFactory factory, int size) - { - AssertUtils.ArgumentNotNull(factory, "factory"); - this.available = new Semaphore(size); - this.factory = factory; - InitItems(size); - } - - /// - /// Obtain an instance from the pool. - /// - /// - /// In case the pool is unusable. - /// - /// - /// - public object BorrowObject() - { - available.Acquire(); - return DoBorrow(); - } - - /// - /// Return an instance to the pool. - /// - /// The instance to be returned to the pool. - /// - /// - public void ReturnObject(object target) - { - if (DoReturn(target)) - { - available.Release(); - } - } - - /// - /// Create an object using the factory set by - /// the property - /// or other implementation dependent mechanism - /// and place it into the pool. - /// - /// - ///

- /// This implementation always throws a - /// . - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - public void AddObject() - { - throw new NotSupportedException(); - } - - /// - /// Synchronized borrow logic. - /// - /// - protected object DoBorrow() - { - lock (this) - { - while (free.Count > 0) - { - int i = free.Count - 1; - object o = free[i]; - free.RemoveAt(i); - factory.ActivateObject(o); - if (factory.ValidateObject(o)) - { - busy.Add(o); - return o; - } - } - if (!closed) - { - throw new PoolException("No more valid objects in pool."); - } - else - { - throw new PoolException("Pool was closed and is unusable."); - } - } - } - - /// - /// Synchronized release logic. - /// - /// - /// The object to release to the pool. - /// - /// - /// if the object was not a busy one. - /// - protected bool DoReturn(object target) - { - lock (this) - { - if (busy.Contains(target)) - { - busy.Remove(target); - factory.PassivateObject(target); - free.Add(target); - return true; - } - return false; - } - } - - /// - /// Instantiates the supplied number of instances and adds - /// them to the pool. - /// - /// - /// The initial number of objects to build. - /// - /// - /// If the supplied number of is - /// less than or equal to zero. - /// - protected void InitItems(int initialInstances) - { - if(initialInstances <= 0) - { - throw new ArgumentException("Cannot pool a negative number of instances.", "initialInstances"); - } - for (int i = 0; i < initialInstances; ++i) - { - free.Add(factory.MakeObject()); - } - } - - /// - /// Close the pool and free any resources associated with it. - /// - public void Close() - { - lock (this) - { - for (IEnumerator e = busy.GetEnumerator(); - e.MoveNext(); - e = busy.GetEnumerator()) - { - ReturnObject(e.Current); - } - foreach (object o in free) - { - factory.DestroyObject(o); - } - MakeNotUsable(); - } - } - - /// - /// Clear objects sitting idle in the pool, releasing any - /// associated resources. - /// - /// - ///

- /// This implementation always throws a - /// . - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - public void Clear() - { - throw new NotSupportedException(); - } - - /// - /// Change the state of the pool to unusable. - /// - private void MakeNotUsable() - { - free = busy = new ArrayList(); - closed = true; - } - - /// - /// Gets the number of instances currently borrowed from the pool. - /// - /// - /// If the implementation does not support the operation. - /// - /// - public int NumActive - { - get { return this.busy.Count; } - } - - /// - /// Gets the number of instances currently idle in the pool. - /// - /// - /// If the implementation does not support the operation. - /// - /// - public int NumIdle - { - get { return this.free.Count; } - } - - /// - /// Set the factory used to create new instances. - /// - /// - ///

- /// This implementation always throws a - /// . - ///

- ///
- /// - /// If the implementation does not support the operation. - /// - public IPoolableObjectFactory PoolableObjectFactory - { - set { throw new NotSupportedException(); } - } - } -} +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Util; +using Spring.Threading; + +#endregion + +namespace Spring.Pool.Support +{ + /// + /// A simple pool implementation + /// + /// + ///

+ /// Based on the implementation found in Concurrent Programming in Java, + /// 2nd ed., by Doug Lea. + ///

+ ///
+ /// Doug Lea + /// Federico Spinazzi + /// Mark Pollack + public class SimplePool : IObjectPool + { + private readonly IPoolableObjectFactory factory; + private bool closed; + private IList free = new ArrayList(); + private IList busy = new ArrayList(); // linear search !! + + /// + /// Set of permits + /// + internal readonly Semaphore available; + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The factory used to instantiate and manage the lifecycle of pooled objects. + /// + /// The initial size of the pool. + /// + /// If the supplied is . + /// + /// + /// If the supplied is less than or equal to zero. + /// + public SimplePool(IPoolableObjectFactory factory, int size) + { + AssertUtils.ArgumentNotNull(factory, "factory"); + this.available = new Semaphore(size); + this.factory = factory; + InitItems(size); + } + + /// + /// Obtain an instance from the pool. + /// + /// + /// In case the pool is unusable. + /// + /// + /// + public object BorrowObject() + { + available.Acquire(); + return DoBorrow(); + } + + /// + /// Return an instance to the pool. + /// + /// The instance to be returned to the pool. + /// + /// + public void ReturnObject(object target) + { + if (DoReturn(target)) + { + available.Release(); + } + } + + /// + /// Create an object using the factory set by + /// the property + /// or other implementation dependent mechanism + /// and place it into the pool. + /// + /// + ///

+ /// This implementation always throws a + /// . + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + public void AddObject() + { + throw new NotSupportedException(); + } + + /// + /// Synchronized borrow logic. + /// + /// + protected object DoBorrow() + { + lock (this) + { + while (free.Count > 0) + { + int i = free.Count - 1; + object o = free[i]; + free.RemoveAt(i); + factory.ActivateObject(o); + if (factory.ValidateObject(o)) + { + busy.Add(o); + return o; + } + } + if (!closed) + { + throw new PoolException("No more valid objects in pool."); + } + else + { + throw new PoolException("Pool was closed and is unusable."); + } + } + } + + /// + /// Synchronized release logic. + /// + /// + /// The object to release to the pool. + /// + /// + /// if the object was not a busy one. + /// + protected bool DoReturn(object target) + { + lock (this) + { + if (busy.Contains(target)) + { + busy.Remove(target); + factory.PassivateObject(target); + free.Add(target); + return true; + } + return false; + } + } + + /// + /// Instantiates the supplied number of instances and adds + /// them to the pool. + /// + /// + /// The initial number of objects to build. + /// + /// + /// If the supplied number of is + /// less than or equal to zero. + /// + protected void InitItems(int initialInstances) + { + if(initialInstances <= 0) + { + throw new ArgumentException("Cannot pool a negative number of instances.", "initialInstances"); + } + for (int i = 0; i < initialInstances; ++i) + { + free.Add(factory.MakeObject()); + } + } + + /// + /// Close the pool and free any resources associated with it. + /// + public void Close() + { + lock (this) + { + for (IEnumerator e = busy.GetEnumerator(); + e.MoveNext(); + e = busy.GetEnumerator()) + { + ReturnObject(e.Current); + } + foreach (object o in free) + { + factory.DestroyObject(o); + } + MakeNotUsable(); + } + } + + /// + /// Clear objects sitting idle in the pool, releasing any + /// associated resources. + /// + /// + ///

+ /// This implementation always throws a + /// . + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + public void Clear() + { + throw new NotSupportedException(); + } + + /// + /// Change the state of the pool to unusable. + /// + private void MakeNotUsable() + { + free = busy = new ArrayList(); + closed = true; + } + + /// + /// Gets the number of instances currently borrowed from the pool. + /// + /// + /// If the implementation does not support the operation. + /// + /// + public int NumActive + { + get { return this.busy.Count; } + } + + /// + /// Gets the number of instances currently idle in the pool. + /// + /// + /// If the implementation does not support the operation. + /// + /// + public int NumIdle + { + get { return this.free.Count; } + } + + /// + /// Set the factory used to create new instances. + /// + /// + ///

+ /// This implementation always throws a + /// . + ///

+ ///
+ /// + /// If the implementation does not support the operation. + /// + public IPoolableObjectFactory PoolableObjectFactory + { + set { throw new NotSupportedException(); } + } + } +} diff --git a/src/Spring/Spring.Core/Proxy/AbstractProxyMethodBuilder.cs b/src/Spring/Spring.Core/Proxy/AbstractProxyMethodBuilder.cs index 288ea069..2fc128f9 100644 --- a/src/Spring/Spring.Core/Proxy/AbstractProxyMethodBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/AbstractProxyMethodBuilder.cs @@ -34,7 +34,6 @@ namespace Spring.Proxy /// Base class for method builders that contains common functionalities. /// /// Bruno Baia - /// $Id: AbstractProxyMethodBuilder.cs,v 1.7 2008/02/06 18:26:42 bbaia Exp $ public abstract class AbstractProxyMethodBuilder : IProxyMethodBuilder { #region Fields diff --git a/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs b/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs index 469cf539..7db27e02 100644 --- a/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs @@ -48,7 +48,6 @@ namespace Spring.Proxy /// /// Aleksandar Seovic /// Bruno Baia - /// $Id: AbstractProxyTypeBuilder.cs,v 1.33 2007/12/07 17:59:20 bbaia Exp $ public abstract class AbstractProxyTypeBuilder : IProxyTypeBuilder, IProxyTypeGenerator { #region Fields diff --git a/src/Spring/Spring.Core/Proxy/BaseProxyMethodBuilder.cs b/src/Spring/Spring.Core/Proxy/BaseProxyMethodBuilder.cs index 75b5bc58..9e48795f 100644 --- a/src/Spring/Spring.Core/Proxy/BaseProxyMethodBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/BaseProxyMethodBuilder.cs @@ -34,7 +34,6 @@ namespace Spring.Proxy /// Implementation of IProxyMethodBuilder that delegates method calls to the base class. /// /// Bruno Baia - /// $Id: BaseProxyMethodBuilder.cs,v 1.1 2006/08/10 18:45:55 bbaia Exp $ public class BaseProxyMethodBuilder : AbstractProxyMethodBuilder { #region Constructor(s) / Destructor diff --git a/src/Spring/Spring.Core/Proxy/CompositionProxyTypeBuilder.cs b/src/Spring/Spring.Core/Proxy/CompositionProxyTypeBuilder.cs index 0ff70f9e..b062a0f5 100644 --- a/src/Spring/Spring.Core/Proxy/CompositionProxyTypeBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/CompositionProxyTypeBuilder.cs @@ -41,7 +41,6 @@ namespace Spring.Proxy /// /// Aleksandar Seovic /// Bruno Baia - /// $Id: CompositionProxyTypeBuilder.cs,v 1.12 2007/03/27 02:27:43 bbaia Exp $ public class CompositionProxyTypeBuilder : AbstractProxyTypeBuilder { #region Fields diff --git a/src/Spring/Spring.Core/Proxy/DynamicProxyManager.cs b/src/Spring/Spring.Core/Proxy/DynamicProxyManager.cs index ede6f5dd..478f78b2 100644 --- a/src/Spring/Spring.Core/Proxy/DynamicProxyManager.cs +++ b/src/Spring/Spring.Core/Proxy/DynamicProxyManager.cs @@ -35,7 +35,6 @@ namespace Spring.Proxy /// /// Aleksandar Seovic /// Bruno Baia - /// $Id: DynamicProxyManager.cs,v 1.6 2007/05/30 17:32:05 oakinger Exp $ public sealed class DynamicProxyManager { #region Fields diff --git a/src/Spring/Spring.Core/Proxy/IProxyMethodBuilder.cs b/src/Spring/Spring.Core/Proxy/IProxyMethodBuilder.cs index 1619674f..b982543e 100644 --- a/src/Spring/Spring.Core/Proxy/IProxyMethodBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/IProxyMethodBuilder.cs @@ -33,7 +33,6 @@ namespace Spring.Proxy /// /// Aleksandar Seovic /// Bruno Baia - /// $Id: IProxyMethodBuilder.cs,v 1.1 2006/08/10 18:45:55 bbaia Exp $ public interface IProxyMethodBuilder { /// diff --git a/src/Spring/Spring.Core/Proxy/IProxyTypeBuilder.cs b/src/Spring/Spring.Core/Proxy/IProxyTypeBuilder.cs index afc6b50a..f6366cc5 100644 --- a/src/Spring/Spring.Core/Proxy/IProxyTypeBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/IProxyTypeBuilder.cs @@ -32,7 +32,6 @@ namespace Spring.Proxy /// used to create a proxy type for any class. /// /// Aleksandar Seovic - /// $Id: IProxyTypeBuilder.cs,v 1.8 2007/06/20 15:59:54 bbaia Exp $ public interface IProxyTypeBuilder { /// diff --git a/src/Spring/Spring.Core/Proxy/IProxyTypeGenerator.cs b/src/Spring/Spring.Core/Proxy/IProxyTypeGenerator.cs index 995c4478..5de52e5d 100644 --- a/src/Spring/Spring.Core/Proxy/IProxyTypeGenerator.cs +++ b/src/Spring/Spring.Core/Proxy/IProxyTypeGenerator.cs @@ -32,7 +32,6 @@ namespace Spring.Proxy /// used to build the proxy type. /// /// Bruno Baia - /// $Id: IProxyTypeGenerator.cs,v 1.3 2006/11/12 01:37:47 bbaia Exp $ public interface IProxyTypeGenerator { // TODO : Why not ? diff --git a/src/Spring/Spring.Core/Proxy/InheritanceProxyTypeBuilder.cs b/src/Spring/Spring.Core/Proxy/InheritanceProxyTypeBuilder.cs index eb00f213..187b9aef 100644 --- a/src/Spring/Spring.Core/Proxy/InheritanceProxyTypeBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/InheritanceProxyTypeBuilder.cs @@ -40,7 +40,6 @@ namespace Spring.Proxy /// /// Aleksandar Seovic /// Bruno Baia - /// $Id: InheritanceProxyTypeBuilder.cs,v 1.14 2007/12/04 18:38:02 bbaia Exp $ public class InheritanceProxyTypeBuilder : AbstractProxyTypeBuilder { #region Fields diff --git a/src/Spring/Spring.Core/Proxy/ProxyIgnoreAttribute.cs b/src/Spring/Spring.Core/Proxy/ProxyIgnoreAttribute.cs index 79c294c8..b4e14341 100644 --- a/src/Spring/Spring.Core/Proxy/ProxyIgnoreAttribute.cs +++ b/src/Spring/Spring.Core/Proxy/ProxyIgnoreAttribute.cs @@ -30,7 +30,6 @@ namespace Spring.Proxy /// This attribute can be used to mark interfaces that should not be proxied /// /// Bruno Baia - /// $Id: ProxyIgnoreAttribute.cs,v 1.1 2006/11/16 02:30:50 bbaia Exp $ [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] [Serializable] public sealed class ProxyIgnoreAttribute : Attribute diff --git a/src/Spring/Spring.Core/Proxy/TargetProxyMethodBuilder.cs b/src/Spring/Spring.Core/Proxy/TargetProxyMethodBuilder.cs index e85a62c7..212fd631 100644 --- a/src/Spring/Spring.Core/Proxy/TargetProxyMethodBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/TargetProxyMethodBuilder.cs @@ -34,7 +34,6 @@ namespace Spring.Proxy /// Implementation of IProxyMethodBuilder that delegates method calls to target object. /// /// Bruno Baia - /// $Id: TargetProxyMethodBuilder.cs,v 1.1 2006/08/10 18:45:55 bbaia Exp $ public class TargetProxyMethodBuilder : AbstractProxyMethodBuilder { #region Constructor(s) / Destructor diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/BaseDynamicMember.cs b/src/Spring/Spring.Core/Reflection/Dynamic/BaseDynamicMember.cs index e592f377..4dafbefd 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/BaseDynamicMember.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/BaseDynamicMember.cs @@ -1,147 +1,146 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; - -#endregion - -namespace Spring.Reflection.Dynamic -{ - /// - /// Base class for dynamic members. - /// - /// Aleksandar Seovic - /// $Id: BaseDynamicMember.cs,v 1.1 2007/08/08 04:05:37 bbaia Exp $ - public class BaseDynamicMember - { - /// - /// Method attributes constant. - /// - protected const MethodAttributes METHOD_ATTRIBUTES = - MethodAttributes.Public | MethodAttributes.HideBySig - | MethodAttributes.NewSlot | MethodAttributes.Virtual - | MethodAttributes.Final; - - private static ConstructorInfo invalidOperationException = - typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) }); - - /// - /// Sets up target instance for invocation. - /// - /// IL generator to use. - /// Type of target instance. - protected static void SetupTargetInstance(ILGenerator il, Type targetType) - { - il.Emit(OpCodes.Ldarg_1); - if (targetType.IsValueType) - { - LocalBuilder target = il.DeclareLocal(targetType); -#if NET_2_0 - il.Emit(OpCodes.Unbox_Any, targetType); -#else - il.Emit(OpCodes.Unbox, targetType); - il.Emit(OpCodes.Ldobj, targetType); -#endif - il.Emit(OpCodes.Stloc, target); - il.Emit(OpCodes.Ldloca, target); - } - else - { - il.Emit(OpCodes.Castclass, targetType); - } - } - - /// - /// Sets up invocation argument. - /// - /// IL generator to use. - /// Argument type. - /// Argument position. - protected static void SetupArgument(ILGenerator il, Type argumentType, int argumentPosition) - { - il.Emit(OpCodes.Ldarg, argumentPosition); - if (argumentType.IsValueType) - { -#if NET_2_0 - il.Emit(OpCodes.Unbox_Any, argumentType); -#else - il.Emit(OpCodes.Unbox, argumentType); - il.Emit(OpCodes.Ldobj, argumentType); -#endif - } - else - { - il.Emit(OpCodes.Castclass, argumentType); - } - } - - /// - /// Generates method invocation code. - /// - /// IL generator to use. - /// Flag specifying whether method is static. - /// Flag specifying whether method is on the value type. - /// Method to invoke. - protected static void InvokeMethod(ILGenerator il, bool isStatic, bool isValueType, MethodInfo method) - { - if (isStatic || isValueType) - { - il.EmitCall(OpCodes.Call, method, null); - } - else - { - il.EmitCall(OpCodes.Callvirt, method, null); - } - } - - /// - /// Generates code to process return value if necessary. - /// - /// IL generator to use. - /// Type of the return value. - protected static void ProcessReturnValue(ILGenerator il, Type returnValueType) - { - if (returnValueType == typeof(void)) - { - il.Emit(OpCodes.Ldnull); - } - else if (returnValueType.IsValueType) - { - il.Emit(OpCodes.Box, returnValueType); - } - } - - /// - /// Generates code that throws . - /// - /// IL generator to use. - /// Error message to use. - protected static void ThrowInvalidOperationException(ILGenerator il, string message) - { - il.Emit(OpCodes.Ldstr, message); - il.Emit(OpCodes.Newobj, invalidOperationException); - il.Emit(OpCodes.Throw); - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; + +#endregion + +namespace Spring.Reflection.Dynamic +{ + /// + /// Base class for dynamic members. + /// + /// Aleksandar Seovic + public class BaseDynamicMember + { + /// + /// Method attributes constant. + /// + protected const MethodAttributes METHOD_ATTRIBUTES = + MethodAttributes.Public | MethodAttributes.HideBySig + | MethodAttributes.NewSlot | MethodAttributes.Virtual + | MethodAttributes.Final; + + private static ConstructorInfo invalidOperationException = + typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) }); + + /// + /// Sets up target instance for invocation. + /// + /// IL generator to use. + /// Type of target instance. + protected static void SetupTargetInstance(ILGenerator il, Type targetType) + { + il.Emit(OpCodes.Ldarg_1); + if (targetType.IsValueType) + { + LocalBuilder target = il.DeclareLocal(targetType); +#if NET_2_0 + il.Emit(OpCodes.Unbox_Any, targetType); +#else + il.Emit(OpCodes.Unbox, targetType); + il.Emit(OpCodes.Ldobj, targetType); +#endif + il.Emit(OpCodes.Stloc, target); + il.Emit(OpCodes.Ldloca, target); + } + else + { + il.Emit(OpCodes.Castclass, targetType); + } + } + + /// + /// Sets up invocation argument. + /// + /// IL generator to use. + /// Argument type. + /// Argument position. + protected static void SetupArgument(ILGenerator il, Type argumentType, int argumentPosition) + { + il.Emit(OpCodes.Ldarg, argumentPosition); + if (argumentType.IsValueType) + { +#if NET_2_0 + il.Emit(OpCodes.Unbox_Any, argumentType); +#else + il.Emit(OpCodes.Unbox, argumentType); + il.Emit(OpCodes.Ldobj, argumentType); +#endif + } + else + { + il.Emit(OpCodes.Castclass, argumentType); + } + } + + /// + /// Generates method invocation code. + /// + /// IL generator to use. + /// Flag specifying whether method is static. + /// Flag specifying whether method is on the value type. + /// Method to invoke. + protected static void InvokeMethod(ILGenerator il, bool isStatic, bool isValueType, MethodInfo method) + { + if (isStatic || isValueType) + { + il.EmitCall(OpCodes.Call, method, null); + } + else + { + il.EmitCall(OpCodes.Callvirt, method, null); + } + } + + /// + /// Generates code to process return value if necessary. + /// + /// IL generator to use. + /// Type of the return value. + protected static void ProcessReturnValue(ILGenerator il, Type returnValueType) + { + if (returnValueType == typeof(void)) + { + il.Emit(OpCodes.Ldnull); + } + else if (returnValueType.IsValueType) + { + il.Emit(OpCodes.Box, returnValueType); + } + } + + /// + /// Generates code that throws . + /// + /// IL generator to use. + /// Error message to use. + protected static void ThrowInvalidOperationException(ILGenerator il, string message) + { + il.Emit(OpCodes.Ldstr, message); + il.Emit(OpCodes.Newobj, invalidOperationException); + il.Emit(OpCodes.Throw); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicConstructor.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicConstructor.cs index 64adb46c..f34d0e22 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicConstructor.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicConstructor.cs @@ -1,199 +1,198 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; -using Spring.Util; - -#endregion - -namespace Spring.Reflection.Dynamic -{ - #region IDynamicConstructor interface - - /// - /// Defines constructors that dynamic constructor class has to implement. - /// - public interface IDynamicConstructor - { - /// - /// Invokes dynamic constructor. - /// - /// - /// Constructor arguments. - /// - /// - /// A constructor value. - /// - object Invoke(object[] arguments); - } - - #endregion - - #region Safe wrapper - - /// - /// Safe wrapper for the dynamic constructor. - /// - /// - /// will attempt to use dynamic - /// constructor if possible, but it will fall back to standard - /// reflection if necessary. - /// - public class SafeConstructor : IDynamicConstructor - { - private ConstructorInfo constructor; - private IDynamicConstructor dynamicConstructor; - private bool isOptimized = false; - - /// - /// Creates a new instance of the safe constructor wrapper. - /// - /// Constructor to wrap. - public SafeConstructor(ConstructorInfo constructor) - { - this.constructor = constructor; - if (constructor.IsPublic && - ReflectionUtils.IsTypeVisible(constructor.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - this.dynamicConstructor = DynamicConstructor.Create(constructor); - this.isOptimized = true; - } - } - - /// - /// Invokes dynamic constructor. - /// - /// - /// Constructor arguments. - /// - /// - /// A constructor value. - /// - public object Invoke(object[] arguments) - { - if (isOptimized) - { - // try dynamic constructor first but fall back to standard reflection - // if arguments are causing InvalidCastExceptions - try - { - return dynamicConstructor.Invoke(arguments); - } - catch (InvalidCastException) - { - isOptimized = false; - return constructor.Invoke(arguments); - } - } - else - { - return constructor.Invoke(arguments); - } - } - } - - #endregion - - /// - /// Factory class for dynamic constructors. - /// - /// Aleksandar Seovic - /// $Id: DynamicConstructor.cs,v 1.1 2007/08/08 04:05:37 bbaia Exp $ - public class DynamicConstructor : BaseDynamicMember - { - private static readonly CreateConstructorCallback s_createCallback = new CreateConstructorCallback(CreateInternal); - - #region Create Constructor - - /// - /// Creates dynamic constructor instance for the specified . - /// - /// Constructor info to create dynamic constructor for. - /// Dynamic constructor for the specified . - public static IDynamicConstructor Create(ConstructorInfo constructor) - { - AssertUtils.ArgumentNotNull(constructor, "You cannot create a dynamic constructor for a null value."); - - IDynamicConstructor dynamicConstructor = DynamicReflectionManager.GetDynamicConstructor(constructor, s_createCallback); - return dynamicConstructor; - } - - private static IDynamicConstructor CreateInternal(ConstructorInfo constructor) - { - IDynamicConstructor dynamicConstructor = null; - - TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Ctor_" + constructor.DeclaringType.Name); - tb.AddInterfaceImplementation(typeof(IDynamicConstructor)); - - GenerateInvoke(tb, constructor); - - Type dynamicConstructorType = tb.CreateType(); - ConstructorInfo ctor = dynamicConstructorType.GetConstructor(Type.EmptyTypes); - dynamicConstructor = (IDynamicConstructor) ctor.Invoke(ObjectUtils.EmptyObjects); - - return dynamicConstructor; - } - - private static void GenerateInvoke(TypeBuilder tb, ConstructorInfo constructor) - { - MethodBuilder invokeMethod = - tb.DefineMethod("Invoke", METHOD_ATTRIBUTES, typeof(object), new Type[] {typeof(object[])}); - invokeMethod.DefineParameter(1, ParameterAttributes.None, "args"); - - ILGenerator il = invokeMethod.GetILGenerator(); - - Type[] argTypes = ReflectionUtils.GetParameterTypes(constructor); - for (int i = 0; i < argTypes.Length; i++) - { - SetupConstructorArgument(il, argTypes[i], i); - } - - il.Emit(OpCodes.Newobj, constructor); - ProcessReturnValue(il, constructor.DeclaringType); - il.Emit(OpCodes.Ret); - } - - private static void SetupConstructorArgument(ILGenerator il, Type argumentType, int argumentPosition) - { - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldc_I4, argumentPosition); - il.Emit(OpCodes.Ldelem_Ref); - if (argumentType.IsValueType) - { -#if NET_2_0 - il.Emit(OpCodes.Unbox_Any, argumentType); -#else - il.Emit(OpCodes.Unbox, argumentType); - il.Emit(OpCodes.Ldobj, argumentType); -#endif - } - else - { - il.Emit(OpCodes.Castclass, argumentType); - } - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; +using Spring.Util; + +#endregion + +namespace Spring.Reflection.Dynamic +{ + #region IDynamicConstructor interface + + /// + /// Defines constructors that dynamic constructor class has to implement. + /// + public interface IDynamicConstructor + { + /// + /// Invokes dynamic constructor. + /// + /// + /// Constructor arguments. + /// + /// + /// A constructor value. + /// + object Invoke(object[] arguments); + } + + #endregion + + #region Safe wrapper + + /// + /// Safe wrapper for the dynamic constructor. + /// + /// + /// will attempt to use dynamic + /// constructor if possible, but it will fall back to standard + /// reflection if necessary. + /// + public class SafeConstructor : IDynamicConstructor + { + private ConstructorInfo constructor; + private IDynamicConstructor dynamicConstructor; + private bool isOptimized = false; + + /// + /// Creates a new instance of the safe constructor wrapper. + /// + /// Constructor to wrap. + public SafeConstructor(ConstructorInfo constructor) + { + this.constructor = constructor; + if (constructor.IsPublic && + ReflectionUtils.IsTypeVisible(constructor.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + this.dynamicConstructor = DynamicConstructor.Create(constructor); + this.isOptimized = true; + } + } + + /// + /// Invokes dynamic constructor. + /// + /// + /// Constructor arguments. + /// + /// + /// A constructor value. + /// + public object Invoke(object[] arguments) + { + if (isOptimized) + { + // try dynamic constructor first but fall back to standard reflection + // if arguments are causing InvalidCastExceptions + try + { + return dynamicConstructor.Invoke(arguments); + } + catch (InvalidCastException) + { + isOptimized = false; + return constructor.Invoke(arguments); + } + } + else + { + return constructor.Invoke(arguments); + } + } + } + + #endregion + + /// + /// Factory class for dynamic constructors. + /// + /// Aleksandar Seovic + public class DynamicConstructor : BaseDynamicMember + { + private static readonly CreateConstructorCallback s_createCallback = new CreateConstructorCallback(CreateInternal); + + #region Create Constructor + + /// + /// Creates dynamic constructor instance for the specified . + /// + /// Constructor info to create dynamic constructor for. + /// Dynamic constructor for the specified . + public static IDynamicConstructor Create(ConstructorInfo constructor) + { + AssertUtils.ArgumentNotNull(constructor, "You cannot create a dynamic constructor for a null value."); + + IDynamicConstructor dynamicConstructor = DynamicReflectionManager.GetDynamicConstructor(constructor, s_createCallback); + return dynamicConstructor; + } + + private static IDynamicConstructor CreateInternal(ConstructorInfo constructor) + { + IDynamicConstructor dynamicConstructor = null; + + TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Ctor_" + constructor.DeclaringType.Name); + tb.AddInterfaceImplementation(typeof(IDynamicConstructor)); + + GenerateInvoke(tb, constructor); + + Type dynamicConstructorType = tb.CreateType(); + ConstructorInfo ctor = dynamicConstructorType.GetConstructor(Type.EmptyTypes); + dynamicConstructor = (IDynamicConstructor) ctor.Invoke(ObjectUtils.EmptyObjects); + + return dynamicConstructor; + } + + private static void GenerateInvoke(TypeBuilder tb, ConstructorInfo constructor) + { + MethodBuilder invokeMethod = + tb.DefineMethod("Invoke", METHOD_ATTRIBUTES, typeof(object), new Type[] {typeof(object[])}); + invokeMethod.DefineParameter(1, ParameterAttributes.None, "args"); + + ILGenerator il = invokeMethod.GetILGenerator(); + + Type[] argTypes = ReflectionUtils.GetParameterTypes(constructor); + for (int i = 0; i < argTypes.Length; i++) + { + SetupConstructorArgument(il, argTypes[i], i); + } + + il.Emit(OpCodes.Newobj, constructor); + ProcessReturnValue(il, constructor.DeclaringType); + il.Emit(OpCodes.Ret); + } + + private static void SetupConstructorArgument(ILGenerator il, Type argumentType, int argumentPosition) + { + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldc_I4, argumentPosition); + il.Emit(OpCodes.Ldelem_Ref); + if (argumentType.IsValueType) + { +#if NET_2_0 + il.Emit(OpCodes.Unbox_Any, argumentType); +#else + il.Emit(OpCodes.Unbox, argumentType); + il.Emit(OpCodes.Ldobj, argumentType); +#endif + } + else + { + il.Emit(OpCodes.Castclass, argumentType); + } + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicField.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicField.cs index 18596835..4c0f4710 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicField.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicField.cs @@ -1,487 +1,485 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; -using Spring.Util; - -#endregion - -namespace Spring.Reflection.Dynamic -{ - #region IDynamicField interface - - /// - /// Defines methods that dynamic field class has to implement. - /// - public interface IDynamicField - { - /// - /// Gets the value of the dynamic field for the specified target object. - /// - /// - /// Target object to get field value from. - /// - /// - /// A field value. - /// - object GetValue(object target); - - /// - /// Gets the value of the dynamic field for the specified target object. - /// - /// - /// Target object to set field value on. - /// - /// - /// A new field value. - /// - void SetValue(object target, object value); - } - - #endregion - - #region Safe wrapper - - /// - /// Safe wrapper for the dynamic field. - /// - /// - /// will attempt to use dynamic - /// field if possible, but it will fall back to standard - /// reflection if necessary. - /// - public class SafeField : IDynamicField - { - private readonly FieldInfo fieldInfo; -#if NET_2_0 - #region Cache - - private static readonly IDictionary fieldCache = new Hashtable(); - - /// - /// Holds cached Getter/Setter delegates for a Field - /// - private class DynamicFieldCacheEntry - { - public readonly GetterDelegate Getter; - public readonly SetterDelegate Setter; - - public DynamicFieldCacheEntry(GetterDelegate getter, SetterDelegate setter) - { - Getter = getter; - Setter = setter; - } - } - - /// - /// Obtains cached fieldInfo or creates a new entry, if none is found. - /// - private static DynamicFieldCacheEntry GetOrCreateDynamicField(FieldInfo field) - { - DynamicFieldCacheEntry fieldInfo = (DynamicFieldCacheEntry)fieldCache[field]; - if (fieldInfo == null) - { - fieldInfo = new DynamicFieldCacheEntry(DynamicReflectionManager.CreateFieldGetter(field), DynamicReflectionManager.CreateFieldSetter(field)); - lock (fieldCache) - { - fieldCache[field] = fieldInfo; - } - } - return fieldInfo; - } - - #endregion - - private readonly GetterDelegate getter; - private readonly SetterDelegate setter; - - /// - /// Creates a new instance of the safe field wrapper. - /// - /// Field to wrap. - public SafeField(FieldInfo field) - { - AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); - - fieldInfo = field; - DynamicFieldCacheEntry fi = GetOrCreateDynamicField(field); - getter = fi.Getter; - setter = fi.Setter; - } - - /// - /// Gets the value of the dynamic field for the specified target object. - /// - /// - /// Target object to get field value from. - /// - /// - /// A field value. - /// - public object GetValue(object target) - { - return getter(target); - } - - /// - /// Gets the value of the dynamic field for the specified target object. - /// - /// - /// Target object to set field value on. - /// - /// - /// A new field value. - /// - public void SetValue(object target, object value) - { - setter(target, value); - } - -#else - /// - /// Returns a implementation - /// by determining the fastest possible dynamic access strategy - /// - /// the field to be wrapped - /// an instance for accessing the - /// field represented by the given - public static IDynamicField CreateFrom(FieldInfo field) - { - AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); - - IDynamicField dynamicField; - - if (field.IsPublic && - ReflectionUtils.IsTypeVisible(field.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - dynamicField = DynamicField.Create(field); - } - else - { - dynamicField = new SafeField(field); - } - - return dynamicField; - } - - private readonly IDynamicField dynamicField; - private readonly bool isOptimizedGet = false; - private bool isOptimizedSet = false; - private readonly bool canSet; - - /// - /// Creates a new instance of the safe field wrapper. - /// - /// Field to wrap. - public SafeField(FieldInfo field) - { - AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); - - this.fieldInfo = field; - this.canSet = (!fieldInfo.IsLiteral - && !fieldInfo.IsInitOnly - && !(fieldInfo.DeclaringType.IsValueType && !fieldInfo.IsStatic)); - - if (fieldInfo.IsPublic && - ReflectionUtils.IsTypeVisible(fieldInfo.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - dynamicField = DynamicField.Create(fieldInfo); - isOptimizedGet = isOptimizedSet = true; - } - } - - /// - /// Gets the value of the dynamic field for the specified target object. - /// - /// - /// Target object to get field value from. - /// - /// - /// A field value. - /// - public object GetValue(object target) - { - if (isOptimizedGet) - { - return dynamicField.GetValue(target); - } - else - { - return fieldInfo.GetValue(target); - } - } - - /// - /// Gets the value of the dynamic field for the specified target object. - /// - /// - /// Target object to set field value on. - /// - /// - /// A new field value. - /// - public void SetValue(object target, object value) - { - if (isOptimizedSet) - { - try - { - dynamicField.SetValue(target, value); - } - catch (InvalidCastException) - { - isOptimizedSet = false; - if (!canSet) - { - throw new InvalidOperationException("Cannot set value of a read-only field or a constant."); - } - - fieldInfo.SetValue(target, value); - } - } - else - { - if (!canSet) - { - throw new InvalidOperationException("Cannot set value of a read-only field or a constant."); - } - fieldInfo.SetValue(target, value); - } - } -#endif - internal FieldInfo FieldInfo - { - get { return fieldInfo; } - } - } - - #endregion - -#if NET_2_0 - /// - /// Factory class for dynamic fields. - /// - /// Aleksandar Seovic - /// $Id: DynamicField.cs,v 1.4 2008/05/16 10:02:39 oakinger Exp $ - public class DynamicField : BaseDynamicMember - { - /// - /// Creates dynamic field instance for the specified . - /// - /// Field info to create dynamic field for. - /// Dynamic field for the specified . - public static IDynamicField Create(FieldInfo field) - { - AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); - - IDynamicField dynamicField = new SafeField(field); - return dynamicField; - } - } -#else - /// - /// Factory class for dynamic fields. - /// - /// Aleksandar Seovic - /// $Id: DynamicField.cs,v 1.4 2008/05/16 10:02:39 oakinger Exp $ - public class DynamicField : BaseDynamicMember - { - private static readonly CreateFieldCallback s_createCallback = new CreateFieldCallback(CreateInternal); - - #region Create Method - - /// - /// Creates dynamic field instance for the specified . - /// - /// Field info to create dynamic field for. - /// Dynamic field for the specified . - public static IDynamicField Create(FieldInfo field) - { - AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); - - IDynamicField dynamicField = DynamicReflectionManager.GetDynamicField(field, s_createCallback); - return dynamicField; - } - - private static IDynamicField CreateInternal(FieldInfo field) - { - IDynamicField dynamicField = null; - - TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Field_" + field.Name); - tb.AddInterfaceImplementation(typeof(IDynamicField)); - - GenerateGetValue(tb, field); - GenerateSetValue(tb, field); - - Type dynamicFieldType = tb.CreateType(); - ConstructorInfo ctor = dynamicFieldType.GetConstructor(Type.EmptyTypes); - dynamicField = (IDynamicField)ctor.Invoke(ObjectUtils.EmptyObjects); - - return dynamicField; - } - - private static void GenerateGetValue(TypeBuilder tb, FieldInfo field) - { - MethodBuilder getValueMethod = - tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object) }); - getValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); - - ILGenerator il = getValueMethod.GetILGenerator(); - if (field.IsLiteral) - { - EmitConstant(il, field.GetValue(field.FieldType)); - } - else if (field.IsStatic) - { - il.Emit(OpCodes.Ldsfld, field); - } - else - { - SetupTargetInstance(il, field.DeclaringType); - il.Emit(OpCodes.Ldfld, field); - } - ProcessReturnValue(il, field.FieldType); - il.Emit(OpCodes.Ret); - } - - private static void EmitConstant(ILGenerator il, object value) - { - if (value is String) - { - il.Emit(OpCodes.Ldstr, (string)value); - return; - } - - if (value is bool) - { - if ((bool)value) - { - il.Emit(OpCodes.Ldc_I4_1); - } - else - { - il.Emit(OpCodes.Ldc_I4_0); - } - return; - } - - if (value is Char) - { - il.Emit(OpCodes.Ldc_I4, (Char)value); - il.Emit(OpCodes.Conv_I2); - return; - } - - if (value is byte) - { - il.Emit(OpCodes.Ldc_I4, (byte)value); - il.Emit(OpCodes.Conv_I1); - } - else if (value is Int16) - { - il.Emit(OpCodes.Ldc_I4, (Int16)value); - il.Emit(OpCodes.Conv_I2); - } - else if (value is Int32) - { - il.Emit(OpCodes.Ldc_I4, (Int32)value); - } - else if (value is Int64) - { - il.Emit(OpCodes.Ldc_I8, (Int64)value); - } - else if (value is UInt16) - { - il.Emit(OpCodes.Ldc_I4, (UInt16)value); - il.Emit(OpCodes.Conv_U2); - } - else if (value is UInt32) - { - il.Emit(OpCodes.Ldc_I4, (UInt32)value); - il.Emit(OpCodes.Conv_U4); - } - else if (value is UInt64) - { - il.Emit(OpCodes.Ldc_I8, (UInt64)value); - il.Emit(OpCodes.Conv_U8); - } - else if (value is Single) - { - il.Emit(OpCodes.Ldc_R4, (Single)value); - } - else if (value is Double) - { - il.Emit(OpCodes.Ldc_R8, (Double)value); - } - } - - private static void GenerateSetValue(TypeBuilder tb, FieldInfo field) - { - MethodBuilder setValueMethod = - tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void), - new Type[] { typeof(object), typeof(object) }); - setValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); - setValueMethod.DefineParameter(2, ParameterAttributes.None, "value"); - - ILGenerator il = setValueMethod.GetILGenerator(); - if (!(field.IsInitOnly || field.IsLiteral)) - { - bool isValueType = field.DeclaringType.IsValueType; - if (isValueType && !field.IsStatic) - { - ThrowInvalidOperationException(il, "Cannot set field value on a value type due to boxing."); - } - else - { - bool isStatic = field.IsStatic; - - if (!isStatic) - { - SetupTargetInstance(il, field.DeclaringType); - } - - SetupArgument(il, field.FieldType, 2); - if (!isStatic) - { - il.Emit(OpCodes.Stfld, field); - } - else - { - il.Emit(OpCodes.Stsfld, field); - } - il.Emit(OpCodes.Ret); - } - } - else - { - ThrowInvalidOperationException(il, "Cannot set value of a read-only field or a constant."); - } - } - - #endregion - } -#endif // NET_2_0 -} - +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using Spring.Util; + +#endregion + +namespace Spring.Reflection.Dynamic +{ + #region IDynamicField interface + + /// + /// Defines methods that dynamic field class has to implement. + /// + public interface IDynamicField + { + /// + /// Gets the value of the dynamic field for the specified target object. + /// + /// + /// Target object to get field value from. + /// + /// + /// A field value. + /// + object GetValue(object target); + + /// + /// Gets the value of the dynamic field for the specified target object. + /// + /// + /// Target object to set field value on. + /// + /// + /// A new field value. + /// + void SetValue(object target, object value); + } + + #endregion + + #region Safe wrapper + + /// + /// Safe wrapper for the dynamic field. + /// + /// + /// will attempt to use dynamic + /// field if possible, but it will fall back to standard + /// reflection if necessary. + /// + public class SafeField : IDynamicField + { + private readonly FieldInfo fieldInfo; +#if NET_2_0 + #region Cache + + private static readonly IDictionary fieldCache = new Hashtable(); + + /// + /// Holds cached Getter/Setter delegates for a Field + /// + private class DynamicFieldCacheEntry + { + public readonly GetterDelegate Getter; + public readonly SetterDelegate Setter; + + public DynamicFieldCacheEntry(GetterDelegate getter, SetterDelegate setter) + { + Getter = getter; + Setter = setter; + } + } + + /// + /// Obtains cached fieldInfo or creates a new entry, if none is found. + /// + private static DynamicFieldCacheEntry GetOrCreateDynamicField(FieldInfo field) + { + DynamicFieldCacheEntry fieldInfo = (DynamicFieldCacheEntry)fieldCache[field]; + if (fieldInfo == null) + { + fieldInfo = new DynamicFieldCacheEntry(DynamicReflectionManager.CreateFieldGetter(field), DynamicReflectionManager.CreateFieldSetter(field)); + lock (fieldCache) + { + fieldCache[field] = fieldInfo; + } + } + return fieldInfo; + } + + #endregion + + private readonly GetterDelegate getter; + private readonly SetterDelegate setter; + + /// + /// Creates a new instance of the safe field wrapper. + /// + /// Field to wrap. + public SafeField(FieldInfo field) + { + AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); + + fieldInfo = field; + DynamicFieldCacheEntry fi = GetOrCreateDynamicField(field); + getter = fi.Getter; + setter = fi.Setter; + } + + /// + /// Gets the value of the dynamic field for the specified target object. + /// + /// + /// Target object to get field value from. + /// + /// + /// A field value. + /// + public object GetValue(object target) + { + return getter(target); + } + + /// + /// Gets the value of the dynamic field for the specified target object. + /// + /// + /// Target object to set field value on. + /// + /// + /// A new field value. + /// + public void SetValue(object target, object value) + { + setter(target, value); + } + +#else + /// + /// Returns a implementation + /// by determining the fastest possible dynamic access strategy + /// + /// the field to be wrapped + /// an instance for accessing the + /// field represented by the given + public static IDynamicField CreateFrom(FieldInfo field) + { + AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); + + IDynamicField dynamicField; + + if (field.IsPublic && + ReflectionUtils.IsTypeVisible(field.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + dynamicField = DynamicField.Create(field); + } + else + { + dynamicField = new SafeField(field); + } + + return dynamicField; + } + + private readonly IDynamicField dynamicField; + private readonly bool isOptimizedGet = false; + private bool isOptimizedSet = false; + private readonly bool canSet; + + /// + /// Creates a new instance of the safe field wrapper. + /// + /// Field to wrap. + public SafeField(FieldInfo field) + { + AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); + + this.fieldInfo = field; + this.canSet = (!fieldInfo.IsLiteral + && !fieldInfo.IsInitOnly + && !(fieldInfo.DeclaringType.IsValueType && !fieldInfo.IsStatic)); + + if (fieldInfo.IsPublic && + ReflectionUtils.IsTypeVisible(fieldInfo.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + dynamicField = DynamicField.Create(fieldInfo); + isOptimizedGet = isOptimizedSet = true; + } + } + + /// + /// Gets the value of the dynamic field for the specified target object. + /// + /// + /// Target object to get field value from. + /// + /// + /// A field value. + /// + public object GetValue(object target) + { + if (isOptimizedGet) + { + return dynamicField.GetValue(target); + } + else + { + return fieldInfo.GetValue(target); + } + } + + /// + /// Gets the value of the dynamic field for the specified target object. + /// + /// + /// Target object to set field value on. + /// + /// + /// A new field value. + /// + public void SetValue(object target, object value) + { + if (isOptimizedSet) + { + try + { + dynamicField.SetValue(target, value); + } + catch (InvalidCastException) + { + isOptimizedSet = false; + if (!canSet) + { + throw new InvalidOperationException("Cannot set value of a read-only field or a constant."); + } + + fieldInfo.SetValue(target, value); + } + } + else + { + if (!canSet) + { + throw new InvalidOperationException("Cannot set value of a read-only field or a constant."); + } + fieldInfo.SetValue(target, value); + } + } +#endif + internal FieldInfo FieldInfo + { + get { return fieldInfo; } + } + } + + #endregion + +#if NET_2_0 + /// + /// Factory class for dynamic fields. + /// + /// Aleksandar Seovic + public class DynamicField : BaseDynamicMember + { + /// + /// Creates dynamic field instance for the specified . + /// + /// Field info to create dynamic field for. + /// Dynamic field for the specified . + public static IDynamicField Create(FieldInfo field) + { + AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); + + IDynamicField dynamicField = new SafeField(field); + return dynamicField; + } + } +#else + /// + /// Factory class for dynamic fields. + /// + /// Aleksandar Seovic + public class DynamicField : BaseDynamicMember + { + private static readonly CreateFieldCallback s_createCallback = new CreateFieldCallback(CreateInternal); + + #region Create Method + + /// + /// Creates dynamic field instance for the specified . + /// + /// Field info to create dynamic field for. + /// Dynamic field for the specified . + public static IDynamicField Create(FieldInfo field) + { + AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value."); + + IDynamicField dynamicField = DynamicReflectionManager.GetDynamicField(field, s_createCallback); + return dynamicField; + } + + private static IDynamicField CreateInternal(FieldInfo field) + { + IDynamicField dynamicField = null; + + TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Field_" + field.Name); + tb.AddInterfaceImplementation(typeof(IDynamicField)); + + GenerateGetValue(tb, field); + GenerateSetValue(tb, field); + + Type dynamicFieldType = tb.CreateType(); + ConstructorInfo ctor = dynamicFieldType.GetConstructor(Type.EmptyTypes); + dynamicField = (IDynamicField)ctor.Invoke(ObjectUtils.EmptyObjects); + + return dynamicField; + } + + private static void GenerateGetValue(TypeBuilder tb, FieldInfo field) + { + MethodBuilder getValueMethod = + tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object) }); + getValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); + + ILGenerator il = getValueMethod.GetILGenerator(); + if (field.IsLiteral) + { + EmitConstant(il, field.GetValue(field.FieldType)); + } + else if (field.IsStatic) + { + il.Emit(OpCodes.Ldsfld, field); + } + else + { + SetupTargetInstance(il, field.DeclaringType); + il.Emit(OpCodes.Ldfld, field); + } + ProcessReturnValue(il, field.FieldType); + il.Emit(OpCodes.Ret); + } + + private static void EmitConstant(ILGenerator il, object value) + { + if (value is String) + { + il.Emit(OpCodes.Ldstr, (string)value); + return; + } + + if (value is bool) + { + if ((bool)value) + { + il.Emit(OpCodes.Ldc_I4_1); + } + else + { + il.Emit(OpCodes.Ldc_I4_0); + } + return; + } + + if (value is Char) + { + il.Emit(OpCodes.Ldc_I4, (Char)value); + il.Emit(OpCodes.Conv_I2); + return; + } + + if (value is byte) + { + il.Emit(OpCodes.Ldc_I4, (byte)value); + il.Emit(OpCodes.Conv_I1); + } + else if (value is Int16) + { + il.Emit(OpCodes.Ldc_I4, (Int16)value); + il.Emit(OpCodes.Conv_I2); + } + else if (value is Int32) + { + il.Emit(OpCodes.Ldc_I4, (Int32)value); + } + else if (value is Int64) + { + il.Emit(OpCodes.Ldc_I8, (Int64)value); + } + else if (value is UInt16) + { + il.Emit(OpCodes.Ldc_I4, (UInt16)value); + il.Emit(OpCodes.Conv_U2); + } + else if (value is UInt32) + { + il.Emit(OpCodes.Ldc_I4, (UInt32)value); + il.Emit(OpCodes.Conv_U4); + } + else if (value is UInt64) + { + il.Emit(OpCodes.Ldc_I8, (UInt64)value); + il.Emit(OpCodes.Conv_U8); + } + else if (value is Single) + { + il.Emit(OpCodes.Ldc_R4, (Single)value); + } + else if (value is Double) + { + il.Emit(OpCodes.Ldc_R8, (Double)value); + } + } + + private static void GenerateSetValue(TypeBuilder tb, FieldInfo field) + { + MethodBuilder setValueMethod = + tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void), + new Type[] { typeof(object), typeof(object) }); + setValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); + setValueMethod.DefineParameter(2, ParameterAttributes.None, "value"); + + ILGenerator il = setValueMethod.GetILGenerator(); + if (!(field.IsInitOnly || field.IsLiteral)) + { + bool isValueType = field.DeclaringType.IsValueType; + if (isValueType && !field.IsStatic) + { + ThrowInvalidOperationException(il, "Cannot set field value on a value type due to boxing."); + } + else + { + bool isStatic = field.IsStatic; + + if (!isStatic) + { + SetupTargetInstance(il, field.DeclaringType); + } + + SetupArgument(il, field.FieldType, 2); + if (!isStatic) + { + il.Emit(OpCodes.Stfld, field); + } + else + { + il.Emit(OpCodes.Stsfld, field); + } + il.Emit(OpCodes.Ret); + } + } + else + { + ThrowInvalidOperationException(il, "Cannot set value of a read-only field or a constant."); + } + } + + #endregion + } +#endif // NET_2_0 +} + diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicIndexer.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicIndexer.cs index f55f68c4..8f706155 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicIndexer.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicIndexer.cs @@ -1,519 +1,518 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; -using Spring.Util; - -#endregion - -namespace Spring.Reflection.Dynamic -{ - #region IDynamicIndexer interface - - /// - /// Defines methods that dynamic indexer class has to implement. - /// - public interface IDynamicIndexer - { - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to get the indexer value from. - /// - /// - /// Indexer argument. - /// - /// - /// A indexer value. - /// - object GetValue(object target, int index); - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to get the indexer value from. - /// - /// - /// Indexer argument. - /// - /// - /// A indexer value. - /// - object GetValue(object target, object index); - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to get the indexer value from. - /// - /// - /// Indexer arguments. - /// - /// - /// A indexer value. - /// - object GetValue(object target, object[] index); - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to set the indexer value on. - /// - /// - /// Indexer argument. - /// - /// - /// A new indexer value. - /// - void SetValue(object target, int index, object value); - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to set the indexer value on. - /// - /// - /// Indexer argument. - /// - /// - /// A new indexer value. - /// - void SetValue(object target, object index, object value); - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to set the indexer value on. - /// - /// - /// Indexer arguments. - /// - /// - /// A new indexer value. - /// - void SetValue(object target, object[] index, object value); - } - - #endregion - - #region Safe wrapper - - /// - /// Safe wrapper for the dynamic indexer. - /// - /// - /// will attempt to use dynamic - /// indexer if possible, but it will fall back to standard - /// reflection if necessary. - /// - public class SafeIndexer : IDynamicIndexer - { - private PropertyInfo indexerProperty; - private IDynamicIndexer dynamicIndexer; - private bool isOptimizedGet = false; - private bool isOptimizedSet = false; - - /// - /// Creates a new instance of the safe indexer wrapper. - /// - /// Indexer to wrap. - public SafeIndexer(PropertyInfo indexer) - { - this.indexerProperty = indexer; - - if (indexer.CanRead - && indexer.GetGetMethod() != null - && ReflectionUtils.IsTypeVisible(indexer.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - dynamicIndexer = DynamicIndexer.Create(indexer); - isOptimizedGet = true; - } - if (indexer.CanWrite - && indexer.GetSetMethod() != null - && ReflectionUtils.IsTypeVisible(indexer.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - if (dynamicIndexer == null) - { - dynamicIndexer = DynamicIndexer.Create(indexer); - } - isOptimizedSet = true; - } - } - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to get indexer value from. - /// - /// - /// Indexer arguments. - /// - /// - /// A indexer value. - /// - public object GetValue(object target, int index) - { - if (isOptimizedGet) - { - return dynamicIndexer.GetValue(target, index); - } - else - { - return indexerProperty.GetValue(target, new object[] { index }); - } - } - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to get the indexer value from. - /// - /// - /// Indexer argument. - /// - /// - /// A indexer value. - /// - public object GetValue(object target, object index) - { - if (isOptimizedGet) - { - return dynamicIndexer.GetValue(target, index); - } - else - { - return indexerProperty.GetValue(target, new object[] { index }); - } - } - - /// - /// Gets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to get indexer value from. - /// - /// - /// Indexer arguments. - /// - /// - /// A indexer value. - /// - public object GetValue(object target, object[] index) - { - if (isOptimizedGet) - { - return dynamicIndexer.GetValue(target, index); - } - else - { - return indexerProperty.GetValue(target, index); - } - } - - /// - /// Sets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to set indexer value on. - /// - /// - /// Indexer arguments. - /// - /// - /// A new indexer value. - /// - public void SetValue(object target, int index, object value) - { - if (isOptimizedSet) - { - try - { - dynamicIndexer.SetValue(target, index, value); - } - catch (InvalidCastException) - { - isOptimizedSet = false; - indexerProperty.SetValue(target, value, new object[] { index }); - } - } - else - { - indexerProperty.SetValue(target, value, new object[] { index }); - } - } - - /// - /// Sets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to set indexer value on. - /// - /// - /// Indexer arguments. - /// - /// - /// A new indexer value. - /// - public void SetValue(object target, object index, object value) - { - if (isOptimizedSet) - { - try - { - dynamicIndexer.SetValue(target, index, value); - } - catch (InvalidCastException) - { - isOptimizedSet = false; - indexerProperty.SetValue(target, value, new object[] { index }); - } - } - else - { - indexerProperty.SetValue(target, value, new object[] { index }); - } - } - - /// - /// Sets the value of the dynamic indexer for the specified target object. - /// - /// - /// Target object to set indexer value on. - /// - /// - /// Indexer arguments. - /// - /// - /// A new indexer value. - /// - public void SetValue(object target, object[] index, object value) - { - if (isOptimizedSet) - { - try - { - dynamicIndexer.SetValue(target, index, value); - } - catch (InvalidCastException) - { - isOptimizedSet = false; - indexerProperty.SetValue(target, value, index); - } - } - else - { - indexerProperty.SetValue(target, value, index); - } - } - - /// - /// Internal PropertyInfo accessor. - /// - internal PropertyInfo IndexerProperty - { - get { return indexerProperty; } - } - } - - #endregion - - /// - /// Factory class for dynamic indexers. - /// - /// Aleksandar Seovic - /// $Id: DynamicIndexer.cs,v 1.1 2007/08/08 04:05:37 bbaia Exp $ - public class DynamicIndexer : BaseDynamicMember - { - private static readonly CreateIndexerCallback s_createCallback = new CreateIndexerCallback(CreateInternal); - - #region Create Method - - /// - /// Creates dynamic indexer instance for the specified . - /// - /// Indexer info to create dynamic indexer for. - /// Dynamic indexer for the specified . - public static IDynamicIndexer Create(PropertyInfo indexer) - { - AssertUtils.ArgumentNotNull(indexer, "You cannot create a dynamic indexer for a null value."); - - IDynamicIndexer dynamicIndexer = DynamicReflectionManager.GetDynamicIndexer(indexer, s_createCallback); - return dynamicIndexer; - } - - private static IDynamicIndexer CreateInternal(PropertyInfo indexer) - { - IDynamicIndexer dynamicIndexer = null; - - TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Indexer_" + indexer.DeclaringType.Name); - tb.AddInterfaceImplementation(typeof(IDynamicIndexer)); - - GenerateGetValue(tb, indexer, typeof(int)); - GenerateGetValue(tb, indexer, typeof(object)); - GenerateGetValue(tb, indexer, typeof(object[])); - GenerateSetValue(tb, indexer, typeof(int)); - GenerateSetValue(tb, indexer, typeof(object)); - GenerateSetValue(tb, indexer, typeof(object[])); - - Type dynamicIndexerType = tb.CreateType(); - ConstructorInfo ctor = dynamicIndexerType.GetConstructor(Type.EmptyTypes); - dynamicIndexer = (IDynamicIndexer) ctor.Invoke(ObjectUtils.EmptyObjects); - - return dynamicIndexer; - } - - private static void GenerateGetValue(TypeBuilder tb, PropertyInfo indexer, Type indexType) - { - MethodBuilder getValueMethod = - tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object), indexType }); - getValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); - getValueMethod.DefineParameter(2, ParameterAttributes.None, "index"); - - ILGenerator il = getValueMethod.GetILGenerator(); - if (indexer.CanRead) - { - MethodInfo getMethod = indexer.GetGetMethod(); - bool isValueType = indexer.DeclaringType.IsValueType; - bool isStatic = getMethod.IsStatic; - - if (!isStatic) - { - SetupTargetInstance(il, indexer.DeclaringType); - } - - if (indexType != typeof(object) && indexType != typeof(object[])) - { - il.Emit(OpCodes.Ldarg_2); - } - else if (indexType == typeof(object)) - { - Type argumentType = ReflectionUtils.GetParameterTypes(getMethod)[0]; - SetupIndexerArgument(il, argumentType, 0, false); - } - else - { - Type[] argTypes = ReflectionUtils.GetParameterTypes(getMethod); - for (int i = 0; i < argTypes.Length; i++) - { - SetupIndexerArgument(il, argTypes[i], i, true); - } - } - InvokeMethod(il, isStatic, isValueType, getMethod); - ProcessReturnValue(il, indexer.PropertyType); - il.Emit(OpCodes.Ret); - } - else - { - ThrowInvalidOperationException(il, "Cannot get value of a non-readable indexer"); - } - } - - private static void GenerateSetValue(TypeBuilder tb, PropertyInfo indexer, Type indexType) - { - MethodBuilder setValueMethod = - tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void), - new Type[] { typeof(object), indexType, typeof(object) }); - setValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); - setValueMethod.DefineParameter(2, ParameterAttributes.None, "value"); - - ILGenerator il = setValueMethod.GetILGenerator(); - if (indexer.CanWrite) - { - bool isValueType = indexer.DeclaringType.IsValueType; - if (isValueType) - { - ThrowInvalidOperationException(il, "Cannot set indexer value on a value type due to boxing."); - } - else - { - MethodInfo setMethod = indexer.GetSetMethod(); - bool isStatic = setMethod.IsStatic; - - if (!isStatic) - { - SetupTargetInstance(il, indexer.DeclaringType); - } - - if (indexType != typeof(object) && indexType != typeof(object[])) - { - il.Emit(OpCodes.Ldarg_2); - } - else if (indexType == typeof(object)) - { - Type argumentType = ReflectionUtils.GetParameterTypes(setMethod)[0]; - SetupIndexerArgument(il, argumentType, 0, false); - } - else - { - Type[] argTypes = ReflectionUtils.GetParameterTypes(setMethod); - for (int i = 0; i < argTypes.Length - 1; i++) - { - SetupIndexerArgument(il, argTypes[i], i, true); - } - } - SetupArgument(il, indexer.PropertyType, 3); - InvokeMethod(il, isStatic, isValueType, setMethod); - il.Emit(OpCodes.Ret); - } - } - else - { - ThrowInvalidOperationException(il, "Cannot set value of a read-only indexer"); - } - } - - private static void SetupIndexerArgument(ILGenerator il, Type argumentType, int argumentPosition, bool isObjectArray) - { - il.Emit(OpCodes.Ldarg_2); - if (isObjectArray) - { - il.Emit(OpCodes.Ldc_I4, argumentPosition); - il.Emit(OpCodes.Ldelem_Ref); - } - if (argumentType.IsValueType) - { -#if NET_2_0 - il.Emit(OpCodes.Unbox_Any, argumentType); -#else - il.Emit(OpCodes.Unbox, argumentType); - il.Emit(OpCodes.Ldobj, argumentType); -#endif - } - else - { - il.Emit(OpCodes.Castclass, argumentType); - } - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; +using Spring.Util; + +#endregion + +namespace Spring.Reflection.Dynamic +{ + #region IDynamicIndexer interface + + /// + /// Defines methods that dynamic indexer class has to implement. + /// + public interface IDynamicIndexer + { + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to get the indexer value from. + /// + /// + /// Indexer argument. + /// + /// + /// A indexer value. + /// + object GetValue(object target, int index); + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to get the indexer value from. + /// + /// + /// Indexer argument. + /// + /// + /// A indexer value. + /// + object GetValue(object target, object index); + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to get the indexer value from. + /// + /// + /// Indexer arguments. + /// + /// + /// A indexer value. + /// + object GetValue(object target, object[] index); + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to set the indexer value on. + /// + /// + /// Indexer argument. + /// + /// + /// A new indexer value. + /// + void SetValue(object target, int index, object value); + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to set the indexer value on. + /// + /// + /// Indexer argument. + /// + /// + /// A new indexer value. + /// + void SetValue(object target, object index, object value); + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to set the indexer value on. + /// + /// + /// Indexer arguments. + /// + /// + /// A new indexer value. + /// + void SetValue(object target, object[] index, object value); + } + + #endregion + + #region Safe wrapper + + /// + /// Safe wrapper for the dynamic indexer. + /// + /// + /// will attempt to use dynamic + /// indexer if possible, but it will fall back to standard + /// reflection if necessary. + /// + public class SafeIndexer : IDynamicIndexer + { + private PropertyInfo indexerProperty; + private IDynamicIndexer dynamicIndexer; + private bool isOptimizedGet = false; + private bool isOptimizedSet = false; + + /// + /// Creates a new instance of the safe indexer wrapper. + /// + /// Indexer to wrap. + public SafeIndexer(PropertyInfo indexer) + { + this.indexerProperty = indexer; + + if (indexer.CanRead + && indexer.GetGetMethod() != null + && ReflectionUtils.IsTypeVisible(indexer.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + dynamicIndexer = DynamicIndexer.Create(indexer); + isOptimizedGet = true; + } + if (indexer.CanWrite + && indexer.GetSetMethod() != null + && ReflectionUtils.IsTypeVisible(indexer.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + if (dynamicIndexer == null) + { + dynamicIndexer = DynamicIndexer.Create(indexer); + } + isOptimizedSet = true; + } + } + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to get indexer value from. + /// + /// + /// Indexer arguments. + /// + /// + /// A indexer value. + /// + public object GetValue(object target, int index) + { + if (isOptimizedGet) + { + return dynamicIndexer.GetValue(target, index); + } + else + { + return indexerProperty.GetValue(target, new object[] { index }); + } + } + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to get the indexer value from. + /// + /// + /// Indexer argument. + /// + /// + /// A indexer value. + /// + public object GetValue(object target, object index) + { + if (isOptimizedGet) + { + return dynamicIndexer.GetValue(target, index); + } + else + { + return indexerProperty.GetValue(target, new object[] { index }); + } + } + + /// + /// Gets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to get indexer value from. + /// + /// + /// Indexer arguments. + /// + /// + /// A indexer value. + /// + public object GetValue(object target, object[] index) + { + if (isOptimizedGet) + { + return dynamicIndexer.GetValue(target, index); + } + else + { + return indexerProperty.GetValue(target, index); + } + } + + /// + /// Sets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to set indexer value on. + /// + /// + /// Indexer arguments. + /// + /// + /// A new indexer value. + /// + public void SetValue(object target, int index, object value) + { + if (isOptimizedSet) + { + try + { + dynamicIndexer.SetValue(target, index, value); + } + catch (InvalidCastException) + { + isOptimizedSet = false; + indexerProperty.SetValue(target, value, new object[] { index }); + } + } + else + { + indexerProperty.SetValue(target, value, new object[] { index }); + } + } + + /// + /// Sets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to set indexer value on. + /// + /// + /// Indexer arguments. + /// + /// + /// A new indexer value. + /// + public void SetValue(object target, object index, object value) + { + if (isOptimizedSet) + { + try + { + dynamicIndexer.SetValue(target, index, value); + } + catch (InvalidCastException) + { + isOptimizedSet = false; + indexerProperty.SetValue(target, value, new object[] { index }); + } + } + else + { + indexerProperty.SetValue(target, value, new object[] { index }); + } + } + + /// + /// Sets the value of the dynamic indexer for the specified target object. + /// + /// + /// Target object to set indexer value on. + /// + /// + /// Indexer arguments. + /// + /// + /// A new indexer value. + /// + public void SetValue(object target, object[] index, object value) + { + if (isOptimizedSet) + { + try + { + dynamicIndexer.SetValue(target, index, value); + } + catch (InvalidCastException) + { + isOptimizedSet = false; + indexerProperty.SetValue(target, value, index); + } + } + else + { + indexerProperty.SetValue(target, value, index); + } + } + + /// + /// Internal PropertyInfo accessor. + /// + internal PropertyInfo IndexerProperty + { + get { return indexerProperty; } + } + } + + #endregion + + /// + /// Factory class for dynamic indexers. + /// + /// Aleksandar Seovic + public class DynamicIndexer : BaseDynamicMember + { + private static readonly CreateIndexerCallback s_createCallback = new CreateIndexerCallback(CreateInternal); + + #region Create Method + + /// + /// Creates dynamic indexer instance for the specified . + /// + /// Indexer info to create dynamic indexer for. + /// Dynamic indexer for the specified . + public static IDynamicIndexer Create(PropertyInfo indexer) + { + AssertUtils.ArgumentNotNull(indexer, "You cannot create a dynamic indexer for a null value."); + + IDynamicIndexer dynamicIndexer = DynamicReflectionManager.GetDynamicIndexer(indexer, s_createCallback); + return dynamicIndexer; + } + + private static IDynamicIndexer CreateInternal(PropertyInfo indexer) + { + IDynamicIndexer dynamicIndexer = null; + + TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Indexer_" + indexer.DeclaringType.Name); + tb.AddInterfaceImplementation(typeof(IDynamicIndexer)); + + GenerateGetValue(tb, indexer, typeof(int)); + GenerateGetValue(tb, indexer, typeof(object)); + GenerateGetValue(tb, indexer, typeof(object[])); + GenerateSetValue(tb, indexer, typeof(int)); + GenerateSetValue(tb, indexer, typeof(object)); + GenerateSetValue(tb, indexer, typeof(object[])); + + Type dynamicIndexerType = tb.CreateType(); + ConstructorInfo ctor = dynamicIndexerType.GetConstructor(Type.EmptyTypes); + dynamicIndexer = (IDynamicIndexer) ctor.Invoke(ObjectUtils.EmptyObjects); + + return dynamicIndexer; + } + + private static void GenerateGetValue(TypeBuilder tb, PropertyInfo indexer, Type indexType) + { + MethodBuilder getValueMethod = + tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object), indexType }); + getValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); + getValueMethod.DefineParameter(2, ParameterAttributes.None, "index"); + + ILGenerator il = getValueMethod.GetILGenerator(); + if (indexer.CanRead) + { + MethodInfo getMethod = indexer.GetGetMethod(); + bool isValueType = indexer.DeclaringType.IsValueType; + bool isStatic = getMethod.IsStatic; + + if (!isStatic) + { + SetupTargetInstance(il, indexer.DeclaringType); + } + + if (indexType != typeof(object) && indexType != typeof(object[])) + { + il.Emit(OpCodes.Ldarg_2); + } + else if (indexType == typeof(object)) + { + Type argumentType = ReflectionUtils.GetParameterTypes(getMethod)[0]; + SetupIndexerArgument(il, argumentType, 0, false); + } + else + { + Type[] argTypes = ReflectionUtils.GetParameterTypes(getMethod); + for (int i = 0; i < argTypes.Length; i++) + { + SetupIndexerArgument(il, argTypes[i], i, true); + } + } + InvokeMethod(il, isStatic, isValueType, getMethod); + ProcessReturnValue(il, indexer.PropertyType); + il.Emit(OpCodes.Ret); + } + else + { + ThrowInvalidOperationException(il, "Cannot get value of a non-readable indexer"); + } + } + + private static void GenerateSetValue(TypeBuilder tb, PropertyInfo indexer, Type indexType) + { + MethodBuilder setValueMethod = + tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void), + new Type[] { typeof(object), indexType, typeof(object) }); + setValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); + setValueMethod.DefineParameter(2, ParameterAttributes.None, "value"); + + ILGenerator il = setValueMethod.GetILGenerator(); + if (indexer.CanWrite) + { + bool isValueType = indexer.DeclaringType.IsValueType; + if (isValueType) + { + ThrowInvalidOperationException(il, "Cannot set indexer value on a value type due to boxing."); + } + else + { + MethodInfo setMethod = indexer.GetSetMethod(); + bool isStatic = setMethod.IsStatic; + + if (!isStatic) + { + SetupTargetInstance(il, indexer.DeclaringType); + } + + if (indexType != typeof(object) && indexType != typeof(object[])) + { + il.Emit(OpCodes.Ldarg_2); + } + else if (indexType == typeof(object)) + { + Type argumentType = ReflectionUtils.GetParameterTypes(setMethod)[0]; + SetupIndexerArgument(il, argumentType, 0, false); + } + else + { + Type[] argTypes = ReflectionUtils.GetParameterTypes(setMethod); + for (int i = 0; i < argTypes.Length - 1; i++) + { + SetupIndexerArgument(il, argTypes[i], i, true); + } + } + SetupArgument(il, indexer.PropertyType, 3); + InvokeMethod(il, isStatic, isValueType, setMethod); + il.Emit(OpCodes.Ret); + } + } + else + { + ThrowInvalidOperationException(il, "Cannot set value of a read-only indexer"); + } + } + + private static void SetupIndexerArgument(ILGenerator il, Type argumentType, int argumentPosition, bool isObjectArray) + { + il.Emit(OpCodes.Ldarg_2); + if (isObjectArray) + { + il.Emit(OpCodes.Ldc_I4, argumentPosition); + il.Emit(OpCodes.Ldelem_Ref); + } + if (argumentType.IsValueType) + { +#if NET_2_0 + il.Emit(OpCodes.Unbox_Any, argumentType); +#else + il.Emit(OpCodes.Unbox, argumentType); + il.Emit(OpCodes.Ldobj, argumentType); +#endif + } + else + { + il.Emit(OpCodes.Castclass, argumentType); + } + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicMethod.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicMethod.cs index ee58a323..608dbba5 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicMethod.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicMethod.cs @@ -1,291 +1,290 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; -using Spring.Util; - -#endregion - -namespace Spring.Reflection.Dynamic -{ - #region IDynamicMethod interface - - /// - /// Defines methods that dynamic method class has to implement. - /// - public interface IDynamicMethod - { - /// - /// Invokes dynamic method on the specified target object. - /// - /// - /// Target object to invoke method on. - /// - /// - /// Method arguments. - /// - /// - /// A method return value. - /// - object Invoke(object target, object[] arguments); - } - - #endregion - - #region Safe wrapper - - /// - /// Safe wrapper for the dynamic method. - /// - /// - /// will attempt to use dynamic - /// method if possible, but it will fall back to standard - /// reflection if necessary. - /// - public class SafeMethod : IDynamicMethod - { - private MethodInfo method; - private IDynamicMethod dynamicMethod; - private bool isOptimized = false; - - /// - /// Creates a new instance of the safe method wrapper. - /// - /// Method to wrap. - public SafeMethod(MethodInfo method) - { - this.method = method; - if (method.IsPublic && - ReflectionUtils.IsTypeVisible(method.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - this.dynamicMethod = DynamicMethod.Create(method); - this.isOptimized = true; - } - } - - /// - /// Gets the class, that declares this method - /// - public Type DeclaringType - { - get { return method.DeclaringType; } - } - - /// - /// Invokes dynamic method. - /// - /// - /// Target object to invoke method on. - /// - /// - /// Method arguments. - /// - /// - /// A method return value. - /// - public object Invoke(object target, object[] arguments) - { - if (isOptimized) - { - // try dynamic method first but fall back to standard reflection - // if arguments are causing InvalidCastExceptions - try - { - return dynamicMethod.Invoke(target, arguments); - } - catch (InvalidCastException e) - { - // Only attempt if DynamicReflection code itself threw the exception. - if (!ExceptionFromDynamicReflection(e)) - { - throw; - } - isOptimized = false; - return method.Invoke(target, arguments); - } - } - else - { - return method.Invoke(target, arguments); - } - } - - private bool ExceptionFromDynamicReflection(InvalidCastException e) - { - return e.TargetSite.DeclaringType.FullName.IndexOf(DynamicReflectionManager.ASSEMBLY_NAME) >= 0; - } - } - - #endregion - - /// - /// Factory class for dynamic methods. - /// - /// Aleksandar Seovic - /// $Id: DynamicMethod.cs,v 1.2 2008/03/06 20:20:37 oakinger Exp $ - public class DynamicMethod : BaseDynamicMember - { - private static readonly CreateMethodCallback s_createMethodCallback = new CreateMethodCallback(CreateInternal); - - #region Create Method - - /// - /// Creates dynamic method instance for the specified . - /// - /// Method info to create dynamic method for. - /// Dynamic method for the specified . - public static IDynamicMethod Create(MethodInfo method) - { - AssertUtils.ArgumentNotNull(method, "You cannot create a dynamic method for a null value."); - - IDynamicMethod dynamicMethod = DynamicReflectionManager.GetDynamicMethod(method, s_createMethodCallback); - return dynamicMethod; - } - - private static IDynamicMethod CreateInternal(MethodInfo method) - { - IDynamicMethod dynamicMethod = null; - - TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Method_" + method.Name); - tb.AddInterfaceImplementation(typeof(IDynamicMethod)); - - GenerateInvoke(tb, method); - - Type dynamicMethodType = tb.CreateType(); - ConstructorInfo ctor = dynamicMethodType.GetConstructor(Type.EmptyTypes); - dynamicMethod = (IDynamicMethod) ctor.Invoke(ObjectUtils.EmptyObjects); - - return dynamicMethod; - } - - private static void GenerateInvoke(TypeBuilder tb, MethodInfo method) - { - MethodBuilder invokeMethod = - tb.DefineMethod("Invoke", METHOD_ATTRIBUTES, typeof(object), new Type[] {typeof(object), typeof(object[])}); - invokeMethod.DefineParameter(1, ParameterAttributes.None, "target"); - invokeMethod.DefineParameter(2, ParameterAttributes.None, "args"); - - ILGenerator il = invokeMethod.GetILGenerator(); - bool isValueType = method.DeclaringType.IsValueType; - bool isStatic = method.IsStatic; - - IDictionary outArgs = new Hashtable(); - ParameterInfo[] args = method.GetParameters(); - for (int i = 0; i < args.Length; i++) - { - if (IsOutputOrRefArgument(args[i])) - { - SetupOutputArgument(il, args[i], outArgs); - } - } - - if (!isStatic) - { - SetupTargetInstance(il, method.DeclaringType); - } - - for (int i = 0; i < args.Length; i++) - { - SetupMethodArgument(il, args[i], outArgs); - } - InvokeMethod(il, isStatic, isValueType, method); - for (int i = 0; i < args.Length; i++) - { - if (IsOutputOrRefArgument(args[i])) - { - ProcessOutputArgument(il, args[i], outArgs); - } - } - ProcessReturnValue(il, method.ReturnType); - il.Emit(OpCodes.Ret); - } - - private static bool IsOutputOrRefArgument(ParameterInfo argInfo) - { - return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith("&"); - } - - private static void SetupOutputArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs) - { - Type argType = argInfo.ParameterType.GetElementType(); - - LocalBuilder lb = il.DeclareLocal(argType); - if (!argInfo.IsOut) - { - PushArgumentValue(il, argType, argInfo.Position); - il.Emit(OpCodes.Stloc, lb); - } - outArgs[argInfo.Position] = lb; - } - - private static void ProcessOutputArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs) - { - Type argType = argInfo.ParameterType.GetElementType(); - - il.Emit(OpCodes.Ldarg_2); - il.Emit(OpCodes.Ldc_I4, argInfo.Position); - il.Emit(OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position]); - if (argType.IsValueType) - { - il.Emit(OpCodes.Box, argType); - } - il.Emit(OpCodes.Stelem_Ref); - } - - private static void SetupMethodArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs) - { - if (IsOutputOrRefArgument(argInfo)) - { - il.Emit(OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position]); - } - else - { - PushArgumentValue(il, argInfo.ParameterType, argInfo.Position); - } - } - - private static void PushArgumentValue(ILGenerator il, Type argumentType, int argumentPosition) - { - il.Emit(OpCodes.Ldarg_2); - il.Emit(OpCodes.Ldc_I4, argumentPosition); - il.Emit(OpCodes.Ldelem_Ref); - if (argumentType.IsValueType) - { -#if NET_2_0 - il.Emit(OpCodes.Unbox_Any, argumentType); -#else - il.Emit(OpCodes.Unbox, argumentType); - il.Emit(OpCodes.Ldobj, argumentType); -#endif - } - else - { - il.Emit(OpCodes.Castclass, argumentType); - } - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using Spring.Util; + +#endregion + +namespace Spring.Reflection.Dynamic +{ + #region IDynamicMethod interface + + /// + /// Defines methods that dynamic method class has to implement. + /// + public interface IDynamicMethod + { + /// + /// Invokes dynamic method on the specified target object. + /// + /// + /// Target object to invoke method on. + /// + /// + /// Method arguments. + /// + /// + /// A method return value. + /// + object Invoke(object target, object[] arguments); + } + + #endregion + + #region Safe wrapper + + /// + /// Safe wrapper for the dynamic method. + /// + /// + /// will attempt to use dynamic + /// method if possible, but it will fall back to standard + /// reflection if necessary. + /// + public class SafeMethod : IDynamicMethod + { + private MethodInfo method; + private IDynamicMethod dynamicMethod; + private bool isOptimized = false; + + /// + /// Creates a new instance of the safe method wrapper. + /// + /// Method to wrap. + public SafeMethod(MethodInfo method) + { + this.method = method; + if (method.IsPublic && + ReflectionUtils.IsTypeVisible(method.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + this.dynamicMethod = DynamicMethod.Create(method); + this.isOptimized = true; + } + } + + /// + /// Gets the class, that declares this method + /// + public Type DeclaringType + { + get { return method.DeclaringType; } + } + + /// + /// Invokes dynamic method. + /// + /// + /// Target object to invoke method on. + /// + /// + /// Method arguments. + /// + /// + /// A method return value. + /// + public object Invoke(object target, object[] arguments) + { + if (isOptimized) + { + // try dynamic method first but fall back to standard reflection + // if arguments are causing InvalidCastExceptions + try + { + return dynamicMethod.Invoke(target, arguments); + } + catch (InvalidCastException e) + { + // Only attempt if DynamicReflection code itself threw the exception. + if (!ExceptionFromDynamicReflection(e)) + { + throw; + } + isOptimized = false; + return method.Invoke(target, arguments); + } + } + else + { + return method.Invoke(target, arguments); + } + } + + private bool ExceptionFromDynamicReflection(InvalidCastException e) + { + return e.TargetSite.DeclaringType.FullName.IndexOf(DynamicReflectionManager.ASSEMBLY_NAME) >= 0; + } + } + + #endregion + + /// + /// Factory class for dynamic methods. + /// + /// Aleksandar Seovic + public class DynamicMethod : BaseDynamicMember + { + private static readonly CreateMethodCallback s_createMethodCallback = new CreateMethodCallback(CreateInternal); + + #region Create Method + + /// + /// Creates dynamic method instance for the specified . + /// + /// Method info to create dynamic method for. + /// Dynamic method for the specified . + public static IDynamicMethod Create(MethodInfo method) + { + AssertUtils.ArgumentNotNull(method, "You cannot create a dynamic method for a null value."); + + IDynamicMethod dynamicMethod = DynamicReflectionManager.GetDynamicMethod(method, s_createMethodCallback); + return dynamicMethod; + } + + private static IDynamicMethod CreateInternal(MethodInfo method) + { + IDynamicMethod dynamicMethod = null; + + TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Method_" + method.Name); + tb.AddInterfaceImplementation(typeof(IDynamicMethod)); + + GenerateInvoke(tb, method); + + Type dynamicMethodType = tb.CreateType(); + ConstructorInfo ctor = dynamicMethodType.GetConstructor(Type.EmptyTypes); + dynamicMethod = (IDynamicMethod) ctor.Invoke(ObjectUtils.EmptyObjects); + + return dynamicMethod; + } + + private static void GenerateInvoke(TypeBuilder tb, MethodInfo method) + { + MethodBuilder invokeMethod = + tb.DefineMethod("Invoke", METHOD_ATTRIBUTES, typeof(object), new Type[] {typeof(object), typeof(object[])}); + invokeMethod.DefineParameter(1, ParameterAttributes.None, "target"); + invokeMethod.DefineParameter(2, ParameterAttributes.None, "args"); + + ILGenerator il = invokeMethod.GetILGenerator(); + bool isValueType = method.DeclaringType.IsValueType; + bool isStatic = method.IsStatic; + + IDictionary outArgs = new Hashtable(); + ParameterInfo[] args = method.GetParameters(); + for (int i = 0; i < args.Length; i++) + { + if (IsOutputOrRefArgument(args[i])) + { + SetupOutputArgument(il, args[i], outArgs); + } + } + + if (!isStatic) + { + SetupTargetInstance(il, method.DeclaringType); + } + + for (int i = 0; i < args.Length; i++) + { + SetupMethodArgument(il, args[i], outArgs); + } + InvokeMethod(il, isStatic, isValueType, method); + for (int i = 0; i < args.Length; i++) + { + if (IsOutputOrRefArgument(args[i])) + { + ProcessOutputArgument(il, args[i], outArgs); + } + } + ProcessReturnValue(il, method.ReturnType); + il.Emit(OpCodes.Ret); + } + + private static bool IsOutputOrRefArgument(ParameterInfo argInfo) + { + return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith("&"); + } + + private static void SetupOutputArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs) + { + Type argType = argInfo.ParameterType.GetElementType(); + + LocalBuilder lb = il.DeclareLocal(argType); + if (!argInfo.IsOut) + { + PushArgumentValue(il, argType, argInfo.Position); + il.Emit(OpCodes.Stloc, lb); + } + outArgs[argInfo.Position] = lb; + } + + private static void ProcessOutputArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs) + { + Type argType = argInfo.ParameterType.GetElementType(); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldc_I4, argInfo.Position); + il.Emit(OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position]); + if (argType.IsValueType) + { + il.Emit(OpCodes.Box, argType); + } + il.Emit(OpCodes.Stelem_Ref); + } + + private static void SetupMethodArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs) + { + if (IsOutputOrRefArgument(argInfo)) + { + il.Emit(OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position]); + } + else + { + PushArgumentValue(il, argInfo.ParameterType, argInfo.Position); + } + } + + private static void PushArgumentValue(ILGenerator il, Type argumentType, int argumentPosition) + { + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldc_I4, argumentPosition); + il.Emit(OpCodes.Ldelem_Ref); + if (argumentType.IsValueType) + { +#if NET_2_0 + il.Emit(OpCodes.Unbox_Any, argumentType); +#else + il.Emit(OpCodes.Unbox, argumentType); + il.Emit(OpCodes.Ldobj, argumentType); +#endif + } + else + { + il.Emit(OpCodes.Castclass, argumentType); + } + } + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicProperty.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicProperty.cs index be833b55..a7b04643 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicProperty.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicProperty.cs @@ -1,449 +1,447 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; - -using Common.Logging; -using Spring.Util; - -#endregion - -namespace Spring.Reflection.Dynamic -{ - #region IDynamicProperty interface - - /// - /// Defines methods that dynamic property class has to implement. - /// - public interface IDynamicProperty - { - /// - /// Gets the value of the dynamic property for the specified target object. - /// - /// - /// Target object to get property value from. - /// - /// - /// A property value. - /// - object GetValue(object target); - - /// - /// Gets the value of the dynamic property for the specified target object. - /// - /// - /// Target object to set property value on. - /// - /// - /// A new property value. - /// - void SetValue(object target, object value); - } - - #endregion - - #region Safe wrapper - - /// - /// Safe wrapper for the dynamic property. - /// - /// - /// will attempt to use dynamic - /// property if possible, but it will fall back to standard - /// reflection if necessary. - /// - public class SafeProperty : IDynamicProperty - { - private static readonly ILog Log = LogManager.GetLogger(typeof(SafeProperty)); - - private readonly PropertyInfo propertyInfo; - -#if NET_2_0 - - #region Cache - - private static readonly IDictionary propertyCache = new Hashtable(); - - /// - /// Holds cached Getter/Setter delegates for a Property - /// - private class DynamicPropertyCacheEntry - { - public readonly GetterDelegate Getter; - public readonly SetterDelegate Setter; - - public DynamicPropertyCacheEntry(GetterDelegate getter, SetterDelegate setter) - { - Getter = getter; - Setter = setter; - } - } - - /// - /// Obtains cached property info or creates a new entry, if none is found. - /// - private static DynamicPropertyCacheEntry GetOrCreateDynamicProperty(PropertyInfo property) - { - DynamicPropertyCacheEntry propertyInfo = (DynamicPropertyCacheEntry)propertyCache[property]; - if (propertyInfo == null) - { - propertyInfo = new DynamicPropertyCacheEntry(DynamicReflectionManager.CreatePropertyGetter(property), DynamicReflectionManager.CreatePropertySetter(property)); - lock (propertyCache) - { - propertyCache[property] = propertyInfo; - } - } - return propertyInfo; - } - - #endregion - - private readonly GetterDelegate getter; - private readonly SetterDelegate setter; - - /// - /// Creates a new instance of the safe property wrapper. - /// - /// Property to wrap. - public SafeProperty(PropertyInfo propertyInfo) - { - AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a dynamic property for a null value."); - - this.propertyInfo = propertyInfo; - DynamicPropertyCacheEntry pi = GetOrCreateDynamicProperty(propertyInfo); - getter = pi.Getter; - setter = pi.Setter; - } - - /// - /// Gets the value of the dynamic property for the specified target object. - /// - /// - /// Target object to get property value from. - /// - /// - /// A property value. - /// - public object GetValue(object target) - { - return getter(target); - } - - /// - /// Gets the value of the dynamic property for the specified target object. - /// - /// - /// Target object to set property value on. - /// - /// - /// A new property value. - /// - public void SetValue(object target, object value) - { - setter(target, value); - } - -#else - private readonly IDynamicProperty dynamicProperty; - private readonly bool isOptimizedGet = false; - private bool isOptimizedSet = false; - private readonly bool canSet; - - /// - /// Creates a new instance of the safe property wrapper. - /// - /// Property to wrap. - public SafeProperty(PropertyInfo property) - { - this.propertyInfo = property; - - if (property.CanRead - && property.GetGetMethod() != null - && ReflectionUtils.IsTypeVisible(property.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - dynamicProperty = DynamicProperty.Create(property); - isOptimizedGet = true; - } - - canSet = property.CanWrite && !(propertyInfo.DeclaringType.IsValueType && !propertyInfo.GetSetMethod(true).IsStatic); - if (property.GetSetMethod() != null - && ReflectionUtils.IsTypeVisible(property.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) - { - if (dynamicProperty == null) - { - dynamicProperty = DynamicProperty.Create(property); - } - isOptimizedSet = true; - } - } - - /// - /// Gets the value of the dynamic property for the specified target object. - /// - /// - /// Target object to get property value from. - /// - /// - /// A property value. - /// - public object GetValue(object target) - { - if (isOptimizedGet) - { - return dynamicProperty.GetValue(target); - } - else - { - return propertyInfo.GetValue(target, null); - } - } - - /// - /// Gets the value of the dynamic property for the specified target object. - /// - /// - /// Target object to set property value on. - /// - /// - /// A new property value. - /// - public void SetValue(object target, object value) - { - try - { - if (isOptimizedSet) - { - try - { - dynamicProperty.SetValue(target, value); - } - catch (InvalidCastException) - { - isOptimizedSet = false; - propertyInfo.SetValue(target, value, null); - } - } - else - { - if (!canSet) - { - throw (propertyInfo.DeclaringType.IsValueType) - ? new InvalidOperationException("Cannot set property value on a value type due to boxing.") - : new InvalidOperationException("Cannot set value of a read-only property."); - } - - propertyInfo.SetValue(target, value, null); - } - } - catch (Exception ex) - { - Log.Error( - string.Format("Failed setting value '{0}' on property '{2}.{1}' on instance of type '{3}'", - (value != null ? value.GetType().FullName : ""), - propertyInfo.Name, - propertyInfo.DeclaringType.FullName, - (target != null ? target.GetType().FullName : "")), ex); - throw; - } - } -#endif - /// - /// Internal PropertyInfo accessor. - /// - internal PropertyInfo PropertyInfo - { - get { return propertyInfo; } - } - } - - #endregion - -#if NET_2_0 - /// - /// Factory class for dynamic properties. - /// - /// Aleksandar Seovic - /// $Id: DynamicProperty.cs,v 1.3 2008/05/17 11:05:26 oakinger Exp $ - public class DynamicProperty : BaseDynamicMember - { - /// - /// Creates safe dynamic property instance for the specified . - /// - /// - ///

This factory method will create a dynamic property with a "safe" wrapper.

- ///

Safe wrapper will attempt to use generated dynamic property if possible, - /// but it will fall back to standard reflection if necessary.

- ///
- /// Property info to create dynamic property for. - /// Safe dynamic property for the specified . - /// - public static IDynamicProperty CreateSafe(PropertyInfo property) - { - return new SafeProperty(property); - } - - /// - /// Creates dynamic property instance for the specified . - /// - /// Property info to create dynamic property for. - /// Dynamic property for the specified . - public static IDynamicProperty Create(PropertyInfo property) - { - AssertUtils.ArgumentNotNull(property, "You cannot create a dynamic property for a null value."); - - IDynamicProperty dynamicProperty = new SafeProperty(property); - return dynamicProperty; - } - } -#else - /// - /// Factory class for dynamic properties. - /// - /// Aleksandar Seovic - /// $Id: DynamicProperty.cs,v 1.3 2008/05/17 11:05:26 oakinger Exp $ - public class DynamicProperty : BaseDynamicMember - { - private readonly static CreatePropertyCallback s_createPropertyCallback = new CreatePropertyCallback(CreateInternal); - - #region Create Method - - /// - /// Creates safe dynamic property instance for the specified . - /// - /// - ///

This factory method will create a dynamic property with a "safe" wrapper.

- ///

Safe wrapper will attempt to use generated dynamic property if possible, - /// but it will fall back to standard reflection if necessary.

- ///
- /// Property info to create dynamic property for. - /// Safe dynamic property for the specified . - /// - public static IDynamicProperty CreateSafe(PropertyInfo property) - { - return new SafeProperty(property); - } - - /// - /// Creates dynamic property instance for the specified . - /// - /// Property info to create dynamic property for. - /// Dynamic property for the specified . - public static IDynamicProperty Create(PropertyInfo property) - { - AssertUtils.ArgumentNotNull(property, "You cannot create a dynamic property for a null value."); - - IDynamicProperty dynamicProperty = DynamicReflectionManager.GetDynamicProperty(property, s_createPropertyCallback); - return dynamicProperty; - } - - private static IDynamicProperty CreateInternal(PropertyInfo property) - { - IDynamicProperty dynamicProperty = null; - - TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Property_" + property.Name); - tb.AddInterfaceImplementation(typeof(IDynamicProperty)); - - GenerateGetValue(tb, property); - GenerateSetValue(tb, property); - - Type dynamicPropertyType = tb.CreateType(); - ConstructorInfo ctor = dynamicPropertyType.GetConstructor(Type.EmptyTypes); - dynamicProperty = (IDynamicProperty)ctor.Invoke(ObjectUtils.EmptyObjects); - - return dynamicProperty; - } - - private static void GenerateGetValue(TypeBuilder tb, PropertyInfo property) - { - MethodBuilder getValueMethod = - tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object) }); - getValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); - - ILGenerator il = getValueMethod.GetILGenerator(); - if (property.CanRead) - { - MethodInfo getMethod = property.GetGetMethod(true); - bool isValueType = property.DeclaringType.IsValueType; - bool isStatic = getMethod.IsStatic; - - if (!isStatic) - { - SetupTargetInstance(il, property.DeclaringType); - } - - InvokeMethod(il, isStatic, isValueType, getMethod); - ProcessReturnValue(il, property.PropertyType); - il.Emit(OpCodes.Ret); - } - else - { - ThrowInvalidOperationException(il, "Cannot get value of a non-readable property"); - } - } - - private static void GenerateSetValue(TypeBuilder tb, PropertyInfo property) - { - MethodBuilder setValueMethod = - tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void), - new Type[] { typeof(object), typeof(object) }); - setValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); - setValueMethod.DefineParameter(2, ParameterAttributes.None, "value"); - - ILGenerator il = setValueMethod.GetILGenerator(); - if (property.CanWrite) - { - bool isValueType = property.DeclaringType.IsValueType; - // we can't set nonstatic properties on value types (due to boxing) - bool canSet = !(isValueType && !property.GetSetMethod(true).IsStatic); - if (!canSet) - { - ThrowInvalidOperationException(il, "Cannot set property value on a value type due to boxing."); - } - else - { - MethodInfo setMethod = property.GetSetMethod(true); - bool isStatic = setMethod.IsStatic; - - if (!isStatic) - { - SetupTargetInstance(il, property.DeclaringType); - } - - SetupArgument(il, property.PropertyType, 2); - InvokeMethod(il, isStatic, property.DeclaringType.IsValueType, setMethod); - il.Emit(OpCodes.Ret); - } - } - else - { - ThrowInvalidOperationException(il, "Cannot set value of a read-only property"); - } - } - - #endregion - } - -#endif +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; + +using Common.Logging; +using Spring.Util; + +#endregion + +namespace Spring.Reflection.Dynamic +{ + #region IDynamicProperty interface + + /// + /// Defines methods that dynamic property class has to implement. + /// + public interface IDynamicProperty + { + /// + /// Gets the value of the dynamic property for the specified target object. + /// + /// + /// Target object to get property value from. + /// + /// + /// A property value. + /// + object GetValue(object target); + + /// + /// Gets the value of the dynamic property for the specified target object. + /// + /// + /// Target object to set property value on. + /// + /// + /// A new property value. + /// + void SetValue(object target, object value); + } + + #endregion + + #region Safe wrapper + + /// + /// Safe wrapper for the dynamic property. + /// + /// + /// will attempt to use dynamic + /// property if possible, but it will fall back to standard + /// reflection if necessary. + /// + public class SafeProperty : IDynamicProperty + { + private static readonly ILog Log = LogManager.GetLogger(typeof(SafeProperty)); + + private readonly PropertyInfo propertyInfo; + +#if NET_2_0 + + #region Cache + + private static readonly IDictionary propertyCache = new Hashtable(); + + /// + /// Holds cached Getter/Setter delegates for a Property + /// + private class DynamicPropertyCacheEntry + { + public readonly GetterDelegate Getter; + public readonly SetterDelegate Setter; + + public DynamicPropertyCacheEntry(GetterDelegate getter, SetterDelegate setter) + { + Getter = getter; + Setter = setter; + } + } + + /// + /// Obtains cached property info or creates a new entry, if none is found. + /// + private static DynamicPropertyCacheEntry GetOrCreateDynamicProperty(PropertyInfo property) + { + DynamicPropertyCacheEntry propertyInfo = (DynamicPropertyCacheEntry)propertyCache[property]; + if (propertyInfo == null) + { + propertyInfo = new DynamicPropertyCacheEntry(DynamicReflectionManager.CreatePropertyGetter(property), DynamicReflectionManager.CreatePropertySetter(property)); + lock (propertyCache) + { + propertyCache[property] = propertyInfo; + } + } + return propertyInfo; + } + + #endregion + + private readonly GetterDelegate getter; + private readonly SetterDelegate setter; + + /// + /// Creates a new instance of the safe property wrapper. + /// + /// Property to wrap. + public SafeProperty(PropertyInfo propertyInfo) + { + AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a dynamic property for a null value."); + + this.propertyInfo = propertyInfo; + DynamicPropertyCacheEntry pi = GetOrCreateDynamicProperty(propertyInfo); + getter = pi.Getter; + setter = pi.Setter; + } + + /// + /// Gets the value of the dynamic property for the specified target object. + /// + /// + /// Target object to get property value from. + /// + /// + /// A property value. + /// + public object GetValue(object target) + { + return getter(target); + } + + /// + /// Gets the value of the dynamic property for the specified target object. + /// + /// + /// Target object to set property value on. + /// + /// + /// A new property value. + /// + public void SetValue(object target, object value) + { + setter(target, value); + } + +#else + private readonly IDynamicProperty dynamicProperty; + private readonly bool isOptimizedGet = false; + private bool isOptimizedSet = false; + private readonly bool canSet; + + /// + /// Creates a new instance of the safe property wrapper. + /// + /// Property to wrap. + public SafeProperty(PropertyInfo property) + { + this.propertyInfo = property; + + if (property.CanRead + && property.GetGetMethod() != null + && ReflectionUtils.IsTypeVisible(property.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + dynamicProperty = DynamicProperty.Create(property); + isOptimizedGet = true; + } + + canSet = property.CanWrite && !(propertyInfo.DeclaringType.IsValueType && !propertyInfo.GetSetMethod(true).IsStatic); + if (property.GetSetMethod() != null + && ReflectionUtils.IsTypeVisible(property.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME)) + { + if (dynamicProperty == null) + { + dynamicProperty = DynamicProperty.Create(property); + } + isOptimizedSet = true; + } + } + + /// + /// Gets the value of the dynamic property for the specified target object. + /// + /// + /// Target object to get property value from. + /// + /// + /// A property value. + /// + public object GetValue(object target) + { + if (isOptimizedGet) + { + return dynamicProperty.GetValue(target); + } + else + { + return propertyInfo.GetValue(target, null); + } + } + + /// + /// Gets the value of the dynamic property for the specified target object. + /// + /// + /// Target object to set property value on. + /// + /// + /// A new property value. + /// + public void SetValue(object target, object value) + { + try + { + if (isOptimizedSet) + { + try + { + dynamicProperty.SetValue(target, value); + } + catch (InvalidCastException) + { + isOptimizedSet = false; + propertyInfo.SetValue(target, value, null); + } + } + else + { + if (!canSet) + { + throw (propertyInfo.DeclaringType.IsValueType) + ? new InvalidOperationException("Cannot set property value on a value type due to boxing.") + : new InvalidOperationException("Cannot set value of a read-only property."); + } + + propertyInfo.SetValue(target, value, null); + } + } + catch (Exception ex) + { + Log.Error( + string.Format("Failed setting value '{0}' on property '{2}.{1}' on instance of type '{3}'", + (value != null ? value.GetType().FullName : ""), + propertyInfo.Name, + propertyInfo.DeclaringType.FullName, + (target != null ? target.GetType().FullName : "")), ex); + throw; + } + } +#endif + /// + /// Internal PropertyInfo accessor. + /// + internal PropertyInfo PropertyInfo + { + get { return propertyInfo; } + } + } + + #endregion + +#if NET_2_0 + /// + /// Factory class for dynamic properties. + /// + /// Aleksandar Seovic + public class DynamicProperty : BaseDynamicMember + { + /// + /// Creates safe dynamic property instance for the specified . + /// + /// + ///

This factory method will create a dynamic property with a "safe" wrapper.

+ ///

Safe wrapper will attempt to use generated dynamic property if possible, + /// but it will fall back to standard reflection if necessary.

+ ///
+ /// Property info to create dynamic property for. + /// Safe dynamic property for the specified . + /// + public static IDynamicProperty CreateSafe(PropertyInfo property) + { + return new SafeProperty(property); + } + + /// + /// Creates dynamic property instance for the specified . + /// + /// Property info to create dynamic property for. + /// Dynamic property for the specified . + public static IDynamicProperty Create(PropertyInfo property) + { + AssertUtils.ArgumentNotNull(property, "You cannot create a dynamic property for a null value."); + + IDynamicProperty dynamicProperty = new SafeProperty(property); + return dynamicProperty; + } + } +#else + /// + /// Factory class for dynamic properties. + /// + /// Aleksandar Seovic + public class DynamicProperty : BaseDynamicMember + { + private readonly static CreatePropertyCallback s_createPropertyCallback = new CreatePropertyCallback(CreateInternal); + + #region Create Method + + /// + /// Creates safe dynamic property instance for the specified . + /// + /// + ///

This factory method will create a dynamic property with a "safe" wrapper.

+ ///

Safe wrapper will attempt to use generated dynamic property if possible, + /// but it will fall back to standard reflection if necessary.

+ ///
+ /// Property info to create dynamic property for. + /// Safe dynamic property for the specified . + /// + public static IDynamicProperty CreateSafe(PropertyInfo property) + { + return new SafeProperty(property); + } + + /// + /// Creates dynamic property instance for the specified . + /// + /// Property info to create dynamic property for. + /// Dynamic property for the specified . + public static IDynamicProperty Create(PropertyInfo property) + { + AssertUtils.ArgumentNotNull(property, "You cannot create a dynamic property for a null value."); + + IDynamicProperty dynamicProperty = DynamicReflectionManager.GetDynamicProperty(property, s_createPropertyCallback); + return dynamicProperty; + } + + private static IDynamicProperty CreateInternal(PropertyInfo property) + { + IDynamicProperty dynamicProperty = null; + + TypeBuilder tb = DynamicReflectionManager.CreateTypeBuilder("Property_" + property.Name); + tb.AddInterfaceImplementation(typeof(IDynamicProperty)); + + GenerateGetValue(tb, property); + GenerateSetValue(tb, property); + + Type dynamicPropertyType = tb.CreateType(); + ConstructorInfo ctor = dynamicPropertyType.GetConstructor(Type.EmptyTypes); + dynamicProperty = (IDynamicProperty)ctor.Invoke(ObjectUtils.EmptyObjects); + + return dynamicProperty; + } + + private static void GenerateGetValue(TypeBuilder tb, PropertyInfo property) + { + MethodBuilder getValueMethod = + tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object) }); + getValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); + + ILGenerator il = getValueMethod.GetILGenerator(); + if (property.CanRead) + { + MethodInfo getMethod = property.GetGetMethod(true); + bool isValueType = property.DeclaringType.IsValueType; + bool isStatic = getMethod.IsStatic; + + if (!isStatic) + { + SetupTargetInstance(il, property.DeclaringType); + } + + InvokeMethod(il, isStatic, isValueType, getMethod); + ProcessReturnValue(il, property.PropertyType); + il.Emit(OpCodes.Ret); + } + else + { + ThrowInvalidOperationException(il, "Cannot get value of a non-readable property"); + } + } + + private static void GenerateSetValue(TypeBuilder tb, PropertyInfo property) + { + MethodBuilder setValueMethod = + tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void), + new Type[] { typeof(object), typeof(object) }); + setValueMethod.DefineParameter(1, ParameterAttributes.None, "target"); + setValueMethod.DefineParameter(2, ParameterAttributes.None, "value"); + + ILGenerator il = setValueMethod.GetILGenerator(); + if (property.CanWrite) + { + bool isValueType = property.DeclaringType.IsValueType; + // we can't set nonstatic properties on value types (due to boxing) + bool canSet = !(isValueType && !property.GetSetMethod(true).IsStatic); + if (!canSet) + { + ThrowInvalidOperationException(il, "Cannot set property value on a value type due to boxing."); + } + else + { + MethodInfo setMethod = property.GetSetMethod(true); + bool isStatic = setMethod.IsStatic; + + if (!isStatic) + { + SetupTargetInstance(il, property.DeclaringType); + } + + SetupArgument(il, property.PropertyType, 2); + InvokeMethod(il, isStatic, property.DeclaringType.IsValueType, setMethod); + il.Emit(OpCodes.Ret); + } + } + else + { + ThrowInvalidOperationException(il, "Cannot set value of a read-only property"); + } + } + + #endregion + } + +#endif } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs index 4f83b80a..ea0426f9 100644 --- a/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs +++ b/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs @@ -1,557 +1,556 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Diagnostics; -using System.Reflection; -using System.Reflection.Emit; -using Spring.Util; - -#if NET_2_0 -using NetDynamicMethod = System.Reflection.Emit.DynamicMethod; -#endif - -#endregion - -namespace Spring.Reflection.Dynamic -{ - /// - /// Represents a Get method - /// - /// the target instance when calling an instance method - /// the value return by the Get method - public delegate object GetterDelegate(object target); - - /// - /// Represents a Set method - /// - /// the target instance when calling an instance method - /// the value to be set - public delegate void SetterDelegate(object target, object value); - - /// - /// Represents a method - /// - /// the target instance when calling an instance method - /// arguments to be passed to the method - /// the value return by the method. null when calling a void method - public delegate object FunctionDelegate(object target, params object[] args); - - /// - /// Represents a callback method used to create an from a instance. - /// - internal delegate IDynamicProperty CreatePropertyCallback(PropertyInfo property); - /// - /// Represents a callback method used to create an from a instance. - /// - internal delegate IDynamicField CreateFieldCallback(FieldInfo property); - /// - /// Represents a callback method used to create an from a instance. - /// - internal delegate IDynamicMethod CreateMethodCallback(MethodInfo method); - /// - /// Represents a callback method used to create an from a instance. - /// - internal delegate IDynamicConstructor CreateConstructorCallback(ConstructorInfo constructor); - /// - /// Represents a callback method used to create an from a instance. - /// - internal delegate IDynamicIndexer CreateIndexerCallback(PropertyInfo indexer); - - /// - /// Allows easy access to existing and creation of new dynamic relection members. - /// - /// Aleksandar Seovic - /// $Id: DynamicReflectionManager.cs,v 1.5 2008/05/17 11:05:26 oakinger Exp $ - public sealed class DynamicReflectionManager - { - #region Fields - - /// - /// The name of the assembly that defines reflection types created. - /// - public const string ASSEMBLY_NAME = "Spring.DynamicReflection"; - - /// - /// The attributes of the reflection type to generate. - /// - private const TypeAttributes TYPE_ATTRIBUTES = TypeAttributes.BeforeFieldInit | TypeAttributes.Public; - - /// - /// Cache for dynamic property types. - /// - private readonly static IDictionary propertyCache = new Hashtable(); - - /// - /// Cache for dynamic field types. - /// - private readonly static IDictionary fieldCache = new Hashtable(); - - /// - /// Cache for dynamic indexer types. - /// - private readonly static IDictionary indexerCache = new Hashtable(); - - /// - /// Cache for dynamic method types. - /// - private readonly static IDictionary methodCache = new Hashtable(); - - /// - /// Cache for dynamic constructor types. - /// - private readonly static IDictionary constructorCache = new Hashtable(); - - #endregion - - #region Public Methods - - /// - /// Creates an appropriate type builder. - /// - /// - /// The base name to use for the reflection type name. - /// - /// The type builder to use. - internal static TypeBuilder CreateTypeBuilder(string name) - { - // Generates type name - string typeName = String.Format("{0}.{1}_{2}", - ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N")); - - ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(ASSEMBLY_NAME); - return module.DefineType(typeName, TYPE_ATTRIBUTES); - } - - /// - /// Returns dynamic property if one exists. - /// - /// Property to look up. - /// callback function that will be called to create the dynamic property - /// An for the given property info. - internal static IDynamicProperty GetDynamicProperty(PropertyInfo property, CreatePropertyCallback createCallback) - { - lock (propertyCache.SyncRoot) - { - IDynamicProperty dynamicProperty = (IDynamicProperty)propertyCache[property]; - if (dynamicProperty == null) - { - dynamicProperty = createCallback(property); - propertyCache[property] = dynamicProperty; - } - return dynamicProperty; - } - } - - /// - /// Returns dynamic field if one exists. - /// - /// Field to look up. - /// callback function that will be called to create the dynamic field - /// An for the given field info. - internal static IDynamicField GetDynamicField(FieldInfo field, CreateFieldCallback createCallback) - { - lock (fieldCache.SyncRoot) - { - IDynamicField dynamicField = (IDynamicField)fieldCache[field]; - if (dynamicField == null) - { - dynamicField = createCallback(field); - fieldCache[field] = dynamicField; - } - return dynamicField; - } - } - - /// - /// Returns dynamic indexer if one exists. - /// - /// Indexer to look up. - /// callback function that will be called to create the dynamic indexer - /// An for the given indexer. - internal static IDynamicIndexer GetDynamicIndexer(PropertyInfo indexer, CreateIndexerCallback createCallback) - { - lock (indexerCache.SyncRoot) - { - IDynamicIndexer dynamicIndexer = (IDynamicIndexer)indexerCache[indexer]; - if (dynamicIndexer == null) - { - dynamicIndexer = createCallback(indexer); - indexerCache[indexer] = dynamicIndexer; - } - return dynamicIndexer; - } - } - - /// - /// Returns dynamic method if one exists. - /// - /// Method to look up. - /// callback function that will be called to create the dynamic method - /// An for the given method. - internal static IDynamicMethod GetDynamicMethod(MethodInfo method, CreateMethodCallback createCallback) - { - lock (methodCache.SyncRoot) - { - IDynamicMethod dynamicMethod = (IDynamicMethod)methodCache[method]; - if (dynamicMethod == null) - { - dynamicMethod = createCallback(method); - methodCache[method] = dynamicMethod; - } - return dynamicMethod; - } - } - - /// - /// Returns dynamic constructor if one exists. - /// - /// Constructor to look up. - /// callback function that will be called to create the dynamic constructor - /// An for the given constructor. - internal static IDynamicConstructor GetDynamicConstructor(ConstructorInfo constructor, CreateConstructorCallback createCallback) - { - lock (constructorCache.SyncRoot) - { - IDynamicConstructor dynamicConstructor = (IDynamicConstructor)constructorCache[constructor]; - if (dynamicConstructor == null) - { - dynamicConstructor = createCallback(constructor); - constructorCache[constructor] = dynamicConstructor; - } - return dynamicConstructor; - } - } - - /// - /// Saves dynamically generated assembly to disk. - /// Can only be called in DEBUG mode, per ConditionalAttribute rules. - /// - [Conditional("DEBUG_DYNAMIC")] - public static void SaveAssembly() - { - DynamicCodeManager.SaveAssembly(ASSEMBLY_NAME); - } - - #endregion - -#if NET_2_0 - private static readonly ConstructorInfo NewInvalidOperationException = - typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) }); - - /// - /// Create a new Get method delegate for the specified field using - /// - /// the field to create the delegate for - /// a delegate that can be used to read the field - public static GetterDelegate CreateFieldGetter(FieldInfo fieldInfo) - { - AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value."); - - System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod("getter", typeof(object), new Type[] { typeof(object) }, fieldInfo.DeclaringType.Module, true); - ILGenerator il = dmGetter.GetILGenerator(); - if (fieldInfo.IsLiteral) - { - object value = fieldInfo.GetValue(null); - EmitConstant(il, value); - } - else if (fieldInfo.IsStatic) - { - il.Emit(OpCodes.Ldsfld, fieldInfo); - } - else - { - EmitTarget(il, fieldInfo.DeclaringType); - il.Emit(OpCodes.Ldfld, fieldInfo); - } - - if (fieldInfo.FieldType.IsValueType) - { - il.Emit(OpCodes.Box, fieldInfo.FieldType); - } - il.Emit(OpCodes.Ret); - return (GetterDelegate)dmGetter.CreateDelegate(typeof(GetterDelegate)); - } - - /// - /// Create a new Set method delegate for the specified field using - /// - /// the field to create the delegate for - /// a delegate that can be used to read the field. - /// - /// If the field's returns true, the returned method - /// will throw an when called. - /// - public static SetterDelegate CreateFieldSetter(FieldInfo fieldInfo) - { - AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value."); - - System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod("setter", null, new Type[] { typeof(object), typeof(object) }, fieldInfo.DeclaringType.Module, true); - ILGenerator il = dmSetter.GetILGenerator(); - - if (!fieldInfo.IsLiteral - && !fieldInfo.IsInitOnly - && !(fieldInfo.DeclaringType.IsValueType && !fieldInfo.IsStatic)) - { - if (!fieldInfo.IsStatic) - { - EmitTarget(il, fieldInfo.DeclaringType); - } - il.Emit(OpCodes.Ldarg_1); - if (fieldInfo.FieldType.IsValueType) - { - il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType); - } - if (fieldInfo.IsStatic) - { - il.Emit(OpCodes.Stsfld, fieldInfo); - } - else - { - il.Emit(OpCodes.Stfld, fieldInfo); - } - il.Emit(OpCodes.Ret); - } - else - { - EmitThrowInvalidOperationException(il, string.Format("Cannot write to constant field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name)); - } - return (SetterDelegate)dmSetter.CreateDelegate(typeof(SetterDelegate)); - } - - /// - /// Create a new Get method delegate for the specified property using - /// - /// the property to create the delegate for - /// a delegate that can be used to read the property. - /// - /// If the property's returns false, the returned method - /// will throw an when called. - /// - public static GetterDelegate CreatePropertyGetter(PropertyInfo propertyInfo) - { - AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value."); - - NetDynamicMethod dm = new NetDynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, propertyInfo.DeclaringType.Module, true); - ILGenerator il = dm.GetILGenerator(); - - if (propertyInfo.CanRead) - { - MethodInfo method = propertyInfo.GetGetMethod(true); - if (!method.IsStatic) - { - EmitTarget(il, method.DeclaringType); - } - EmitCall(il, method); - if (propertyInfo.PropertyType.IsValueType) - { - il.Emit(OpCodes.Box, propertyInfo.PropertyType); - } - il.Emit(OpCodes.Ret); - } - else - { - EmitThrowInvalidOperationException(il, string.Format("Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name)); - } - return (GetterDelegate)dm.CreateDelegate(typeof(GetterDelegate)); - } - - /// - /// Create a new Set method delegate for the specified property using - /// - /// the property to create the delegate for - /// a delegate that can be used to write the property. - /// - /// If the property's returns false, the returned method - /// will throw an when called. - /// - public static SetterDelegate CreatePropertySetter(PropertyInfo propertyInfo) - { - AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value."); - - NetDynamicMethod dm = new NetDynamicMethod(string.Empty, null, new Type[] { typeof(object), typeof(object) }, propertyInfo.DeclaringType.Module, true); - ILGenerator il = dm.GetILGenerator(); - - if (propertyInfo.CanWrite - && !(propertyInfo.DeclaringType.IsValueType && !propertyInfo.GetSetMethod(true).IsStatic)) - { - MethodInfo method = propertyInfo.GetSetMethod(true); - if (!method.IsStatic) - { - EmitTarget(il, method.DeclaringType); - } - - il.Emit(OpCodes.Ldarg_1); - if (propertyInfo.PropertyType.IsValueType) - { - il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); - } - EmitCall(il, method); - il.Emit(OpCodes.Ret); - } - else - { - EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name)); - } - - return (SetterDelegate)dm.CreateDelegate(typeof(SetterDelegate)); - } - - /// - /// Create a new method delegate for the specified method using - /// - /// the method to create the delegate for - /// a delegate that can be used to invoke the method. - private static FunctionDelegate CreateFunctionDelegate(MethodInfo method) - { - NetDynamicMethod dm = new NetDynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, method.DeclaringType.Module, true); - ILGenerator il = dm.GetILGenerator(); - ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - ParameterInfo p = parameters[i]; - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldc_I4, i); - il.Emit(OpCodes.Ldelem_Ref); - if (p.ParameterType.IsValueType) - { - il.Emit(OpCodes.Unbox_Any, p.ParameterType); - } - } - - if (!method.IsStatic) - { - EmitTarget(il, method.DeclaringType); - } - EmitCall(il, method); - - if (method.ReturnType == typeof(void)) - { - il.Emit(OpCodes.Ldnull); - } - il.Emit(OpCodes.Ret); - return (FunctionDelegate)dm.CreateDelegate(typeof(FunctionDelegate)); - } - - private static void EmitTarget(ILGenerator il, Type targetType) - { - il.Emit(OpCodes.Ldarg_0); - if (targetType.IsValueType) - { - LocalBuilder local = il.DeclareLocal(targetType); - il.Emit(OpCodes.Unbox_Any, targetType); - il.Emit(OpCodes.Stloc_0); - il.Emit(OpCodes.Ldloca_S, 0); - } - } - - private static void EmitCall(ILGenerator il, MethodInfo method) - { - il.Emit((method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method); - } - - private static void EmitConstant(ILGenerator il, object value) - { - if (value is String) - { - il.Emit(OpCodes.Ldstr, (string)value); - return; - } - - if (value is bool) - { - if ((bool)value) - { - il.Emit(OpCodes.Ldc_I4_1); - } - else - { - il.Emit(OpCodes.Ldc_I4_0); - } - return; - } - - if (value is Char) - { - il.Emit(OpCodes.Ldc_I4, (Char)value); - il.Emit(OpCodes.Conv_I2); - return; - } - - if (value is byte) - { - il.Emit(OpCodes.Ldc_I4, (byte)value); - il.Emit(OpCodes.Conv_I1); - } - else if (value is Int16) - { - il.Emit(OpCodes.Ldc_I4, (Int16)value); - il.Emit(OpCodes.Conv_I2); - } - else if (value is Int32) - { - il.Emit(OpCodes.Ldc_I4, (Int32)value); - } - else if (value is Int64) - { - il.Emit(OpCodes.Ldc_I8, (Int64)value); - } - else if (value is UInt16) - { - il.Emit(OpCodes.Ldc_I4, (UInt16)value); - il.Emit(OpCodes.Conv_U2); - } - else if (value is UInt32) - { - il.Emit(OpCodes.Ldc_I4, (UInt32)value); - il.Emit(OpCodes.Conv_U4); - } - else if (value is UInt64) - { - il.Emit(OpCodes.Ldc_I8, (UInt64)value); - il.Emit(OpCodes.Conv_U8); - } - else if (value is Single) - { - il.Emit(OpCodes.Ldc_R4, (Single)value); - } - else if (value is Double) - { - il.Emit(OpCodes.Ldc_R8, (Double)value); - } - } - - /// - /// Generates code that throws . - /// - /// IL generator to use. - /// Error message to use. - private static void EmitThrowInvalidOperationException(ILGenerator il, string message) - { - il.Emit(OpCodes.Ldstr, message); - il.Emit(OpCodes.Newobj, NewInvalidOperationException); - il.Emit(OpCodes.Throw); - } -#endif - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; +using Spring.Util; + +#if NET_2_0 +using NetDynamicMethod = System.Reflection.Emit.DynamicMethod; +#endif + +#endregion + +namespace Spring.Reflection.Dynamic +{ + /// + /// Represents a Get method + /// + /// the target instance when calling an instance method + /// the value return by the Get method + public delegate object GetterDelegate(object target); + + /// + /// Represents a Set method + /// + /// the target instance when calling an instance method + /// the value to be set + public delegate void SetterDelegate(object target, object value); + + /// + /// Represents a method + /// + /// the target instance when calling an instance method + /// arguments to be passed to the method + /// the value return by the method. null when calling a void method + public delegate object FunctionDelegate(object target, params object[] args); + + /// + /// Represents a callback method used to create an from a instance. + /// + internal delegate IDynamicProperty CreatePropertyCallback(PropertyInfo property); + /// + /// Represents a callback method used to create an from a instance. + /// + internal delegate IDynamicField CreateFieldCallback(FieldInfo property); + /// + /// Represents a callback method used to create an from a instance. + /// + internal delegate IDynamicMethod CreateMethodCallback(MethodInfo method); + /// + /// Represents a callback method used to create an from a instance. + /// + internal delegate IDynamicConstructor CreateConstructorCallback(ConstructorInfo constructor); + /// + /// Represents a callback method used to create an from a instance. + /// + internal delegate IDynamicIndexer CreateIndexerCallback(PropertyInfo indexer); + + /// + /// Allows easy access to existing and creation of new dynamic relection members. + /// + /// Aleksandar Seovic + public sealed class DynamicReflectionManager + { + #region Fields + + /// + /// The name of the assembly that defines reflection types created. + /// + public const string ASSEMBLY_NAME = "Spring.DynamicReflection"; + + /// + /// The attributes of the reflection type to generate. + /// + private const TypeAttributes TYPE_ATTRIBUTES = TypeAttributes.BeforeFieldInit | TypeAttributes.Public; + + /// + /// Cache for dynamic property types. + /// + private readonly static IDictionary propertyCache = new Hashtable(); + + /// + /// Cache for dynamic field types. + /// + private readonly static IDictionary fieldCache = new Hashtable(); + + /// + /// Cache for dynamic indexer types. + /// + private readonly static IDictionary indexerCache = new Hashtable(); + + /// + /// Cache for dynamic method types. + /// + private readonly static IDictionary methodCache = new Hashtable(); + + /// + /// Cache for dynamic constructor types. + /// + private readonly static IDictionary constructorCache = new Hashtable(); + + #endregion + + #region Public Methods + + /// + /// Creates an appropriate type builder. + /// + /// + /// The base name to use for the reflection type name. + /// + /// The type builder to use. + internal static TypeBuilder CreateTypeBuilder(string name) + { + // Generates type name + string typeName = String.Format("{0}.{1}_{2}", + ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N")); + + ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(ASSEMBLY_NAME); + return module.DefineType(typeName, TYPE_ATTRIBUTES); + } + + /// + /// Returns dynamic property if one exists. + /// + /// Property to look up. + /// callback function that will be called to create the dynamic property + /// An for the given property info. + internal static IDynamicProperty GetDynamicProperty(PropertyInfo property, CreatePropertyCallback createCallback) + { + lock (propertyCache.SyncRoot) + { + IDynamicProperty dynamicProperty = (IDynamicProperty)propertyCache[property]; + if (dynamicProperty == null) + { + dynamicProperty = createCallback(property); + propertyCache[property] = dynamicProperty; + } + return dynamicProperty; + } + } + + /// + /// Returns dynamic field if one exists. + /// + /// Field to look up. + /// callback function that will be called to create the dynamic field + /// An for the given field info. + internal static IDynamicField GetDynamicField(FieldInfo field, CreateFieldCallback createCallback) + { + lock (fieldCache.SyncRoot) + { + IDynamicField dynamicField = (IDynamicField)fieldCache[field]; + if (dynamicField == null) + { + dynamicField = createCallback(field); + fieldCache[field] = dynamicField; + } + return dynamicField; + } + } + + /// + /// Returns dynamic indexer if one exists. + /// + /// Indexer to look up. + /// callback function that will be called to create the dynamic indexer + /// An for the given indexer. + internal static IDynamicIndexer GetDynamicIndexer(PropertyInfo indexer, CreateIndexerCallback createCallback) + { + lock (indexerCache.SyncRoot) + { + IDynamicIndexer dynamicIndexer = (IDynamicIndexer)indexerCache[indexer]; + if (dynamicIndexer == null) + { + dynamicIndexer = createCallback(indexer); + indexerCache[indexer] = dynamicIndexer; + } + return dynamicIndexer; + } + } + + /// + /// Returns dynamic method if one exists. + /// + /// Method to look up. + /// callback function that will be called to create the dynamic method + /// An for the given method. + internal static IDynamicMethod GetDynamicMethod(MethodInfo method, CreateMethodCallback createCallback) + { + lock (methodCache.SyncRoot) + { + IDynamicMethod dynamicMethod = (IDynamicMethod)methodCache[method]; + if (dynamicMethod == null) + { + dynamicMethod = createCallback(method); + methodCache[method] = dynamicMethod; + } + return dynamicMethod; + } + } + + /// + /// Returns dynamic constructor if one exists. + /// + /// Constructor to look up. + /// callback function that will be called to create the dynamic constructor + /// An for the given constructor. + internal static IDynamicConstructor GetDynamicConstructor(ConstructorInfo constructor, CreateConstructorCallback createCallback) + { + lock (constructorCache.SyncRoot) + { + IDynamicConstructor dynamicConstructor = (IDynamicConstructor)constructorCache[constructor]; + if (dynamicConstructor == null) + { + dynamicConstructor = createCallback(constructor); + constructorCache[constructor] = dynamicConstructor; + } + return dynamicConstructor; + } + } + + /// + /// Saves dynamically generated assembly to disk. + /// Can only be called in DEBUG mode, per ConditionalAttribute rules. + /// + [Conditional("DEBUG_DYNAMIC")] + public static void SaveAssembly() + { + DynamicCodeManager.SaveAssembly(ASSEMBLY_NAME); + } + + #endregion + +#if NET_2_0 + private static readonly ConstructorInfo NewInvalidOperationException = + typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) }); + + /// + /// Create a new Get method delegate for the specified field using + /// + /// the field to create the delegate for + /// a delegate that can be used to read the field + public static GetterDelegate CreateFieldGetter(FieldInfo fieldInfo) + { + AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value."); + + System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod("getter", typeof(object), new Type[] { typeof(object) }, fieldInfo.DeclaringType.Module, true); + ILGenerator il = dmGetter.GetILGenerator(); + if (fieldInfo.IsLiteral) + { + object value = fieldInfo.GetValue(null); + EmitConstant(il, value); + } + else if (fieldInfo.IsStatic) + { + il.Emit(OpCodes.Ldsfld, fieldInfo); + } + else + { + EmitTarget(il, fieldInfo.DeclaringType); + il.Emit(OpCodes.Ldfld, fieldInfo); + } + + if (fieldInfo.FieldType.IsValueType) + { + il.Emit(OpCodes.Box, fieldInfo.FieldType); + } + il.Emit(OpCodes.Ret); + return (GetterDelegate)dmGetter.CreateDelegate(typeof(GetterDelegate)); + } + + /// + /// Create a new Set method delegate for the specified field using + /// + /// the field to create the delegate for + /// a delegate that can be used to read the field. + /// + /// If the field's returns true, the returned method + /// will throw an when called. + /// + public static SetterDelegate CreateFieldSetter(FieldInfo fieldInfo) + { + AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value."); + + System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod("setter", null, new Type[] { typeof(object), typeof(object) }, fieldInfo.DeclaringType.Module, true); + ILGenerator il = dmSetter.GetILGenerator(); + + if (!fieldInfo.IsLiteral + && !fieldInfo.IsInitOnly + && !(fieldInfo.DeclaringType.IsValueType && !fieldInfo.IsStatic)) + { + if (!fieldInfo.IsStatic) + { + EmitTarget(il, fieldInfo.DeclaringType); + } + il.Emit(OpCodes.Ldarg_1); + if (fieldInfo.FieldType.IsValueType) + { + il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType); + } + if (fieldInfo.IsStatic) + { + il.Emit(OpCodes.Stsfld, fieldInfo); + } + else + { + il.Emit(OpCodes.Stfld, fieldInfo); + } + il.Emit(OpCodes.Ret); + } + else + { + EmitThrowInvalidOperationException(il, string.Format("Cannot write to constant field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name)); + } + return (SetterDelegate)dmSetter.CreateDelegate(typeof(SetterDelegate)); + } + + /// + /// Create a new Get method delegate for the specified property using + /// + /// the property to create the delegate for + /// a delegate that can be used to read the property. + /// + /// If the property's returns false, the returned method + /// will throw an when called. + /// + public static GetterDelegate CreatePropertyGetter(PropertyInfo propertyInfo) + { + AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value."); + + NetDynamicMethod dm = new NetDynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, propertyInfo.DeclaringType.Module, true); + ILGenerator il = dm.GetILGenerator(); + + if (propertyInfo.CanRead) + { + MethodInfo method = propertyInfo.GetGetMethod(true); + if (!method.IsStatic) + { + EmitTarget(il, method.DeclaringType); + } + EmitCall(il, method); + if (propertyInfo.PropertyType.IsValueType) + { + il.Emit(OpCodes.Box, propertyInfo.PropertyType); + } + il.Emit(OpCodes.Ret); + } + else + { + EmitThrowInvalidOperationException(il, string.Format("Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name)); + } + return (GetterDelegate)dm.CreateDelegate(typeof(GetterDelegate)); + } + + /// + /// Create a new Set method delegate for the specified property using + /// + /// the property to create the delegate for + /// a delegate that can be used to write the property. + /// + /// If the property's returns false, the returned method + /// will throw an when called. + /// + public static SetterDelegate CreatePropertySetter(PropertyInfo propertyInfo) + { + AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value."); + + NetDynamicMethod dm = new NetDynamicMethod(string.Empty, null, new Type[] { typeof(object), typeof(object) }, propertyInfo.DeclaringType.Module, true); + ILGenerator il = dm.GetILGenerator(); + + if (propertyInfo.CanWrite + && !(propertyInfo.DeclaringType.IsValueType && !propertyInfo.GetSetMethod(true).IsStatic)) + { + MethodInfo method = propertyInfo.GetSetMethod(true); + if (!method.IsStatic) + { + EmitTarget(il, method.DeclaringType); + } + + il.Emit(OpCodes.Ldarg_1); + if (propertyInfo.PropertyType.IsValueType) + { + il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); + } + EmitCall(il, method); + il.Emit(OpCodes.Ret); + } + else + { + EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name)); + } + + return (SetterDelegate)dm.CreateDelegate(typeof(SetterDelegate)); + } + + /// + /// Create a new method delegate for the specified method using + /// + /// the method to create the delegate for + /// a delegate that can be used to invoke the method. + private static FunctionDelegate CreateFunctionDelegate(MethodInfo method) + { + NetDynamicMethod dm = new NetDynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, method.DeclaringType.Module, true); + ILGenerator il = dm.GetILGenerator(); + ParameterInfo[] parameters = method.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + ParameterInfo p = parameters[i]; + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldc_I4, i); + il.Emit(OpCodes.Ldelem_Ref); + if (p.ParameterType.IsValueType) + { + il.Emit(OpCodes.Unbox_Any, p.ParameterType); + } + } + + if (!method.IsStatic) + { + EmitTarget(il, method.DeclaringType); + } + EmitCall(il, method); + + if (method.ReturnType == typeof(void)) + { + il.Emit(OpCodes.Ldnull); + } + il.Emit(OpCodes.Ret); + return (FunctionDelegate)dm.CreateDelegate(typeof(FunctionDelegate)); + } + + private static void EmitTarget(ILGenerator il, Type targetType) + { + il.Emit(OpCodes.Ldarg_0); + if (targetType.IsValueType) + { + LocalBuilder local = il.DeclareLocal(targetType); + il.Emit(OpCodes.Unbox_Any, targetType); + il.Emit(OpCodes.Stloc_0); + il.Emit(OpCodes.Ldloca_S, 0); + } + } + + private static void EmitCall(ILGenerator il, MethodInfo method) + { + il.Emit((method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method); + } + + private static void EmitConstant(ILGenerator il, object value) + { + if (value is String) + { + il.Emit(OpCodes.Ldstr, (string)value); + return; + } + + if (value is bool) + { + if ((bool)value) + { + il.Emit(OpCodes.Ldc_I4_1); + } + else + { + il.Emit(OpCodes.Ldc_I4_0); + } + return; + } + + if (value is Char) + { + il.Emit(OpCodes.Ldc_I4, (Char)value); + il.Emit(OpCodes.Conv_I2); + return; + } + + if (value is byte) + { + il.Emit(OpCodes.Ldc_I4, (byte)value); + il.Emit(OpCodes.Conv_I1); + } + else if (value is Int16) + { + il.Emit(OpCodes.Ldc_I4, (Int16)value); + il.Emit(OpCodes.Conv_I2); + } + else if (value is Int32) + { + il.Emit(OpCodes.Ldc_I4, (Int32)value); + } + else if (value is Int64) + { + il.Emit(OpCodes.Ldc_I8, (Int64)value); + } + else if (value is UInt16) + { + il.Emit(OpCodes.Ldc_I4, (UInt16)value); + il.Emit(OpCodes.Conv_U2); + } + else if (value is UInt32) + { + il.Emit(OpCodes.Ldc_I4, (UInt32)value); + il.Emit(OpCodes.Conv_U4); + } + else if (value is UInt64) + { + il.Emit(OpCodes.Ldc_I8, (UInt64)value); + il.Emit(OpCodes.Conv_U8); + } + else if (value is Single) + { + il.Emit(OpCodes.Ldc_R4, (Single)value); + } + else if (value is Double) + { + il.Emit(OpCodes.Ldc_R8, (Double)value); + } + } + + /// + /// Generates code that throws . + /// + /// IL generator to use. + /// Error message to use. + private static void EmitThrowInvalidOperationException(ILGenerator il, string message) + { + il.Emit(OpCodes.Ldstr, message); + il.Emit(OpCodes.Newobj, NewInvalidOperationException); + il.Emit(OpCodes.Throw); + } +#endif + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/CallContextStorage.cs b/src/Spring/Spring.Core/Threading/CallContextStorage.cs index c56b046f..7e96f4de 100644 --- a/src/Spring/Spring.Core/Threading/CallContextStorage.cs +++ b/src/Spring/Spring.Core/Threading/CallContextStorage.cs @@ -1,41 +1,40 @@ -using System.Runtime.Remoting.Messaging; - -namespace Spring.Threading -{ - /// - /// Implements by using . - /// - /// Erich Eichinger - /// $Id: CallContextStorage.cs,v 1.1 2007/02/02 21:30:34 oakinger Exp $ - public class CallContextStorage : IThreadStorage - { - /// - /// Retrieves an object with the specified name. - /// - /// The name of the item. - /// The object in the call context associated with the specified name or null if no object has been stored previously - public object GetData(string name) - { - return CallContext.GetData(name); - } - - /// - /// Stores a given object and associates it with the specified name. - /// - /// The name with which to associate the new item. - /// The object to store in the call context. - public void SetData(string name, object value) - { - CallContext.SetData(name, value); - } - - /// - /// Empties a data slot with the specified name. - /// - /// The name of the data slot to empty. - public void FreeNamedDataSlot(string name) - { - CallContext.FreeNamedDataSlot(name); - } - } +using System.Runtime.Remoting.Messaging; + +namespace Spring.Threading +{ + /// + /// Implements by using . + /// + /// Erich Eichinger + public class CallContextStorage : IThreadStorage + { + /// + /// Retrieves an object with the specified name. + /// + /// The name of the item. + /// The object in the call context associated with the specified name or null if no object has been stored previously + public object GetData(string name) + { + return CallContext.GetData(name); + } + + /// + /// Stores a given object and associates it with the specified name. + /// + /// The name with which to associate the new item. + /// The object to store in the call context. + public void SetData(string name, object value) + { + CallContext.SetData(name, value); + } + + /// + /// Empties a data slot with the specified name. + /// + /// The name of the data slot to empty. + public void FreeNamedDataSlot(string name) + { + CallContext.FreeNamedDataSlot(name); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/ISync.cs b/src/Spring/Spring.Core/Threading/ISync.cs index e0deeee2..d42a3edc 100644 --- a/src/Spring/Spring.Core/Threading/ISync.cs +++ b/src/Spring/Spring.Core/Threading/ISync.cs @@ -1,92 +1,91 @@ -#region License -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ -#endregion - -namespace Spring.Threading -{ - /// - /// Acquire/Release protocol, base of many concurrency utilities. - /// - /// - /// - ///

objects isolate waiting and notification for particular logical - /// states, resource availability, events, and the like that are shared - /// across multiple threads.

- /// - ///

Use of s sometimes (but by no means always) adds - /// flexibility and efficiency compared to the use of plain - /// .Net monitor methods and locking, and are sometimes (but by no means - /// always) simpler to program with.

- /// - ///

Used for implementation of a

- ///
- /// - /// Doug Lea - /// Federico Spinazzi (.Net) - /// $Id: ISync.cs,v 1.6 2006/09/15 19:06:08 markpollack Exp $ - public interface ISync - { - /// Wait (possibly forever) until successful passage. - /// Fail only upon interuption. Interruptions always result in - /// `clean' failures. On failure, you can be sure that it has not - /// been acquired, and that no - /// corresponding release should be performed. Conversely, - /// a normal return guarantees that the acquire was successful. - /// - /// - void Acquire(); - - /// Potentially enable others to pass. - ///

- /// Because release does not raise exceptions, - /// it can be used in `finally' clauses without requiring extra - /// embedded try/catch blocks. But keep in mind that - /// as with any java method, implementations may - /// still throw unchecked exceptions such as Error or NullPointerException - /// when faced with uncontinuable errors. However, these should normally - /// only be caught by higher-level error handlers. - ///

- ///
- void Release (); - - /// - /// Wait at most msecs to pass; report whether passed. - ///

- /// The method has best-effort semantics: - /// The msecs bound cannot - /// be guaranteed to be a precise upper bound on wait time in Java. - /// Implementations generally can only attempt to return as soon as possible - /// after the specified bound. Also, timers in Java do not stop during garbage - /// collection, so timeouts can occur just because a GC intervened. - /// So, msecs arguments should be used in - /// a coarse-grained manner. Further, - /// implementations cannot always guarantee that this method - /// will return at all without blocking indefinitely when used in - /// unintended ways. For example, deadlocks may be encountered - /// when called in an unintended context. - ///

- ///
- /// the number of milleseconds to wait - /// An argument less than or equal to zero means not to wait at all. - /// However, this may still require - /// access to a synchronization lock, which can impose unbounded - /// delay if there is a lot of contention among threads. - /// - /// true if acquired - bool Attempt(long msecs); - } -} +#region License +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ +#endregion + +namespace Spring.Threading +{ + /// + /// Acquire/Release protocol, base of many concurrency utilities. + /// + /// + /// + ///

objects isolate waiting and notification for particular logical + /// states, resource availability, events, and the like that are shared + /// across multiple threads.

+ /// + ///

Use of s sometimes (but by no means always) adds + /// flexibility and efficiency compared to the use of plain + /// .Net monitor methods and locking, and are sometimes (but by no means + /// always) simpler to program with.

+ /// + ///

Used for implementation of a

+ ///
+ /// + /// Doug Lea + /// Federico Spinazzi (.Net) + public interface ISync + { + /// Wait (possibly forever) until successful passage. + /// Fail only upon interuption. Interruptions always result in + /// `clean' failures. On failure, you can be sure that it has not + /// been acquired, and that no + /// corresponding release should be performed. Conversely, + /// a normal return guarantees that the acquire was successful. + /// + /// + void Acquire(); + + /// Potentially enable others to pass. + ///

+ /// Because release does not raise exceptions, + /// it can be used in `finally' clauses without requiring extra + /// embedded try/catch blocks. But keep in mind that + /// as with any java method, implementations may + /// still throw unchecked exceptions such as Error or NullPointerException + /// when faced with uncontinuable errors. However, these should normally + /// only be caught by higher-level error handlers. + ///

+ ///
+ void Release (); + + /// + /// Wait at most msecs to pass; report whether passed. + ///

+ /// The method has best-effort semantics: + /// The msecs bound cannot + /// be guaranteed to be a precise upper bound on wait time in Java. + /// Implementations generally can only attempt to return as soon as possible + /// after the specified bound. Also, timers in Java do not stop during garbage + /// collection, so timeouts can occur just because a GC intervened. + /// So, msecs arguments should be used in + /// a coarse-grained manner. Further, + /// implementations cannot always guarantee that this method + /// will return at all without blocking indefinitely when used in + /// unintended ways. For example, deadlocks may be encountered + /// when called in an unintended context. + ///

+ ///
+ /// the number of milleseconds to wait + /// An argument less than or equal to zero means not to wait at all. + /// However, this may still require + /// access to a synchronization lock, which can impose unbounded + /// delay if there is a lot of contention among threads. + /// + /// true if acquired + bool Attempt(long msecs); + } +} diff --git a/src/Spring/Spring.Core/Threading/IThreadStorage.cs b/src/Spring/Spring.Core/Threading/IThreadStorage.cs index 13199766..d7dcade9 100644 --- a/src/Spring/Spring.Core/Threading/IThreadStorage.cs +++ b/src/Spring/Spring.Core/Threading/IThreadStorage.cs @@ -1,40 +1,39 @@ -namespace Spring.Threading -{ - /// - /// Specifies the contract a strategy must be implement to store and - /// retrieve data that is specific to the executing thread. - /// - /// - /// All implementations of this interface must treat keys case-sensitive. - /// - /// Erich Eichinger - /// $Id: IThreadStorage.cs,v 1.1 2007/02/02 21:30:34 oakinger Exp $ - public interface IThreadStorage - { - /// - /// Retrieves an object with the specified . - /// - /// The name of the item. - /// - /// The object in the current thread's context associated with the - /// specified or null if no object has been stored previously - /// - object GetData(string name); - - /// - /// Stores a given object and associates it with the specified . - /// - /// The name with which to associate the new item. - /// The object to store in the current thread's context. - void SetData(string name, object value); - - /// - /// Empties a data slot with the specified name. - /// - /// - /// If the object with the specified is not found, the method does nothing. - /// - /// The name of the object to remove. - void FreeNamedDataSlot(string name); - } +namespace Spring.Threading +{ + /// + /// Specifies the contract a strategy must be implement to store and + /// retrieve data that is specific to the executing thread. + /// + /// + /// All implementations of this interface must treat keys case-sensitive. + /// + /// Erich Eichinger + public interface IThreadStorage + { + /// + /// Retrieves an object with the specified . + /// + /// The name of the item. + /// + /// The object in the current thread's context associated with the + /// specified or null if no object has been stored previously + /// + object GetData(string name); + + /// + /// Stores a given object and associates it with the specified . + /// + /// The name with which to associate the new item. + /// The object to store in the current thread's context. + void SetData(string name, object value); + + /// + /// Empties a data slot with the specified name. + /// + /// + /// If the object with the specified is not found, the method does nothing. + /// + /// The name of the object to remove. + void FreeNamedDataSlot(string name); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/Latch.cs b/src/Spring/Spring.Core/Threading/Latch.cs index 17ba51ff..6832caed 100644 --- a/src/Spring/Spring.Core/Threading/Latch.cs +++ b/src/Spring/Spring.Core/Threading/Latch.cs @@ -1,132 +1,131 @@ -#region License -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ -#endregion - -using System; -using System.Threading; - -namespace Spring.Threading -{ - /// A latch is a boolean condition that is set at most once, ever. - /// Once a single release is issued, all acquires will pass. - ///

- /// Sample usage. Here are a set of classes that use - /// a latch as a start signal for a group of worker threads that - /// are created and started beforehand, and then later enabled. - ///

- /// - /// class Worker implements IRunnable { - /// private readonly Latch startSignal; - /// Worker(Latch l) - /// { - /// startSignal = l; - /// } - /// - /// public void Run() { - /// startSignal.acquire(); - /// DoWork(); - /// } - /// - /// void DoWork() { ... } - /// } - /// - /// class Driver { // ... - /// void Main() { - /// Latch go = new Latch(); - /// for (int i = 0; i < N; ++i) // make threads - /// new Thread(new ThreadStart(new Worker(go)).Start(); - /// DoSomethingElse(); // don't let run yet - /// go.Release(); // let all threads proceed - /// } - /// } - /// - ///
- /// Doug Lea - /// Federico Spinazzi (.Net) - /// $Id: Latch.cs,v 1.11 2006/09/15 19:06:08 markpollack Exp $ - public class Latch : ISync - { - /// - /// can acquire ? - /// - protected bool latched_ = false; - - /// - /// Method mainly used by clients who are trying to get the latch - /// - public void Acquire () - { - lock (this) - { - while (!latched_) - { - Monitor.Wait (this); - } - } - } - - /// Wait at most msecs millisconds for a permit - public bool Attempt (long msecs) - { - lock (this) - { - if (latched_) - { - return true; - } - else if (msecs <= 0) - { - return false; - } - else - { - long waitTime = msecs; - //double start = new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds; - double start = Utils.CurrentTimeMillis; - for (;;) - { - Monitor.Wait (this, TimeSpan.FromMilliseconds(waitTime)); - if (latched_) - { - return true; - } - else - { - waitTime = (long) (msecs - (Utils.CurrentTimeMillis - start)); - if (waitTime <= 0) - { - return false; - } - } - } - } - } - } - - /// - /// Enable all current and future acquires to pass - /// - public void Release () - { - lock (this) - { - latched_ = true; - Monitor.PulseAll(this); - } - } - } +#region License +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ +#endregion + +using System; +using System.Threading; + +namespace Spring.Threading +{ + /// A latch is a boolean condition that is set at most once, ever. + /// Once a single release is issued, all acquires will pass. + ///

+ /// Sample usage. Here are a set of classes that use + /// a latch as a start signal for a group of worker threads that + /// are created and started beforehand, and then later enabled. + ///

+ /// + /// class Worker implements IRunnable { + /// private readonly Latch startSignal; + /// Worker(Latch l) + /// { + /// startSignal = l; + /// } + /// + /// public void Run() { + /// startSignal.acquire(); + /// DoWork(); + /// } + /// + /// void DoWork() { ... } + /// } + /// + /// class Driver { // ... + /// void Main() { + /// Latch go = new Latch(); + /// for (int i = 0; i < N; ++i) // make threads + /// new Thread(new ThreadStart(new Worker(go)).Start(); + /// DoSomethingElse(); // don't let run yet + /// go.Release(); // let all threads proceed + /// } + /// } + /// + ///
+ /// Doug Lea + /// Federico Spinazzi (.Net) + public class Latch : ISync + { + /// + /// can acquire ? + /// + protected bool latched_ = false; + + /// + /// Method mainly used by clients who are trying to get the latch + /// + public void Acquire () + { + lock (this) + { + while (!latched_) + { + Monitor.Wait (this); + } + } + } + + /// Wait at most msecs millisconds for a permit + public bool Attempt (long msecs) + { + lock (this) + { + if (latched_) + { + return true; + } + else if (msecs <= 0) + { + return false; + } + else + { + long waitTime = msecs; + //double start = new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds; + double start = Utils.CurrentTimeMillis; + for (;;) + { + Monitor.Wait (this, TimeSpan.FromMilliseconds(waitTime)); + if (latched_) + { + return true; + } + else + { + waitTime = (long) (msecs - (Utils.CurrentTimeMillis - start)); + if (waitTime <= 0) + { + return false; + } + } + } + } + } + } + + /// + /// Enable all current and future acquires to pass + /// + public void Release () + { + lock (this) + { + latched_ = true; + Monitor.PulseAll(this); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/LogicalThreadContext.cs b/src/Spring/Spring.Core/Threading/LogicalThreadContext.cs index fc471af4..ad9890c0 100644 --- a/src/Spring/Spring.Core/Threading/LogicalThreadContext.cs +++ b/src/Spring/Spring.Core/Threading/LogicalThreadContext.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Remoting.Messaging; -using Spring.Util; - -#endregion - -namespace Spring.Threading -{ - /// - /// An abstraction to safely store "ThreadStatic" data. - /// - /// - /// By default, is used to store thread-specific data. - /// You may switch the storage strategy by calling .

- /// NOTE: Access to the underlying storage is not synchronized for performance reasons. - /// You should call only once at application startup! - /// - /// Erich Eichinger - /// $Id: LogicalThreadContext.cs,v 1.3 2007/07/03 22:32:04 markpollack Exp $ - public sealed class LogicalThreadContext - { - ///

- /// Holds the current strategy. - /// - /// - /// Access to this variable is not synchronized on purpose for performance reasons. - /// Setting a different strategy should happen only once - /// at application startup. - /// - private static IThreadStorage threadStorage = new CallContextStorage(); - - /// - /// Set the new strategy. - /// - public static void SetStorage(IThreadStorage storage) - { - AssertUtils.ArgumentNotNull(storage, "storage"); - threadStorage = storage; - } - - private LogicalThreadContext() - { - throw new NotSupportedException("must not be instantiated"); - } - - /// - /// Retrieves an object with the specified name. - /// - /// The name of the item. - /// The object in the context associated with the specified name or null if no object has been stored previously - public static object GetData(string name) - { - return threadStorage.GetData(name); - } - - /// - /// Stores a given object and associates it with the specified name. - /// - /// The name with which to associate the new item. - /// The object to store in the current thread's context. - public static void SetData(string name, object value) - { - threadStorage.SetData(name, value); - } - - /// - /// Empties a data slot with the specified name. - /// - /// The name of the data slot to empty. - public static void FreeNamedDataSlot(string name) - { - threadStorage.FreeNamedDataSlot(name); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Remoting.Messaging; +using Spring.Util; + +#endregion + +namespace Spring.Threading +{ + /// + /// An abstraction to safely store "ThreadStatic" data. + /// + /// + /// By default, is used to store thread-specific data. + /// You may switch the storage strategy by calling .

+ /// NOTE: Access to the underlying storage is not synchronized for performance reasons. + /// You should call only once at application startup! + /// + /// Erich Eichinger + public sealed class LogicalThreadContext + { + ///

+ /// Holds the current strategy. + /// + /// + /// Access to this variable is not synchronized on purpose for performance reasons. + /// Setting a different strategy should happen only once + /// at application startup. + /// + private static IThreadStorage threadStorage = new CallContextStorage(); + + /// + /// Set the new strategy. + /// + public static void SetStorage(IThreadStorage storage) + { + AssertUtils.ArgumentNotNull(storage, "storage"); + threadStorage = storage; + } + + private LogicalThreadContext() + { + throw new NotSupportedException("must not be instantiated"); + } + + /// + /// Retrieves an object with the specified name. + /// + /// The name of the item. + /// The object in the context associated with the specified name or null if no object has been stored previously + public static object GetData(string name) + { + return threadStorage.GetData(name); + } + + /// + /// Stores a given object and associates it with the specified name. + /// + /// The name with which to associate the new item. + /// The object to store in the current thread's context. + public static void SetData(string name, object value) + { + threadStorage.SetData(name, value); + } + + /// + /// Empties a data slot with the specified name. + /// + /// The name of the data slot to empty. + public static void FreeNamedDataSlot(string name) + { + threadStorage.FreeNamedDataSlot(name); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/Semaphore.cs b/src/Spring/Spring.Core/Threading/Semaphore.cs index 9541ab64..28a9b381 100644 --- a/src/Spring/Spring.Core/Threading/Semaphore.cs +++ b/src/Spring/Spring.Core/Threading/Semaphore.cs @@ -1,187 +1,186 @@ -#region License -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ -#endregion - -using System; -using System.Threading; - -namespace Spring.Threading -{ - /// - ///

Base class for counting semaphores based on Semaphore implementation - /// from Doug Lea.

- ///
- /// - /// - ///

Conceptually, a semaphore - /// maintains a set of permits. Each acquire() blocks if - /// necessary until a permit is available, and then takes it.

- /// - ///

Each release adds a permit. However, no actual permit objects are used; - /// the Semaphore just keeps a count of the number available - /// and acts accordingly.

- /// - ///

A semaphore initialized to 1 can serve as a mutual exclusion lock.

- /// - /// Used for implementation of a - ///
- /// Doug Lea - /// Federico Spinazzi (.Net) - /// $Id: Semaphore.cs,v 1.10 2006/09/15 21:30:09 markpollack Exp $ - public class Semaphore : ISync - { - /// - /// current number of available permits - /// - protected long nPermits; - - /// - ///

Create a Semaphore with the given initial number of permits.

- ///

Using a seed of 1 makes the semaphore act as a mutual - /// exclusion lock.

- /// - ///

Negative seeds are also allowed, - /// in which case no acquires will proceed until the number of - /// releases has pushed the number of permits past 0.

- ///
- public Semaphore(long initialPermits) - { - nPermits = initialPermits; - } - - /// - /// Release a permit - /// - public virtual void Release () - { - lock (this) - { - ++nPermits; - Monitor.Pulse(this); - } - } - - /// - /// Acquire a permit - /// - public virtual void Acquire () - { - lock (this) - { - try - { - while (nPermits <= 0) - Monitor.Wait(this); - --nPermits; - } - catch (ThreadInterruptedException ex) - { - Monitor.Pulse(this); - throw ex; - } - } - } - - /// - /// Wait at most msecs millisconds for a permit - /// - /// number of ms to wait - /// true if aquired - public virtual bool Attempt(long msecs) - { - lock (this) - { - if (nPermits > 0) - { - --nPermits; - return true; - } - else if (msecs <= 0) - return false; - else - { - try - { - double startTime = Utils.CurrentTimeMillis; - long waitTime = msecs; - - for (; ; ) - { - Monitor.Wait(this, TimeSpan.FromMilliseconds(waitTime)); - if (nPermits > 0) - { - --nPermits; - return true; - } - else - { - waitTime = (long) (msecs - (Utils.CurrentTimeMillis - startTime)); - if (waitTime <= 0) - return false; - } - } - } - catch (ThreadInterruptedException ex) - { - Monitor.Pulse(this); - throw ex; - } - } - } - } - - /// Release N permits. release(n) is - /// equivalent in effect to: - ///
-        /// for (int i = 0; i < n; ++i) release();
-        /// 
- /// But may be more efficient in some semaphore implementations. - ///
- /// if n is negative. - /// - /// - public virtual void Release(long n) - { - lock (this) - { - if (n < 0) - throw new ArgumentOutOfRangeException("n", n, "Negative argument"); - - nPermits += n; - for (long i = 0; i < n; ++i) - Monitor.Pulse(this); - } - } - - /// Return the current number of available permits. - /// Returns an accurate, but possibly unstable value, - /// that may change immediately after returning. - /// - public virtual long Permits - { - get - { - lock (this) - { - return nPermits; - } - } - } - - - } -} +#region License +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ +#endregion + +using System; +using System.Threading; + +namespace Spring.Threading +{ + /// + ///

Base class for counting semaphores based on Semaphore implementation + /// from Doug Lea.

+ ///
+ /// + /// + ///

Conceptually, a semaphore + /// maintains a set of permits. Each acquire() blocks if + /// necessary until a permit is available, and then takes it.

+ /// + ///

Each release adds a permit. However, no actual permit objects are used; + /// the Semaphore just keeps a count of the number available + /// and acts accordingly.

+ /// + ///

A semaphore initialized to 1 can serve as a mutual exclusion lock.

+ /// + /// Used for implementation of a + ///
+ /// Doug Lea + /// Federico Spinazzi (.Net) + public class Semaphore : ISync + { + /// + /// current number of available permits + /// + protected long nPermits; + + /// + ///

Create a Semaphore with the given initial number of permits.

+ ///

Using a seed of 1 makes the semaphore act as a mutual + /// exclusion lock.

+ /// + ///

Negative seeds are also allowed, + /// in which case no acquires will proceed until the number of + /// releases has pushed the number of permits past 0.

+ ///
+ public Semaphore(long initialPermits) + { + nPermits = initialPermits; + } + + /// + /// Release a permit + /// + public virtual void Release () + { + lock (this) + { + ++nPermits; + Monitor.Pulse(this); + } + } + + /// + /// Acquire a permit + /// + public virtual void Acquire () + { + lock (this) + { + try + { + while (nPermits <= 0) + Monitor.Wait(this); + --nPermits; + } + catch (ThreadInterruptedException ex) + { + Monitor.Pulse(this); + throw ex; + } + } + } + + /// + /// Wait at most msecs millisconds for a permit + /// + /// number of ms to wait + /// true if aquired + public virtual bool Attempt(long msecs) + { + lock (this) + { + if (nPermits > 0) + { + --nPermits; + return true; + } + else if (msecs <= 0) + return false; + else + { + try + { + double startTime = Utils.CurrentTimeMillis; + long waitTime = msecs; + + for (; ; ) + { + Monitor.Wait(this, TimeSpan.FromMilliseconds(waitTime)); + if (nPermits > 0) + { + --nPermits; + return true; + } + else + { + waitTime = (long) (msecs - (Utils.CurrentTimeMillis - startTime)); + if (waitTime <= 0) + return false; + } + } + } + catch (ThreadInterruptedException ex) + { + Monitor.Pulse(this); + throw ex; + } + } + } + } + + /// Release N permits. release(n) is + /// equivalent in effect to: + ///
+        /// for (int i = 0; i < n; ++i) release();
+        /// 
+ /// But may be more efficient in some semaphore implementations. + ///
+ /// if n is negative. + /// + /// + public virtual void Release(long n) + { + lock (this) + { + if (n < 0) + throw new ArgumentOutOfRangeException("n", n, "Negative argument"); + + nPermits += n; + for (long i = 0; i < n; ++i) + Monitor.Pulse(this); + } + } + + /// Return the current number of available permits. + /// Returns an accurate, but possibly unstable value, + /// that may change immediately after returning. + /// + public virtual long Permits + { + get + { + lock (this) + { + return nPermits; + } + } + } + + + } +} diff --git a/src/Spring/Spring.Core/Threading/SyncHolder.cs b/src/Spring/Spring.Core/Threading/SyncHolder.cs index fe03a134..c8cbece3 100644 --- a/src/Spring/Spring.Core/Threading/SyncHolder.cs +++ b/src/Spring/Spring.Core/Threading/SyncHolder.cs @@ -1,70 +1,70 @@ -#region License -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ -#endregion - -using System; - -namespace Spring.Threading -{ - /// - /// Utility class to use an with the - /// C# using () {} idiom - /// - public class SyncHolder : IDisposable - { - ISync _sync; - - /// - /// Creates a new trying to the given - /// - /// - /// the to be held - public SyncHolder (ISync sync) - { - Init (sync); - } - - /// - /// Creates a new trying to the given - /// - /// - /// the to be held - /// millisecond to try to acquire the lock - public SyncHolder (ISync sync, long msecs) - { - Init(new TimeoutSync(sync, msecs)); - } - - /// - /// Releases the held - /// - public void Dispose () - { - _sync.Release(); - } - - /// - /// initializes and acquire access to the - /// - /// - private void Init (ISync sync) - { - this._sync = sync; - _sync.Acquire(); - } - } -} +#region License +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ +#endregion + +using System; + +namespace Spring.Threading +{ + /// + /// Utility class to use an with the + /// C# using () {} idiom + /// + public class SyncHolder : IDisposable + { + ISync _sync; + + /// + /// Creates a new trying to the given + /// + /// + /// the to be held + public SyncHolder (ISync sync) + { + Init (sync); + } + + /// + /// Creates a new trying to the given + /// + /// + /// the to be held + /// millisecond to try to acquire the lock + public SyncHolder (ISync sync, long msecs) + { + Init(new TimeoutSync(sync, msecs)); + } + + /// + /// Releases the held + /// + public void Dispose () + { + _sync.Release(); + } + + /// + /// initializes and acquire access to the + /// + /// + private void Init (ISync sync) + { + this._sync = sync; + _sync.Acquire(); + } + } +} diff --git a/src/Spring/Spring.Core/Threading/ThreadStaticStorage.cs b/src/Spring/Spring.Core/Threading/ThreadStaticStorage.cs index ab79444d..ea120cba 100644 --- a/src/Spring/Spring.Core/Threading/ThreadStaticStorage.cs +++ b/src/Spring/Spring.Core/Threading/ThreadStaticStorage.cs @@ -1,54 +1,53 @@ -using System; -using System.Collections; - -namespace Spring.Threading -{ - /// - /// Implements by using a hashtable. - /// - /// Erich Eichinger - /// $Id: ThreadStaticStorage.cs,v 1.1 2007/02/02 21:30:34 oakinger Exp $ - public class ThreadStaticStorage : IThreadStorage - { - [ThreadStatic] - private static Hashtable data; - - private static Hashtable Data - { - get - { - if (data == null) data = new Hashtable(); - return data; - } - } - - /// - /// Retrieves an object with the specified name. - /// - /// The name of the item. - /// The object in the call context associated with the specified name or null if no object has been stored previously - public object GetData(string name) - { - return Data[name]; - } - - /// - /// Stores a given object and associates it with the specified name. - /// - /// The name with which to associate the new item. - /// The object to store in the call context. - public void SetData(string name, object value) - { - Data[name] = value; - } - - /// - /// Empties a data slot with the specified name. - /// - /// The name of the data slot to empty. - public void FreeNamedDataSlot(string name) - { - Data.Remove(name); - } - } +using System; +using System.Collections; + +namespace Spring.Threading +{ + /// + /// Implements by using a hashtable. + /// + /// Erich Eichinger + public class ThreadStaticStorage : IThreadStorage + { + [ThreadStatic] + private static Hashtable data; + + private static Hashtable Data + { + get + { + if (data == null) data = new Hashtable(); + return data; + } + } + + /// + /// Retrieves an object with the specified name. + /// + /// The name of the item. + /// The object in the call context associated with the specified name or null if no object has been stored previously + public object GetData(string name) + { + return Data[name]; + } + + /// + /// Stores a given object and associates it with the specified name. + /// + /// The name with which to associate the new item. + /// The object to store in the call context. + public void SetData(string name, object value) + { + Data[name] = value; + } + + /// + /// Empties a data slot with the specified name. + /// + /// The name of the data slot to empty. + public void FreeNamedDataSlot(string name) + { + Data.Remove(name); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/TimeoutException.cs b/src/Spring/Spring.Core/Threading/TimeoutException.cs index 0b129e83..4bbe1488 100644 --- a/src/Spring/Spring.Core/Threading/TimeoutException.cs +++ b/src/Spring/Spring.Core/Threading/TimeoutException.cs @@ -1,128 +1,128 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -using System; -using System.Runtime.Serialization; -using System.Threading; - - -/* -Originally written by Doug Lea and released into the public domain. -This may be used for any purposes whatsoever without acknowledgment. -Thanks for the assistance and support of Sun Microsystems Labs, -and everyone contributing, testing, and using this code. -*/ -namespace Spring.Threading -{ - /// Thrown by synchronization classes that report - /// timeouts via exceptions. The exception is treated - /// as a form (subclass) of InterruptedException. This both - /// simplifies handling, and conceptually reflects the fact that - /// timed-out operations are artificially interrupted by timers. - /// - /// - [Serializable] - public class TimeoutException : ThreadInterruptedException - { - /// The approximate time that the operation lasted before - /// this timeout exception was thrown. - /// - /// - private readonly long _duration; - /// - /// Creates a new instance of the - /// class. - /// - public TimeoutException( ) : base(){} - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - public TimeoutException( string message ) : base( message ){} - /// - /// Creates a new instance of the - /// class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public TimeoutException( string message, Exception innerException ) : base( message, innerException ){} - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TimeoutException( SerializationInfo info, StreamingContext context ) - : base( info, context ) - { - _duration = info.GetInt32( "duration" ); - } - /// - /// Override of GetObjectData to allow for private serialization - /// - /// serialization info - /// streaming context - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "duration", _duration ); - base.GetObjectData( info, context ); - } - /// Constructs a TimeoutException with given duration value. - /// - /// - public TimeoutException( long time ) - { - _duration = time; - } - /// Constructs a TimeoutException with the - /// specified duration value and detail message. - /// - public TimeoutException( long time, String message ) : base( message ) - { - _duration = time; - } - /// - /// Gets the approximate time that the operation lasted before - /// this timeout exception was thrown. - /// - public long Duration - { - get - { - return _duration; - } - } - } +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +using System; +using System.Runtime.Serialization; +using System.Threading; + + +/* +Originally written by Doug Lea and released into the public domain. +This may be used for any purposes whatsoever without acknowledgment. +Thanks for the assistance and support of Sun Microsystems Labs, +and everyone contributing, testing, and using this code. +*/ +namespace Spring.Threading +{ + /// Thrown by synchronization classes that report + /// timeouts via exceptions. The exception is treated + /// as a form (subclass) of InterruptedException. This both + /// simplifies handling, and conceptually reflects the fact that + /// timed-out operations are artificially interrupted by timers. + /// + /// + [Serializable] + public class TimeoutException : ThreadInterruptedException + { + /// The approximate time that the operation lasted before + /// this timeout exception was thrown. + /// + /// + private readonly long _duration; + /// + /// Creates a new instance of the + /// class. + /// + public TimeoutException( ) : base(){} + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + public TimeoutException( string message ) : base( message ){} + /// + /// Creates a new instance of the + /// class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public TimeoutException( string message, Exception innerException ) : base( message, innerException ){} + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TimeoutException( SerializationInfo info, StreamingContext context ) + : base( info, context ) + { + _duration = info.GetInt32( "duration" ); + } + /// + /// Override of GetObjectData to allow for private serialization + /// + /// serialization info + /// streaming context + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "duration", _duration ); + base.GetObjectData( info, context ); + } + /// Constructs a TimeoutException with given duration value. + /// + /// + public TimeoutException( long time ) + { + _duration = time; + } + /// Constructs a TimeoutException with the + /// specified duration value and detail message. + /// + public TimeoutException( long time, String message ) : base( message ) + { + _duration = time; + } + /// + /// Gets the approximate time that the operation lasted before + /// this timeout exception was thrown. + /// + public long Duration + { + get + { + return _duration; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/TimeoutSync.cs b/src/Spring/Spring.Core/Threading/TimeoutSync.cs index b28cc7fb..148dd2c8 100644 --- a/src/Spring/Spring.Core/Threading/TimeoutSync.cs +++ b/src/Spring/Spring.Core/Threading/TimeoutSync.cs @@ -1,79 +1,79 @@ -#region License -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ -#endregion -/* -Originally written by Doug Lea and released into the public domain. -This may be used for any purposes whatsoever without acknowledgment. -Thanks for the assistance and support of Sun Microsystems Labs, -and everyone contributing, testing, and using this code. -*/ - -namespace Spring.Threading -{ - - /// A TimeoutSync is an adaptor class that transforms all - /// calls to acquire to instead invoke attempt with a predetermined - /// timeout value. - /// - /// - public class TimeoutSync : ISync - { - /// - /// the adapted sync - /// - protected readonly internal ISync sync_; - /// - /// timeout value - /// - protected readonly internal long timeout_; - - /// Create a TimeoutSync using the given Sync object, and - /// using the given timeout value for all calls to acquire. - /// - public TimeoutSync(ISync sync, long timeout) - { - sync_ = sync; - timeout_ = timeout; - } - - /// - /// Try to acquire the sync before the timeout - /// - /// In case a time out occurred - public virtual void Acquire() - { - if (!sync_.Attempt(timeout_)) - throw new TimeoutException(timeout_); - } - - /// - /// - /// - public virtual bool Attempt(long msecs) - { - return sync_.Attempt(msecs); - } - - /// - /// - /// - public virtual void Release() - { - sync_.Release(); - } - } +#region License +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ +#endregion +/* +Originally written by Doug Lea and released into the public domain. +This may be used for any purposes whatsoever without acknowledgment. +Thanks for the assistance and support of Sun Microsystems Labs, +and everyone contributing, testing, and using this code. +*/ + +namespace Spring.Threading +{ + + /// A TimeoutSync is an adaptor class that transforms all + /// calls to acquire to instead invoke attempt with a predetermined + /// timeout value. + /// + /// + public class TimeoutSync : ISync + { + /// + /// the adapted sync + /// + protected readonly internal ISync sync_; + /// + /// timeout value + /// + protected readonly internal long timeout_; + + /// Create a TimeoutSync using the given Sync object, and + /// using the given timeout value for all calls to acquire. + /// + public TimeoutSync(ISync sync, long timeout) + { + sync_ = sync; + timeout_ = timeout; + } + + /// + /// Try to acquire the sync before the timeout + /// + /// In case a time out occurred + public virtual void Acquire() + { + if (!sync_.Attempt(timeout_)) + throw new TimeoutException(timeout_); + } + + /// + /// + /// + public virtual bool Attempt(long msecs) + { + return sync_.Attempt(msecs); + } + + /// + /// + /// + public virtual void Release() + { + sync_.Release(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Threading/Utils.cs b/src/Spring/Spring.Core/Threading/Utils.cs index 97a61aa0..d999718c 100644 --- a/src/Spring/Spring.Core/Threading/Utils.cs +++ b/src/Spring/Spring.Core/Threading/Utils.cs @@ -1,136 +1,136 @@ -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -using System; -using System.Threading; - -namespace Spring.Threading -{ - /// - /// Support to account for differences between java nad .NET: - ///
    - ///
- ///
- public class Utils - { - private Utils() - { - } - - /// - /// .NET threads have not a method to check if they have been interrupted. - /// Moreover, differently from java threads, when entering locked - /// blocks, Monitor, Sleep, SpinWait and so on, a - /// will be raised by the runtime. - ///

Spring.Threading classes usually call this method before entering a lock block, to mirror java code - ///

Usually this is non issue because the same exception will be raised entering the monitor - /// associated with the lock () - ///

- ///
- /// if the thread has been interrupted - public static void FailFastIfInterrupted() - { - Thread.Sleep(0); - } - - /// - /// Placeholder for java.lang.System.currentTimeMillis - /// - /// The current machine time in milliseconds - public static long CurrentTimeMillis - { - get { return ToTimeMillis(DateTime.Now); } - } - - /// - /// Normalize the given so that - /// is is comparable with . - /// - /// Date. - /// - public static long ToTimeMillis(DateTime date) - { - // may be also new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds; - // see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_jlca/html/vberrjavalangsystemcurrenttimemillis.asp - return (date.Ticks - 621355968000000000)/10000; - } - - /// - /// - /// - /// - /// - /// the difference between millisecodns of the first and second date - public static long DeltaTimeMillis(DateTime one, DateTime another) - { - return (one.Ticks - another.Ticks)/10000; - } - - /// - /// Returns the number of nanoseconds for the current value of - /// - /// Current number of nanoseconds - public static long CurrentNanoSeconds() - { - return (DateTime.Now.Ticks - 621355968000000000)/10000*1000000; - } - - /// - /// Returns the number of nano seconds represented by the - /// - /// to use - /// Number of nano seconds for - public static long TimeSpanNanoSeconds(TimeSpan timeSpan) - { - return (timeSpan.Ticks - 621355968000000000)/10000*1000000; - } - /// - /// Returns a representing the number of nanoseconds passed in via . - /// - /// Number of nanoseconds. - /// representing the number of nanoseconds passed in. - public static TimeSpan NanoSecondsTimeSpan(long nanoSeconds ) - { - int milliseconds = Convert.ToInt32(nanoSeconds / 1000000); - return new TimeSpan(0,0,0,0, milliseconds); - } - - /// - /// Has been interrupted this thread - /// - public static bool ThreadInterrupted - { - get - { - bool interrupted = false; - try - { - Utils.FailFastIfInterrupted(); - } - catch (ThreadInterruptedException) - { - Thread.CurrentThread.Interrupt(); - interrupted = true; - } - return interrupted; - } - } - } +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +using System; +using System.Threading; + +namespace Spring.Threading +{ + /// + /// Support to account for differences between java nad .NET: + ///
    + ///
+ ///
+ public class Utils + { + private Utils() + { + } + + /// + /// .NET threads have not a method to check if they have been interrupted. + /// Moreover, differently from java threads, when entering locked + /// blocks, Monitor, Sleep, SpinWait and so on, a + /// will be raised by the runtime. + ///

Spring.Threading classes usually call this method before entering a lock block, to mirror java code + ///

Usually this is non issue because the same exception will be raised entering the monitor + /// associated with the lock () + ///

+ ///
+ /// if the thread has been interrupted + public static void FailFastIfInterrupted() + { + Thread.Sleep(0); + } + + /// + /// Placeholder for java.lang.System.currentTimeMillis + /// + /// The current machine time in milliseconds + public static long CurrentTimeMillis + { + get { return ToTimeMillis(DateTime.Now); } + } + + /// + /// Normalize the given so that + /// is is comparable with . + /// + /// Date. + /// + public static long ToTimeMillis(DateTime date) + { + // may be also new TimeSpan(DateTime.UtcNow.Ticks).TotalMilliseconds; + // see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_jlca/html/vberrjavalangsystemcurrenttimemillis.asp + return (date.Ticks - 621355968000000000)/10000; + } + + /// + /// + /// + /// + /// + /// the difference between millisecodns of the first and second date + public static long DeltaTimeMillis(DateTime one, DateTime another) + { + return (one.Ticks - another.Ticks)/10000; + } + + /// + /// Returns the number of nanoseconds for the current value of + /// + /// Current number of nanoseconds + public static long CurrentNanoSeconds() + { + return (DateTime.Now.Ticks - 621355968000000000)/10000*1000000; + } + + /// + /// Returns the number of nano seconds represented by the + /// + /// to use + /// Number of nano seconds for + public static long TimeSpanNanoSeconds(TimeSpan timeSpan) + { + return (timeSpan.Ticks - 621355968000000000)/10000*1000000; + } + /// + /// Returns a representing the number of nanoseconds passed in via . + /// + /// Number of nanoseconds. + /// representing the number of nanoseconds passed in. + public static TimeSpan NanoSecondsTimeSpan(long nanoSeconds ) + { + int milliseconds = Convert.ToInt32(nanoSeconds / 1000000); + return new TimeSpan(0,0,0,0, milliseconds); + } + + /// + /// Has been interrupted this thread + /// + public static bool ThreadInterrupted + { + get + { + bool interrupted = false; + try + { + Utils.FailFastIfInterrupted(); + } + catch (ThreadInterruptedException) + { + Thread.CurrentThread.Interrupt(); + interrupted = true; + } + return interrupted; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/ArrayUtils.cs b/src/Spring/Spring.Core/Util/ArrayUtils.cs index 2428ebc0..b5c2291e 100644 --- a/src/Spring/Spring.Core/Util/ArrayUtils.cs +++ b/src/Spring/Spring.Core/Util/ArrayUtils.cs @@ -1,163 +1,162 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Text; - -#endregion - -namespace Spring.Util -{ - /// - /// Various utility methods relating to the manipulation of arrays. - /// - /// Aleksandar Seovic - /// $Id: ArrayUtils.cs,v 1.15 2007/02/17 08:28:12 bbaia Exp $ - public sealed class ArrayUtils - { - /// - /// Checks if the given array or collection is null or has no elements. - /// - /// - /// - public static bool HasLength(ICollection collection) - { - return !( (collection == null) || (collection.Count == 0) ); - } - - /// - /// Tests equality of two single-dimensional arrays by checking each element - /// for equality. - /// - /// The first array to be checked. - /// The second array to be checked. - /// True if arrays are the same, false otherwise. - public static bool AreEqual(Array a, Array b) - { - if (a == null && b == null) - { - return true; - } - - if (a != null && b != null) - { - if (a.Length == b.Length) - { - for (int i = 0; i < a.Length; i++) - { - object elemA = a.GetValue(i); - object elemB = b.GetValue(i); - - if (elemA is Array && elemB is Array) - { - if (!AreEqual(elemA as Array, elemB as Array)) - { - return false; - } - } - else if (!Equals(elemA, elemB)) - { - return false; - } - } - return true; - } - } - return false; - } - - /// - /// Returns hash code for an array that is generated based on the elements. - /// - /// - /// Hash code returned by this method is guaranteed to be the same for - /// arrays with equal elements. - /// - /// - /// Array to calculate hash code for. - /// - /// - /// A hash code for the specified array. - /// - public static int GetHashCode(Array array) - { - int hashCode = 0; - - if (array != null) - { - for (int i = 0; i < array.Length; i++) - { - object el = array.GetValue(i); - if (el != null) - { - if (el is Array) - { - hashCode += 17 * GetHashCode(el as Array); - } - else - { - hashCode += 13 * el.GetHashCode(); - } - } - } - } - - return hashCode; - } - - /// - /// Returns string representation of an array. - /// - /// - /// Array to return as a string. - /// - /// - /// String representation of the specified . - /// - public static string ToString(Array array) - { - if (array == null) - { - return "null"; - } - - StringBuilder sb = new StringBuilder(); - sb.Append('{'); - - for (int i = 0; i < array.Length; i++) - { - object val = array.GetValue(i); - sb.Append(val == null ? "null" : val.ToString()); - - if (i < array.Length - 1) - { - sb.Append(", "); - } - } - - sb.Append('}'); - - return sb.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Text; + +#endregion + +namespace Spring.Util +{ + /// + /// Various utility methods relating to the manipulation of arrays. + /// + /// Aleksandar Seovic + public sealed class ArrayUtils + { + /// + /// Checks if the given array or collection is null or has no elements. + /// + /// + /// + public static bool HasLength(ICollection collection) + { + return !( (collection == null) || (collection.Count == 0) ); + } + + /// + /// Tests equality of two single-dimensional arrays by checking each element + /// for equality. + /// + /// The first array to be checked. + /// The second array to be checked. + /// True if arrays are the same, false otherwise. + public static bool AreEqual(Array a, Array b) + { + if (a == null && b == null) + { + return true; + } + + if (a != null && b != null) + { + if (a.Length == b.Length) + { + for (int i = 0; i < a.Length; i++) + { + object elemA = a.GetValue(i); + object elemB = b.GetValue(i); + + if (elemA is Array && elemB is Array) + { + if (!AreEqual(elemA as Array, elemB as Array)) + { + return false; + } + } + else if (!Equals(elemA, elemB)) + { + return false; + } + } + return true; + } + } + return false; + } + + /// + /// Returns hash code for an array that is generated based on the elements. + /// + /// + /// Hash code returned by this method is guaranteed to be the same for + /// arrays with equal elements. + /// + /// + /// Array to calculate hash code for. + /// + /// + /// A hash code for the specified array. + /// + public static int GetHashCode(Array array) + { + int hashCode = 0; + + if (array != null) + { + for (int i = 0; i < array.Length; i++) + { + object el = array.GetValue(i); + if (el != null) + { + if (el is Array) + { + hashCode += 17 * GetHashCode(el as Array); + } + else + { + hashCode += 13 * el.GetHashCode(); + } + } + } + } + + return hashCode; + } + + /// + /// Returns string representation of an array. + /// + /// + /// Array to return as a string. + /// + /// + /// String representation of the specified . + /// + public static string ToString(Array array) + { + if (array == null) + { + return "null"; + } + + StringBuilder sb = new StringBuilder(); + sb.Append('{'); + + for (int i = 0; i < array.Length; i++) + { + object val = array.GetValue(i); + sb.Append(val == null ? "null" : val.ToString()); + + if (i < array.Length - 1) + { + sb.Append(", "); + } + } + + sb.Append('}'); + + return sb.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/AssertUtils.cs b/src/Spring/Spring.Core/Util/AssertUtils.cs index 6c2664e7..e4e2e78c 100644 --- a/src/Spring/Spring.Core/Util/AssertUtils.cs +++ b/src/Spring/Spring.Core/Util/AssertUtils.cs @@ -1,233 +1,232 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; - -#endregion - -namespace Spring.Util -{ - /// - /// Assertion utility methods that simplify things such as argument checks. - /// - /// - ///

- /// Not intended to be used directly by applications. - ///

- ///
- /// Aleksandar Seovic - /// $Id: AssertUtils.cs,v 1.13 2008/03/14 10:45:08 bbaia Exp $ - public sealed class AssertUtils - { - /// - /// Checks the value of the supplied and throws an - /// if it is . - /// - /// The object to check. - /// The argument name. - /// - /// If the supplied is . - /// - public static void ArgumentNotNull(object argument, string name) - { - if (argument == null) - { - throw new ArgumentNullException ( - name, - string.Format ( - CultureInfo.InvariantCulture, - "Argument '{0}' cannot be null.", name)); - } - } - - /// - /// Checks the value of the supplied and throws an - /// if it is . - /// - /// The object to check. - /// The argument name. - /// - /// An arbitrary message that will be passed to any thrown - /// . - /// - /// - /// If the supplied is . - /// - public static void ArgumentNotNull(object argument, string name, string message) - { - if (argument == null) - { - throw new ArgumentNullException(name, message); - } - } - - /// - /// Checks the value of the supplied string and throws an - /// if it is or - /// contains only whitespace character(s). - /// - /// The string to check. - /// The argument name. - /// - /// If the supplied is or - /// contains only whitespace character(s). - /// - public static void ArgumentHasText(string argument, string name) - { - if (StringUtils.IsNullOrEmpty(argument)) - { - throw new ArgumentNullException ( - name, - string.Format ( - CultureInfo.InvariantCulture, - "Argument '{0}' cannot be null or resolve to an empty string : '{1}'.", name, argument)); - } - } - - /// - /// Checks the value of the supplied string and throws an - /// if it is or - /// contains only whitespace character(s). - /// - /// The string to check. - /// The argument name. - /// - /// An arbitrary message that will be passed to any thrown - /// . - /// - /// - /// If the supplied is or - /// contains only whitespace character(s). - /// - public static void ArgumentHasText(string argument, string name, string message) - { - if (StringUtils.IsNullOrEmpty(argument)) - { - throw new ArgumentNullException(name, message); - } - } - - /// - /// Checks the value of the supplied and throws - /// an if it is or contains no elements. - /// - /// The array or collection to check. - /// The argument name. - /// - /// If the supplied is or - /// contains no elements. - /// - public static void ArgumentHasLength(ICollection argument, string name) - { - if (!ArrayUtils.HasLength(argument)) - { - throw new ArgumentNullException( - name, - string.Format( - CultureInfo.InvariantCulture, - "Argument '{0}' cannot be null or resolve to an empty array", name)); - } - } - - /// - /// Checks the value of the supplied and throws - /// an if it is or contains no elements. - /// - /// The array or collection to check. - /// The argument name. - /// An arbitrary message that will be passed to any thrown . - /// - /// If the supplied is or - /// contains no elements. - /// - public static void ArgumentHasLength(ICollection argument, string name, string message) - { - if(!ArrayUtils.HasLength(argument)) - { - throw new ArgumentNullException(name, message); - } - } - - /// - /// Checks whether the specified can be cast - /// into the . - /// - /// - /// The argument to check. - /// - /// - /// The name of the argument to check. - /// - /// - /// The required type for the argument. - /// - /// - /// An arbitrary message that will be passed to any thrown - /// . - /// - public static void AssertArgumentType(object argument, string argumentName, Type requiredType, string message) - { - if (argument != null && requiredType != null && !requiredType.IsAssignableFrom(argument.GetType())) - { - throw new ArgumentException(message, argumentName); - } - } - - /// - /// Assert a bool expression, throwing InvalidOperationException - /// if the expression is false. - /// - /// a boolean expression. - /// The exception message to use if the assertion fails - /// if expression is false - public static void State(bool expression, string message) - { - if (!expression) - { - throw new InvalidOperationException(message); - } - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private AssertUtils() - { - } - - // CLOVER:ON - - #endregion - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; + +#endregion + +namespace Spring.Util +{ + /// + /// Assertion utility methods that simplify things such as argument checks. + /// + /// + ///

+ /// Not intended to be used directly by applications. + ///

+ ///
+ /// Aleksandar Seovic + public sealed class AssertUtils + { + /// + /// Checks the value of the supplied and throws an + /// if it is . + /// + /// The object to check. + /// The argument name. + /// + /// If the supplied is . + /// + public static void ArgumentNotNull(object argument, string name) + { + if (argument == null) + { + throw new ArgumentNullException ( + name, + string.Format ( + CultureInfo.InvariantCulture, + "Argument '{0}' cannot be null.", name)); + } + } + + /// + /// Checks the value of the supplied and throws an + /// if it is . + /// + /// The object to check. + /// The argument name. + /// + /// An arbitrary message that will be passed to any thrown + /// . + /// + /// + /// If the supplied is . + /// + public static void ArgumentNotNull(object argument, string name, string message) + { + if (argument == null) + { + throw new ArgumentNullException(name, message); + } + } + + /// + /// Checks the value of the supplied string and throws an + /// if it is or + /// contains only whitespace character(s). + /// + /// The string to check. + /// The argument name. + /// + /// If the supplied is or + /// contains only whitespace character(s). + /// + public static void ArgumentHasText(string argument, string name) + { + if (StringUtils.IsNullOrEmpty(argument)) + { + throw new ArgumentNullException ( + name, + string.Format ( + CultureInfo.InvariantCulture, + "Argument '{0}' cannot be null or resolve to an empty string : '{1}'.", name, argument)); + } + } + + /// + /// Checks the value of the supplied string and throws an + /// if it is or + /// contains only whitespace character(s). + /// + /// The string to check. + /// The argument name. + /// + /// An arbitrary message that will be passed to any thrown + /// . + /// + /// + /// If the supplied is or + /// contains only whitespace character(s). + /// + public static void ArgumentHasText(string argument, string name, string message) + { + if (StringUtils.IsNullOrEmpty(argument)) + { + throw new ArgumentNullException(name, message); + } + } + + /// + /// Checks the value of the supplied and throws + /// an if it is or contains no elements. + /// + /// The array or collection to check. + /// The argument name. + /// + /// If the supplied is or + /// contains no elements. + /// + public static void ArgumentHasLength(ICollection argument, string name) + { + if (!ArrayUtils.HasLength(argument)) + { + throw new ArgumentNullException( + name, + string.Format( + CultureInfo.InvariantCulture, + "Argument '{0}' cannot be null or resolve to an empty array", name)); + } + } + + /// + /// Checks the value of the supplied and throws + /// an if it is or contains no elements. + /// + /// The array or collection to check. + /// The argument name. + /// An arbitrary message that will be passed to any thrown . + /// + /// If the supplied is or + /// contains no elements. + /// + public static void ArgumentHasLength(ICollection argument, string name, string message) + { + if(!ArrayUtils.HasLength(argument)) + { + throw new ArgumentNullException(name, message); + } + } + + /// + /// Checks whether the specified can be cast + /// into the . + /// + /// + /// The argument to check. + /// + /// + /// The name of the argument to check. + /// + /// + /// The required type for the argument. + /// + /// + /// An arbitrary message that will be passed to any thrown + /// . + /// + public static void AssertArgumentType(object argument, string argumentName, Type requiredType, string message) + { + if (argument != null && requiredType != null && !requiredType.IsAssignableFrom(argument.GetType())) + { + throw new ArgumentException(message, argumentName); + } + } + + /// + /// Assert a bool expression, throwing InvalidOperationException + /// if the expression is false. + /// + /// a boolean expression. + /// The exception message to use if the assertion fails + /// if expression is false + public static void State(bool expression, string message) + { + if (!expression) + { + throw new InvalidOperationException(message); + } + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private AssertUtils() + { + } + + // CLOVER:ON + + #endregion + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/CollectionUtils.cs b/src/Spring/Spring.Core/Util/CollectionUtils.cs index 266edabc..64ae4364 100644 --- a/src/Spring/Spring.Core/Util/CollectionUtils.cs +++ b/src/Spring/Spring.Core/Util/CollectionUtils.cs @@ -1,207 +1,206 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -#endregion - -namespace Spring.Util -{ - /// - /// Miscellaneous collection utility methods. - /// - /// - /// Mainly for internal use within the framework. - /// - /// Mark Pollack (.NET) - /// $Id: CollectionUtils.cs,v 1.9 2006/04/09 07:19:00 markpollack Exp $ - public sealed class CollectionUtils - { - #region Methods - - /// - /// Determine whether a given collection only contains - /// a single unique object - /// - /// - /// - public static bool HasUniqueObject(ICollection coll) - { - if (coll.Count == 0) - { - return false; - } - object candidate = null; - foreach (object elem in coll) - { - if (candidate == null) - { - candidate = elem; - } - else if (candidate != elem) - { - return false; - } - } - return true; - } - - /// - /// Determines whether the contains the specified . - /// - /// The collection to check. - /// The object to locate in the collection. - /// if the element is in the collection, otherwise. - public static bool Contains(ICollection collection, Object element) - { - if (collection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - MethodInfo method; - method = collection.GetType().GetMethod("contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - if (null == method) - { - throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Contains() method."); - } - return (bool) method.Invoke(collection, new Object[] {element}); - } - - /// - /// Adds the specified to the specified . - /// - /// The collection to add the element to. - /// The object to add to the collection. - public static void Add(ICollection collection, object element) - { - if (collection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - MethodInfo method; - method = collection.GetType().GetMethod("add", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - if (null == method) - { - throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Add() method."); - } - method.Invoke(collection, new Object[] {element}); - } - - /// - /// Determines whether the collection contains all the elements in the specified collection. - /// - /// The collection to check. - /// Collection whose elements would be checked for containment. - /// true if the target collection contains all the elements of the specified collection. - public static bool ContainsAll(ICollection targetCollection, ICollection sourceCollection) - { - if (targetCollection == null || sourceCollection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - if ( sourceCollection.Count == 0 && targetCollection.Count > 1 ) - return true; - - IEnumerator sourceCollectionEnumerator = sourceCollection.GetEnumerator(); - - bool contains = false; - - MethodInfo method; - method = targetCollection.GetType().GetMethod("containsAll", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - - if (method != null) - contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollection}); - else - { - method = targetCollection.GetType().GetMethod("Contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - if (method == null) - { - throw new InvalidOperationException("Target collection does not implment a Contains() or ContainsAll() method."); - } - while (sourceCollectionEnumerator.MoveNext() == true) - { - if ((contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollectionEnumerator.Current})) == false) - break; - } - } - return contains; - } - - /// - /// Removes all the elements from the target collection that are contained in the source collection. - /// - /// Collection where the elements will be removed. - /// Elements to remove from the target collection. - public static void RemoveAll(ICollection targetCollection, ICollection sourceCollection) - { - if (targetCollection == null || sourceCollection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - ArrayList al = ToArrayList(sourceCollection); - - MethodInfo method; - method = targetCollection.GetType().GetMethod("removeAll", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - - if (method != null) - method.Invoke(targetCollection, new Object[] {al}); - else - { - method = targetCollection.GetType().GetMethod("Remove", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, new Type[1] {typeof(object)}, null ); - MethodInfo methodContains = targetCollection.GetType().GetMethod("Contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - if ( method == null ) - { - throw new InvalidOperationException("Target Collection must implement either a RemoveAll() or Remove() method."); - } - if ( methodContains == null ) - { - throw new InvalidOperationException("TargetCollection must implement a Contains() method."); - } - IEnumerator e = al.GetEnumerator(); - while (e.MoveNext() == true) - { - while ((bool) methodContains.Invoke(targetCollection, new Object[] {e.Current}) == true) - method.Invoke(targetCollection, new Object[] {e.Current}); - } - } - } - - /// - /// Converts an instance to an instance. - /// - /// The instance to be converted. - /// An instance in which its elements are the elements of the instance. - /// if the is null. - public static ArrayList ToArrayList(ICollection inputCollection) - { - if ( inputCollection == null ) - { - throw new ArgumentNullException("Collection cannot be null."); - } - return new ArrayList(inputCollection); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +#endregion + +namespace Spring.Util +{ + /// + /// Miscellaneous collection utility methods. + /// + /// + /// Mainly for internal use within the framework. + /// + /// Mark Pollack (.NET) + public sealed class CollectionUtils + { + #region Methods + + /// + /// Determine whether a given collection only contains + /// a single unique object + /// + /// + /// + public static bool HasUniqueObject(ICollection coll) + { + if (coll.Count == 0) + { + return false; + } + object candidate = null; + foreach (object elem in coll) + { + if (candidate == null) + { + candidate = elem; + } + else if (candidate != elem) + { + return false; + } + } + return true; + } + + /// + /// Determines whether the contains the specified . + /// + /// The collection to check. + /// The object to locate in the collection. + /// if the element is in the collection, otherwise. + public static bool Contains(ICollection collection, Object element) + { + if (collection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + MethodInfo method; + method = collection.GetType().GetMethod("contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + if (null == method) + { + throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Contains() method."); + } + return (bool) method.Invoke(collection, new Object[] {element}); + } + + /// + /// Adds the specified to the specified . + /// + /// The collection to add the element to. + /// The object to add to the collection. + public static void Add(ICollection collection, object element) + { + if (collection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + MethodInfo method; + method = collection.GetType().GetMethod("add", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + if (null == method) + { + throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Add() method."); + } + method.Invoke(collection, new Object[] {element}); + } + + /// + /// Determines whether the collection contains all the elements in the specified collection. + /// + /// The collection to check. + /// Collection whose elements would be checked for containment. + /// true if the target collection contains all the elements of the specified collection. + public static bool ContainsAll(ICollection targetCollection, ICollection sourceCollection) + { + if (targetCollection == null || sourceCollection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + if ( sourceCollection.Count == 0 && targetCollection.Count > 1 ) + return true; + + IEnumerator sourceCollectionEnumerator = sourceCollection.GetEnumerator(); + + bool contains = false; + + MethodInfo method; + method = targetCollection.GetType().GetMethod("containsAll", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + + if (method != null) + contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollection}); + else + { + method = targetCollection.GetType().GetMethod("Contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + if (method == null) + { + throw new InvalidOperationException("Target collection does not implment a Contains() or ContainsAll() method."); + } + while (sourceCollectionEnumerator.MoveNext() == true) + { + if ((contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollectionEnumerator.Current})) == false) + break; + } + } + return contains; + } + + /// + /// Removes all the elements from the target collection that are contained in the source collection. + /// + /// Collection where the elements will be removed. + /// Elements to remove from the target collection. + public static void RemoveAll(ICollection targetCollection, ICollection sourceCollection) + { + if (targetCollection == null || sourceCollection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + ArrayList al = ToArrayList(sourceCollection); + + MethodInfo method; + method = targetCollection.GetType().GetMethod("removeAll", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + + if (method != null) + method.Invoke(targetCollection, new Object[] {al}); + else + { + method = targetCollection.GetType().GetMethod("Remove", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, new Type[1] {typeof(object)}, null ); + MethodInfo methodContains = targetCollection.GetType().GetMethod("Contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + if ( method == null ) + { + throw new InvalidOperationException("Target Collection must implement either a RemoveAll() or Remove() method."); + } + if ( methodContains == null ) + { + throw new InvalidOperationException("TargetCollection must implement a Contains() method."); + } + IEnumerator e = al.GetEnumerator(); + while (e.MoveNext() == true) + { + while ((bool) methodContains.Invoke(targetCollection, new Object[] {e.Current}) == true) + method.Invoke(targetCollection, new Object[] {e.Current}); + } + } + } + + /// + /// Converts an instance to an instance. + /// + /// The instance to be converted. + /// An instance in which its elements are the elements of the instance. + /// if the is null. + public static ArrayList ToArrayList(ICollection inputCollection) + { + if ( inputCollection == null ) + { + throw new ArgumentNullException("Collection cannot be null."); + } + return new ArrayList(inputCollection); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/CompareUtils.cs b/src/Spring/Spring.Core/Util/CompareUtils.cs index 16c8e756..f7459667 100644 --- a/src/Spring/Spring.Core/Util/CompareUtils.cs +++ b/src/Spring/Spring.Core/Util/CompareUtils.cs @@ -1,90 +1,89 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Util -{ - /// - /// Utility class containing helper methods for object comparison. - /// - /// Aleksandar Seovic - /// $Id: CompareUtils.cs,v 1.2 2007/02/17 08:28:12 bbaia Exp $ - public class CompareUtils - { - /// Compares two objects. - /// First object. - /// Second object. - /// - /// 0, if objects are equal; - /// less than zero, if the first object is smaller than the second one; - /// greater than zero, if the first object is greater than the second one. - public static int Compare(object first, object second) - { - // anything is greater than null, unless both operands are null - if (first == null) - { - return (second == null ? 0 : -1); - } - else if (second == null) - { - return 1; - } - - if (!first.GetType().Equals(second.GetType())) - { - if (!CoerceTypes(ref first, ref second)) - { - throw new ArgumentException("Cannot compare instances of [" - + first.GetType().FullName - + "] and [" - + second.GetType().FullName - + "] because they cannot be coerced to the same type."); - } - } - - if (first is IComparable) - { - return ((IComparable)first).CompareTo(second); - } - else - { - throw new ArgumentException("Cannot compare instances of the type [" - + first.GetType().FullName - + "] because it doesn't implement IComparable"); - } - } - - private static bool CoerceTypes(ref object left, ref object right) - { - if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) - { - NumberUtils.CoerceTypes(ref right, ref left); - return true; - } - return false; - } - - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Util +{ + /// + /// Utility class containing helper methods for object comparison. + /// + /// Aleksandar Seovic + public class CompareUtils + { + /// Compares two objects. + /// First object. + /// Second object. + /// + /// 0, if objects are equal; + /// less than zero, if the first object is smaller than the second one; + /// greater than zero, if the first object is greater than the second one. + public static int Compare(object first, object second) + { + // anything is greater than null, unless both operands are null + if (first == null) + { + return (second == null ? 0 : -1); + } + else if (second == null) + { + return 1; + } + + if (!first.GetType().Equals(second.GetType())) + { + if (!CoerceTypes(ref first, ref second)) + { + throw new ArgumentException("Cannot compare instances of [" + + first.GetType().FullName + + "] and [" + + second.GetType().FullName + + "] because they cannot be coerced to the same type."); + } + } + + if (first is IComparable) + { + return ((IComparable)first).CompareTo(second); + } + else + { + throw new ArgumentException("Cannot compare instances of the type [" + + first.GetType().FullName + + "] because it doesn't implement IComparable"); + } + } + + private static bool CoerceTypes(ref object left, ref object right) + { + if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right)) + { + NumberUtils.CoerceTypes(ref right, ref left); + return true; + } + return false; + } + + } +} diff --git a/src/Spring/Spring.Core/Util/ConfigurationUtils.cs b/src/Spring/Spring.Core/Util/ConfigurationUtils.cs index a544b76d..a4d05948 100644 --- a/src/Spring/Spring.Core/Util/ConfigurationUtils.cs +++ b/src/Spring/Spring.Core/Util/ConfigurationUtils.cs @@ -1,222 +1,221 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Configuration; -using System.Xml; - -#endregion - -namespace Spring.Util -{ - /// - /// Utility class for .NET configuration files management. - /// - /// Aleksandar Seovic - /// $Id: ConfigurationUtils.cs,v 1.5 2008/01/10 16:37:43 bbaia Exp $ - public class ConfigurationUtils - { - /// - /// Parses the configuration section. - /// - /// - ///

- /// Primary purpose of this method is to allow us to parse and - /// load configuration sections using the same API regardless - /// of the .NET framework version. - ///

- ///

- /// If Microsoft paid a bit more attention to preserving backwards - /// compatibility we would not even need it, but... :( - ///

- ///
- /// Name of the configuration section. - /// Object created by a corresponding . - public static object GetSection(string sectionName) - { -#if !NET_2_0 - return ConfigurationSettings.GetConfig(sectionName.TrimEnd('/')); -#else - return ConfigurationManager.GetSection(sectionName.TrimEnd('/')); -#endif - } - - /// - /// Refresh the configuration section. - /// - /// - ///

- /// Primary purpose of this method is to allow us to parse and - /// load configuration sections using the same API regardless - /// of the .NET framework version. - ///

- ///

- /// If Microsoft paid a bit more attention to preserving backwards - /// compatibility we would not even need it, but... :( - ///

- ///
- /// Name of the configuration section. - public static void RefreshSection(string sectionName) - { -#if !NET_2_0 - // TODO : Add support for .NET 1.x -#else - ConfigurationManager.RefreshSection(sectionName); -#endif - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// The inner exception. - /// Name of the configuration file. - /// The line where exception occured. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, Exception inner, string fileName, int line) - { -#if !NET_2_0 - return new ConfigurationException(message, inner, fileName, line); -#else - return new ConfigurationErrorsException(message, inner, fileName, line); -#endif - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// Name of the configuration file. - /// The line where exception occured. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, string fileName, int line) - { - return CreateConfigurationException(message, null, fileName, line); - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// The inner exception. - /// XML node where exception occured. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, Exception inner, XmlNode node) - { -#if !NET_2_0 - return new ConfigurationException(message, inner, node); -#else - return new ConfigurationErrorsException(message, inner, node); -#endif - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// XML node where exception occured. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, XmlNode node) - { - return CreateConfigurationException(message, null, node); - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// The inner exception. - /// Configuration exception. - public static Exception CreateConfigurationException(string message, Exception inner) - { -#if !NET_2_0 - return new ConfigurationException(message, inner); -#else - return new ConfigurationErrorsException(message, inner); -#endif - } - - /// - /// Creates the configuration exception. - /// - /// The message to display to the client when the exception is thrown. - /// Configuration exception. - public static Exception CreateConfigurationException(string message) - { - return CreateConfigurationException(message, (Exception) null); - } - - /// - /// Creates the configuration exception. - /// - /// Configuration exception. - public static Exception CreateConfigurationException() - { - return CreateConfigurationException(null, (Exception) null); - } - - /// - /// Determines whether the specified exception is configuration exception. - /// - /// The exception to check. - /// - /// true if the specified exception is configuration exception; otherwise, false. - /// - public static bool IsConfigurationException(Exception exception) - { -#if !NET_2_0 - return exception is ConfigurationException; -#else - return exception is ConfigurationErrorsException; -#endif - } - - /// - /// Returns the line number of the specified node. - /// - /// Node to get the line number for. - /// The line number of the specified node. - public static int GetLineNumber(XmlNode node) - { -#if !NET_2_0 - return ConfigurationException.GetXmlNodeLineNumber(node); -#else - return ConfigurationErrorsException.GetLineNumber(node); -#endif - } - - /// - /// Returns the name of the file specified node is defined in. - /// - /// Node to get the file name for. - /// The name of the file specified node is defined in. - public static string GetFileName(XmlNode node) - { -#if !NET_2_0 - return ConfigurationException.GetXmlNodeFilename(node); -#else - return ConfigurationErrorsException.GetFilename(node); -#endif - } - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Configuration; +using System.Xml; + +#endregion + +namespace Spring.Util +{ + /// + /// Utility class for .NET configuration files management. + /// + /// Aleksandar Seovic + public class ConfigurationUtils + { + /// + /// Parses the configuration section. + /// + /// + ///

+ /// Primary purpose of this method is to allow us to parse and + /// load configuration sections using the same API regardless + /// of the .NET framework version. + ///

+ ///

+ /// If Microsoft paid a bit more attention to preserving backwards + /// compatibility we would not even need it, but... :( + ///

+ ///
+ /// Name of the configuration section. + /// Object created by a corresponding . + public static object GetSection(string sectionName) + { +#if !NET_2_0 + return ConfigurationSettings.GetConfig(sectionName.TrimEnd('/')); +#else + return ConfigurationManager.GetSection(sectionName.TrimEnd('/')); +#endif + } + + /// + /// Refresh the configuration section. + /// + /// + ///

+ /// Primary purpose of this method is to allow us to parse and + /// load configuration sections using the same API regardless + /// of the .NET framework version. + ///

+ ///

+ /// If Microsoft paid a bit more attention to preserving backwards + /// compatibility we would not even need it, but... :( + ///

+ ///
+ /// Name of the configuration section. + public static void RefreshSection(string sectionName) + { +#if !NET_2_0 + // TODO : Add support for .NET 1.x +#else + ConfigurationManager.RefreshSection(sectionName); +#endif + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// The inner exception. + /// Name of the configuration file. + /// The line where exception occured. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, Exception inner, string fileName, int line) + { +#if !NET_2_0 + return new ConfigurationException(message, inner, fileName, line); +#else + return new ConfigurationErrorsException(message, inner, fileName, line); +#endif + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// Name of the configuration file. + /// The line where exception occured. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, string fileName, int line) + { + return CreateConfigurationException(message, null, fileName, line); + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// The inner exception. + /// XML node where exception occured. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, Exception inner, XmlNode node) + { +#if !NET_2_0 + return new ConfigurationException(message, inner, node); +#else + return new ConfigurationErrorsException(message, inner, node); +#endif + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// XML node where exception occured. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, XmlNode node) + { + return CreateConfigurationException(message, null, node); + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// The inner exception. + /// Configuration exception. + public static Exception CreateConfigurationException(string message, Exception inner) + { +#if !NET_2_0 + return new ConfigurationException(message, inner); +#else + return new ConfigurationErrorsException(message, inner); +#endif + } + + /// + /// Creates the configuration exception. + /// + /// The message to display to the client when the exception is thrown. + /// Configuration exception. + public static Exception CreateConfigurationException(string message) + { + return CreateConfigurationException(message, (Exception) null); + } + + /// + /// Creates the configuration exception. + /// + /// Configuration exception. + public static Exception CreateConfigurationException() + { + return CreateConfigurationException(null, (Exception) null); + } + + /// + /// Determines whether the specified exception is configuration exception. + /// + /// The exception to check. + /// + /// true if the specified exception is configuration exception; otherwise, false. + /// + public static bool IsConfigurationException(Exception exception) + { +#if !NET_2_0 + return exception is ConfigurationException; +#else + return exception is ConfigurationErrorsException; +#endif + } + + /// + /// Returns the line number of the specified node. + /// + /// Node to get the line number for. + /// The line number of the specified node. + public static int GetLineNumber(XmlNode node) + { +#if !NET_2_0 + return ConfigurationException.GetXmlNodeLineNumber(node); +#else + return ConfigurationErrorsException.GetLineNumber(node); +#endif + } + + /// + /// Returns the name of the file specified node is defined in. + /// + /// Node to get the file name for. + /// The name of the file specified node is defined in. + public static string GetFileName(XmlNode node) + { +#if !NET_2_0 + return ConfigurationException.GetXmlNodeFilename(node); +#else + return ConfigurationErrorsException.GetFilename(node); +#endif + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/DelegateInfo.cs b/src/Spring/Spring.Core/Util/DelegateInfo.cs index 7ebdbe57..e9ffb48d 100644 --- a/src/Spring/Spring.Core/Util/DelegateInfo.cs +++ b/src/Spring/Spring.Core/Util/DelegateInfo.cs @@ -1,255 +1,254 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Util -{ - /// - /// Discovers the attributes of a - /// and provides access to the - /// s metadata. - /// - /// Rick Evans - /// $Id: DelegateInfo.cs,v 1.9 2006/04/09 07:19:00 markpollack Exp $ - public sealed class DelegateInfo - { - #region Constants - - /// - /// The method name associated with a delegate invocation. - /// - private const string InvocationMethod = "Invoke"; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The event used to extract the delegate - /// from. - /// - /// - /// if the supplied is - /// . - /// - public DelegateInfo(EventInfo eventMeta) : this(eventMeta.EventHandlerType) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The delegate . - /// - /// - /// If the supplied is not a subclass of the - /// class, or is . - /// - public DelegateInfo(Type type) - { - DelegateType = type; - } - - #endregion - - #region Properties - - /// - /// The of the delegate. - /// - private Type DelegateType - { - get { return _delegateType; } - set - { - if (!DelegateInfo.IsDelegate(value)) - { - throw new ArgumentException("Not a delegate Type"); - } - _delegateType = value; - } - } - - #endregion - - #region Methods - - /// - /// Checks to see if the method encapsulated by the supplied method - /// metadata is compatible with the method signature associated with - /// this delegate type. - /// - /// The method to be checked. - /// - /// if the method signature is compatible with - /// the signature of this delegate; if not, or - /// if the supplied parameter is - /// . - /// - public bool IsSignatureCompatible(MethodInfo method) - { - if (method != null && - method.ReturnType.Equals(GetReturnType())) - { - ParameterInfo[] methodParameters = - method.GetParameters(); - Type[] delegateParameters = GetParameterTypes(); - if (methodParameters.Length == delegateParameters.Length) - { - for (int i = 0; i < methodParameters.Length; ++i) - { - if (!methodParameters[i].ParameterType. - Equals(delegateParameters[i])) - { - return false; - } - } - return true; - } - } - return false; - } - - /// - /// Gets the s of the parameters of the - /// method signature associated with this delegate type. - /// - /// - ///

- /// This method will never return ; the returned - /// array may be empty, but it most certainly - /// will not be . - ///

- ///
- /// - /// A array of the parameter - /// s; or the - /// array if the method signature has no parameters. - /// - public Type[] GetParameterTypes() - { - ParameterInfo[] parameters = GetMethod().GetParameters(); - if (parameters != null - && parameters.Length > 0) - { - Type[] types = new Type[parameters.Length]; - for (int i = 0; i < parameters.Length; ++i) - { - types[i] = parameters[i].ParameterType; - } - return types; - } - return Type.EmptyTypes; - } - - /// - /// Gets the return of the - /// method signature associated with this delegate type. - /// - /// The return . - public Type GetReturnType() - { - return GetMethod().ReturnType; - } - - /// - /// Gets the metadata about the method signature associated - /// with this delegate type. - /// - /// - /// The metadata about the method signature associated - /// with this delegate type. - /// - public MethodInfo GetMethod() - { - return DelegateType.GetMethod(DelegateInfo.InvocationMethod); - } - - /// - /// Determines whether the supplied - /// is a type. - /// - /// - /// The to be checked. - /// - /// - /// if the supplied - /// is a ; - /// if not or the supplied - /// is . - /// - public static bool IsDelegate(Type type) - { - return type == null ? - false : - type.IsSubclassOf(typeof (Delegate)); - } - - /// - /// Checks if the signature of the supplied - /// is compatible with the signature expected by the supplied - /// . - /// - /// The event to be checked against. - /// - /// The method signature to check for compatibility. - /// - /// - /// if the signature of the supplied - /// is compatible with the signature - /// expected by the supplied ; - /// if not or either of the supplied - /// parameters is . - /// - /// - public static bool IsSignatureCompatible( - EventInfo eventMeta, MethodInfo handlerMethod) - { - bool compatible = false; - if (eventMeta != null - && DelegateInfo.IsDelegate(eventMeta.EventHandlerType)) - { - compatible = new DelegateInfo(eventMeta.EventHandlerType) - .IsSignatureCompatible(handlerMethod); - } - return compatible; - } - - #endregion - - #region Fields - - private Type _delegateType; - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Util +{ + /// + /// Discovers the attributes of a + /// and provides access to the + /// s metadata. + /// + /// Rick Evans + public sealed class DelegateInfo + { + #region Constants + + /// + /// The method name associated with a delegate invocation. + /// + private const string InvocationMethod = "Invoke"; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The event used to extract the delegate + /// from. + /// + /// + /// if the supplied is + /// . + /// + public DelegateInfo(EventInfo eventMeta) : this(eventMeta.EventHandlerType) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The delegate . + /// + /// + /// If the supplied is not a subclass of the + /// class, or is . + /// + public DelegateInfo(Type type) + { + DelegateType = type; + } + + #endregion + + #region Properties + + /// + /// The of the delegate. + /// + private Type DelegateType + { + get { return _delegateType; } + set + { + if (!DelegateInfo.IsDelegate(value)) + { + throw new ArgumentException("Not a delegate Type"); + } + _delegateType = value; + } + } + + #endregion + + #region Methods + + /// + /// Checks to see if the method encapsulated by the supplied method + /// metadata is compatible with the method signature associated with + /// this delegate type. + /// + /// The method to be checked. + /// + /// if the method signature is compatible with + /// the signature of this delegate; if not, or + /// if the supplied parameter is + /// . + /// + public bool IsSignatureCompatible(MethodInfo method) + { + if (method != null && + method.ReturnType.Equals(GetReturnType())) + { + ParameterInfo[] methodParameters = + method.GetParameters(); + Type[] delegateParameters = GetParameterTypes(); + if (methodParameters.Length == delegateParameters.Length) + { + for (int i = 0; i < methodParameters.Length; ++i) + { + if (!methodParameters[i].ParameterType. + Equals(delegateParameters[i])) + { + return false; + } + } + return true; + } + } + return false; + } + + /// + /// Gets the s of the parameters of the + /// method signature associated with this delegate type. + /// + /// + ///

+ /// This method will never return ; the returned + /// array may be empty, but it most certainly + /// will not be . + ///

+ ///
+ /// + /// A array of the parameter + /// s; or the + /// array if the method signature has no parameters. + /// + public Type[] GetParameterTypes() + { + ParameterInfo[] parameters = GetMethod().GetParameters(); + if (parameters != null + && parameters.Length > 0) + { + Type[] types = new Type[parameters.Length]; + for (int i = 0; i < parameters.Length; ++i) + { + types[i] = parameters[i].ParameterType; + } + return types; + } + return Type.EmptyTypes; + } + + /// + /// Gets the return of the + /// method signature associated with this delegate type. + /// + /// The return . + public Type GetReturnType() + { + return GetMethod().ReturnType; + } + + /// + /// Gets the metadata about the method signature associated + /// with this delegate type. + /// + /// + /// The metadata about the method signature associated + /// with this delegate type. + /// + public MethodInfo GetMethod() + { + return DelegateType.GetMethod(DelegateInfo.InvocationMethod); + } + + /// + /// Determines whether the supplied + /// is a type. + /// + /// + /// The to be checked. + /// + /// + /// if the supplied + /// is a ; + /// if not or the supplied + /// is . + /// + public static bool IsDelegate(Type type) + { + return type == null ? + false : + type.IsSubclassOf(typeof (Delegate)); + } + + /// + /// Checks if the signature of the supplied + /// is compatible with the signature expected by the supplied + /// . + /// + /// The event to be checked against. + /// + /// The method signature to check for compatibility. + /// + /// + /// if the signature of the supplied + /// is compatible with the signature + /// expected by the supplied ; + /// if not or either of the supplied + /// parameters is . + /// + /// + public static bool IsSignatureCompatible( + EventInfo eventMeta, MethodInfo handlerMethod) + { + bool compatible = false; + if (eventMeta != null + && DelegateInfo.IsDelegate(eventMeta.EventHandlerType)) + { + compatible = new DelegateInfo(eventMeta.EventHandlerType) + .IsSignatureCompatible(handlerMethod); + } + return compatible; + } + + #endregion + + #region Fields + + private Type _delegateType; + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Util/DynamicCodeManager.cs b/src/Spring/Spring.Core/Util/DynamicCodeManager.cs index cfceb9d6..ac0873eb 100644 --- a/src/Spring/Spring.Core/Util/DynamicCodeManager.cs +++ b/src/Spring/Spring.Core/Util/DynamicCodeManager.cs @@ -1,144 +1,143 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Diagnostics; -using System.Reflection; -using System.Reflection.Emit; - -#endregion - -namespace Spring.Util -{ - /// - /// Use this class for obtaining instances for dynamic code generation. - /// - /// - ///

- /// The purpose of this class is to provide a simple abstraction for creating and managing dynamic assemblies. - ///

- /// - /// Using this factory you can't define several modules within a single dynamic assembly - only a simple one2one relation between assembly/module is used. - /// - ///
- /// - ///

The following excerpt from demonstrates usage:

- /// - /// public class DynamicProxyManager - /// { - /// public const string PROXY_ASSEMBLY_NAME = "Spring.Proxy"; - /// - /// public static TypeBuilder CreateTypeBuilder(string name, Type baseType) - /// { - /// // Generates type name - /// string typeName = String.Format("{0}.{1}_{2}", PROXY_ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N")); - /// ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(PROXY_ASSEMBLY_NAME); - /// return module.DefineType(typeName, PROXY_TYPE_ATTRIBUTES); - /// } - /// } - /// - ///
- /// Erich Eichinger - /// $Id: DynamicCodeManager.cs,v 1.6 2007/08/08 04:00:16 bbaia Exp $ - /// - /// - /// - public sealed class DynamicCodeManager - { - private static readonly Hashtable s_moduleCache = CollectionsUtil.CreateCaseInsensitiveHashtable(); - - /// - /// prevent instantiation - /// - private DynamicCodeManager() - { - throw new InvalidOperationException(); - } - - /// - /// Returns the for the dynamic module within the specified assembly. - /// - /// - /// If the assembly does not exist yet, it will be created.
- /// This factory caches any dynamic assembly it creates - calling GetModule() twice with - /// the same name will *not* create 2 distinct modules! - ///
- /// The assembly-name of the module to be returned - /// the that can be used to define new types within the specified assembly - public static ModuleBuilder GetModuleBuilder( string assemblyName ) - { - lock(s_moduleCache.SyncRoot) - { - ModuleBuilder module = (ModuleBuilder) s_moduleCache[assemblyName]; - if (module == null) - { - AssemblyName an = new AssemblyName(); - an.Name = assemblyName; - - AssemblyBuilder assembly; -#if DEBUG_DYNAMIC - assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave, null, null, null, null,null, true ); - module = assembly.DefineDynamicModule(an.Name, an.Name + ".dll", true); -#else - assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, null, null, null, null,null, true ); -#if DEBUG - module = assembly.DefineDynamicModule(an.Name, true); -#else - module = assembly.DefineDynamicModule(an.Name, false); -#endif -#endif - s_moduleCache[assemblyName] = module; - } - return module; - } - } - - /// - /// Persists the specified dynamic assembly to the file-system - /// - /// the name of the dynamic assembly to persist - /// - /// Can only be called in DEBUG_DYNAMIC mode, per ConditionalAttribute rules. - /// - [Conditional("DEBUG_DYNAMIC")] - public static void SaveAssembly( string assemblyName ) - { - AssertUtils.ArgumentHasText(assemblyName, "assemblyName"); - - ModuleBuilder module = null; - lock(s_moduleCache.SyncRoot) - { - module = (ModuleBuilder) s_moduleCache[assemblyName]; - } - - if(module == null) - { - throw new ArgumentException(string.Format("'{0}' is not a valid dynamic assembly name", assemblyName), "assemblyName"); - } - - AssemblyBuilder assembly = (AssemblyBuilder) module.Assembly; - assembly.Save(assembly.GetName().Name + ".dll"); - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Reflection; +using System.Reflection.Emit; + +#endregion + +namespace Spring.Util +{ + /// + /// Use this class for obtaining instances for dynamic code generation. + /// + /// + ///

+ /// The purpose of this class is to provide a simple abstraction for creating and managing dynamic assemblies. + ///

+ /// + /// Using this factory you can't define several modules within a single dynamic assembly - only a simple one2one relation between assembly/module is used. + /// + ///
+ /// + ///

The following excerpt from demonstrates usage:

+ /// + /// public class DynamicProxyManager + /// { + /// public const string PROXY_ASSEMBLY_NAME = "Spring.Proxy"; + /// + /// public static TypeBuilder CreateTypeBuilder(string name, Type baseType) + /// { + /// // Generates type name + /// string typeName = String.Format("{0}.{1}_{2}", PROXY_ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N")); + /// ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(PROXY_ASSEMBLY_NAME); + /// return module.DefineType(typeName, PROXY_TYPE_ATTRIBUTES); + /// } + /// } + /// + ///
+ /// Erich Eichinger + /// + /// + /// + public sealed class DynamicCodeManager + { + private static readonly Hashtable s_moduleCache = CollectionsUtil.CreateCaseInsensitiveHashtable(); + + /// + /// prevent instantiation + /// + private DynamicCodeManager() + { + throw new InvalidOperationException(); + } + + /// + /// Returns the for the dynamic module within the specified assembly. + /// + /// + /// If the assembly does not exist yet, it will be created.
+ /// This factory caches any dynamic assembly it creates - calling GetModule() twice with + /// the same name will *not* create 2 distinct modules! + ///
+ /// The assembly-name of the module to be returned + /// the that can be used to define new types within the specified assembly + public static ModuleBuilder GetModuleBuilder( string assemblyName ) + { + lock(s_moduleCache.SyncRoot) + { + ModuleBuilder module = (ModuleBuilder) s_moduleCache[assemblyName]; + if (module == null) + { + AssemblyName an = new AssemblyName(); + an.Name = assemblyName; + + AssemblyBuilder assembly; +#if DEBUG_DYNAMIC + assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave, null, null, null, null,null, true ); + module = assembly.DefineDynamicModule(an.Name, an.Name + ".dll", true); +#else + assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, null, null, null, null,null, true ); +#if DEBUG + module = assembly.DefineDynamicModule(an.Name, true); +#else + module = assembly.DefineDynamicModule(an.Name, false); +#endif +#endif + s_moduleCache[assemblyName] = module; + } + return module; + } + } + + /// + /// Persists the specified dynamic assembly to the file-system + /// + /// the name of the dynamic assembly to persist + /// + /// Can only be called in DEBUG_DYNAMIC mode, per ConditionalAttribute rules. + /// + [Conditional("DEBUG_DYNAMIC")] + public static void SaveAssembly( string assemblyName ) + { + AssertUtils.ArgumentHasText(assemblyName, "assemblyName"); + + ModuleBuilder module = null; + lock(s_moduleCache.SyncRoot) + { + module = (ModuleBuilder) s_moduleCache[assemblyName]; + } + + if(module == null) + { + throw new ArgumentException(string.Format("'{0}' is not a valid dynamic assembly name", assemblyName), "assemblyName"); + } + + AssemblyBuilder assembly = (AssemblyBuilder) module.Assembly; + assembly.Save(assembly.GetName().Name + ".dll"); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/EventUtils.cs b/src/Spring/Spring.Core/Util/EventUtils.cs index a2561a94..538d842f 100644 --- a/src/Spring/Spring.Core/Util/EventUtils.cs +++ b/src/Spring/Spring.Core/Util/EventUtils.cs @@ -1,108 +1,106 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Util -{ - /// - /// A utility class for raising events in a generic and consistent fashion. - /// - /// Rick Evans - /// $Id: EventUtils.cs,v 1.5 2006/04/09 07:19:00 markpollack Exp $ - public class EventRaiser - { - /// - /// Raises the event encapsulated by the supplied - /// , passing the supplied - /// to the event. - /// - /// The event to be raised. - /// The arguments to the event. - public virtual void Raise (Delegate source, params object [] arguments) - { - if (source == null) - { - return; - } - Delegate [] delegates = source.GetInvocationList (); - foreach (Delegate sink in delegates) - { - Invoke (sink, arguments); - } - } - - /// - /// Invokes the supplied , passing the supplied - /// to the sink. - /// - /// The sink to be invoked. - /// The arguments to the sink. - protected virtual void Invoke (Delegate sink, object [] arguments) - { - try - { - sink.DynamicInvoke (arguments); - } - catch (TargetInvocationException ex) - { - // unwrap the exception that actually caused the TargetInvocationException and throw that... - throw ex.GetBaseException(); - } - } - } - - /// - /// Raises events defensively. - /// - /// - ///

- /// Raising events defensively means that as the raised event is passed to each handler, - /// any thrown by a handler will be caught and silently - /// ignored. - ///

- ///
- /// Rick Evans - /// $Id: EventUtils.cs,v 1.5 2006/04/09 07:19:00 markpollack Exp $ - public class DefensiveEventRaiser : EventRaiser - { - /// - /// Defensively invokes the supplied , passing the - /// supplied to the sink. - /// - /// The sink to be invoked. - /// The arguments to the sink. - protected override void Invoke (Delegate sink, object [] arguments) - { - try - { - sink.DynamicInvoke (arguments); - } - catch - { - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Util +{ + /// + /// A utility class for raising events in a generic and consistent fashion. + /// + /// Rick Evans + public class EventRaiser + { + /// + /// Raises the event encapsulated by the supplied + /// , passing the supplied + /// to the event. + /// + /// The event to be raised. + /// The arguments to the event. + public virtual void Raise (Delegate source, params object [] arguments) + { + if (source == null) + { + return; + } + Delegate [] delegates = source.GetInvocationList (); + foreach (Delegate sink in delegates) + { + Invoke (sink, arguments); + } + } + + /// + /// Invokes the supplied , passing the supplied + /// to the sink. + /// + /// The sink to be invoked. + /// The arguments to the sink. + protected virtual void Invoke (Delegate sink, object [] arguments) + { + try + { + sink.DynamicInvoke (arguments); + } + catch (TargetInvocationException ex) + { + // unwrap the exception that actually caused the TargetInvocationException and throw that... + throw ex.GetBaseException(); + } + } + } + + /// + /// Raises events defensively. + /// + /// + ///

+ /// Raising events defensively means that as the raised event is passed to each handler, + /// any thrown by a handler will be caught and silently + /// ignored. + ///

+ ///
+ /// Rick Evans + public class DefensiveEventRaiser : EventRaiser + { + /// + /// Defensively invokes the supplied , passing the + /// supplied to the sink. + /// + /// The sink to be invoked. + /// The arguments to the sink. + protected override void Invoke (Delegate sink, object [] arguments) + { + try + { + sink.DynamicInvoke (arguments); + } + catch + { + } + } + } +} diff --git a/src/Spring/Spring.Core/Util/FatalReflectionException.cs b/src/Spring/Spring.Core/Util/FatalReflectionException.cs index 747563a5..ab7f097f 100644 --- a/src/Spring/Spring.Core/Util/FatalReflectionException.cs +++ b/src/Spring/Spring.Core/Util/FatalReflectionException.cs @@ -1,92 +1,90 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Util; - -#endregion - -namespace Spring.Util -{ - /// - /// Thrown on an unrecoverable problem encountered in the - /// objects namespace or sub-namespaces, e.g. bad class or field. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: FatalReflectionException.cs,v 1.1 2007/07/31 03:47:23 markpollack Exp $ - /// - [Serializable] - public class FatalReflectionException : ReflectionException - { - /// - /// Creates a new instance of the FatalObjectException class. - /// - public FatalReflectionException() - { - } - - /// - /// Creates a new instance of the FatalObjectException class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - public FatalReflectionException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the FatalObjectException class with the - /// specified message. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public FatalReflectionException(string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the FatalObjectException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected FatalReflectionException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Util; + +#endregion + +namespace Spring.Util +{ + /// + /// Thrown on an unrecoverable problem encountered in the + /// objects namespace or sub-namespaces, e.g. bad class or field. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class FatalReflectionException : ReflectionException + { + /// + /// Creates a new instance of the FatalObjectException class. + /// + public FatalReflectionException() + { + } + + /// + /// Creates a new instance of the FatalObjectException class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + public FatalReflectionException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the FatalObjectException class with the + /// specified message. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public FatalReflectionException(string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the FatalObjectException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected FatalReflectionException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/Generic/CollectionUtils.cs b/src/Spring/Spring.Core/Util/Generic/CollectionUtils.cs index c83f977e..a1d1c368 100644 --- a/src/Spring/Spring.Core/Util/Generic/CollectionUtils.cs +++ b/src/Spring/Spring.Core/Util/Generic/CollectionUtils.cs @@ -1,137 +1,136 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; - -#endregion - -namespace Spring.Util.Generic -{ - /// - /// Miscellaneous generic collection utility methods. - /// - /// - /// Mainly for internal use within the framework. - /// - /// Mark Pollack (.NET) - /// $Id: CollectionUtils.cs,v 1.2 2006/12/02 07:51:28 markpollack Exp $ - public sealed class CollectionUtils - { - #region Methods - - /// - /// Determine whether a given collection only contains - /// a single unique object - /// - /// - /// - public static bool HasUniqueObject(ICollection coll) - { - if (coll.Count == 0) - { - return false; - } - object candidate = null; - foreach (object elem in coll) - { - if (candidate == null) - { - candidate = elem; - } - else if (candidate != elem) - { - return false; - } - } - return true; - } - - /// - /// Determines whether the contains the specified . - /// - /// The collection to check. - /// The object to locate in the collection. - /// if the element is in the collection, otherwise. - public static bool Contains(ICollection collection, Object element) - { - if (collection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - MethodInfo method; - method = collection.GetType().GetMethod("contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - if (null == method) - { - throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Contains() method."); - } - return (bool) method.Invoke(collection, new Object[] {element}); - } - - /// - /// Determines whether the collection contains all the elements in the specified collection. - /// - /// The collection to check. - /// Collection whose elements would be checked for containment. - /// true if the target collection contains all the elements of the specified collection. - public static bool ContainsAll(ICollection targetCollection, ICollection sourceCollection) - { - if (targetCollection == null || sourceCollection == null) - { - throw new ArgumentNullException("Collection cannot be null."); - } - if ( sourceCollection.Count == 0 && targetCollection.Count > 1 ) - return true; - - IEnumerator sourceCollectionEnumerator = sourceCollection.GetEnumerator(); - - bool contains = false; - - MethodInfo method; - method = targetCollection.GetType().GetMethod("containsAll", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - - if (method != null) - contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollection}); - else - { - method = targetCollection.GetType().GetMethod("Contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - if (method == null) - { - throw new InvalidOperationException("Target collection does not implment a Contains() or ContainsAll() method."); - } - while (sourceCollectionEnumerator.MoveNext()) - { - if ((contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollectionEnumerator.Current})) == false) - break; - } - } - return contains; - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; + +#endregion + +namespace Spring.Util.Generic +{ + /// + /// Miscellaneous generic collection utility methods. + /// + /// + /// Mainly for internal use within the framework. + /// + /// Mark Pollack (.NET) + public sealed class CollectionUtils + { + #region Methods + + /// + /// Determine whether a given collection only contains + /// a single unique object + /// + /// + /// + public static bool HasUniqueObject(ICollection coll) + { + if (coll.Count == 0) + { + return false; + } + object candidate = null; + foreach (object elem in coll) + { + if (candidate == null) + { + candidate = elem; + } + else if (candidate != elem) + { + return false; + } + } + return true; + } + + /// + /// Determines whether the contains the specified . + /// + /// The collection to check. + /// The object to locate in the collection. + /// if the element is in the collection, otherwise. + public static bool Contains(ICollection collection, Object element) + { + if (collection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + MethodInfo method; + method = collection.GetType().GetMethod("contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + if (null == method) + { + throw new InvalidOperationException("Collection type " + collection.GetType() + " does not implement a Contains() method."); + } + return (bool) method.Invoke(collection, new Object[] {element}); + } + + /// + /// Determines whether the collection contains all the elements in the specified collection. + /// + /// The collection to check. + /// Collection whose elements would be checked for containment. + /// true if the target collection contains all the elements of the specified collection. + public static bool ContainsAll(ICollection targetCollection, ICollection sourceCollection) + { + if (targetCollection == null || sourceCollection == null) + { + throw new ArgumentNullException("Collection cannot be null."); + } + if ( sourceCollection.Count == 0 && targetCollection.Count > 1 ) + return true; + + IEnumerator sourceCollectionEnumerator = sourceCollection.GetEnumerator(); + + bool contains = false; + + MethodInfo method; + method = targetCollection.GetType().GetMethod("containsAll", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + + if (method != null) + contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollection}); + else + { + method = targetCollection.GetType().GetMethod("Contains", BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); + if (method == null) + { + throw new InvalidOperationException("Target collection does not implment a Contains() or ContainsAll() method."); + } + while (sourceCollectionEnumerator.MoveNext()) + { + if ((contains = (bool) method.Invoke(targetCollection, new Object[] {sourceCollectionEnumerator.Current})) == false) + break; + } + } + return contains; + } + + #endregion + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/NumberUtils.cs b/src/Spring/Spring.Core/Util/NumberUtils.cs index 79faf987..694615e0 100644 --- a/src/Spring/Spring.Core/Util/NumberUtils.cs +++ b/src/Spring/Spring.Core/Util/NumberUtils.cs @@ -1,349 +1,348 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ComponentModel; -using Spring.Core.TypeConversion; - -#endregion - -namespace Spring.Util -{ - /// - /// Various utility methods relating to numbers. - /// - /// - ///

- /// Mainly for internal use within the framework. - ///

- ///
- /// Aleksandar Seovic - /// $Id: NumberUtils.cs,v 1.6 2008/03/20 23:58:16 oakinger Exp $ - public sealed class NumberUtils - { - /// - /// Determines whether the supplied is an integer. - /// - /// The object to check. - /// - /// if the supplied is an integer. - /// - public static bool IsInteger(object number) - { - return (number is Int32 || number is Int16 || number is Int64 || number is UInt32 - || number is UInt16 || number is UInt64 || number is Byte || number is SByte); - } - - /// - /// Determines whether the supplied is a decimal number. - /// - /// The object to check. - /// - /// if the supplied is a decimal number. - /// - public static bool IsDecimal(object number) - { - - return (number is Single || number is Double || number is Decimal); - } - - /// - /// Determines whether the supplied is of numeric type. - /// - /// The object to check. - /// - /// true if the specified object is of numeric type; otherwise, false. - /// - public static bool IsNumber(object number) - { - return (IsInteger(number) || IsDecimal(number)); - } - - /// - /// Determines whether the supplied can be converted to an integer. - /// - /// The object to check. - /// - /// if the supplied can be converted to an integer. - /// - public static bool CanConvertToInteger(object number) - { - TypeConverter converter = TypeDescriptor.GetConverter(number); - return (converter.CanConvertTo(typeof(Int32)) - || converter.CanConvertTo(typeof(Int16)) - || converter.CanConvertTo(typeof(Int64)) - || converter.CanConvertTo(typeof(UInt16)) - || converter.CanConvertTo(typeof(UInt64)) - || converter.CanConvertTo(typeof(Byte)) - || converter.CanConvertTo(typeof(SByte)) - ); - } - - /// - /// Determines whether the supplied can be converted to an integer. - /// - /// The object to check. - /// - /// if the supplied can be converted to an integer. - /// - public static bool CanConvertToDecimal(object number) - { - TypeConverter converter = TypeDescriptor.GetConverter(number); - return (converter.CanConvertTo(typeof(Single)) - || converter.CanConvertTo(typeof(Double)) - || converter.CanConvertTo(typeof(Decimal)) - ); - } - - /// - /// Determines whether the supplied can be converted to a number. - /// - /// The object to check. - /// - /// true if the specified object is decimal number; otherwise, false. - /// - public static bool CanConvertToNumber(object number) - { - return (CanConvertToInteger(number) || CanConvertToDecimal(number)); - } - - /// - /// Is the supplied equal to zero (0)? - /// - /// The number to check. - /// - /// id the supplied is equal to zero (0). - /// - public static bool IsZero(object number) - { - if (number is Int32) return ((Int32) number) == 0; - else if (number is Int16) return ((Int16) number) == 0; - else if (number is Int64) return ((Int64) number) == 0; - else if (number is UInt16) return ((Int32) number) == 0; - else if (number is UInt32) return ((Int64) number) == 0; - else if (number is UInt64) return (Convert.ToDecimal(number) == 0); - else if (number is Byte) return ((Int16) number) == 0; - else if (number is SByte) return ((Int16) number) == 0; - else if (number is Single) return ((Single) number) == 0f; - else if (number is Double) return ((Double) number) == 0d; - else if (number is Decimal) return ((Decimal) number) == 0m; - return false; - } - - /// - /// Negates the supplied . - /// - /// The number to negate. - /// The supplied negated. - /// - /// If the supplied is not a supported numeric type. - /// - public static object Negate(object number) - { - if (number is Int32) return -((Int32) number); - else if (number is Int16) return -((Int16) number); - else if (number is Int64) return -((Int64) number); - else if (number is UInt16) return -((Int32) number); - else if (number is UInt32) return -((Int64) number); - else if (number is UInt64) return -(Convert.ToDecimal(number)); - else if (number is Byte) return -((Int16) number); - else if (number is SByte) return -((Int16) number); - else if (number is Single) return -((Single) number); - else if (number is Double) return -((Double) number); - else if (number is Decimal) return -((Decimal) number); - else - { - throw new ArgumentException(string.Format("'{0}' is not one of the supported numeric types.", number)); - } - } - - /// - /// Adds the specified numbers. - /// - /// The first number. - /// The second number. - public static object Add(object m, object n) - { - CoerceTypes(ref m, ref n); - - if (n is Int32) return (Int32) m + (Int32) n; - else if (n is Int16) return (Int16) m + (Int16) n; - else if (n is Int64) return (Int64) m + (Int64) n; - else if (n is UInt16) return (UInt16) m + (UInt16) n; - else if (n is UInt32) return (UInt32) m + (UInt32) n; - else if (n is UInt64) return (UInt64) m + (UInt64) n; - else if (n is Byte) return (Byte) m + (Byte) n; - else if (n is SByte) return (SByte) m + (SByte) n; - else if (n is Single) return (Single) m + (Single) n; - else if (n is Double) return (Double) m + (Double) n; - else if (n is Decimal) return (Decimal) m + (Decimal) n; - - return null; - } - - /// - /// Subtracts the specified numbers. - /// - /// The first number. - /// The second number. - public static object Subtract(object m, object n) - { - CoerceTypes(ref m, ref n); - - if (n is Int32) return (Int32) m - (Int32) n; - else if (n is Int16) return (Int16) m - (Int16) n; - else if (n is Int64) return (Int64) m - (Int64) n; - else if (n is UInt16) return (UInt16) m - (UInt16) n; - else if (n is UInt32) return (UInt32) m - (UInt32) n; - else if (n is UInt64) return (UInt64) m - (UInt64) n; - else if (n is Byte) return (Byte) m - (Byte) n; - else if (n is SByte) return (SByte) m - (SByte) n; - else if (n is Single) return (Single) m - (Single) n; - else if (n is Double) return (Double) m - (Double) n; - else if (n is Decimal) return (Decimal) m - (Decimal) n; - - return null; - } - - /// - /// Multiplies the specified numbers. - /// - /// The first number. - /// The second number. - public static object Multiply(object m, object n) - { - CoerceTypes(ref m, ref n); - - if (n is Int32) return (Int32) m*(Int32) n; - else if (n is Int16) return (Int16) m*(Int16) n; - else if (n is Int64) return (Int64) m*(Int64) n; - else if (n is UInt16) return (UInt16) m*(UInt16) n; - else if (n is UInt32) return (UInt32) m*(UInt32) n; - else if (n is UInt64) return (UInt64) m*(UInt64) n; - else if (n is Byte) return (Byte) m*(Byte) n; - else if (n is SByte) return (SByte) m*(SByte) n; - else if (n is Single) return (Single) m*(Single) n; - else if (n is Double) return (Double) m*(Double) n; - else if (n is Decimal) return (Decimal) m*(Decimal) n; - - return null; - } - - /// - /// Divides the specified numbers. - /// - /// The first number. - /// The second number. - public static object Divide(object m, object n) - { - CoerceTypes(ref m, ref n); - - if (n is Int32) return (Int32) m/(Int32) n; - else if (n is Int16) return (Int16) m/(Int16) n; - else if (n is Int64) return (Int64) m/(Int64) n; - else if (n is UInt16) return (UInt16) m/(UInt16) n; - else if (n is UInt32) return (UInt32) m/(UInt32) n; - else if (n is UInt64) return (UInt64) m/(UInt64) n; - else if (n is Byte) return (Byte) m/(Byte) n; - else if (n is SByte) return (SByte) m/(SByte) n; - else if (n is Single) return (Single) m/(Single) n; - else if (n is Double) return (Double) m/(Double) n; - else if (n is Decimal) return (Decimal) m/(Decimal) n; - - return null; - } - - /// - /// Calculates remainder for the specified numbers. - /// - /// The first number (dividend). - /// The second number (divisor). - public static object Modulus(object m, object n) - { - CoerceTypes(ref m, ref n); - - if (n is Int32) return (Int32) m%(Int32) n; - else if (n is Int16) return (Int16) m%(Int16) n; - else if (n is Int64) return (Int64) m%(Int64) n; - else if (n is UInt16) return (UInt16) m%(UInt16) n; - else if (n is UInt32) return (UInt32) m%(UInt32) n; - else if (n is UInt64) return (UInt64) m%(UInt64) n; - else if (n is Byte) return (Byte) m%(Byte) n; - else if (n is SByte) return (SByte) m%(SByte) n; - else if (n is Single) return (Single) m%(Single) n; - else if (n is Double) return (Double) m%(Double) n; - else if (n is Decimal) return (Decimal) m%(Decimal) n; - - return null; - } - - /// - /// Raises first number to the power of the second one. - /// - /// The first number. - /// The second number. - public static object Power(object m, object n) - { - return Math.Pow(Convert.ToDouble(m), Convert.ToDouble(n)); - } - - /// - /// Coerces the types so they can be compared. - /// - /// The right. - /// The left. - public static void CoerceTypes(ref object m, ref object n) - { - TypeCode leftTypeCode = Convert.GetTypeCode(m); - TypeCode rightTypeCode = Convert.GetTypeCode(n); - - if (leftTypeCode > rightTypeCode) - { - n = Convert.ChangeType(n, leftTypeCode); - } - else - { - m = Convert.ChangeType(m, rightTypeCode); - } - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private NumberUtils() - { - } - - // CLOVER:ON - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ComponentModel; +using Spring.Core.TypeConversion; + +#endregion + +namespace Spring.Util +{ + /// + /// Various utility methods relating to numbers. + /// + /// + ///

+ /// Mainly for internal use within the framework. + ///

+ ///
+ /// Aleksandar Seovic + public sealed class NumberUtils + { + /// + /// Determines whether the supplied is an integer. + /// + /// The object to check. + /// + /// if the supplied is an integer. + /// + public static bool IsInteger(object number) + { + return (number is Int32 || number is Int16 || number is Int64 || number is UInt32 + || number is UInt16 || number is UInt64 || number is Byte || number is SByte); + } + + /// + /// Determines whether the supplied is a decimal number. + /// + /// The object to check. + /// + /// if the supplied is a decimal number. + /// + public static bool IsDecimal(object number) + { + + return (number is Single || number is Double || number is Decimal); + } + + /// + /// Determines whether the supplied is of numeric type. + /// + /// The object to check. + /// + /// true if the specified object is of numeric type; otherwise, false. + /// + public static bool IsNumber(object number) + { + return (IsInteger(number) || IsDecimal(number)); + } + + /// + /// Determines whether the supplied can be converted to an integer. + /// + /// The object to check. + /// + /// if the supplied can be converted to an integer. + /// + public static bool CanConvertToInteger(object number) + { + TypeConverter converter = TypeDescriptor.GetConverter(number); + return (converter.CanConvertTo(typeof(Int32)) + || converter.CanConvertTo(typeof(Int16)) + || converter.CanConvertTo(typeof(Int64)) + || converter.CanConvertTo(typeof(UInt16)) + || converter.CanConvertTo(typeof(UInt64)) + || converter.CanConvertTo(typeof(Byte)) + || converter.CanConvertTo(typeof(SByte)) + ); + } + + /// + /// Determines whether the supplied can be converted to an integer. + /// + /// The object to check. + /// + /// if the supplied can be converted to an integer. + /// + public static bool CanConvertToDecimal(object number) + { + TypeConverter converter = TypeDescriptor.GetConverter(number); + return (converter.CanConvertTo(typeof(Single)) + || converter.CanConvertTo(typeof(Double)) + || converter.CanConvertTo(typeof(Decimal)) + ); + } + + /// + /// Determines whether the supplied can be converted to a number. + /// + /// The object to check. + /// + /// true if the specified object is decimal number; otherwise, false. + /// + public static bool CanConvertToNumber(object number) + { + return (CanConvertToInteger(number) || CanConvertToDecimal(number)); + } + + /// + /// Is the supplied equal to zero (0)? + /// + /// The number to check. + /// + /// id the supplied is equal to zero (0). + /// + public static bool IsZero(object number) + { + if (number is Int32) return ((Int32) number) == 0; + else if (number is Int16) return ((Int16) number) == 0; + else if (number is Int64) return ((Int64) number) == 0; + else if (number is UInt16) return ((Int32) number) == 0; + else if (number is UInt32) return ((Int64) number) == 0; + else if (number is UInt64) return (Convert.ToDecimal(number) == 0); + else if (number is Byte) return ((Int16) number) == 0; + else if (number is SByte) return ((Int16) number) == 0; + else if (number is Single) return ((Single) number) == 0f; + else if (number is Double) return ((Double) number) == 0d; + else if (number is Decimal) return ((Decimal) number) == 0m; + return false; + } + + /// + /// Negates the supplied . + /// + /// The number to negate. + /// The supplied negated. + /// + /// If the supplied is not a supported numeric type. + /// + public static object Negate(object number) + { + if (number is Int32) return -((Int32) number); + else if (number is Int16) return -((Int16) number); + else if (number is Int64) return -((Int64) number); + else if (number is UInt16) return -((Int32) number); + else if (number is UInt32) return -((Int64) number); + else if (number is UInt64) return -(Convert.ToDecimal(number)); + else if (number is Byte) return -((Int16) number); + else if (number is SByte) return -((Int16) number); + else if (number is Single) return -((Single) number); + else if (number is Double) return -((Double) number); + else if (number is Decimal) return -((Decimal) number); + else + { + throw new ArgumentException(string.Format("'{0}' is not one of the supported numeric types.", number)); + } + } + + /// + /// Adds the specified numbers. + /// + /// The first number. + /// The second number. + public static object Add(object m, object n) + { + CoerceTypes(ref m, ref n); + + if (n is Int32) return (Int32) m + (Int32) n; + else if (n is Int16) return (Int16) m + (Int16) n; + else if (n is Int64) return (Int64) m + (Int64) n; + else if (n is UInt16) return (UInt16) m + (UInt16) n; + else if (n is UInt32) return (UInt32) m + (UInt32) n; + else if (n is UInt64) return (UInt64) m + (UInt64) n; + else if (n is Byte) return (Byte) m + (Byte) n; + else if (n is SByte) return (SByte) m + (SByte) n; + else if (n is Single) return (Single) m + (Single) n; + else if (n is Double) return (Double) m + (Double) n; + else if (n is Decimal) return (Decimal) m + (Decimal) n; + + return null; + } + + /// + /// Subtracts the specified numbers. + /// + /// The first number. + /// The second number. + public static object Subtract(object m, object n) + { + CoerceTypes(ref m, ref n); + + if (n is Int32) return (Int32) m - (Int32) n; + else if (n is Int16) return (Int16) m - (Int16) n; + else if (n is Int64) return (Int64) m - (Int64) n; + else if (n is UInt16) return (UInt16) m - (UInt16) n; + else if (n is UInt32) return (UInt32) m - (UInt32) n; + else if (n is UInt64) return (UInt64) m - (UInt64) n; + else if (n is Byte) return (Byte) m - (Byte) n; + else if (n is SByte) return (SByte) m - (SByte) n; + else if (n is Single) return (Single) m - (Single) n; + else if (n is Double) return (Double) m - (Double) n; + else if (n is Decimal) return (Decimal) m - (Decimal) n; + + return null; + } + + /// + /// Multiplies the specified numbers. + /// + /// The first number. + /// The second number. + public static object Multiply(object m, object n) + { + CoerceTypes(ref m, ref n); + + if (n is Int32) return (Int32) m*(Int32) n; + else if (n is Int16) return (Int16) m*(Int16) n; + else if (n is Int64) return (Int64) m*(Int64) n; + else if (n is UInt16) return (UInt16) m*(UInt16) n; + else if (n is UInt32) return (UInt32) m*(UInt32) n; + else if (n is UInt64) return (UInt64) m*(UInt64) n; + else if (n is Byte) return (Byte) m*(Byte) n; + else if (n is SByte) return (SByte) m*(SByte) n; + else if (n is Single) return (Single) m*(Single) n; + else if (n is Double) return (Double) m*(Double) n; + else if (n is Decimal) return (Decimal) m*(Decimal) n; + + return null; + } + + /// + /// Divides the specified numbers. + /// + /// The first number. + /// The second number. + public static object Divide(object m, object n) + { + CoerceTypes(ref m, ref n); + + if (n is Int32) return (Int32) m/(Int32) n; + else if (n is Int16) return (Int16) m/(Int16) n; + else if (n is Int64) return (Int64) m/(Int64) n; + else if (n is UInt16) return (UInt16) m/(UInt16) n; + else if (n is UInt32) return (UInt32) m/(UInt32) n; + else if (n is UInt64) return (UInt64) m/(UInt64) n; + else if (n is Byte) return (Byte) m/(Byte) n; + else if (n is SByte) return (SByte) m/(SByte) n; + else if (n is Single) return (Single) m/(Single) n; + else if (n is Double) return (Double) m/(Double) n; + else if (n is Decimal) return (Decimal) m/(Decimal) n; + + return null; + } + + /// + /// Calculates remainder for the specified numbers. + /// + /// The first number (dividend). + /// The second number (divisor). + public static object Modulus(object m, object n) + { + CoerceTypes(ref m, ref n); + + if (n is Int32) return (Int32) m%(Int32) n; + else if (n is Int16) return (Int16) m%(Int16) n; + else if (n is Int64) return (Int64) m%(Int64) n; + else if (n is UInt16) return (UInt16) m%(UInt16) n; + else if (n is UInt32) return (UInt32) m%(UInt32) n; + else if (n is UInt64) return (UInt64) m%(UInt64) n; + else if (n is Byte) return (Byte) m%(Byte) n; + else if (n is SByte) return (SByte) m%(SByte) n; + else if (n is Single) return (Single) m%(Single) n; + else if (n is Double) return (Double) m%(Double) n; + else if (n is Decimal) return (Decimal) m%(Decimal) n; + + return null; + } + + /// + /// Raises first number to the power of the second one. + /// + /// The first number. + /// The second number. + public static object Power(object m, object n) + { + return Math.Pow(Convert.ToDouble(m), Convert.ToDouble(n)); + } + + /// + /// Coerces the types so they can be compared. + /// + /// The right. + /// The left. + public static void CoerceTypes(ref object m, ref object n) + { + TypeCode leftTypeCode = Convert.GetTypeCode(m); + TypeCode rightTypeCode = Convert.GetTypeCode(n); + + if (leftTypeCode > rightTypeCode) + { + n = Convert.ChangeType(n, leftTypeCode); + } + else + { + m = Convert.ChangeType(m, rightTypeCode); + } + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private NumberUtils() + { + } + + // CLOVER:ON + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/ObjectUtils.cs b/src/Spring/Spring.Core/Util/ObjectUtils.cs index 9596fe6b..8d6141fe 100644 --- a/src/Spring/Spring.Core/Util/ObjectUtils.cs +++ b/src/Spring/Spring.Core/Util/ObjectUtils.cs @@ -1,492 +1,491 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Reflection; -using System.Runtime.Remoting; -using Spring.Objects; - -#endregion - -namespace Spring.Util -{ - /// - /// Helper methods with regard to objects, types, properties, etc. - /// - /// - ///

- /// Not intended to be used directly by applications. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - /// $Id: ObjectUtils.cs,v 1.9 2007/12/29 00:31:00 markpollack Exp $ - public sealed class ObjectUtils - { - #region Constants - - /// - /// An empty object array. - /// - public static readonly object[] EmptyObjects = new object[] {}; - - #endregion - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private ObjectUtils() - { - } - - // CLOVER:ON - - #endregion - - #region Methods - - /// - /// Instantiates the type using the assembly specified to load the type. - /// - /// This is a convenience in the case of needing to instantiate a type but not - /// wanting to specify in the string the version, culture and public key token. - /// The assembly. - /// Name of the type. - /// - /// - /// If the or is - /// - /// - /// If cannot load the type from the assembly or the call to InstantiateType(Type) fails. - /// - public static object InstantiateType(Assembly assembly, string typeName) - { - AssertUtils.ArgumentNotNull(assembly, "assembly"); - AssertUtils.ArgumentNotNull(typeName, "typeName"); - Type resolvedType = assembly.GetType(typeName, false, false); - if (resolvedType == null) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot load type named [{0}] from assembly [{1}].", typeName, assembly)); - } - return InstantiateType(resolvedType); - } - /// - /// Convenience method to instantiate a using - /// its no-arg constructor. - /// - /// - ///

- /// As this method doesn't try to instantiate s - /// by name, it should avoid loading issues. - ///

- ///
- /// - /// The to instantiate* - /// - /// A new instance of the . - /// - /// If the is - /// - /// - /// If the is an abstract class, an interface, - /// an open generic type or does not have a public no-argument constructor. - /// - public static object InstantiateType(Type type) - { - AssertUtils.ArgumentNotNull(type, "type"); - - ConstructorInfo constructor = GetZeroArgConstructorInfo(type); - return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); - } - - /// - /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. - /// - /// The type. - /// Zero argument ConstructorInfo - /// - /// If the type is an interface, abstract, open generic type, or does not have a zero-arg constructor. - /// - public static ConstructorInfo GetZeroArgConstructorInfo(Type type) - { - IsInstantiable(type); - ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); - if (constructor == null) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a public no-argument constructor [{0}].", type)); - } - return constructor; - } - - /// - /// Determines whether the specified type is instantiable, i.e. not an interface, abstract class or contains - /// open generic type parameters. - /// - /// The type. - public static void IsInstantiable(Type type) - { - if (type.IsInterface) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", type)); - } - if (type.IsAbstract) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", type)); - } -#if NET_2_0 - if (type.ContainsGenericParameters) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", type)); - } -#endif - } - - /// - /// Convenience method to instantiate a using - /// the given constructor. - /// - /// - ///

- /// As this method doesn't try to instantiate s - /// by name, it should avoid loading issues. - ///

- ///
- /// - /// The constructor to use for the instantiation. - /// - /// - /// The arguments to be passed to the constructor. - /// - /// A new instance. - /// - /// If the is - /// - /// - /// If the 's declaring type is an abstract class, - /// an interface, an open generic type or does not have a public no-argument constructor. - /// - public static object InstantiateType(ConstructorInfo constructor, object[] arguments) - { - AssertUtils.ArgumentNotNull(constructor, "constructor"); - - if (constructor.DeclaringType.IsInterface) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", constructor.DeclaringType)); - } - if (constructor.DeclaringType.IsAbstract) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", constructor.DeclaringType)); - } -#if NET_2_0 - if (constructor.DeclaringType.ContainsGenericParameters) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", constructor.DeclaringType)); - } -#endif - try - { - return constructor.Invoke(arguments); - } - catch (Exception ex) - { - Type ctorType = constructor.DeclaringType; - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, - "Cannot instantiate Type [{0}] using ctor [{1}] : '{2}'", - constructor.DeclaringType, constructor, ex.Message), - ex); - } - } - - /// - /// Checks whether the supplied is not a transparent proxy and is - /// assignable to the supplied . - /// - /// - ///

- /// Neccessary when dealing with server-activated remote objects, because the - /// object is of the type TransparentProxy and regular is testing for assignable - /// types does not work. - ///

- ///

- /// Transparent proxy instances always return when tested - /// with the 'is' operator (C#). This method only checks if the object - /// is assignable to the type if it is not a transparent proxy. - ///

- ///
- /// The target to be checked. - /// The value that should be assigned to the type. - /// - /// if the supplied is not a - /// transparent proxy and is assignable to the supplied . - /// - public static bool IsAssignableAndNotTransparentProxy(Type type, object instance) - { - if (!RemotingServices.IsTransparentProxy(instance)) - { - return IsAssignable(type, instance); - } - return false; - } - - /// - /// Determine if the given is assignable from the - /// given value, assuming setting by reflection. - /// - /// - ///

- /// Considers primitive wrapper classes as assignable to the - /// corresponding primitive types. - ///

- ///

- /// For example used in an object factory's constructor resolution. - ///

- ///
- /// The target . - /// The value that should be assigned to the type. - /// True if the type is assignable from the value. - public static bool IsAssignable(Type type, object obj) - { - return (type.IsInstanceOfType(obj) || - (!type.IsPrimitive && obj == null) || - (type.Equals(typeof (bool)) && obj is Boolean) || - (type.Equals(typeof (byte)) && obj is Byte) || - (type.Equals(typeof (char)) && obj is Char) || - (type.Equals(typeof (sbyte)) && obj is SByte) || - (type.Equals(typeof (int)) && obj is Int32) || - (type.Equals(typeof (short)) && obj is Int16) || - (type.Equals(typeof (long)) && obj is Int64) || - (type.Equals(typeof (float)) && obj is Single) || - (type.Equals(typeof (double)) && obj is Double)); - } - - /// - /// Check if the given represents a - /// "simple" property, - /// i.e. a primitive, a , a - /// , or a corresponding array. - /// - /// - ///

- /// Used to determine properties to check for a "simple" dependency-check. - ///

- ///
- /// - /// The to check. - /// - public static bool IsSimpleProperty(Type type) - { - return type.IsPrimitive - || type.Equals(typeof (string)) - || type.Equals(typeof (string[])) - || IsPrimitiveArray(type) - || type.Equals(typeof (Type)) - || type.Equals(typeof (Type[])); - } - - /// - /// Check if the given class represents a primitive array, - /// i.e. boolean, byte, char, short, int, long, float, or double. - /// - public static bool IsPrimitiveArray(Type type) - { - return typeof (bool[]).Equals(type) - || typeof (sbyte[]).Equals(type) - || typeof (char[]).Equals(type) - || typeof (short[]).Equals(type) - || typeof (int[]).Equals(type) - || typeof (long[]).Equals(type) - || typeof (float[]).Equals(type) - || typeof (double[]).Equals(type); - } - - /// - /// Determine if the given objects are equal, returning - /// if both are respectively - /// if only one is . - /// - /// The first object to compare. - /// The second object to compare. - /// - /// if the given objects are equal. - /// - public static bool NullSafeEquals(object o1, object o2) - { - return (o1 == o2 || (o1 != null && o1.Equals(o2))); - } - - /// - /// Returns the first element in the supplied . - /// - /// - /// The to use to enumerate - /// elements. - /// - /// - /// The first element in the supplied . - /// - /// - /// If the supplied did not have any elements. - /// - public static object EnumerateFirstElement(IEnumerator enumerator) - { - return ObjectUtils.EnumerateElementAtIndex(enumerator, 0); - } - - /// - /// Returns the first element in the supplied . - /// - /// - /// The to use to enumerate - /// elements. - /// - /// - /// The first element in the supplied . - /// - /// - /// If the supplied did not have any elements. - /// - /// - /// If the supplied is . - /// - public static object EnumerateFirstElement(IEnumerable enumerable) - { - AssertUtils.ArgumentNotNull(enumerable, "enumerable"); - return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), 0); - } - - /// - /// Returns the element at the specified index using the supplied - /// . - /// - /// - /// The to use to enumerate - /// elements until the supplied is reached. - /// - /// - /// The index of the element in the enumeration to return. - /// - /// - /// The element at the specified index using the supplied - /// . - /// - /// - /// If the supplied was less than zero, or the - /// supplied did not contain enough elements - /// to be able to reach the supplied . - /// - public static object EnumerateElementAtIndex(IEnumerator enumerator, int index) - { - if (index < 0) - { - throw new ArgumentOutOfRangeException(); - } - object element = null; - int i = 0; - while (enumerator.MoveNext()) - { - element = enumerator.Current; - if (++i > index) - { - break; - } - } - if (i < index) - { - throw new ArgumentOutOfRangeException(); - } - return element; - } - - /// - /// Returns the element at the specified index using the supplied - /// . - /// - /// - /// The to use to enumerate - /// elements until the supplied is reached. - /// - /// - /// The index of the element in the enumeration to return. - /// - /// - /// The element at the specified index using the supplied - /// . - /// - /// - /// If the supplied was less than zero, or the - /// supplied did not contain enough elements - /// to be able to reach the supplied . - /// - /// - /// If the supplied is . - /// - public static object EnumerateElementAtIndex(IEnumerable enumerable, int index) - { - AssertUtils.ArgumentNotNull(enumerable, "enumerable"); - return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), index); - } - - #endregion - - /// - /// Gets the qualified name of the given method, consisting of - /// fully qualified interface/class name + "." method name. - /// - /// The method. - /// qualified name of the method. - public static string GetQualifiedMethodName(MethodInfo method) - { - AssertUtils.ArgumentNotNull(method,"method", "MethodInfo must not be null"); - return method.DeclaringType.FullName + "." + method.Name; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Reflection; +using System.Runtime.Remoting; +using Spring.Objects; + +#endregion + +namespace Spring.Util +{ + /// + /// Helper methods with regard to objects, types, properties, etc. + /// + /// + ///

+ /// Not intended to be used directly by applications. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public sealed class ObjectUtils + { + #region Constants + + /// + /// An empty object array. + /// + public static readonly object[] EmptyObjects = new object[] {}; + + #endregion + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private ObjectUtils() + { + } + + // CLOVER:ON + + #endregion + + #region Methods + + /// + /// Instantiates the type using the assembly specified to load the type. + /// + /// This is a convenience in the case of needing to instantiate a type but not + /// wanting to specify in the string the version, culture and public key token. + /// The assembly. + /// Name of the type. + /// + /// + /// If the or is + /// + /// + /// If cannot load the type from the assembly or the call to InstantiateType(Type) fails. + /// + public static object InstantiateType(Assembly assembly, string typeName) + { + AssertUtils.ArgumentNotNull(assembly, "assembly"); + AssertUtils.ArgumentNotNull(typeName, "typeName"); + Type resolvedType = assembly.GetType(typeName, false, false); + if (resolvedType == null) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot load type named [{0}] from assembly [{1}].", typeName, assembly)); + } + return InstantiateType(resolvedType); + } + /// + /// Convenience method to instantiate a using + /// its no-arg constructor. + /// + /// + ///

+ /// As this method doesn't try to instantiate s + /// by name, it should avoid loading issues. + ///

+ ///
+ /// + /// The to instantiate* + /// + /// A new instance of the . + /// + /// If the is + /// + /// + /// If the is an abstract class, an interface, + /// an open generic type or does not have a public no-argument constructor. + /// + public static object InstantiateType(Type type) + { + AssertUtils.ArgumentNotNull(type, "type"); + + ConstructorInfo constructor = GetZeroArgConstructorInfo(type); + return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); + } + + /// + /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. + /// + /// The type. + /// Zero argument ConstructorInfo + /// + /// If the type is an interface, abstract, open generic type, or does not have a zero-arg constructor. + /// + public static ConstructorInfo GetZeroArgConstructorInfo(Type type) + { + IsInstantiable(type); + ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); + if (constructor == null) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a public no-argument constructor [{0}].", type)); + } + return constructor; + } + + /// + /// Determines whether the specified type is instantiable, i.e. not an interface, abstract class or contains + /// open generic type parameters. + /// + /// The type. + public static void IsInstantiable(Type type) + { + if (type.IsInterface) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", type)); + } + if (type.IsAbstract) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", type)); + } +#if NET_2_0 + if (type.ContainsGenericParameters) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", type)); + } +#endif + } + + /// + /// Convenience method to instantiate a using + /// the given constructor. + /// + /// + ///

+ /// As this method doesn't try to instantiate s + /// by name, it should avoid loading issues. + ///

+ ///
+ /// + /// The constructor to use for the instantiation. + /// + /// + /// The arguments to be passed to the constructor. + /// + /// A new instance. + /// + /// If the is + /// + /// + /// If the 's declaring type is an abstract class, + /// an interface, an open generic type or does not have a public no-argument constructor. + /// + public static object InstantiateType(ConstructorInfo constructor, object[] arguments) + { + AssertUtils.ArgumentNotNull(constructor, "constructor"); + + if (constructor.DeclaringType.IsInterface) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", constructor.DeclaringType)); + } + if (constructor.DeclaringType.IsAbstract) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", constructor.DeclaringType)); + } +#if NET_2_0 + if (constructor.DeclaringType.ContainsGenericParameters) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", constructor.DeclaringType)); + } +#endif + try + { + return constructor.Invoke(arguments); + } + catch (Exception ex) + { + Type ctorType = constructor.DeclaringType; + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, + "Cannot instantiate Type [{0}] using ctor [{1}] : '{2}'", + constructor.DeclaringType, constructor, ex.Message), + ex); + } + } + + /// + /// Checks whether the supplied is not a transparent proxy and is + /// assignable to the supplied . + /// + /// + ///

+ /// Neccessary when dealing with server-activated remote objects, because the + /// object is of the type TransparentProxy and regular is testing for assignable + /// types does not work. + ///

+ ///

+ /// Transparent proxy instances always return when tested + /// with the 'is' operator (C#). This method only checks if the object + /// is assignable to the type if it is not a transparent proxy. + ///

+ ///
+ /// The target to be checked. + /// The value that should be assigned to the type. + /// + /// if the supplied is not a + /// transparent proxy and is assignable to the supplied . + /// + public static bool IsAssignableAndNotTransparentProxy(Type type, object instance) + { + if (!RemotingServices.IsTransparentProxy(instance)) + { + return IsAssignable(type, instance); + } + return false; + } + + /// + /// Determine if the given is assignable from the + /// given value, assuming setting by reflection. + /// + /// + ///

+ /// Considers primitive wrapper classes as assignable to the + /// corresponding primitive types. + ///

+ ///

+ /// For example used in an object factory's constructor resolution. + ///

+ ///
+ /// The target . + /// The value that should be assigned to the type. + /// True if the type is assignable from the value. + public static bool IsAssignable(Type type, object obj) + { + return (type.IsInstanceOfType(obj) || + (!type.IsPrimitive && obj == null) || + (type.Equals(typeof (bool)) && obj is Boolean) || + (type.Equals(typeof (byte)) && obj is Byte) || + (type.Equals(typeof (char)) && obj is Char) || + (type.Equals(typeof (sbyte)) && obj is SByte) || + (type.Equals(typeof (int)) && obj is Int32) || + (type.Equals(typeof (short)) && obj is Int16) || + (type.Equals(typeof (long)) && obj is Int64) || + (type.Equals(typeof (float)) && obj is Single) || + (type.Equals(typeof (double)) && obj is Double)); + } + + /// + /// Check if the given represents a + /// "simple" property, + /// i.e. a primitive, a , a + /// , or a corresponding array. + /// + /// + ///

+ /// Used to determine properties to check for a "simple" dependency-check. + ///

+ ///
+ /// + /// The to check. + /// + public static bool IsSimpleProperty(Type type) + { + return type.IsPrimitive + || type.Equals(typeof (string)) + || type.Equals(typeof (string[])) + || IsPrimitiveArray(type) + || type.Equals(typeof (Type)) + || type.Equals(typeof (Type[])); + } + + /// + /// Check if the given class represents a primitive array, + /// i.e. boolean, byte, char, short, int, long, float, or double. + /// + public static bool IsPrimitiveArray(Type type) + { + return typeof (bool[]).Equals(type) + || typeof (sbyte[]).Equals(type) + || typeof (char[]).Equals(type) + || typeof (short[]).Equals(type) + || typeof (int[]).Equals(type) + || typeof (long[]).Equals(type) + || typeof (float[]).Equals(type) + || typeof (double[]).Equals(type); + } + + /// + /// Determine if the given objects are equal, returning + /// if both are respectively + /// if only one is . + /// + /// The first object to compare. + /// The second object to compare. + /// + /// if the given objects are equal. + /// + public static bool NullSafeEquals(object o1, object o2) + { + return (o1 == o2 || (o1 != null && o1.Equals(o2))); + } + + /// + /// Returns the first element in the supplied . + /// + /// + /// The to use to enumerate + /// elements. + /// + /// + /// The first element in the supplied . + /// + /// + /// If the supplied did not have any elements. + /// + public static object EnumerateFirstElement(IEnumerator enumerator) + { + return ObjectUtils.EnumerateElementAtIndex(enumerator, 0); + } + + /// + /// Returns the first element in the supplied . + /// + /// + /// The to use to enumerate + /// elements. + /// + /// + /// The first element in the supplied . + /// + /// + /// If the supplied did not have any elements. + /// + /// + /// If the supplied is . + /// + public static object EnumerateFirstElement(IEnumerable enumerable) + { + AssertUtils.ArgumentNotNull(enumerable, "enumerable"); + return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), 0); + } + + /// + /// Returns the element at the specified index using the supplied + /// . + /// + /// + /// The to use to enumerate + /// elements until the supplied is reached. + /// + /// + /// The index of the element in the enumeration to return. + /// + /// + /// The element at the specified index using the supplied + /// . + /// + /// + /// If the supplied was less than zero, or the + /// supplied did not contain enough elements + /// to be able to reach the supplied . + /// + public static object EnumerateElementAtIndex(IEnumerator enumerator, int index) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(); + } + object element = null; + int i = 0; + while (enumerator.MoveNext()) + { + element = enumerator.Current; + if (++i > index) + { + break; + } + } + if (i < index) + { + throw new ArgumentOutOfRangeException(); + } + return element; + } + + /// + /// Returns the element at the specified index using the supplied + /// . + /// + /// + /// The to use to enumerate + /// elements until the supplied is reached. + /// + /// + /// The index of the element in the enumeration to return. + /// + /// + /// The element at the specified index using the supplied + /// . + /// + /// + /// If the supplied was less than zero, or the + /// supplied did not contain enough elements + /// to be able to reach the supplied . + /// + /// + /// If the supplied is . + /// + public static object EnumerateElementAtIndex(IEnumerable enumerable, int index) + { + AssertUtils.ArgumentNotNull(enumerable, "enumerable"); + return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), index); + } + + #endregion + + /// + /// Gets the qualified name of the given method, consisting of + /// fully qualified interface/class name + "." method name. + /// + /// The method. + /// qualified name of the method. + public static string GetQualifiedMethodName(MethodInfo method) + { + AssertUtils.ArgumentNotNull(method,"method", "MethodInfo must not be null"); + return method.DeclaringType.FullName + "." + method.Name; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/PathMatcher.cs b/src/Spring/Spring.Core/Util/PathMatcher.cs index f604275e..76675acf 100644 --- a/src/Spring/Spring.Core/Util/PathMatcher.cs +++ b/src/Spring/Spring.Core/Util/PathMatcher.cs @@ -1,229 +1,228 @@ -//// -#region License - -/* -* Copyright © 2002-2005 the original author or authors. -* -* 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. -*/ - -#endregion - -#region Imports - -using System; -using System.Text; -using System.Text.RegularExpressions; - -#endregion - -namespace Spring.Util -{ - /// - /// Support matching of file system paths in a manner similar to that of the - /// NAnt FileSet. - /// - /// - ///

- /// Any (back)slashes are converted to forward slashes. - ///

- ///
- /// - /// - /// // true - /// PathMatcher.Match("c:/*.bat", @"c:\autoexec.bat"); - /// PathMatcher.Match("c:\fo*\*.bat", @"c:/foobar/autoexec.bat"); - /// PathMatcher.Match("c:\fo?\*.bat", @"c:/foo/autoexec.bat"); - /// // false - /// PathMatcher.Match("c:\fo?\*.bat", @"c:/fo/autoexec.bat"); - /// - /// - /// Federico Spinazzi - /// $Id: PathMatcher.cs,v 1.7 2007/02/23 18:46:41 markpollack Exp $ - public sealed class PathMatcher - { - private const string AllFilesInThisDirectory = "*.*"; - - /// - /// Determines if a given path matches a NAnt-like pattern. - /// - /// - /// A forward or back-slashed fileset-like pattern. - /// - /// A forward or back-slashed full path. - /// should the match consider the case - /// - /// if the path is matched by the pattern; - /// otherwise . - /// - //// - public static bool Match(string pattern, string path, bool ignoreCase) - //// - { - return Match(ToLower(pattern), ToLower(path)); - } - - /// - /// Determines if a given path matches a NAnt-like pattern. - /// - /// - /// A forward or back-slashed fileset-like pattern. - /// - /// A forward or back-slashed full path. - /// - /// if the path is matched by the pattern; - /// otherwise . - /// - //// - public static bool Match(string pattern, string path) - //// - { - pattern = ForwardifySlashes(pattern); - path = ForwardifySlashes(path); - - if (MatchAll(pattern)) - return true; - - String regex = BuildRegex(pattern); - return Regex.Match(path, regex).Success; - } - - /// - /// Replaces back(slashes) with forward slashes. - /// - /// - /// The path or the pattern to modify. - /// - /// A forward-slashed string. - public static string ForwardifySlashes(string path) - { - return path.Replace("\\", "/"); - } - - /// - /// Helper method to convert a NAnt-like pattern into the - /// appropriate pattern for a regular expression. - /// - /// The NAnt-like pattern. - /// A regex-compatible pattern. - public static String BuildRegex(string pattern) - { - if (AllFilesInThisDirectory.Equals(pattern)) - { - return "^[^/]*$"; - } - string[] parts = pattern.Split('/'); - int indexOfLastSplittedPart = parts.Length - 1; - int indexOfTheCurrentSplittedPart = 0; - StringBuilder regex = new StringBuilder(); - foreach (string currentSplittedPart in parts) - { - bool currentPartIsTheLast = indexOfTheCurrentSplittedPart == indexOfLastSplittedPart; - string partToAdd = currentSplittedPart; - switch (currentSplittedPart) - { - case "**": - partToAdd = TranslateDoubleAsterisk(currentPartIsTheLast); - break; - default: - partToAdd = TranslateDot(partToAdd); - partToAdd = TranslateAsterisk(partToAdd); - partToAdd = TranslateQuestionMark(partToAdd); - partToAdd = TranslateLiteral(partToAdd, currentPartIsTheLast); - break; - } - regex.Append(partToAdd); - indexOfTheCurrentSplittedPart++; - } - return regex.ToString(); - } - - private static string ToLower(string pattern) - { - return pattern == null ? pattern : pattern.ToLower(); - } - - private static string TranslateLiteral(string part, bool isLastPart) - { - if (isLastPart) - { - return part + "$"; - } - else - { - return part + "/?"; - } - } - - private static string TranslateDoubleAsterisk(bool isLastPart) - { - string slashTerminated = "(.*/?(?<=/))"; - if (isLastPart) - slashTerminated = String.Format("($|(?<=/){0}*)", slashTerminated); - return slashTerminated; - } - - private static string TranslateQuestionMark(string thisPart) - { - return thisPart.Replace("?", "[^./]"); - } - - private static string TranslateAsterisk(string thisPart) - { - return thisPart.Replace("*", "[^/]*"); - } - - private static string TranslateDot(string thisPart) - { - return thisPart.Replace(".", @"\."); - } - - private static bool MatchAll(string pattern) - { - if (AllFilesInThisDirectory.Equals(pattern)) - { - return false; - } - - foreach (char c in pattern) - { - if (c != '*' && c != '/' && c != '.') - { - return false; - } - } - return true; - } - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private PathMatcher() - { - } - - // CLOVER:ON - - #endregion - } -} +//// +#region License + +/* +* Copyright © 2002-2005 the original author or authors. +* +* 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. +*/ + +#endregion + +#region Imports + +using System; +using System.Text; +using System.Text.RegularExpressions; + +#endregion + +namespace Spring.Util +{ + /// + /// Support matching of file system paths in a manner similar to that of the + /// NAnt FileSet. + /// + /// + ///

+ /// Any (back)slashes are converted to forward slashes. + ///

+ ///
+ /// + /// + /// // true + /// PathMatcher.Match("c:/*.bat", @"c:\autoexec.bat"); + /// PathMatcher.Match("c:\fo*\*.bat", @"c:/foobar/autoexec.bat"); + /// PathMatcher.Match("c:\fo?\*.bat", @"c:/foo/autoexec.bat"); + /// // false + /// PathMatcher.Match("c:\fo?\*.bat", @"c:/fo/autoexec.bat"); + /// + /// + /// Federico Spinazzi + public sealed class PathMatcher + { + private const string AllFilesInThisDirectory = "*.*"; + + /// + /// Determines if a given path matches a NAnt-like pattern. + /// + /// + /// A forward or back-slashed fileset-like pattern. + /// + /// A forward or back-slashed full path. + /// should the match consider the case + /// + /// if the path is matched by the pattern; + /// otherwise . + /// + //// + public static bool Match(string pattern, string path, bool ignoreCase) + //// + { + return Match(ToLower(pattern), ToLower(path)); + } + + /// + /// Determines if a given path matches a NAnt-like pattern. + /// + /// + /// A forward or back-slashed fileset-like pattern. + /// + /// A forward or back-slashed full path. + /// + /// if the path is matched by the pattern; + /// otherwise . + /// + //// + public static bool Match(string pattern, string path) + //// + { + pattern = ForwardifySlashes(pattern); + path = ForwardifySlashes(path); + + if (MatchAll(pattern)) + return true; + + String regex = BuildRegex(pattern); + return Regex.Match(path, regex).Success; + } + + /// + /// Replaces back(slashes) with forward slashes. + /// + /// + /// The path or the pattern to modify. + /// + /// A forward-slashed string. + public static string ForwardifySlashes(string path) + { + return path.Replace("\\", "/"); + } + + /// + /// Helper method to convert a NAnt-like pattern into the + /// appropriate pattern for a regular expression. + /// + /// The NAnt-like pattern. + /// A regex-compatible pattern. + public static String BuildRegex(string pattern) + { + if (AllFilesInThisDirectory.Equals(pattern)) + { + return "^[^/]*$"; + } + string[] parts = pattern.Split('/'); + int indexOfLastSplittedPart = parts.Length - 1; + int indexOfTheCurrentSplittedPart = 0; + StringBuilder regex = new StringBuilder(); + foreach (string currentSplittedPart in parts) + { + bool currentPartIsTheLast = indexOfTheCurrentSplittedPart == indexOfLastSplittedPart; + string partToAdd = currentSplittedPart; + switch (currentSplittedPart) + { + case "**": + partToAdd = TranslateDoubleAsterisk(currentPartIsTheLast); + break; + default: + partToAdd = TranslateDot(partToAdd); + partToAdd = TranslateAsterisk(partToAdd); + partToAdd = TranslateQuestionMark(partToAdd); + partToAdd = TranslateLiteral(partToAdd, currentPartIsTheLast); + break; + } + regex.Append(partToAdd); + indexOfTheCurrentSplittedPart++; + } + return regex.ToString(); + } + + private static string ToLower(string pattern) + { + return pattern == null ? pattern : pattern.ToLower(); + } + + private static string TranslateLiteral(string part, bool isLastPart) + { + if (isLastPart) + { + return part + "$"; + } + else + { + return part + "/?"; + } + } + + private static string TranslateDoubleAsterisk(bool isLastPart) + { + string slashTerminated = "(.*/?(?<=/))"; + if (isLastPart) + slashTerminated = String.Format("($|(?<=/){0}*)", slashTerminated); + return slashTerminated; + } + + private static string TranslateQuestionMark(string thisPart) + { + return thisPart.Replace("?", "[^./]"); + } + + private static string TranslateAsterisk(string thisPart) + { + return thisPart.Replace("*", "[^/]*"); + } + + private static string TranslateDot(string thisPart) + { + return thisPart.Replace(".", @"\."); + } + + private static bool MatchAll(string pattern) + { + if (AllFilesInThisDirectory.Equals(pattern)) + { + return false; + } + + foreach (char c in pattern) + { + if (c != '*' && c != '/' && c != '.') + { + return false; + } + } + return true; + } + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private PathMatcher() + { + } + + // CLOVER:ON + + #endregion + } +} ////
\ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/PatternMatchUtils.cs b/src/Spring/Spring.Core/Util/PatternMatchUtils.cs index 74a53a7d..c577ce0e 100644 --- a/src/Spring/Spring.Core/Util/PatternMatchUtils.cs +++ b/src/Spring/Spring.Core/Util/PatternMatchUtils.cs @@ -1,99 +1,98 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Text.RegularExpressions; - -#endregion - -namespace Spring.Util -{ - /// Utility methods for simple pattern matching, in particular for - /// Spring's typical "xxx*", "*xxx" and "*xxx*" pattern styles. - /// - /// Juergen Hoeller - /// Mark Pollack - /// $Id: PatternMatchUtils.cs,v 1.4 2007/07/31 18:16:25 bbaia Exp $ - public abstract class PatternMatchUtils - { - /// Match a String against the given pattern, supporting the following simple - /// pattern styles: "xxx*", "*xxx" and "*xxx*" matches, as well as direct equality. - /// - /// the pattern to match against - /// - /// the String to match - /// - /// whether the String matches the given pattern - /// - public static bool SimpleMatch(System.String pattern, System.String str) - { - if (ObjectUtils.NullSafeEquals(pattern, str) || "*".Equals(pattern)) - { - return true; - } - if (pattern == null || str == null) - { - return false; - } - if (pattern.StartsWith("*") && pattern.EndsWith("*") && - str.IndexOf(pattern.Substring(1, (pattern.Length - 1) - (1))) != -1) - { - return true; - } - if (pattern.StartsWith("*") && str.EndsWith(pattern.Substring(1, (pattern.Length) - (1)))) - { - return true; - } - if (pattern.EndsWith("*") && str.StartsWith(pattern.Substring(0, (pattern.Length - 1) - (0)))) - { - return true; - } - return false; - } - - /// Match a String against the given patterns, supporting the following simple - /// pattern styles: "xxx*", "*xxx" and "*xxx*" matches, as well as direct equality. - /// - /// the patterns to match against - /// - /// the String to match - /// - /// whether the String matches any of the given patterns - /// - public static bool SimpleMatch(System.String[] patterns, System.String str) - { - if (patterns != null) - { - for (int i = 0; i < patterns.Length; i++) - { - - if (SimpleMatch(patterns[i], str)) - { - return true; - } - } - } - return false; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Text.RegularExpressions; + +#endregion + +namespace Spring.Util +{ + /// Utility methods for simple pattern matching, in particular for + /// Spring's typical "xxx*", "*xxx" and "*xxx*" pattern styles. + /// + /// Juergen Hoeller + /// Mark Pollack + public abstract class PatternMatchUtils + { + /// Match a String against the given pattern, supporting the following simple + /// pattern styles: "xxx*", "*xxx" and "*xxx*" matches, as well as direct equality. + /// + /// the pattern to match against + /// + /// the String to match + /// + /// whether the String matches the given pattern + /// + public static bool SimpleMatch(System.String pattern, System.String str) + { + if (ObjectUtils.NullSafeEquals(pattern, str) || "*".Equals(pattern)) + { + return true; + } + if (pattern == null || str == null) + { + return false; + } + if (pattern.StartsWith("*") && pattern.EndsWith("*") && + str.IndexOf(pattern.Substring(1, (pattern.Length - 1) - (1))) != -1) + { + return true; + } + if (pattern.StartsWith("*") && str.EndsWith(pattern.Substring(1, (pattern.Length) - (1)))) + { + return true; + } + if (pattern.EndsWith("*") && str.StartsWith(pattern.Substring(0, (pattern.Length - 1) - (0)))) + { + return true; + } + return false; + } + + /// Match a String against the given patterns, supporting the following simple + /// pattern styles: "xxx*", "*xxx" and "*xxx*" matches, as well as direct equality. + /// + /// the patterns to match against + /// + /// the String to match + /// + /// whether the String matches any of the given patterns + /// + public static bool SimpleMatch(System.String[] patterns, System.String str) + { + if (patterns != null) + { + for (int i = 0; i < patterns.Length; i++) + { + + if (SimpleMatch(patterns[i], str)) + { + return true; + } + } + } + return false; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/Properties.cs b/src/Spring/Spring.Core/Util/Properties.cs index 6a10b56f..c61b9725 100644 --- a/src/Spring/Spring.Core/Util/Properties.cs +++ b/src/Spring/Spring.Core/Util/Properties.cs @@ -1,325 +1,324 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.IO; - -#endregion - -namespace Spring.Util -{ - /// - /// An implementation of the Java Properties class. - /// - /// Simon White - /// $Id: Properties.cs,v 1.16 2007/07/31 18:16:26 bbaia Exp $ - [Serializable] - public class Properties : Hashtable - { - #region Constants - - private const string Comments = "#!"; - private const string Separators = ":="; - private const string Whitespace = " \t\r\n"; - private const string WhitespaceWithSeparators = Whitespace + Separators; - - #endregion - - #region Constructor (s) / Destructor - - /// - /// Creates an empty property list with no default values. - /// - public Properties() - { - } - - /// - /// Creates a property list with the specified initial properties. - /// - /// The initial properties. - public Properties(Properties p) : base(p) - { - } - - #endregion - - #region Methods - - /// - /// Reads a property list (key and element pairs) from the input stream. - /// - /// The stream to load from. - public void Load(Stream stream) - { - Load(this, stream); - } - - /// - /// Reads a property list (key and element pairs) from a text reader. - /// - /// The text reader to load from. - public void Load(TextReader textReader) - { - Load(this, textReader); - } - - /// - /// Reads a property list (key and element pairs) from the input stream. - /// - /// the dictionary to put it in - /// The stream to load from. - public static void Load(IDictionary dictionary, Stream stream) - { - using (StreamReader streamReader = new StreamReader(stream)) - { - Load(dictionary, streamReader); - } - } - - /// - /// Reads a property list (key and element pairs) from a text reader. - /// - /// the dictionary to put it in - /// The text reader to load from. - public static void Load(IDictionary dictionary, TextReader textReader) - { - bool isContinuation = false; - string key = null; - string value = null; - string line = null; - while ((line = textReader.ReadLine()) != null) - { - line = RemoveLeadingWhitespace(line); - if (line != null && Comments.IndexOf(line[0]) == -1) - { - if (!isContinuation) - { - string[] keyvalue = SplitLine(line); - if (keyvalue == null) - { - continue; - } - key = keyvalue[0]; - value = keyvalue[1]; - - if (value.EndsWith("\\")) - { - value = value.Substring(0, value.Length - 1); - isContinuation = true; - } - else - { - dictionary[key] = StringUtils.ConvertEscapedCharacters(value); - } - } - else - { - if (line.EndsWith("\\")) - { - value += line.Substring(0, line.Length - 1); - } - else - { - value += line; - isContinuation = false; - dictionary[key] = StringUtils.ConvertEscapedCharacters(value); - } - } - } - } - } - - /// - /// Strips whitespace from the front of the specified string. - /// - /// The string. - /// The string with all leading whitespace removed. - private static string RemoveLeadingWhitespace(string line) - { - string trimmed = null; - for (int i = 0; i < line.Length; i++) - { - if (Whitespace.IndexOf(line[i]) == -1) - { - trimmed = line.Substring(i); - break; - } - } - return trimmed; - } - - /// - /// Splits the specified string into a key / value pair. - /// - /// The line to split. - /// An array containing the key / value pair. - private static string[] SplitLine(string line) - { - string key = null; - string value = null; - - int index = 0; - int len = line.Length; - for (; index < len; index++) - { - if (WhitespaceWithSeparators.IndexOf(line[index]) != -1) - { - if (line[index - 1].Equals('\\')) - { - line = line.Remove(index - 1, 1); - len--; - index--; - } - else - { - key = line.Substring(0, index); - break; - } - } - } - - // got key, now find the start of the value - // first ignore leading whitespace and initial separator - // (if one's there) - index++; - if (index >= len) - { - return null; - } - value = line.Substring(index); - value = RemoveLeadingWhitespace(value); - - if (Separators.IndexOf(value[0]) != -1) - { - value = value.Substring(1); - value = RemoveLeadingWhitespace(value); - } - - return new string[] {key, value}; - } - - /// - /// Searches for the property with the specified key in this property list. - /// - /// The key. - /// The property, or null if the key was not found. - public string GetProperty(string key) - { - return this[key] as string; - } - - /// - /// Searches for the property with the specified key in this property list. - /// - /// The key. - /// - /// The default value to be returned if the key is not found. - /// - /// The property, or the default value. - public string GetProperty(string key, string def) - { - string val = this[key] as string; - return (val != null ? val : def); - } - - /// - /// Writes this property list out to the specified stream. - /// - /// The stream to write to. - public void List(Stream stream) - { - using (StreamWriter sw = new StreamWriter(stream)) - { - foreach (DictionaryEntry de in this) - { - sw.WriteLine(de.Key + "=" + de.Value); - } - } - } - - /// - /// Sets the specified property key / value pair. - /// - /// The key. - /// The value. - public void SetProperty(string key, string theValue) - { - this[key] = theValue; - } - - /// - /// Writes the properties in this instance out to the supplied stream. - /// - /// The stream to write to. - /// Arbitrary header information. - public void Store(Stream stream, string header) - { - using (StreamWriter sw = new StreamWriter(stream)) - { - sw.WriteLine(header); - - foreach (DictionaryEntry de in this) - { - sw.WriteLine(de.Key + "=" + de.Value); - } - } - } - - #endregion - - #region IDictionary Members - - /// - /// Adds the specified key / object pair to this collection. - /// - public override object this[object key] - { - get { return base[key as string]; } - set { base[key as string] = value as string; } - } - - /// - /// Removes the key / value pair identified by the supplied key. - /// - /// - /// The key identifying the key / value pair to be removed. - /// - public override void Remove(object key) - { - base.Remove(key as string); - } - - /// - /// Adds the specified key / object pair to this collection. - /// - /// The key. - /// The value. - public override void Add(object key, object value) - { - base.Add(key as string, value as string); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.IO; + +#endregion + +namespace Spring.Util +{ + /// + /// An implementation of the Java Properties class. + /// + /// Simon White + [Serializable] + public class Properties : Hashtable + { + #region Constants + + private const string Comments = "#!"; + private const string Separators = ":="; + private const string Whitespace = " \t\r\n"; + private const string WhitespaceWithSeparators = Whitespace + Separators; + + #endregion + + #region Constructor (s) / Destructor + + /// + /// Creates an empty property list with no default values. + /// + public Properties() + { + } + + /// + /// Creates a property list with the specified initial properties. + /// + /// The initial properties. + public Properties(Properties p) : base(p) + { + } + + #endregion + + #region Methods + + /// + /// Reads a property list (key and element pairs) from the input stream. + /// + /// The stream to load from. + public void Load(Stream stream) + { + Load(this, stream); + } + + /// + /// Reads a property list (key and element pairs) from a text reader. + /// + /// The text reader to load from. + public void Load(TextReader textReader) + { + Load(this, textReader); + } + + /// + /// Reads a property list (key and element pairs) from the input stream. + /// + /// the dictionary to put it in + /// The stream to load from. + public static void Load(IDictionary dictionary, Stream stream) + { + using (StreamReader streamReader = new StreamReader(stream)) + { + Load(dictionary, streamReader); + } + } + + /// + /// Reads a property list (key and element pairs) from a text reader. + /// + /// the dictionary to put it in + /// The text reader to load from. + public static void Load(IDictionary dictionary, TextReader textReader) + { + bool isContinuation = false; + string key = null; + string value = null; + string line = null; + while ((line = textReader.ReadLine()) != null) + { + line = RemoveLeadingWhitespace(line); + if (line != null && Comments.IndexOf(line[0]) == -1) + { + if (!isContinuation) + { + string[] keyvalue = SplitLine(line); + if (keyvalue == null) + { + continue; + } + key = keyvalue[0]; + value = keyvalue[1]; + + if (value.EndsWith("\\")) + { + value = value.Substring(0, value.Length - 1); + isContinuation = true; + } + else + { + dictionary[key] = StringUtils.ConvertEscapedCharacters(value); + } + } + else + { + if (line.EndsWith("\\")) + { + value += line.Substring(0, line.Length - 1); + } + else + { + value += line; + isContinuation = false; + dictionary[key] = StringUtils.ConvertEscapedCharacters(value); + } + } + } + } + } + + /// + /// Strips whitespace from the front of the specified string. + /// + /// The string. + /// The string with all leading whitespace removed. + private static string RemoveLeadingWhitespace(string line) + { + string trimmed = null; + for (int i = 0; i < line.Length; i++) + { + if (Whitespace.IndexOf(line[i]) == -1) + { + trimmed = line.Substring(i); + break; + } + } + return trimmed; + } + + /// + /// Splits the specified string into a key / value pair. + /// + /// The line to split. + /// An array containing the key / value pair. + private static string[] SplitLine(string line) + { + string key = null; + string value = null; + + int index = 0; + int len = line.Length; + for (; index < len; index++) + { + if (WhitespaceWithSeparators.IndexOf(line[index]) != -1) + { + if (line[index - 1].Equals('\\')) + { + line = line.Remove(index - 1, 1); + len--; + index--; + } + else + { + key = line.Substring(0, index); + break; + } + } + } + + // got key, now find the start of the value + // first ignore leading whitespace and initial separator + // (if one's there) + index++; + if (index >= len) + { + return null; + } + value = line.Substring(index); + value = RemoveLeadingWhitespace(value); + + if (Separators.IndexOf(value[0]) != -1) + { + value = value.Substring(1); + value = RemoveLeadingWhitespace(value); + } + + return new string[] {key, value}; + } + + /// + /// Searches for the property with the specified key in this property list. + /// + /// The key. + /// The property, or null if the key was not found. + public string GetProperty(string key) + { + return this[key] as string; + } + + /// + /// Searches for the property with the specified key in this property list. + /// + /// The key. + /// + /// The default value to be returned if the key is not found. + /// + /// The property, or the default value. + public string GetProperty(string key, string def) + { + string val = this[key] as string; + return (val != null ? val : def); + } + + /// + /// Writes this property list out to the specified stream. + /// + /// The stream to write to. + public void List(Stream stream) + { + using (StreamWriter sw = new StreamWriter(stream)) + { + foreach (DictionaryEntry de in this) + { + sw.WriteLine(de.Key + "=" + de.Value); + } + } + } + + /// + /// Sets the specified property key / value pair. + /// + /// The key. + /// The value. + public void SetProperty(string key, string theValue) + { + this[key] = theValue; + } + + /// + /// Writes the properties in this instance out to the supplied stream. + /// + /// The stream to write to. + /// Arbitrary header information. + public void Store(Stream stream, string header) + { + using (StreamWriter sw = new StreamWriter(stream)) + { + sw.WriteLine(header); + + foreach (DictionaryEntry de in this) + { + sw.WriteLine(de.Key + "=" + de.Value); + } + } + } + + #endregion + + #region IDictionary Members + + /// + /// Adds the specified key / object pair to this collection. + /// + public override object this[object key] + { + get { return base[key as string]; } + set { base[key as string] = value as string; } + } + + /// + /// Removes the key / value pair identified by the supplied key. + /// + /// + /// The key identifying the key / value pair to be removed. + /// + public override void Remove(object key) + { + base.Remove(key as string); + } + + /// + /// Adds the specified key / object pair to this collection. + /// + /// The key. + /// The value. + public override void Add(object key, object value) + { + base.Add(key as string, value as string); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/ReflectionException.cs b/src/Spring/Spring.Core/Util/ReflectionException.cs index 5c069dc3..84451288 100644 --- a/src/Spring/Spring.Core/Util/ReflectionException.cs +++ b/src/Spring/Spring.Core/Util/ReflectionException.cs @@ -1,89 +1,87 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Util -{ - /// - /// Superclass for all exceptions thrown in the Objects namespace and sub-namespaces. - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: ReflectionException.cs,v 1.1 2007/07/31 03:47:23 markpollack Exp $ - /// - [Serializable] - public class ReflectionException : ApplicationException - { - #region Constructor (s) / Destructor - /// Creates a new instance of the ObjectsException class. - public ReflectionException() - { - } - - /// - /// Creates a new instance of the ObjectsException class. with the specified message. - /// - /// - /// A message about the exception. - /// - public ReflectionException (string message) : base(message) - { - } - - /// - /// Creates a new instance of the ObjectsException class with the specified message - /// and root cause. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public ReflectionException (string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the ObjectsException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ReflectionException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Util +{ + /// + /// Superclass for all exceptions thrown in the Objects namespace and sub-namespaces. + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class ReflectionException : ApplicationException + { + #region Constructor (s) / Destructor + /// Creates a new instance of the ObjectsException class. + public ReflectionException() + { + } + + /// + /// Creates a new instance of the ObjectsException class. with the specified message. + /// + /// + /// A message about the exception. + /// + public ReflectionException (string message) : base(message) + { + } + + /// + /// Creates a new instance of the ObjectsException class with the specified message + /// and root cause. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public ReflectionException (string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the ObjectsException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ReflectionException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/ReflectionUtils.cs b/src/Spring/Spring.Core/Util/ReflectionUtils.cs index f0c07c7b..6e4637aa 100644 --- a/src/Spring/Spring.Core/Util/ReflectionUtils.cs +++ b/src/Spring/Spring.Core/Util/ReflectionUtils.cs @@ -1,1474 +1,1472 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -#if NET_2_0 -using System.Collections.Generic; -using System.Collections.ObjectModel; -#endif -using System.Globalization; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Runtime.CompilerServices; - -#endregion - -namespace Spring.Util -{ - /// - /// Various reflection related methods that are missing from the standard library. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Aleksandar Seovic (.NET) - /// Stan Dvoychenko (.NET) - /// Bruno Baia (.NET) - /// $Id: ReflectionUtils.cs,v 1.59 2008/05/13 14:22:46 oakinger Exp $ - public sealed class ReflectionUtils - { - /// - /// Convenience value that will - /// match all private and public, static and instance members on a class - /// in a case inSenSItivE fashion. - /// - public const BindingFlags AllMembersCaseInsensitiveFlags = BindingFlags.Public | - BindingFlags.NonPublic | BindingFlags.Instance - | BindingFlags.Static - | BindingFlags.IgnoreCase; - - /// - /// Returns signature for the specified , method name and argument - /// s. - /// - /// The the method is in. - /// The method name. - /// - /// The argument s. - /// - /// The method signature. - public static string GetSignature( - Type type, string method, Type[] argumentTypes) - { - StringBuilder sb = new StringBuilder(); - sb.Append(type.FullName).Append("::").Append(method).Append("("); - string separator = ""; - for (int i = 0; i < argumentTypes.Length; i++) - { - sb.Append(separator).Append(argumentTypes[i].FullName); - separator = ","; - } - sb.Append(")"); - return sb.ToString(); - } - - - /// - /// Returns method for the specified , method - /// name and argument - /// s. - /// - /// Searches with BindingFlags - /// - /// The target to find the method on. - /// - /// The method to find. - /// - /// The argument s. May be - /// if the method has no arguments. - /// - /// The target method. - public static MethodInfo GetMethod( - Type targetType, string method, Type[] argumentTypes) - { - AssertUtils.ArgumentNotNull(targetType, "Type must not be null"); - // try method exactly as specified first... - MethodInfo retMethod = targetType.GetMethod( - method, - ReflectionUtils.AllMembersCaseInsensitiveFlags, - null, - argumentTypes == null ? Type.EmptyTypes : argumentTypes, - null); - - if (retMethod == null) - { - // try explicit interface implementation... - int idx = method.LastIndexOf('.'); - if (idx > -1) - { - method = method.Substring(idx + 1); - retMethod = ReflectionUtils.GetMethod(targetType, method, argumentTypes); - } - } - return retMethod; - } - - /// - /// Returns an array of parameter s for the specified method - /// or constructor. - /// - /// The method (or constructor). - /// An array containing the parameter s. - /// - /// If is . - /// - public static Type[] GetParameterTypes(MethodBase method) - { - AssertUtils.ArgumentNotNull(method, "method"); - return GetParameterTypes(method.GetParameters()); - } - - /// - /// Returns an array of parameter s for the - /// specified parameter info array. - /// - /// The parameter info array. - /// An array containing parameter s. - /// - /// If is or any of the - /// elements is . - /// - public static Type[] GetParameterTypes(ParameterInfo[] args) - { - AssertUtils.ArgumentNotNull(args, "args"); - Type[] types = new Type[args.Length]; - for (int i = 0; i < args.Length; i++) - { - types[i] = args[i].ParameterType; - } - return types; - } - -#if NET_2_0 - /// - /// Returns an array of s that represent - /// the names of the generic type parameter. - /// - /// The method. - /// An array containing the parameter names. - /// - /// If is . - /// - public static string[] GetGenericParameterNames(MethodInfo method) - { - AssertUtils.ArgumentNotNull(method, "method"); - return GetGenericParameterNames(method.GetGenericArguments()); - } - - /// - /// Returns an array of s that represent - /// the names of the generic type parameter. - /// - /// The parameter info array. - /// An array containing parameter names. - /// - /// If is or any of the - /// elements is . - /// - public static string[] GetGenericParameterNames(Type[] args) - { - AssertUtils.ArgumentNotNull(args, "args"); - string[] names = new string[args.Length]; - for (int i = 0; i < args.Length; i++) - { - names[i] = args[i].Name; - } - return names; - } -#endif - - /// - /// From a given list of methods, selects the method having an exact match on the given ' types. - /// - /// the list of methods to choose from - /// the arguments to the method - /// the method matching exactly the passed ' types - /// - /// If more than 1 matching methods are found in the list. - /// - public static MethodInfo GetMethodByArgumentValues(MethodInfo[] methods, object[] argValues) - { - return (MethodInfo)GetMethodBaseByArgumentValues("method", methods, argValues); - } - - /// - /// From a given list of methods, selects the method having an exact match on the given ' types. - /// - /// the type of method (used for exception reporting only) - /// the list of methods to choose from - /// the arguments to the method - /// the method matching exactly the passed ' types - /// - /// If more than 1 matching methods are found in the list. - /// - private static MethodBase GetMethodBaseByArgumentValues(string methodTypeName, MethodBase[] methods, - object[] argValues) - { - MethodBase match = null; - int matchCount = 0; - - foreach (MethodBase m in methods) - { - ParameterInfo[] parameters = m.GetParameters(); - bool isMatch = true; - bool isExactMatch = true; - object[] paramValues = argValues; - - try - { - if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) - { - paramValues = - PackageParamArray(argValues, parameters.Length, - lastParameter.ParameterType.GetElementType()); - } - } - - for (int i = 0; i < parameters.Length; i++) - { - Type paramType = parameters[i].ParameterType; - object paramValue = paramValues[i]; - if ((paramValue == null && paramType.IsValueType) - || (paramValue != null && !paramType.IsAssignableFrom(paramValue.GetType()))) - { - isMatch = false; - break; - } - if (paramValue == null || paramType != paramValue.GetType()) - { - isExactMatch = false; - } - } - } - catch (InvalidCastException) - { - isMatch = false; - } - - if (isMatch) - { - if (isExactMatch) - { - return m; - } - - matchCount++; - if (matchCount == 1) - { - match = m; - } - else - { - throw new AmbiguousMatchException( - string.Format("Ambiguous match for {0} '{1}' for the specified number and types of arguments.", methodTypeName, - m.Name)); - } - } - } - - return match; - } - - /// - /// From a given list of constructors, selects the constructor having an exact match on the given ' types. - /// - /// the list of constructors to choose from - /// the arguments to the method - /// the constructor matching exactly the passed ' types - /// - /// If more than 1 matching methods are found in the list. - /// - public static ConstructorInfo GetConstructorByArgumentValues(ConstructorInfo[] methods, object[] argValues) - { - return (ConstructorInfo)GetMethodBaseByArgumentValues("constructor", methods, argValues); - } - - - /// - /// Packages arguments into argument list containing parameter array as a last argument. - /// - /// Argument vaklues to package. - /// Total number of oarameters. - /// Type of the param array element. - /// Packaged arguments. - public static object[] PackageParamArray(object[] argValues, int argCount, Type elementType) - { - object[] values = new object[argCount]; - int i = 0; - - // copy regular arguments - while (i < argCount - 1) - { - values[i] = argValues[i]; - i++; - } - - // package param array into last argument - Array paramArray = Array.CreateInstance(elementType, argValues.Length - i); - int j = 0; - while (i < argValues.Length) - { - paramArray.SetValue(argValues[i++], j++); - } - values[values.Length - 1] = paramArray; - - return values; - } - - /// - /// Convenience method to convert an interface - /// to a array that contains - /// all the interfaces inherited and the specified interface. - /// - /// The interface to convert. - /// An array of interface s. - /// - /// If the specified is not an interface. - /// - /// - /// If is . - /// - public static Type[] ToInterfaceArray(Type intf) - { - AssertUtils.ArgumentNotNull(intf, "intf"); - - if (!intf.IsInterface) - { - throw new ArgumentException( - string.Format(CultureInfo.InvariantCulture, - "[{0}] is a class.", - intf.FullName)); - } - - ArrayList interfaces = new ArrayList(intf.GetInterfaces()); - interfaces.Add(intf); - - return (Type[])interfaces.ToArray(typeof(Type)); - } - - /// - /// Is the supplied the default indexer for the - /// supplied ? - /// - /// - /// The name of the property on the supplied to be checked. - /// - /// - /// The to be checked. - /// - /// - /// if the supplied is the - /// default indexer for the supplied . - /// - /// - /// If the supplied is . - /// - public static bool PropertyIsIndexer(string propertyName, Type type) - { - DefaultMemberAttribute[] attribs = - (DefaultMemberAttribute[])type.GetCustomAttributes(typeof(DefaultMemberAttribute), true); - if (attribs.Length != 0) - { - foreach (DefaultMemberAttribute attrib in attribs) - { - if (attrib.MemberName.Equals(propertyName)) - { - return true; - } - } - } - return false; - } - - /// - /// Is the supplied declared on one of these interfaces? - /// - /// The method to check. - /// The array of interfaces we want to check. - /// - /// if the method is declared on one of these interfaces. - /// - /// - /// If any of the s specified is not an interface. - /// - /// - /// If or any of the specified interfaces is - /// . - /// - public static bool MethodIsOnOneOfTheseInterfaces(MethodBase method, Type[] interfaces) - { - AssertUtils.ArgumentNotNull(method, "method"); - if (interfaces == null) - { - return false; - } - Type[] paramTypes = GetParameterTypes(method.GetParameters()); - for (int i = 0; i < interfaces.Length; i++) - { - Type interfaceType = interfaces[i]; - AssertUtils.ArgumentNotNull(interfaceType, StringUtils.Surround("interfaces[", i, "]")); - if (!interfaceType.IsInterface) - { - throw new ArgumentException(interfaces[i].FullName + " is not an interface"); - } - try - { - MethodInfo mi = interfaceType.GetMethod( - method.Name, - BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, - null, paramTypes, null); - if (mi != null) - { - // found it... - return true; - } - } - catch - { - // didn't find it, so keep going... - } - } - return false; - } - - /// - /// Returns the default value for the specified - /// - /// - ///

- /// Follows the standard .NET conventions for default values where - /// relevant; for example, all numeric types default to the value - /// 0. - ///

- ///
- /// - /// The to return default value for. - /// - /// - /// The default value for the specified . - /// - /// - /// If the supplied is an enumerated type that - /// has no values. - /// - public static object GetDefaultValue(Type type) - { - if (!type.IsValueType) - { - return null; - } - if (type == typeof(Boolean)) - { - return false; - } - if (type == typeof(DateTime)) - { - return DateTime.MinValue; - } - if (type == typeof(Char)) - { - return Char.MinValue; - } - if (type.IsEnum) - { - Array values = Enum.GetValues(type); - if (values == null || values.Length == 0) - { - throw new ArgumentException("Bad 'enum' Type : cannot get default value because 'enum' has no values."); - } - return values.GetValue(0); - } - return 0; - } - - /// - /// Returns an array consisting of the default values for the supplied - /// . - /// - /// - /// The array of s to return default values for. - /// - /// - /// An array consisting of the default values for the supplied - /// . - /// - /// - /// If any of the elements in the supplied - /// array is an enumerated type that has no values. - /// - /// - public static object[] GetDefaultValues(Type[] types) - { - object[] defaults = new object[types.Length]; - for (int i = 0; i < types.Length; ++i) - { - defaults[i] = GetDefaultValue(types[i]); - } - return defaults; - } - - /// - /// Checks that the parameter s of the - /// supplied match the parameter - /// s of the supplied - /// . - /// - /// The method to be checked. - /// - /// The array of parameter s to check against. - /// - /// - /// if the parameter s - /// match. - /// - public static bool ParameterTypesMatch( - MethodInfo candidate, Type[] parameterTypes) - { - #region Sanity Checks - - AssertUtils.ArgumentNotNull(candidate, "candidate"); - AssertUtils.ArgumentNotNull(parameterTypes, "parameterTypes"); - - #endregion - - Type[] candidatesParameterTypes - = ReflectionUtils.GetParameterTypes(candidate); - if (candidatesParameterTypes.Length != parameterTypes.Length) - { - return false; - } - for (int i = 0; i < candidatesParameterTypes.Length; ++i) - { - if (!candidatesParameterTypes[i].Equals(parameterTypes[i])) - { - return false; - } - } - return true; - } - - /// - /// Returns an array containing the s of the - /// objects in the supplied array. - /// - /// - /// The objects array for which the corresponding s - /// are needed. - /// - /// - /// An array containing the s of the objects - /// in the supplied array; this array will be empty (but not - /// if the supplied - /// is null or has no elements. - /// - /// - ///

- /// [C#]
- /// Given an array containing the following objects, - /// [83, "Foo", new object ()], the - /// array returned from this method call would consist of the following - /// elements... - /// [Int32, String, Object]. - ///

- ///
- public static Type[] GetTypes(object[] args) - { - if (args == null || args.Length == 0) - { - return Type.EmptyTypes; - } - Type[] paramsType = new Type[args.Length]; - for (int i = 0; i < args.Length; ++i) - { - object arg = args[i]; - paramsType[i] = (arg != null) ? args[i].GetType() : typeof(object); - } - return paramsType; - } - - /// - /// Does the given and/or it's superclasses - /// have at least one or more methods with the given name (with any - /// argument types)? - /// - /// - ///

- /// Includes non-public methods in the methods searched. - ///

- ///
- /// - /// The to be checked. - /// - /// - /// The name of the method to be searched for. Case inSenSItivE. - /// - /// - /// if the given or / and it's - /// superclasses have at least one or more methods (with any argument types); - /// if not, or either of the parameters is . - /// - public static bool HasAtLeastOneMethodWithName(Type type, string name) - { - if (type == null || StringUtils.IsNullOrEmpty(name)) - { - return false; - } - return MethodCountForName(type, name) > 0; - } - - /// - /// Within , counts the number of overloads for the method with the given (case-insensitive!) - /// - /// The type to be searched - /// the name of the method for which overloads shall be counted - /// The number of overloads for method within type - public static int MethodCountForName(Type type, string name) - { - AssertUtils.ArgumentNotNull(type, "type", "Type must not be null"); - AssertUtils.ArgumentNotNull(name, "name", "Method name must not be null"); - MemberInfo[] methods = type.FindMembers( - MemberTypes.Method, - ReflectionUtils.AllMembersCaseInsensitiveFlags, - new MemberFilter(ReflectionUtils.MethodNameFilter), - name); - return methods.Length; - } - - private static bool MethodNameFilter(MemberInfo member, object criteria) - { - MethodInfo method = member as MethodInfo; - string name = criteria as string; - return String.Compare(method.Name, name, true, CultureInfo.InvariantCulture) == 0; - } - - /// - /// Creates a . - /// - /// - ///

- /// Note that if a non- - /// is supplied, any read write properties exposed by the - /// will be used to overwrite values that may have been passed in via the - /// . That is, the will be used - /// to initialize the custom attribute, and then any read-write properties on the - /// will be plugged in. - ///

- ///
- /// - /// The desired . - /// - /// - /// Any constructor arguments for the attribute (may be - /// in the case of no arguments). - /// - /// - /// Source attribute to copy properties from (may be ). - /// - /// A custom attribute builder. - /// - /// If the parameter is . - /// - /// - /// If the parameter is not a - /// that derives from the class. - /// - /// - public static CustomAttributeBuilder CreateCustomAttribute( - Type type, object[] ctorArgs, Attribute sourceAttribute) - { - #region Sanity Checks - - AssertUtils.ArgumentNotNull(type, "type"); - if (!typeof(Attribute).IsAssignableFrom(type)) - { - throw new ArgumentException( - string.Format("[{0}] does not derive from the [System.Attribute] class.", - type.FullName)); - } - - #endregion - - ConstructorInfo ci = type.GetConstructor(ReflectionUtils.GetTypes(ctorArgs)); - if (ci == null && ctorArgs.Length == 0) - { - ci = type.GetConstructors()[0]; - ctorArgs = GetDefaultValues(GetParameterTypes(ci.GetParameters())); - } - - if (sourceAttribute != null) - { - object defaultAttribute = null; - try - { - defaultAttribute = ci.Invoke(ctorArgs); - } - catch - { - } - - IList getSetProps = new ArrayList(); - IList getSetValues = new ArrayList(); - IList readOnlyProps = new ArrayList(); - IList readOnlyValues = new ArrayList(); - foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) - { - if (pi.DeclaringType == typeof(Attribute)) - continue; - - if (pi.CanRead) - { - if (pi.CanWrite) - { - object propValue = pi.GetValue(sourceAttribute, null); - if (defaultAttribute != null) - { - object defaultValue = pi.GetValue(defaultAttribute, null); - if ((propValue == null && defaultValue == null) || - (propValue != null && propValue.Equals(defaultValue))) - continue; - } - getSetProps.Add(pi); - getSetValues.Add(propValue); - } - else - { - readOnlyProps.Add(pi); - readOnlyValues.Add(pi.GetValue(sourceAttribute, null)); - } - } - } - - if (readOnlyProps.Count == 1) - { - PropertyInfo pi = readOnlyProps[0] as PropertyInfo; - ConstructorInfo ciTemp = type.GetConstructor(new Type[1] { pi.PropertyType }); - if (ciTemp != null) - { - ci = ciTemp; - ctorArgs = new object[1] { readOnlyValues[0] }; - } - else - { - ciTemp = type.GetConstructor(new Type[1] { readOnlyValues[0].GetType() }); - if (ciTemp != null) - { - ci = ciTemp; - ctorArgs = new object[1] { readOnlyValues[0] }; - } - } - } - - PropertyInfo[] propertyInfos = new PropertyInfo[getSetProps.Count]; - getSetProps.CopyTo(propertyInfos, 0); - - object[] propertyValues = new object[getSetValues.Count]; - getSetValues.CopyTo(propertyValues, 0); - - return new CustomAttributeBuilder(ci, ctorArgs, propertyInfos, propertyValues); - } - else - { - return new CustomAttributeBuilder(ci, ctorArgs); - } - } - - /// - /// Creates a . - /// - /// - /// The desired . - /// - /// - /// Source attribute to copy properties from (may be ). - /// - /// A custom attribute builder. - public static CustomAttributeBuilder CreateCustomAttribute( - Type type, Attribute sourceAttribute) - { - return CreateCustomAttribute(type, new object[] { }, sourceAttribute); - } - - /// - /// Creates a . - /// - /// - /// The source attribute to copy properties from. - /// - /// A custom attribute builder. - /// - /// If the supplied is - /// . - /// - public static CustomAttributeBuilder CreateCustomAttribute(Attribute sourceAttribute) - { - return CreateCustomAttribute(sourceAttribute.GetType(), sourceAttribute); - } - - /// - /// Creates a . - /// - /// - /// The desired . - /// - /// A custom attribute builder. - public static CustomAttributeBuilder CreateCustomAttribute(Type type) - { - return CreateCustomAttribute(type, new object[] { }, null); - } - - /// - /// Creates a . - /// - /// - /// The desired . - /// - /// - /// Any constructor arguments for the attribute (may be - /// in the case of no arguments). - /// - /// A custom attribute builder. - public static CustomAttributeBuilder CreateCustomAttribute( - Type type, params object[] ctorArgs) - { - return CreateCustomAttribute(type, ctorArgs, null); - } - -#if NET_2_0 - /// - /// Creates a . - /// - /// - /// The to create - /// the custom attribute builder from. - /// - /// A custom attribute builder. - public static CustomAttributeBuilder CreateCustomAttribute(CustomAttributeData attributeData) - { - object[] parameterValues = new object[attributeData.ConstructorArguments.Count]; - Type[] parameterTypes = new Type[attributeData.ConstructorArguments.Count]; - - IList namedParameterValues = new ArrayList(); - IList namedFieldValues = new ArrayList(); - - // Fill arrays of the constructor parameters - for (int i = 0; i < attributeData.ConstructorArguments.Count; i++) - { - parameterTypes[i] = attributeData.ConstructorArguments[i].ArgumentType; - parameterValues[i] = ConvertValueIfNecessary(attributeData.ConstructorArguments[i].Value); - } - - Type attributeType = attributeData.Constructor.DeclaringType; - PropertyInfo[] attributeProperties = attributeType.GetProperties( - BindingFlags.Instance | BindingFlags.Public); - FieldInfo[] attributeFields = attributeType.GetFields( - BindingFlags.Instance | BindingFlags.Public); - - // Not using generics bellow as probably Spring.NET tries to keep - // it on .NET1 compatibility level right now I believe (SD) - // In case of using List the above note makes - // no sense (SD:) - IList propertiesToSet = new ArrayList(); - int k = 0; - - IList fieldsToSet = new ArrayList(); - int n = 0; - - - // Fills arrays of the constructor named parameters - foreach (CustomAttributeNamedArgument namedArgument in attributeData.NamedArguments) - { - bool noMatchingProperty = false; - - // Now iterate through all of the PropertyInfo, find the - // one with the corresponding to the NamedProperty name - // and add it to the array of properties to set. - for (int j = 0; j < attributeProperties.Length; j++) - { - if (attributeProperties[j].Name == namedArgument.MemberInfo.Name) - { - propertiesToSet.Add(attributeProperties[j]); - namedParameterValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value)); - break; - } - else - { - if (j == attributeProperties.Length - 1) - { - // In case of no match, throw - noMatchingProperty = true; - /* - throw new InvalidOperationException( - String.Format(CultureInfo.InvariantCulture, - "The property with name {0} can't be found in the " + - "type {1}, but is present as a named property " + - "on the attributeData {2}", namedArgument.MemberInfo.Name, - attributeType.FullName, attributeData)); - */ - } - } - } - if (noMatchingProperty) - { - for (int j = 0; j < attributeFields.Length; j++) - { - if (attributeFields[j].Name == namedArgument.MemberInfo.Name) - { - fieldsToSet.Add(attributeFields[j]); - namedFieldValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value)); - break; - } - else - { - if (j == attributeFields.Length - 1) - { - throw new InvalidOperationException( - String.Format(CultureInfo.InvariantCulture, - "A property or public field with name {0} can't be found in the " + - "type {1}, but is present as a named property " + - "on the attributeData {2}", namedArgument.MemberInfo.Name, - attributeType.FullName, attributeData)); - } - } - } - } - } - // Get constructor corresponding to the parameters and their types - ConstructorInfo constructor = attributeType.GetConstructor(parameterTypes); - - PropertyInfo[] namedProperties = new PropertyInfo[propertiesToSet.Count]; - propertiesToSet.CopyTo(namedProperties, 0); - - object[] propertyValues = new object[namedParameterValues.Count]; - namedParameterValues.CopyTo(propertyValues, 0); - - if (fieldsToSet.Count == 0) - { - return new CustomAttributeBuilder( - constructor, parameterValues, namedProperties, propertyValues); - } - else - { - FieldInfo[] namedFields = new FieldInfo[fieldsToSet.Count]; - fieldsToSet.CopyTo(namedFields, 0); - - object[] fieldValues = new object[namedFieldValues.Count]; - namedFieldValues.CopyTo(fieldValues, 0); - - return new CustomAttributeBuilder( - constructor, parameterValues, namedProperties, propertyValues, namedFields, fieldValues); - } - - - - } - - private static object ConvertValueIfNecessary(object value) - { - if (value == null) return value; - - // We are only hunting for the case of the ReadOnlyCollection here. - ReadOnlyCollection sourceArray = - value as ReadOnlyCollection; - - if (sourceArray == null) return value; - - Type underlyingType = null; // type to be used for arguments - Array returnArray = null; - for (int i = 0; i < sourceArray.Count; i++) - { - if (underlyingType == null) - { - underlyingType = sourceArray[i].ArgumentType; - returnArray = Array.CreateInstance(underlyingType, sourceArray.Count); - } - if (!underlyingType.Equals(sourceArray[i].ArgumentType)) - { - throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, - "Types for the same named parameter of array type are expected to be same")); - } - - returnArray.SetValue(sourceArray[i].Value, i); - } - - return returnArray; - - } -#endif - - /// - /// Tries to find matching methods in the specified - /// for each method in the supplied list. - /// - /// - /// The to look for matching methods in. - /// - /// The methods to match. - /// - /// A flag that specifies whether to throw an exception if a matching - /// method is not found. - /// - /// A list of the matched methods. - /// - /// If either of the or - /// parameters are . - /// - public static MethodInfo[] GetMatchingMethods(Type type, MethodInfo[] methods, bool strict) - { - AssertUtils.ArgumentNotNull(type, "type"); - AssertUtils.ArgumentNotNull(methods, "methods"); - - BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase; - - MethodInfo[] matched = new MethodInfo[methods.Length]; - for (int i = 0; i < methods.Length; i++) - { - MethodInfo method = methods[i]; - MethodInfo match = type.GetMethod(method.Name, flags, null, ReflectionUtils.GetParameterTypes(method), null); - if ((match == null || match.ReturnType != method.ReturnType) && strict) - { - throw new Exception( - string.Format("Method '{0}' could not be matched in the target class [{1}].", - method.Name, type.FullName)); - } - matched[i] = match; - } - return matched; - } - - /// - /// Returns the of the supplied - /// . - /// - /// - ///

- /// If the is a - /// instance, the return value of this method call with be the - /// parameter cast to a - /// . If the is - /// anything other than a , the return value - /// will be the result of invoking the 's - /// method. - ///

- ///
- /// - /// A or instance. - /// - /// - /// The argument if it is a - /// or the result of invoking - /// on the argument if it - /// is an . - /// - /// - /// If the is . - /// - public static Type TypeOfOrType(object source) - { - return source is Type ? source as Type : source.GetType(); - } - - -#if NET_2_0 - private static readonly MethodInfo Exception_InternalPreserveStackTrace = - typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic); -#else - private static readonly FieldInfo Exception_RemoteStackTraceString = - typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); -#endif - - /// - /// Unwraps the supplied - /// and returns the inner exception preserving the stack trace. - /// - /// - /// The to unwrap. - /// - /// The unwrapped exception. - public static Exception UnwrapTargetInvocationException(TargetInvocationException ex) - { -#if NET_2_0 - Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] { }); -#else - Exception_RemoteStackTraceString.SetValue(ex.InnerException, ex.InnerException.StackTrace + Environment.NewLine); -#endif - return ex.InnerException; - } - - /// - /// Is the supplied can be accessed outside the assembly ? - /// - /// The type to check. - /// - /// if the type can be accessed outside the assembly; - /// Otherwise . - /// - public static bool IsTypeVisible(Type type) - { - return IsTypeVisible(type, null); - } - - /// - /// Is the supplied can be accessed - /// from the supplied friendly assembly ? - /// - /// The type to check. - /// The friendly assembly name. - /// - /// if the type can be accessed - /// from the supplied friendly assembly; Otherwise . - /// - public static bool IsTypeVisible(Type type, string friendlyAssemblyName) - { -#if NET_2_0 - if (type.IsVisible) - { - return true; - } - else - { - if (friendlyAssemblyName != null - && friendlyAssemblyName.Length > 0 - && (!type.IsNested || type.IsNestedPublic || - (!type.IsNestedPrivate && (type.IsNestedAssembly || type.IsNestedFamORAssem)))) - { - object[] attrs = type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), false); - foreach (InternalsVisibleToAttribute ivta in attrs) - { - if (ivta.AssemblyName == friendlyAssemblyName) - { - return true; - } - } - } - } -#else - if (type.IsPublic || (type.IsNestedPublic && type.DeclaringType.IsPublic)) - { - return true; - } -#endif - return false; - } - - /// - /// Gets all of the interfaces implemented by - /// the specified . - /// - /// - /// The object to get the interfaces of. - /// - /// - /// All of the interfaces implemented by the - /// . - /// - public static Type[] GetInterfaces(Type type) - { - AssertUtils.ArgumentNotNull(type, "type"); - - if (type.IsInterface) - { - ArrayList interfaces = new ArrayList(); - interfaces.Add(type); - interfaces.AddRange(type.GetInterfaces()); - return (Type[])interfaces.ToArray(typeof(Type)); - } - else - { - return type.GetInterfaces(); - } - } - - /// - /// Returns the explicit that is the root cause of an exception. - /// - /// - /// If the InnerException property of the current exception is a null reference - /// or a , returns the current exception. - /// - /// The last exception thrown. - /// - /// The first explicit exception thrown in a chain of exceptions. - /// - public static Exception GetExplicitBaseException(Exception ex) - { - Exception innerEx = ex.InnerException; - while (innerEx != null && - !(innerEx is NullReferenceException)) - { - ex = innerEx; - innerEx = innerEx.InnerException; - } - return ex; - } - - /// - /// Copies all fields from one object to another. - /// - /// - /// The types of both objects must be related. This means, that either of the following is true: - /// - /// fromObject.GetType() == toObject.GetType() - /// fromObject.GetType() is derived from toObject.GetType() - /// toObject.GetType() is derived from fromObject.GetType() - /// - /// - /// The source object - /// The object, who's fields will be populated with values from the source object - /// If the object's types are not related - public static void MemberwiseCopy(object fromObject, object toObject) - { - Type fromType = fromObject.GetType(); - Type toType = toObject.GetType(); - - Type smallerType; - - if (fromType.IsAssignableFrom(toType)) - { - smallerType = fromType; - } - else if (toType.IsAssignableFrom(fromType)) - { - smallerType = toType; - } - else - { - throw new ArgumentException("object types are not related"); - } - - MemberwiseCopyInternal(fromObject, toObject, smallerType); - } - -#if NET_2_0 - private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType) - { - MemberwiseCopyHandler impl = GetImpl(smallerType); - impl(fromObject, toObject); - } - - private delegate void MemberwiseCopyHandler(object a, object b); - - private static readonly Hashtable s_handlerCache = new Hashtable(); - - private static MemberwiseCopyHandler GetImpl(Type type) - { - MemberwiseCopyHandler handler = s_handlerCache[type] as MemberwiseCopyHandler; - if (handler != null) return handler; - - lock (s_handlerCache) - { - handler = s_handlerCache[type] as MemberwiseCopyHandler; - if (handler != null) return handler; - - FieldInfo[] fields = GetFields(type); - DynamicMethod dm = new DynamicMethod(type.FullName + ".ShallowCopy", null, new Type[] { typeof(object), typeof(object) }, type.Module, true); - ILGenerator ilGen = dm.GetILGenerator(); - ilGen.DeclareLocal(type); - ilGen.DeclareLocal(type); - ilGen.Emit(OpCodes.Ldarg_0); - ilGen.Emit(OpCodes.Castclass, type); - ilGen.Emit(OpCodes.Stloc_0); - ilGen.Emit(OpCodes.Ldarg_1); - ilGen.Emit(OpCodes.Castclass, type); - ilGen.Emit(OpCodes.Stloc_1); - - foreach (FieldInfo field in fields) - { - ilGen.Emit(OpCodes.Ldloc_1); - ilGen.Emit(OpCodes.Ldloc_0); - ilGen.Emit(OpCodes.Ldfld, field); - ilGen.Emit(OpCodes.Stfld, field); - } - ilGen.Emit(OpCodes.Ret); - - handler = (MemberwiseCopyHandler)dm.CreateDelegate(typeof(MemberwiseCopyHandler)); - s_handlerCache[type] = handler; - } - return handler; - } -#else - private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType) - { - FieldInfo[] fields = GetFields(smallerType); - for (int i = 0; i < fields.Length; i++) - { - FieldInfo field = fields[i]; - field.SetValue(toObject, field.GetValue(fromObject)); - } - } -#endif - - #region Field Cache Management for "MemberwiseCopy" - - private const BindingFlags FIELDBINDINGS = - BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic; - - private static readonly Hashtable s_fieldCache = new Hashtable(); - - private static FieldInfo[] GetFields(Type type) - { - lock (s_fieldCache) - { - FieldInfo[] fields = (FieldInfo[])s_fieldCache[type]; - if (fields == null) - { - ArrayList fieldList = new ArrayList(); - CollectFieldsRecursive(type, fieldList); - fields = (FieldInfo[])fieldList.ToArray(typeof(FieldInfo)); - s_fieldCache[type] = fields; - } - return fields; - } - } - - private static void CollectFieldsRecursive(Type type, ArrayList fieldList) - { - if (type == typeof(object)) return; - - FieldInfo[] fields = type.GetFields(FIELDBINDINGS); - fieldList.AddRange(fields); - CollectFieldsRecursive(type.BaseType, fieldList); - } - - #endregion Field Cache Management for "MemberwiseCopy" - - - #region CustomAttributeBuilderBuilder inner class definition - - /// - /// Creates a . - /// - /// Bruno Baia - /// $Id: ReflectionUtils.cs,v 1.59 2008/05/13 14:22:46 oakinger Exp $ - public class CustomAttributeBuilderBuilder - { - #region Fields - - private Type type; - private ArrayList constructorArgs; - private ArrayList namedProperties; - private ArrayList propertyValues; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// The custom attribute type. - public CustomAttributeBuilderBuilder(Type attributeType) - : - this(attributeType, ObjectUtils.EmptyObjects) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The custom attribute type. - /// The custom attribute constructor arguments. - public CustomAttributeBuilderBuilder(Type attributeType, params object[] constructorArgs) - { - AssertUtils.ArgumentNotNull(attributeType, "attributeType"); - if (!typeof(Attribute).IsAssignableFrom(attributeType)) - { - throw new ArgumentException( - string.Format("[{0}] does not derive from the [System.Attribute] class.", - attributeType.FullName)); - } - this.type = attributeType; - this.constructorArgs = new ArrayList(constructorArgs); - this.namedProperties = new ArrayList(); - this.propertyValues = new ArrayList(); - } - - #endregion - - #region Public Methods - - /// - /// Adds the specified values to the constructor argument list - /// used to create the custom attribute. - /// - /// An array of argument values. - public void AddContructorArgument(params object[] values) - { - this.constructorArgs.AddRange(values); - } - - /// - /// Adds a property value to the custom attribute. - /// - /// The property name. - /// The property value. - public void AddPropertyValue(string name, object value) - { - PropertyInfo propertyInfo = this.type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public); - if (propertyInfo == null) - { - throw new ArgumentException( - String.Format("The property '{0}' does no exist in the attribute '{1}'.", name, this.type)); - } - - this.namedProperties.Add(propertyInfo); - this.propertyValues.Add(value); - } - - /// - /// Creates the . - /// - /// The created . - public CustomAttributeBuilder Build() - { - object[] caArray = (object[])this.constructorArgs.ToArray(typeof(object)); - ConstructorInfo ci = this.type.GetConstructor(ReflectionUtils.GetTypes(caArray)); - if (ci == null && caArray.Length == 0) - { - ci = this.type.GetConstructors()[0]; - caArray = ReflectionUtils.GetDefaultValues(ReflectionUtils.GetParameterTypes(ci.GetParameters())); - } - - if (namedProperties.Count > 0) - { - PropertyInfo[] npArray = (PropertyInfo[])this.namedProperties.ToArray(typeof(PropertyInfo)); - object[] pvArray = (object[])this.propertyValues.ToArray(typeof(object)); - return new CustomAttributeBuilder(ci, caArray, npArray, pvArray); - } - else - { - return new CustomAttributeBuilder(ci, caArray); - } - - } - - #endregion - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +#if NET_2_0 +using System.Collections.Generic; +using System.Collections.ObjectModel; +#endif +using System.Globalization; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Runtime.CompilerServices; + +#endregion + +namespace Spring.Util +{ + /// + /// Various reflection related methods that are missing from the standard library. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Aleksandar Seovic (.NET) + /// Stan Dvoychenko (.NET) + /// Bruno Baia (.NET) + public sealed class ReflectionUtils + { + /// + /// Convenience value that will + /// match all private and public, static and instance members on a class + /// in a case inSenSItivE fashion. + /// + public const BindingFlags AllMembersCaseInsensitiveFlags = BindingFlags.Public | + BindingFlags.NonPublic | BindingFlags.Instance + | BindingFlags.Static + | BindingFlags.IgnoreCase; + + /// + /// Returns signature for the specified , method name and argument + /// s. + /// + /// The the method is in. + /// The method name. + /// + /// The argument s. + /// + /// The method signature. + public static string GetSignature( + Type type, string method, Type[] argumentTypes) + { + StringBuilder sb = new StringBuilder(); + sb.Append(type.FullName).Append("::").Append(method).Append("("); + string separator = ""; + for (int i = 0; i < argumentTypes.Length; i++) + { + sb.Append(separator).Append(argumentTypes[i].FullName); + separator = ","; + } + sb.Append(")"); + return sb.ToString(); + } + + + /// + /// Returns method for the specified , method + /// name and argument + /// s. + /// + /// Searches with BindingFlags + /// + /// The target to find the method on. + /// + /// The method to find. + /// + /// The argument s. May be + /// if the method has no arguments. + /// + /// The target method. + public static MethodInfo GetMethod( + Type targetType, string method, Type[] argumentTypes) + { + AssertUtils.ArgumentNotNull(targetType, "Type must not be null"); + // try method exactly as specified first... + MethodInfo retMethod = targetType.GetMethod( + method, + ReflectionUtils.AllMembersCaseInsensitiveFlags, + null, + argumentTypes == null ? Type.EmptyTypes : argumentTypes, + null); + + if (retMethod == null) + { + // try explicit interface implementation... + int idx = method.LastIndexOf('.'); + if (idx > -1) + { + method = method.Substring(idx + 1); + retMethod = ReflectionUtils.GetMethod(targetType, method, argumentTypes); + } + } + return retMethod; + } + + /// + /// Returns an array of parameter s for the specified method + /// or constructor. + /// + /// The method (or constructor). + /// An array containing the parameter s. + /// + /// If is . + /// + public static Type[] GetParameterTypes(MethodBase method) + { + AssertUtils.ArgumentNotNull(method, "method"); + return GetParameterTypes(method.GetParameters()); + } + + /// + /// Returns an array of parameter s for the + /// specified parameter info array. + /// + /// The parameter info array. + /// An array containing parameter s. + /// + /// If is or any of the + /// elements is . + /// + public static Type[] GetParameterTypes(ParameterInfo[] args) + { + AssertUtils.ArgumentNotNull(args, "args"); + Type[] types = new Type[args.Length]; + for (int i = 0; i < args.Length; i++) + { + types[i] = args[i].ParameterType; + } + return types; + } + +#if NET_2_0 + /// + /// Returns an array of s that represent + /// the names of the generic type parameter. + /// + /// The method. + /// An array containing the parameter names. + /// + /// If is . + /// + public static string[] GetGenericParameterNames(MethodInfo method) + { + AssertUtils.ArgumentNotNull(method, "method"); + return GetGenericParameterNames(method.GetGenericArguments()); + } + + /// + /// Returns an array of s that represent + /// the names of the generic type parameter. + /// + /// The parameter info array. + /// An array containing parameter names. + /// + /// If is or any of the + /// elements is . + /// + public static string[] GetGenericParameterNames(Type[] args) + { + AssertUtils.ArgumentNotNull(args, "args"); + string[] names = new string[args.Length]; + for (int i = 0; i < args.Length; i++) + { + names[i] = args[i].Name; + } + return names; + } +#endif + + /// + /// From a given list of methods, selects the method having an exact match on the given ' types. + /// + /// the list of methods to choose from + /// the arguments to the method + /// the method matching exactly the passed ' types + /// + /// If more than 1 matching methods are found in the list. + /// + public static MethodInfo GetMethodByArgumentValues(MethodInfo[] methods, object[] argValues) + { + return (MethodInfo)GetMethodBaseByArgumentValues("method", methods, argValues); + } + + /// + /// From a given list of methods, selects the method having an exact match on the given ' types. + /// + /// the type of method (used for exception reporting only) + /// the list of methods to choose from + /// the arguments to the method + /// the method matching exactly the passed ' types + /// + /// If more than 1 matching methods are found in the list. + /// + private static MethodBase GetMethodBaseByArgumentValues(string methodTypeName, MethodBase[] methods, + object[] argValues) + { + MethodBase match = null; + int matchCount = 0; + + foreach (MethodBase m in methods) + { + ParameterInfo[] parameters = m.GetParameters(); + bool isMatch = true; + bool isExactMatch = true; + object[] paramValues = argValues; + + try + { + if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) + { + paramValues = + PackageParamArray(argValues, parameters.Length, + lastParameter.ParameterType.GetElementType()); + } + } + + for (int i = 0; i < parameters.Length; i++) + { + Type paramType = parameters[i].ParameterType; + object paramValue = paramValues[i]; + if ((paramValue == null && paramType.IsValueType) + || (paramValue != null && !paramType.IsAssignableFrom(paramValue.GetType()))) + { + isMatch = false; + break; + } + if (paramValue == null || paramType != paramValue.GetType()) + { + isExactMatch = false; + } + } + } + catch (InvalidCastException) + { + isMatch = false; + } + + if (isMatch) + { + if (isExactMatch) + { + return m; + } + + matchCount++; + if (matchCount == 1) + { + match = m; + } + else + { + throw new AmbiguousMatchException( + string.Format("Ambiguous match for {0} '{1}' for the specified number and types of arguments.", methodTypeName, + m.Name)); + } + } + } + + return match; + } + + /// + /// From a given list of constructors, selects the constructor having an exact match on the given ' types. + /// + /// the list of constructors to choose from + /// the arguments to the method + /// the constructor matching exactly the passed ' types + /// + /// If more than 1 matching methods are found in the list. + /// + public static ConstructorInfo GetConstructorByArgumentValues(ConstructorInfo[] methods, object[] argValues) + { + return (ConstructorInfo)GetMethodBaseByArgumentValues("constructor", methods, argValues); + } + + + /// + /// Packages arguments into argument list containing parameter array as a last argument. + /// + /// Argument vaklues to package. + /// Total number of oarameters. + /// Type of the param array element. + /// Packaged arguments. + public static object[] PackageParamArray(object[] argValues, int argCount, Type elementType) + { + object[] values = new object[argCount]; + int i = 0; + + // copy regular arguments + while (i < argCount - 1) + { + values[i] = argValues[i]; + i++; + } + + // package param array into last argument + Array paramArray = Array.CreateInstance(elementType, argValues.Length - i); + int j = 0; + while (i < argValues.Length) + { + paramArray.SetValue(argValues[i++], j++); + } + values[values.Length - 1] = paramArray; + + return values; + } + + /// + /// Convenience method to convert an interface + /// to a array that contains + /// all the interfaces inherited and the specified interface. + /// + /// The interface to convert. + /// An array of interface s. + /// + /// If the specified is not an interface. + /// + /// + /// If is . + /// + public static Type[] ToInterfaceArray(Type intf) + { + AssertUtils.ArgumentNotNull(intf, "intf"); + + if (!intf.IsInterface) + { + throw new ArgumentException( + string.Format(CultureInfo.InvariantCulture, + "[{0}] is a class.", + intf.FullName)); + } + + ArrayList interfaces = new ArrayList(intf.GetInterfaces()); + interfaces.Add(intf); + + return (Type[])interfaces.ToArray(typeof(Type)); + } + + /// + /// Is the supplied the default indexer for the + /// supplied ? + /// + /// + /// The name of the property on the supplied to be checked. + /// + /// + /// The to be checked. + /// + /// + /// if the supplied is the + /// default indexer for the supplied . + /// + /// + /// If the supplied is . + /// + public static bool PropertyIsIndexer(string propertyName, Type type) + { + DefaultMemberAttribute[] attribs = + (DefaultMemberAttribute[])type.GetCustomAttributes(typeof(DefaultMemberAttribute), true); + if (attribs.Length != 0) + { + foreach (DefaultMemberAttribute attrib in attribs) + { + if (attrib.MemberName.Equals(propertyName)) + { + return true; + } + } + } + return false; + } + + /// + /// Is the supplied declared on one of these interfaces? + /// + /// The method to check. + /// The array of interfaces we want to check. + /// + /// if the method is declared on one of these interfaces. + /// + /// + /// If any of the s specified is not an interface. + /// + /// + /// If or any of the specified interfaces is + /// . + /// + public static bool MethodIsOnOneOfTheseInterfaces(MethodBase method, Type[] interfaces) + { + AssertUtils.ArgumentNotNull(method, "method"); + if (interfaces == null) + { + return false; + } + Type[] paramTypes = GetParameterTypes(method.GetParameters()); + for (int i = 0; i < interfaces.Length; i++) + { + Type interfaceType = interfaces[i]; + AssertUtils.ArgumentNotNull(interfaceType, StringUtils.Surround("interfaces[", i, "]")); + if (!interfaceType.IsInterface) + { + throw new ArgumentException(interfaces[i].FullName + " is not an interface"); + } + try + { + MethodInfo mi = interfaceType.GetMethod( + method.Name, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, + null, paramTypes, null); + if (mi != null) + { + // found it... + return true; + } + } + catch + { + // didn't find it, so keep going... + } + } + return false; + } + + /// + /// Returns the default value for the specified + /// + /// + ///

+ /// Follows the standard .NET conventions for default values where + /// relevant; for example, all numeric types default to the value + /// 0. + ///

+ ///
+ /// + /// The to return default value for. + /// + /// + /// The default value for the specified . + /// + /// + /// If the supplied is an enumerated type that + /// has no values. + /// + public static object GetDefaultValue(Type type) + { + if (!type.IsValueType) + { + return null; + } + if (type == typeof(Boolean)) + { + return false; + } + if (type == typeof(DateTime)) + { + return DateTime.MinValue; + } + if (type == typeof(Char)) + { + return Char.MinValue; + } + if (type.IsEnum) + { + Array values = Enum.GetValues(type); + if (values == null || values.Length == 0) + { + throw new ArgumentException("Bad 'enum' Type : cannot get default value because 'enum' has no values."); + } + return values.GetValue(0); + } + return 0; + } + + /// + /// Returns an array consisting of the default values for the supplied + /// . + /// + /// + /// The array of s to return default values for. + /// + /// + /// An array consisting of the default values for the supplied + /// . + /// + /// + /// If any of the elements in the supplied + /// array is an enumerated type that has no values. + /// + /// + public static object[] GetDefaultValues(Type[] types) + { + object[] defaults = new object[types.Length]; + for (int i = 0; i < types.Length; ++i) + { + defaults[i] = GetDefaultValue(types[i]); + } + return defaults; + } + + /// + /// Checks that the parameter s of the + /// supplied match the parameter + /// s of the supplied + /// . + /// + /// The method to be checked. + /// + /// The array of parameter s to check against. + /// + /// + /// if the parameter s + /// match. + /// + public static bool ParameterTypesMatch( + MethodInfo candidate, Type[] parameterTypes) + { + #region Sanity Checks + + AssertUtils.ArgumentNotNull(candidate, "candidate"); + AssertUtils.ArgumentNotNull(parameterTypes, "parameterTypes"); + + #endregion + + Type[] candidatesParameterTypes + = ReflectionUtils.GetParameterTypes(candidate); + if (candidatesParameterTypes.Length != parameterTypes.Length) + { + return false; + } + for (int i = 0; i < candidatesParameterTypes.Length; ++i) + { + if (!candidatesParameterTypes[i].Equals(parameterTypes[i])) + { + return false; + } + } + return true; + } + + /// + /// Returns an array containing the s of the + /// objects in the supplied array. + /// + /// + /// The objects array for which the corresponding s + /// are needed. + /// + /// + /// An array containing the s of the objects + /// in the supplied array; this array will be empty (but not + /// if the supplied + /// is null or has no elements. + /// + /// + ///

+ /// [C#]
+ /// Given an array containing the following objects, + /// [83, "Foo", new object ()], the + /// array returned from this method call would consist of the following + /// elements... + /// [Int32, String, Object]. + ///

+ ///
+ public static Type[] GetTypes(object[] args) + { + if (args == null || args.Length == 0) + { + return Type.EmptyTypes; + } + Type[] paramsType = new Type[args.Length]; + for (int i = 0; i < args.Length; ++i) + { + object arg = args[i]; + paramsType[i] = (arg != null) ? args[i].GetType() : typeof(object); + } + return paramsType; + } + + /// + /// Does the given and/or it's superclasses + /// have at least one or more methods with the given name (with any + /// argument types)? + /// + /// + ///

+ /// Includes non-public methods in the methods searched. + ///

+ ///
+ /// + /// The to be checked. + /// + /// + /// The name of the method to be searched for. Case inSenSItivE. + /// + /// + /// if the given or / and it's + /// superclasses have at least one or more methods (with any argument types); + /// if not, or either of the parameters is . + /// + public static bool HasAtLeastOneMethodWithName(Type type, string name) + { + if (type == null || StringUtils.IsNullOrEmpty(name)) + { + return false; + } + return MethodCountForName(type, name) > 0; + } + + /// + /// Within , counts the number of overloads for the method with the given (case-insensitive!) + /// + /// The type to be searched + /// the name of the method for which overloads shall be counted + /// The number of overloads for method within type + public static int MethodCountForName(Type type, string name) + { + AssertUtils.ArgumentNotNull(type, "type", "Type must not be null"); + AssertUtils.ArgumentNotNull(name, "name", "Method name must not be null"); + MemberInfo[] methods = type.FindMembers( + MemberTypes.Method, + ReflectionUtils.AllMembersCaseInsensitiveFlags, + new MemberFilter(ReflectionUtils.MethodNameFilter), + name); + return methods.Length; + } + + private static bool MethodNameFilter(MemberInfo member, object criteria) + { + MethodInfo method = member as MethodInfo; + string name = criteria as string; + return String.Compare(method.Name, name, true, CultureInfo.InvariantCulture) == 0; + } + + /// + /// Creates a . + /// + /// + ///

+ /// Note that if a non- + /// is supplied, any read write properties exposed by the + /// will be used to overwrite values that may have been passed in via the + /// . That is, the will be used + /// to initialize the custom attribute, and then any read-write properties on the + /// will be plugged in. + ///

+ ///
+ /// + /// The desired . + /// + /// + /// Any constructor arguments for the attribute (may be + /// in the case of no arguments). + /// + /// + /// Source attribute to copy properties from (may be ). + /// + /// A custom attribute builder. + /// + /// If the parameter is . + /// + /// + /// If the parameter is not a + /// that derives from the class. + /// + /// + public static CustomAttributeBuilder CreateCustomAttribute( + Type type, object[] ctorArgs, Attribute sourceAttribute) + { + #region Sanity Checks + + AssertUtils.ArgumentNotNull(type, "type"); + if (!typeof(Attribute).IsAssignableFrom(type)) + { + throw new ArgumentException( + string.Format("[{0}] does not derive from the [System.Attribute] class.", + type.FullName)); + } + + #endregion + + ConstructorInfo ci = type.GetConstructor(ReflectionUtils.GetTypes(ctorArgs)); + if (ci == null && ctorArgs.Length == 0) + { + ci = type.GetConstructors()[0]; + ctorArgs = GetDefaultValues(GetParameterTypes(ci.GetParameters())); + } + + if (sourceAttribute != null) + { + object defaultAttribute = null; + try + { + defaultAttribute = ci.Invoke(ctorArgs); + } + catch + { + } + + IList getSetProps = new ArrayList(); + IList getSetValues = new ArrayList(); + IList readOnlyProps = new ArrayList(); + IList readOnlyValues = new ArrayList(); + foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + if (pi.DeclaringType == typeof(Attribute)) + continue; + + if (pi.CanRead) + { + if (pi.CanWrite) + { + object propValue = pi.GetValue(sourceAttribute, null); + if (defaultAttribute != null) + { + object defaultValue = pi.GetValue(defaultAttribute, null); + if ((propValue == null && defaultValue == null) || + (propValue != null && propValue.Equals(defaultValue))) + continue; + } + getSetProps.Add(pi); + getSetValues.Add(propValue); + } + else + { + readOnlyProps.Add(pi); + readOnlyValues.Add(pi.GetValue(sourceAttribute, null)); + } + } + } + + if (readOnlyProps.Count == 1) + { + PropertyInfo pi = readOnlyProps[0] as PropertyInfo; + ConstructorInfo ciTemp = type.GetConstructor(new Type[1] { pi.PropertyType }); + if (ciTemp != null) + { + ci = ciTemp; + ctorArgs = new object[1] { readOnlyValues[0] }; + } + else + { + ciTemp = type.GetConstructor(new Type[1] { readOnlyValues[0].GetType() }); + if (ciTemp != null) + { + ci = ciTemp; + ctorArgs = new object[1] { readOnlyValues[0] }; + } + } + } + + PropertyInfo[] propertyInfos = new PropertyInfo[getSetProps.Count]; + getSetProps.CopyTo(propertyInfos, 0); + + object[] propertyValues = new object[getSetValues.Count]; + getSetValues.CopyTo(propertyValues, 0); + + return new CustomAttributeBuilder(ci, ctorArgs, propertyInfos, propertyValues); + } + else + { + return new CustomAttributeBuilder(ci, ctorArgs); + } + } + + /// + /// Creates a . + /// + /// + /// The desired . + /// + /// + /// Source attribute to copy properties from (may be ). + /// + /// A custom attribute builder. + public static CustomAttributeBuilder CreateCustomAttribute( + Type type, Attribute sourceAttribute) + { + return CreateCustomAttribute(type, new object[] { }, sourceAttribute); + } + + /// + /// Creates a . + /// + /// + /// The source attribute to copy properties from. + /// + /// A custom attribute builder. + /// + /// If the supplied is + /// . + /// + public static CustomAttributeBuilder CreateCustomAttribute(Attribute sourceAttribute) + { + return CreateCustomAttribute(sourceAttribute.GetType(), sourceAttribute); + } + + /// + /// Creates a . + /// + /// + /// The desired . + /// + /// A custom attribute builder. + public static CustomAttributeBuilder CreateCustomAttribute(Type type) + { + return CreateCustomAttribute(type, new object[] { }, null); + } + + /// + /// Creates a . + /// + /// + /// The desired . + /// + /// + /// Any constructor arguments for the attribute (may be + /// in the case of no arguments). + /// + /// A custom attribute builder. + public static CustomAttributeBuilder CreateCustomAttribute( + Type type, params object[] ctorArgs) + { + return CreateCustomAttribute(type, ctorArgs, null); + } + +#if NET_2_0 + /// + /// Creates a . + /// + /// + /// The to create + /// the custom attribute builder from. + /// + /// A custom attribute builder. + public static CustomAttributeBuilder CreateCustomAttribute(CustomAttributeData attributeData) + { + object[] parameterValues = new object[attributeData.ConstructorArguments.Count]; + Type[] parameterTypes = new Type[attributeData.ConstructorArguments.Count]; + + IList namedParameterValues = new ArrayList(); + IList namedFieldValues = new ArrayList(); + + // Fill arrays of the constructor parameters + for (int i = 0; i < attributeData.ConstructorArguments.Count; i++) + { + parameterTypes[i] = attributeData.ConstructorArguments[i].ArgumentType; + parameterValues[i] = ConvertValueIfNecessary(attributeData.ConstructorArguments[i].Value); + } + + Type attributeType = attributeData.Constructor.DeclaringType; + PropertyInfo[] attributeProperties = attributeType.GetProperties( + BindingFlags.Instance | BindingFlags.Public); + FieldInfo[] attributeFields = attributeType.GetFields( + BindingFlags.Instance | BindingFlags.Public); + + // Not using generics bellow as probably Spring.NET tries to keep + // it on .NET1 compatibility level right now I believe (SD) + // In case of using List the above note makes + // no sense (SD:) + IList propertiesToSet = new ArrayList(); + int k = 0; + + IList fieldsToSet = new ArrayList(); + int n = 0; + + + // Fills arrays of the constructor named parameters + foreach (CustomAttributeNamedArgument namedArgument in attributeData.NamedArguments) + { + bool noMatchingProperty = false; + + // Now iterate through all of the PropertyInfo, find the + // one with the corresponding to the NamedProperty name + // and add it to the array of properties to set. + for (int j = 0; j < attributeProperties.Length; j++) + { + if (attributeProperties[j].Name == namedArgument.MemberInfo.Name) + { + propertiesToSet.Add(attributeProperties[j]); + namedParameterValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value)); + break; + } + else + { + if (j == attributeProperties.Length - 1) + { + // In case of no match, throw + noMatchingProperty = true; + /* + throw new InvalidOperationException( + String.Format(CultureInfo.InvariantCulture, + "The property with name {0} can't be found in the " + + "type {1}, but is present as a named property " + + "on the attributeData {2}", namedArgument.MemberInfo.Name, + attributeType.FullName, attributeData)); + */ + } + } + } + if (noMatchingProperty) + { + for (int j = 0; j < attributeFields.Length; j++) + { + if (attributeFields[j].Name == namedArgument.MemberInfo.Name) + { + fieldsToSet.Add(attributeFields[j]); + namedFieldValues.Add(ConvertValueIfNecessary(namedArgument.TypedValue.Value)); + break; + } + else + { + if (j == attributeFields.Length - 1) + { + throw new InvalidOperationException( + String.Format(CultureInfo.InvariantCulture, + "A property or public field with name {0} can't be found in the " + + "type {1}, but is present as a named property " + + "on the attributeData {2}", namedArgument.MemberInfo.Name, + attributeType.FullName, attributeData)); + } + } + } + } + } + // Get constructor corresponding to the parameters and their types + ConstructorInfo constructor = attributeType.GetConstructor(parameterTypes); + + PropertyInfo[] namedProperties = new PropertyInfo[propertiesToSet.Count]; + propertiesToSet.CopyTo(namedProperties, 0); + + object[] propertyValues = new object[namedParameterValues.Count]; + namedParameterValues.CopyTo(propertyValues, 0); + + if (fieldsToSet.Count == 0) + { + return new CustomAttributeBuilder( + constructor, parameterValues, namedProperties, propertyValues); + } + else + { + FieldInfo[] namedFields = new FieldInfo[fieldsToSet.Count]; + fieldsToSet.CopyTo(namedFields, 0); + + object[] fieldValues = new object[namedFieldValues.Count]; + namedFieldValues.CopyTo(fieldValues, 0); + + return new CustomAttributeBuilder( + constructor, parameterValues, namedProperties, propertyValues, namedFields, fieldValues); + } + + + + } + + private static object ConvertValueIfNecessary(object value) + { + if (value == null) return value; + + // We are only hunting for the case of the ReadOnlyCollection here. + ReadOnlyCollection sourceArray = + value as ReadOnlyCollection; + + if (sourceArray == null) return value; + + Type underlyingType = null; // type to be used for arguments + Array returnArray = null; + for (int i = 0; i < sourceArray.Count; i++) + { + if (underlyingType == null) + { + underlyingType = sourceArray[i].ArgumentType; + returnArray = Array.CreateInstance(underlyingType, sourceArray.Count); + } + if (!underlyingType.Equals(sourceArray[i].ArgumentType)) + { + throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, + "Types for the same named parameter of array type are expected to be same")); + } + + returnArray.SetValue(sourceArray[i].Value, i); + } + + return returnArray; + + } +#endif + + /// + /// Tries to find matching methods in the specified + /// for each method in the supplied list. + /// + /// + /// The to look for matching methods in. + /// + /// The methods to match. + /// + /// A flag that specifies whether to throw an exception if a matching + /// method is not found. + /// + /// A list of the matched methods. + /// + /// If either of the or + /// parameters are . + /// + public static MethodInfo[] GetMatchingMethods(Type type, MethodInfo[] methods, bool strict) + { + AssertUtils.ArgumentNotNull(type, "type"); + AssertUtils.ArgumentNotNull(methods, "methods"); + + BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase; + + MethodInfo[] matched = new MethodInfo[methods.Length]; + for (int i = 0; i < methods.Length; i++) + { + MethodInfo method = methods[i]; + MethodInfo match = type.GetMethod(method.Name, flags, null, ReflectionUtils.GetParameterTypes(method), null); + if ((match == null || match.ReturnType != method.ReturnType) && strict) + { + throw new Exception( + string.Format("Method '{0}' could not be matched in the target class [{1}].", + method.Name, type.FullName)); + } + matched[i] = match; + } + return matched; + } + + /// + /// Returns the of the supplied + /// . + /// + /// + ///

+ /// If the is a + /// instance, the return value of this method call with be the + /// parameter cast to a + /// . If the is + /// anything other than a , the return value + /// will be the result of invoking the 's + /// method. + ///

+ ///
+ /// + /// A or instance. + /// + /// + /// The argument if it is a + /// or the result of invoking + /// on the argument if it + /// is an . + /// + /// + /// If the is . + /// + public static Type TypeOfOrType(object source) + { + return source is Type ? source as Type : source.GetType(); + } + + +#if NET_2_0 + private static readonly MethodInfo Exception_InternalPreserveStackTrace = + typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic); +#else + private static readonly FieldInfo Exception_RemoteStackTraceString = + typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); +#endif + + /// + /// Unwraps the supplied + /// and returns the inner exception preserving the stack trace. + /// + /// + /// The to unwrap. + /// + /// The unwrapped exception. + public static Exception UnwrapTargetInvocationException(TargetInvocationException ex) + { +#if NET_2_0 + Exception_InternalPreserveStackTrace.Invoke(ex.InnerException, new Object[] { }); +#else + Exception_RemoteStackTraceString.SetValue(ex.InnerException, ex.InnerException.StackTrace + Environment.NewLine); +#endif + return ex.InnerException; + } + + /// + /// Is the supplied can be accessed outside the assembly ? + /// + /// The type to check. + /// + /// if the type can be accessed outside the assembly; + /// Otherwise . + /// + public static bool IsTypeVisible(Type type) + { + return IsTypeVisible(type, null); + } + + /// + /// Is the supplied can be accessed + /// from the supplied friendly assembly ? + /// + /// The type to check. + /// The friendly assembly name. + /// + /// if the type can be accessed + /// from the supplied friendly assembly; Otherwise . + /// + public static bool IsTypeVisible(Type type, string friendlyAssemblyName) + { +#if NET_2_0 + if (type.IsVisible) + { + return true; + } + else + { + if (friendlyAssemblyName != null + && friendlyAssemblyName.Length > 0 + && (!type.IsNested || type.IsNestedPublic || + (!type.IsNestedPrivate && (type.IsNestedAssembly || type.IsNestedFamORAssem)))) + { + object[] attrs = type.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), false); + foreach (InternalsVisibleToAttribute ivta in attrs) + { + if (ivta.AssemblyName == friendlyAssemblyName) + { + return true; + } + } + } + } +#else + if (type.IsPublic || (type.IsNestedPublic && type.DeclaringType.IsPublic)) + { + return true; + } +#endif + return false; + } + + /// + /// Gets all of the interfaces implemented by + /// the specified . + /// + /// + /// The object to get the interfaces of. + /// + /// + /// All of the interfaces implemented by the + /// . + /// + public static Type[] GetInterfaces(Type type) + { + AssertUtils.ArgumentNotNull(type, "type"); + + if (type.IsInterface) + { + ArrayList interfaces = new ArrayList(); + interfaces.Add(type); + interfaces.AddRange(type.GetInterfaces()); + return (Type[])interfaces.ToArray(typeof(Type)); + } + else + { + return type.GetInterfaces(); + } + } + + /// + /// Returns the explicit that is the root cause of an exception. + /// + /// + /// If the InnerException property of the current exception is a null reference + /// or a , returns the current exception. + /// + /// The last exception thrown. + /// + /// The first explicit exception thrown in a chain of exceptions. + /// + public static Exception GetExplicitBaseException(Exception ex) + { + Exception innerEx = ex.InnerException; + while (innerEx != null && + !(innerEx is NullReferenceException)) + { + ex = innerEx; + innerEx = innerEx.InnerException; + } + return ex; + } + + /// + /// Copies all fields from one object to another. + /// + /// + /// The types of both objects must be related. This means, that either of the following is true: + /// + /// fromObject.GetType() == toObject.GetType() + /// fromObject.GetType() is derived from toObject.GetType() + /// toObject.GetType() is derived from fromObject.GetType() + /// + /// + /// The source object + /// The object, who's fields will be populated with values from the source object + /// If the object's types are not related + public static void MemberwiseCopy(object fromObject, object toObject) + { + Type fromType = fromObject.GetType(); + Type toType = toObject.GetType(); + + Type smallerType; + + if (fromType.IsAssignableFrom(toType)) + { + smallerType = fromType; + } + else if (toType.IsAssignableFrom(fromType)) + { + smallerType = toType; + } + else + { + throw new ArgumentException("object types are not related"); + } + + MemberwiseCopyInternal(fromObject, toObject, smallerType); + } + +#if NET_2_0 + private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType) + { + MemberwiseCopyHandler impl = GetImpl(smallerType); + impl(fromObject, toObject); + } + + private delegate void MemberwiseCopyHandler(object a, object b); + + private static readonly Hashtable s_handlerCache = new Hashtable(); + + private static MemberwiseCopyHandler GetImpl(Type type) + { + MemberwiseCopyHandler handler = s_handlerCache[type] as MemberwiseCopyHandler; + if (handler != null) return handler; + + lock (s_handlerCache) + { + handler = s_handlerCache[type] as MemberwiseCopyHandler; + if (handler != null) return handler; + + FieldInfo[] fields = GetFields(type); + DynamicMethod dm = new DynamicMethod(type.FullName + ".ShallowCopy", null, new Type[] { typeof(object), typeof(object) }, type.Module, true); + ILGenerator ilGen = dm.GetILGenerator(); + ilGen.DeclareLocal(type); + ilGen.DeclareLocal(type); + ilGen.Emit(OpCodes.Ldarg_0); + ilGen.Emit(OpCodes.Castclass, type); + ilGen.Emit(OpCodes.Stloc_0); + ilGen.Emit(OpCodes.Ldarg_1); + ilGen.Emit(OpCodes.Castclass, type); + ilGen.Emit(OpCodes.Stloc_1); + + foreach (FieldInfo field in fields) + { + ilGen.Emit(OpCodes.Ldloc_1); + ilGen.Emit(OpCodes.Ldloc_0); + ilGen.Emit(OpCodes.Ldfld, field); + ilGen.Emit(OpCodes.Stfld, field); + } + ilGen.Emit(OpCodes.Ret); + + handler = (MemberwiseCopyHandler)dm.CreateDelegate(typeof(MemberwiseCopyHandler)); + s_handlerCache[type] = handler; + } + return handler; + } +#else + private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType) + { + FieldInfo[] fields = GetFields(smallerType); + for (int i = 0; i < fields.Length; i++) + { + FieldInfo field = fields[i]; + field.SetValue(toObject, field.GetValue(fromObject)); + } + } +#endif + + #region Field Cache Management for "MemberwiseCopy" + + private const BindingFlags FIELDBINDINGS = + BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic; + + private static readonly Hashtable s_fieldCache = new Hashtable(); + + private static FieldInfo[] GetFields(Type type) + { + lock (s_fieldCache) + { + FieldInfo[] fields = (FieldInfo[])s_fieldCache[type]; + if (fields == null) + { + ArrayList fieldList = new ArrayList(); + CollectFieldsRecursive(type, fieldList); + fields = (FieldInfo[])fieldList.ToArray(typeof(FieldInfo)); + s_fieldCache[type] = fields; + } + return fields; + } + } + + private static void CollectFieldsRecursive(Type type, ArrayList fieldList) + { + if (type == typeof(object)) return; + + FieldInfo[] fields = type.GetFields(FIELDBINDINGS); + fieldList.AddRange(fields); + CollectFieldsRecursive(type.BaseType, fieldList); + } + + #endregion Field Cache Management for "MemberwiseCopy" + + + #region CustomAttributeBuilderBuilder inner class definition + + /// + /// Creates a . + /// + /// Bruno Baia + public class CustomAttributeBuilderBuilder + { + #region Fields + + private Type type; + private ArrayList constructorArgs; + private ArrayList namedProperties; + private ArrayList propertyValues; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// The custom attribute type. + public CustomAttributeBuilderBuilder(Type attributeType) + : + this(attributeType, ObjectUtils.EmptyObjects) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The custom attribute type. + /// The custom attribute constructor arguments. + public CustomAttributeBuilderBuilder(Type attributeType, params object[] constructorArgs) + { + AssertUtils.ArgumentNotNull(attributeType, "attributeType"); + if (!typeof(Attribute).IsAssignableFrom(attributeType)) + { + throw new ArgumentException( + string.Format("[{0}] does not derive from the [System.Attribute] class.", + attributeType.FullName)); + } + this.type = attributeType; + this.constructorArgs = new ArrayList(constructorArgs); + this.namedProperties = new ArrayList(); + this.propertyValues = new ArrayList(); + } + + #endregion + + #region Public Methods + + /// + /// Adds the specified values to the constructor argument list + /// used to create the custom attribute. + /// + /// An array of argument values. + public void AddContructorArgument(params object[] values) + { + this.constructorArgs.AddRange(values); + } + + /// + /// Adds a property value to the custom attribute. + /// + /// The property name. + /// The property value. + public void AddPropertyValue(string name, object value) + { + PropertyInfo propertyInfo = this.type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public); + if (propertyInfo == null) + { + throw new ArgumentException( + String.Format("The property '{0}' does no exist in the attribute '{1}'.", name, this.type)); + } + + this.namedProperties.Add(propertyInfo); + this.propertyValues.Add(value); + } + + /// + /// Creates the . + /// + /// The created . + public CustomAttributeBuilder Build() + { + object[] caArray = (object[])this.constructorArgs.ToArray(typeof(object)); + ConstructorInfo ci = this.type.GetConstructor(ReflectionUtils.GetTypes(caArray)); + if (ci == null && caArray.Length == 0) + { + ci = this.type.GetConstructors()[0]; + caArray = ReflectionUtils.GetDefaultValues(ReflectionUtils.GetParameterTypes(ci.GetParameters())); + } + + if (namedProperties.Count > 0) + { + PropertyInfo[] npArray = (PropertyInfo[])this.namedProperties.ToArray(typeof(PropertyInfo)); + object[] pvArray = (object[])this.propertyValues.ToArray(typeof(object)); + return new CustomAttributeBuilder(ci, caArray, npArray, pvArray); + } + else + { + return new CustomAttributeBuilder(ci, caArray); + } + + } + + #endregion + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/StringUtils.cs b/src/Spring/Spring.Core/Util/StringUtils.cs index ef9ffcb3..279168ab 100644 --- a/src/Spring/Spring.Core/Util/StringUtils.cs +++ b/src/Spring/Spring.Core/Util/StringUtils.cs @@ -1,575 +1,574 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Text; - -#endregion - -namespace Spring.Util -{ - /// - /// Miscellaneous utility methods. - /// - /// - ///

- /// Mainly for internal use within the framework. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Keith Donald - /// Aleksandar Seovic (.NET) - /// Mark Pollack (.NET) - /// Rick Evans (.NET) - /// $Id: StringUtils.cs,v 1.29 2006/04/09 07:19:00 markpollack Exp $ - public sealed class StringUtils - { - /// - /// An empty array of instances. - /// - public static readonly string[] EmptyStrings = new string[] {}; - - /// - /// The string that signals the start of an Ant-style expression. - /// - private const string AntExpressionPrefix = "${"; - - /// - /// The string that signals the end of an Ant-style expression. - /// - private const string AntExpressionSuffix = "}"; - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private StringUtils() - { - } - - // CLOVER:ON - - #endregion - - /// - /// Tokenize the given into a - /// array. - /// - /// - ///

- /// If is , returns an empty - /// array. - ///

- ///

- /// If is or the empty - /// , returns a array with one - /// element: itself. - ///

- ///
- /// The to tokenize. - /// - /// The delimiter characters, assembled as a . - /// - /// - /// Trim the tokens via . - /// - /// - /// Omit empty tokens from the result array. - /// An array of the tokens. - public static string[] Split( - string s, string delimiters, bool trimTokens, bool ignoreEmptyTokens) - { - if (s == null) - { - return new string[0]; - } - if (StringUtils.IsNullOrEmpty(delimiters)) - { - return new string[] {s}; - } - string[] tmp = s.Split(delimiters.ToCharArray()); - // short circuit if String.Split default behavior is ok - if (!trimTokens && !ignoreEmptyTokens) - { - return tmp; - } - else - { - ArrayList tokens = new ArrayList(tmp.Length); - for (int i = 0; i < tmp.Length; ++i) - { - string token = (trimTokens ? tmp[i].Trim() : tmp[i]); - if (!(ignoreEmptyTokens && token.Length == 0)) - { - tokens.Add(token); - } - } - return (string[]) tokens.ToArray(typeof (string)); - } - } - - /// - /// Convert a CSV list into an array of s. - /// - /// A CSV list. - /// - /// An array of s, or the empty array - /// if is . - /// - public static string[] CommaDelimitedListToStringArray(string s) - { - return DelimitedListToStringArray(s, ","); - } - - /// - /// Take a which is a delimited list - /// and convert it to a array. - /// - /// - ///

- /// If the supplied is a - /// or zero-length string, then a single element - /// array composed of the supplied - /// will be - /// eturned. If the supplied - /// is , then an empty, - /// zero-length array will be returned. - ///

- ///
- /// - /// The to be parsed. - /// - /// - /// The delimeter (this will not be returned). Note that only the first - /// character of the supplied is used. - /// - /// - /// An array of the tokens in the list. - /// - public static string[] DelimitedListToStringArray(string input, string delimiter) - { - if (input == null) - { - return new string[0]; - } - if (!HasLength(delimiter)) - { - return new string[] {input}; - } - return input.Split(delimiter[0]); - } - - /// - /// Convenience method to return an - /// as a delimited - /// (e.g. CSV) . - /// - /// - /// The to parse. - /// - /// - /// The delimiter to use (probably a ','). - /// - /// The delimited string representation. - public static string CollectionToDelimitedString( - ICollection c, string delimiter) - { - if (c == null) - { - return "null"; - } - StringBuilder sb = new StringBuilder(); - int i = 0; - foreach (object obj in c) - { - if (i++ > 0) - { - sb.Append(delimiter); - } - sb.Append(obj); - } - return sb.ToString(); - } - - /// - /// Convenience method to return an - /// as a CSV - /// . - /// - /// - /// The to display. - /// - /// The delimited string representation. - public static string CollectionToCommaDelimitedString( - ICollection collection) - { - return CollectionToDelimitedString(collection, ","); - } - - /// - /// Convenience method to return an array as a CSV - /// . - /// - /// - /// The array to parse. Elements may be of any type ( - /// will be called on each - /// element). - /// - public static string ArrayToCommaDelimitedString(object[] source) - { - return ArrayToDelimitedString(source, ","); - } - - /// - /// Convenience method to return a - /// array as a delimited (e.g. CSV) . - /// - /// - /// The array to parse. Elements may be of any type ( - /// will be called on each - /// element). - /// - /// - /// The delimiter to use (probably a ','). - /// - public static string ArrayToDelimitedString( - object[] source, string delimiter) - { - if (source == null) - { - return "null"; - } - else - { - return StringUtils.CollectionToDelimitedString(source, delimiter); - } - } - - /// Checks if a string has length. - /// - /// The string to check, may be . - /// - /// - /// if the string has length and is not - /// . - /// - /// - /// - /// StringUtils.HasLength(null) = false - /// StringUtils.HasLength("") = false - /// StringUtils.HasLength(" ") = true - /// StringUtils.HasLength("Hello") = true - /// - /// - public static bool HasLength(string target) - { - return (target != null && target.Length > 0); - } - - /// - /// Checks if a has text. - /// - /// - ///

- /// More specifically, returns if the string is - /// not , it's is > - /// zero (0), and it has at least one non-whitespace character. - ///

- ///
- /// - /// The string to check, may be . - /// - /// - /// if the is not - /// , - /// > zero (0), and does not consist - /// solely of whitespace. - /// - /// - /// - /// StringUtils.HasText(null) = false - /// StringUtils.HasText("") = false - /// StringUtils.HasText(" ") = false - /// StringUtils.HasText("12345") = true - /// StringUtils.HasText(" 12345 ") = true - /// - /// - public static bool HasText(string target) - { - if (target == null) - { - return false; - } - else - { - return HasLength(target.Trim()); - } - } - - /// - /// Checks if a is - /// or an empty string. - /// - /// - ///

- /// More specifically, returns if the string is - /// , it's is equal - /// to zero (0), or it is composed entirely of whitespace - /// characters. - ///

- ///
- /// - /// The string to check, may (obviously) be . - /// - /// - /// if the is - /// , has a length equal to zero (0), or - /// is composed entirely of whitespace characters. - /// - /// - /// - /// StringUtils.IsNullOrEmpty(null) = true - /// StringUtils.IsNullOrEmpty("") = true - /// StringUtils.IsNullOrEmpty(" ") = true - /// StringUtils.IsNullOrEmpty("12345") = false - /// StringUtils.IsNullOrEmpty(" 12345 ") = false - /// - /// - public static bool IsNullOrEmpty(string target) - { - return !HasText(target); - } - - /// - /// Strips first and last character off the string. - /// - /// The string to strip. - /// The stripped string. - public static string StripFirstAndLastCharacter(string text) - { - if (text != null - && text.Length > 2) - { - return text.Substring(1, text.Length - 2); - } - else - { - return String.Empty; - } - } - - /// - /// Returns a list of Ant-style expressions from the specified text. - /// - /// The text to inspect. - /// - /// A list of expressions that exist in the specified text. - /// - /// - /// If any of the expressions in the supplied - /// is empty (${}). - /// - public static IList GetAntExpressions(string text) - { - IList expressions = new ArrayList(); - if (StringUtils.HasText(text)) - { - int start = text.IndexOf(AntExpressionPrefix); - while (start >= 0) - { - int end = text.IndexOf(AntExpressionSuffix, start + 2); - if (end == -1) - { - // terminator character not found, so let's quit... - start = -1; - } - else - { - string exp = text.Substring(start + 2, end - start - 2); - if(StringUtils.IsNullOrEmpty(exp)) - { - throw new FormatException( - string.Format("Empty {0}{1} value found in text : '{2}'.", - AntExpressionPrefix, - AntExpressionSuffix, - text)); - } - if (expressions.IndexOf(exp) < 0) - { - expressions.Add(exp); - } - start = text.IndexOf(AntExpressionPrefix, end); - } - } - } - return expressions; - } - - /// - /// Replaces Ant-style expression placeholder with expression value. - /// - /// - ///

- /// - ///

- ///
- /// The string to set the value in. - /// The name of the expression to set. - /// The expression value. - /// - /// A new string with the expression value set; the - /// value if the supplied - /// is , has a length - /// equal to zero (0), or is composed entirely of whitespace - /// characters. - /// - public static string SetAntExpression(string text, string expression, object expValue) - { - if (StringUtils.IsNullOrEmpty(text)) - { - return String.Empty; - } - if (expValue == null) - { - expValue = String.Empty; - } - return text.Replace( - StringUtils.Surround(AntExpressionPrefix, expression, AntExpressionSuffix), expValue.ToString()); - } - - /// - /// Surrounds (prepends and appends) the string value of the supplied - /// to the supplied . - /// - /// - ///

- /// The return value of this method call is always guaranteed to be non - /// . If every value passed as a parameter to this method is - /// , the string will be returned. - ///

- ///
- /// - /// The prefix and suffix that respectively will be prepended and - /// appended to the target . If this value - /// is not a value, it's attendant - /// value will be used. - /// - /// - /// The target that is to be surrounded. If this value is not a - /// value, it's attendant - /// value will be used. - /// - /// The surrounded string. - public static string Surround(object fix, object target) - { - return StringUtils.Surround(fix, target, fix); - } - - /// - /// Surrounds (prepends and appends) the string values of the supplied - /// and to the supplied - /// . - /// - /// - ///

- /// The return value of this method call is always guaranteed to be non - /// . If every value passed as a parameter to this method is - /// , the string will be returned. - ///

- ///
- /// - /// The value that will be prepended to the . If this value - /// is not a value, it's attendant - /// value will be used. - /// - /// - /// The target that is to be surrounded. If this value is not a - /// value, it's attendant - /// value will be used. - /// - /// - /// The value that will be appended to the . If this value - /// is not a value, it's attendant - /// value will be used. - /// - /// The surrounded string. - public static string Surround(object prefix, object target, object suffix) - { - return string.Format( - CultureInfo.InvariantCulture, "{0}{1}{2}", prefix, target, suffix); - } - - /// - /// Converts escaped characters (for example "\t") within a string - /// to their real character. - /// - /// The string to convert. - /// The converted string. - public static string ConvertEscapedCharacters( string inputString ) - { - StringBuilder sb = new StringBuilder(inputString.Length); - for (int i = 0 ; i < inputString.Length ; i++) - { - if (inputString[i].Equals('\\')) - { - i++; - if (inputString[i].Equals('t')) - { - sb.Append('\t'); - } - else if (inputString[i].Equals('r')) - { - sb.Append('\r'); - } - else if (inputString[i].Equals('n')) - { - sb.Append('\n'); - } - else if (inputString[i].Equals('\\')) - { - sb.Append('\\'); - } - else - { - sb.Append("\\" + inputString[i]); - } - } - else - { - sb.Append(inputString[i]); - } - } - return sb.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Text; + +#endregion + +namespace Spring.Util +{ + /// + /// Miscellaneous utility methods. + /// + /// + ///

+ /// Mainly for internal use within the framework. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Keith Donald + /// Aleksandar Seovic (.NET) + /// Mark Pollack (.NET) + /// Rick Evans (.NET) + public sealed class StringUtils + { + /// + /// An empty array of instances. + /// + public static readonly string[] EmptyStrings = new string[] {}; + + /// + /// The string that signals the start of an Ant-style expression. + /// + private const string AntExpressionPrefix = "${"; + + /// + /// The string that signals the end of an Ant-style expression. + /// + private const string AntExpressionSuffix = "}"; + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private StringUtils() + { + } + + // CLOVER:ON + + #endregion + + /// + /// Tokenize the given into a + /// array. + /// + /// + ///

+ /// If is , returns an empty + /// array. + ///

+ ///

+ /// If is or the empty + /// , returns a array with one + /// element: itself. + ///

+ ///
+ /// The to tokenize. + /// + /// The delimiter characters, assembled as a . + /// + /// + /// Trim the tokens via . + /// + /// + /// Omit empty tokens from the result array. + /// An array of the tokens. + public static string[] Split( + string s, string delimiters, bool trimTokens, bool ignoreEmptyTokens) + { + if (s == null) + { + return new string[0]; + } + if (StringUtils.IsNullOrEmpty(delimiters)) + { + return new string[] {s}; + } + string[] tmp = s.Split(delimiters.ToCharArray()); + // short circuit if String.Split default behavior is ok + if (!trimTokens && !ignoreEmptyTokens) + { + return tmp; + } + else + { + ArrayList tokens = new ArrayList(tmp.Length); + for (int i = 0; i < tmp.Length; ++i) + { + string token = (trimTokens ? tmp[i].Trim() : tmp[i]); + if (!(ignoreEmptyTokens && token.Length == 0)) + { + tokens.Add(token); + } + } + return (string[]) tokens.ToArray(typeof (string)); + } + } + + /// + /// Convert a CSV list into an array of s. + /// + /// A CSV list. + /// + /// An array of s, or the empty array + /// if is . + /// + public static string[] CommaDelimitedListToStringArray(string s) + { + return DelimitedListToStringArray(s, ","); + } + + /// + /// Take a which is a delimited list + /// and convert it to a array. + /// + /// + ///

+ /// If the supplied is a + /// or zero-length string, then a single element + /// array composed of the supplied + /// will be + /// eturned. If the supplied + /// is , then an empty, + /// zero-length array will be returned. + ///

+ ///
+ /// + /// The to be parsed. + /// + /// + /// The delimeter (this will not be returned). Note that only the first + /// character of the supplied is used. + /// + /// + /// An array of the tokens in the list. + /// + public static string[] DelimitedListToStringArray(string input, string delimiter) + { + if (input == null) + { + return new string[0]; + } + if (!HasLength(delimiter)) + { + return new string[] {input}; + } + return input.Split(delimiter[0]); + } + + /// + /// Convenience method to return an + /// as a delimited + /// (e.g. CSV) . + /// + /// + /// The to parse. + /// + /// + /// The delimiter to use (probably a ','). + /// + /// The delimited string representation. + public static string CollectionToDelimitedString( + ICollection c, string delimiter) + { + if (c == null) + { + return "null"; + } + StringBuilder sb = new StringBuilder(); + int i = 0; + foreach (object obj in c) + { + if (i++ > 0) + { + sb.Append(delimiter); + } + sb.Append(obj); + } + return sb.ToString(); + } + + /// + /// Convenience method to return an + /// as a CSV + /// . + /// + /// + /// The to display. + /// + /// The delimited string representation. + public static string CollectionToCommaDelimitedString( + ICollection collection) + { + return CollectionToDelimitedString(collection, ","); + } + + /// + /// Convenience method to return an array as a CSV + /// . + /// + /// + /// The array to parse. Elements may be of any type ( + /// will be called on each + /// element). + /// + public static string ArrayToCommaDelimitedString(object[] source) + { + return ArrayToDelimitedString(source, ","); + } + + /// + /// Convenience method to return a + /// array as a delimited (e.g. CSV) . + /// + /// + /// The array to parse. Elements may be of any type ( + /// will be called on each + /// element). + /// + /// + /// The delimiter to use (probably a ','). + /// + public static string ArrayToDelimitedString( + object[] source, string delimiter) + { + if (source == null) + { + return "null"; + } + else + { + return StringUtils.CollectionToDelimitedString(source, delimiter); + } + } + + /// Checks if a string has length. + /// + /// The string to check, may be . + /// + /// + /// if the string has length and is not + /// . + /// + /// + /// + /// StringUtils.HasLength(null) = false + /// StringUtils.HasLength("") = false + /// StringUtils.HasLength(" ") = true + /// StringUtils.HasLength("Hello") = true + /// + /// + public static bool HasLength(string target) + { + return (target != null && target.Length > 0); + } + + /// + /// Checks if a has text. + /// + /// + ///

+ /// More specifically, returns if the string is + /// not , it's is > + /// zero (0), and it has at least one non-whitespace character. + ///

+ ///
+ /// + /// The string to check, may be . + /// + /// + /// if the is not + /// , + /// > zero (0), and does not consist + /// solely of whitespace. + /// + /// + /// + /// StringUtils.HasText(null) = false + /// StringUtils.HasText("") = false + /// StringUtils.HasText(" ") = false + /// StringUtils.HasText("12345") = true + /// StringUtils.HasText(" 12345 ") = true + /// + /// + public static bool HasText(string target) + { + if (target == null) + { + return false; + } + else + { + return HasLength(target.Trim()); + } + } + + /// + /// Checks if a is + /// or an empty string. + /// + /// + ///

+ /// More specifically, returns if the string is + /// , it's is equal + /// to zero (0), or it is composed entirely of whitespace + /// characters. + ///

+ ///
+ /// + /// The string to check, may (obviously) be . + /// + /// + /// if the is + /// , has a length equal to zero (0), or + /// is composed entirely of whitespace characters. + /// + /// + /// + /// StringUtils.IsNullOrEmpty(null) = true + /// StringUtils.IsNullOrEmpty("") = true + /// StringUtils.IsNullOrEmpty(" ") = true + /// StringUtils.IsNullOrEmpty("12345") = false + /// StringUtils.IsNullOrEmpty(" 12345 ") = false + /// + /// + public static bool IsNullOrEmpty(string target) + { + return !HasText(target); + } + + /// + /// Strips first and last character off the string. + /// + /// The string to strip. + /// The stripped string. + public static string StripFirstAndLastCharacter(string text) + { + if (text != null + && text.Length > 2) + { + return text.Substring(1, text.Length - 2); + } + else + { + return String.Empty; + } + } + + /// + /// Returns a list of Ant-style expressions from the specified text. + /// + /// The text to inspect. + /// + /// A list of expressions that exist in the specified text. + /// + /// + /// If any of the expressions in the supplied + /// is empty (${}). + /// + public static IList GetAntExpressions(string text) + { + IList expressions = new ArrayList(); + if (StringUtils.HasText(text)) + { + int start = text.IndexOf(AntExpressionPrefix); + while (start >= 0) + { + int end = text.IndexOf(AntExpressionSuffix, start + 2); + if (end == -1) + { + // terminator character not found, so let's quit... + start = -1; + } + else + { + string exp = text.Substring(start + 2, end - start - 2); + if(StringUtils.IsNullOrEmpty(exp)) + { + throw new FormatException( + string.Format("Empty {0}{1} value found in text : '{2}'.", + AntExpressionPrefix, + AntExpressionSuffix, + text)); + } + if (expressions.IndexOf(exp) < 0) + { + expressions.Add(exp); + } + start = text.IndexOf(AntExpressionPrefix, end); + } + } + } + return expressions; + } + + /// + /// Replaces Ant-style expression placeholder with expression value. + /// + /// + ///

+ /// + ///

+ ///
+ /// The string to set the value in. + /// The name of the expression to set. + /// The expression value. + /// + /// A new string with the expression value set; the + /// value if the supplied + /// is , has a length + /// equal to zero (0), or is composed entirely of whitespace + /// characters. + /// + public static string SetAntExpression(string text, string expression, object expValue) + { + if (StringUtils.IsNullOrEmpty(text)) + { + return String.Empty; + } + if (expValue == null) + { + expValue = String.Empty; + } + return text.Replace( + StringUtils.Surround(AntExpressionPrefix, expression, AntExpressionSuffix), expValue.ToString()); + } + + /// + /// Surrounds (prepends and appends) the string value of the supplied + /// to the supplied . + /// + /// + ///

+ /// The return value of this method call is always guaranteed to be non + /// . If every value passed as a parameter to this method is + /// , the string will be returned. + ///

+ ///
+ /// + /// The prefix and suffix that respectively will be prepended and + /// appended to the target . If this value + /// is not a value, it's attendant + /// value will be used. + /// + /// + /// The target that is to be surrounded. If this value is not a + /// value, it's attendant + /// value will be used. + /// + /// The surrounded string. + public static string Surround(object fix, object target) + { + return StringUtils.Surround(fix, target, fix); + } + + /// + /// Surrounds (prepends and appends) the string values of the supplied + /// and to the supplied + /// . + /// + /// + ///

+ /// The return value of this method call is always guaranteed to be non + /// . If every value passed as a parameter to this method is + /// , the string will be returned. + ///

+ ///
+ /// + /// The value that will be prepended to the . If this value + /// is not a value, it's attendant + /// value will be used. + /// + /// + /// The target that is to be surrounded. If this value is not a + /// value, it's attendant + /// value will be used. + /// + /// + /// The value that will be appended to the . If this value + /// is not a value, it's attendant + /// value will be used. + /// + /// The surrounded string. + public static string Surround(object prefix, object target, object suffix) + { + return string.Format( + CultureInfo.InvariantCulture, "{0}{1}{2}", prefix, target, suffix); + } + + /// + /// Converts escaped characters (for example "\t") within a string + /// to their real character. + /// + /// The string to convert. + /// The converted string. + public static string ConvertEscapedCharacters( string inputString ) + { + StringBuilder sb = new StringBuilder(inputString.Length); + for (int i = 0 ; i < inputString.Length ; i++) + { + if (inputString[i].Equals('\\')) + { + i++; + if (inputString[i].Equals('t')) + { + sb.Append('\t'); + } + else if (inputString[i].Equals('r')) + { + sb.Append('\r'); + } + else if (inputString[i].Equals('n')) + { + sb.Append('\n'); + } + else if (inputString[i].Equals('\\')) + { + sb.Append('\\'); + } + else + { + sb.Append("\\" + inputString[i]); + } + } + else + { + sb.Append(inputString[i]); + } + } + return sb.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/SystemUtils.cs b/src/Spring/Spring.Core/Util/SystemUtils.cs index c927f2f5..ddba4339 100644 --- a/src/Spring/Spring.Core/Util/SystemUtils.cs +++ b/src/Spring/Spring.Core/Util/SystemUtils.cs @@ -1,117 +1,116 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Configuration; -using System.Reflection; -using System.Threading; -using System.Xml; - -#endregion - -namespace Spring.Util -{ - /// - /// Utility class containing miscellaneous system-level functionality. - /// - /// Aleksandar Seovic - /// $Id: SystemUtils.cs,v 1.5 2007/09/07 02:46:49 markpollack Exp $ - public sealed class SystemUtils - { - private static bool assemblyResolverRegistered = false; - private static object assemblyResolverLock = new object(); - - private static readonly bool isMono = Type.GetType("Mono.Runtime") == null ? false : true; - - /// - /// Registers assembly resolver that iterates over the - /// assemblies loaded into the current - /// in order to find an assembly that cannot be resolved. - /// - /// - /// This method has to be called if you need to serialize dynamically - /// generated types in transient assemblies, such as Spring AOP proxies, - /// because standard .NET serialization engine always tries to load - /// assembly from the disk. - /// - public static void RegisterLoadedAssemblyResolver() - { - if (!assemblyResolverRegistered) - { - lock(assemblyResolverLock) - { - AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(LoadedAssemblyResolver); - assemblyResolverRegistered = true; - } - } - } - - private static Assembly LoadedAssemblyResolver(object sender, ResolveEventArgs args) - { - Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly assembly in loadedAssemblies) - { - if (assembly.FullName == args.Name) - { - return assembly; - } - } - return null; - } - - - /// - /// Returns true if running on Mono - /// - /// Tests for the presence of the type Mono.Runtime - public static bool MonoRuntime - { - get { return isMono; } - } - - /// - /// Gets the thread id for the current thread. Use thread name is available, - /// otherwise use CurrentThread.GetHashCode() for .NET 1.0/1.1 and - /// CurrentThread.ManagedThreadId otherwise. - /// - /// The thread id. - public static string ThreadId - { - get - { - string name = Thread.CurrentThread.Name; - if (StringUtils.HasText(name)) - { - return name; - } - else - { -#if NET_1_0 || NET_1_1 - return Thread.CurrentThread.GetHashCode().ToString(); -#else - return Thread.CurrentThread.ManagedThreadId.ToString(); -#endif - } - } - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Configuration; +using System.Reflection; +using System.Threading; +using System.Xml; + +#endregion + +namespace Spring.Util +{ + /// + /// Utility class containing miscellaneous system-level functionality. + /// + /// Aleksandar Seovic + public sealed class SystemUtils + { + private static bool assemblyResolverRegistered = false; + private static object assemblyResolverLock = new object(); + + private static readonly bool isMono = Type.GetType("Mono.Runtime") == null ? false : true; + + /// + /// Registers assembly resolver that iterates over the + /// assemblies loaded into the current + /// in order to find an assembly that cannot be resolved. + /// + /// + /// This method has to be called if you need to serialize dynamically + /// generated types in transient assemblies, such as Spring AOP proxies, + /// because standard .NET serialization engine always tries to load + /// assembly from the disk. + /// + public static void RegisterLoadedAssemblyResolver() + { + if (!assemblyResolverRegistered) + { + lock(assemblyResolverLock) + { + AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(LoadedAssemblyResolver); + assemblyResolverRegistered = true; + } + } + } + + private static Assembly LoadedAssemblyResolver(object sender, ResolveEventArgs args) + { + Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (Assembly assembly in loadedAssemblies) + { + if (assembly.FullName == args.Name) + { + return assembly; + } + } + return null; + } + + + /// + /// Returns true if running on Mono + /// + /// Tests for the presence of the type Mono.Runtime + public static bool MonoRuntime + { + get { return isMono; } + } + + /// + /// Gets the thread id for the current thread. Use thread name is available, + /// otherwise use CurrentThread.GetHashCode() for .NET 1.0/1.1 and + /// CurrentThread.ManagedThreadId otherwise. + /// + /// The thread id. + public static string ThreadId + { + get + { + string name = Thread.CurrentThread.Name; + if (StringUtils.HasText(name)) + { + return name; + } + else + { +#if NET_1_0 || NET_1_1 + return Thread.CurrentThread.GetHashCode().ToString(); +#else + return Thread.CurrentThread.ManagedThreadId.ToString(); +#endif + } + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/UniqueKey.cs b/src/Spring/Spring.Core/Util/UniqueKey.cs index db6213c7..128f9c4e 100644 --- a/src/Spring/Spring.Core/Util/UniqueKey.cs +++ b/src/Spring/Spring.Core/Util/UniqueKey.cs @@ -1,175 +1,175 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.ComponentModel; -using System.Text; -using Spring.Core.TypeConversion; - -#endregion - -namespace Spring.Util -{ - /// - /// UniqueKey allows for generating keys unique to a type or particular instance and a partial name, - /// that can e.g. be used as keys in . - /// - /// - /// // shows usage type-scoped keys - /// UniqueKey classAKey = UniqueKey.GetTypeScoped(typeof(ClassA), "myKey"); - /// UniqueKey classBKey = UniqueKey.GetTypeScoped(typeof(ClassB), "myKey"); - /// - /// HttpContext.Current.Items.Add( classAKey, "some value unqiue for class A having key 'myKey'"); - /// object value = HttpContext.Current.Items[ UniqueKey.GetTypeScoped(typeof(ClassA), "myKey") ]; - /// Assert.AreEqual( "some value unique for class A having key 'myKey'", value); - /// - /// HttpContext.Current.Items.Add( classBKey, "some value unqiue for class B having key 'myKey'"); - /// object value = HttpContext.Current.Items[ UniqueKey.GetTypeScoped(typeof(ClassB), "myKey") ]; - /// Assert.AreEqual( "some value unique for class B having key 'myKey'", value); - /// - [Serializable] - [TypeConverter(typeof(UniqueKeyConverter))] - public sealed class UniqueKey -#if NET_2_0 - : IEquatable -#endif - { - private readonly string _generatedKey; - - /// - /// Initialize a new instance of from its string representation. - /// See and See for details. - /// - /// The string representation of the new instance. - internal UniqueKey(string key) - { - AssertUtils.ArgumentNotNull(key, "key"); - _generatedKey = key; - } - - /// - /// Compares this instance to another. - /// - public bool Equals(UniqueKey uniqueKey) - { - if (uniqueKey == null) return false; - return Equals(_generatedKey, uniqueKey._generatedKey); - } - - /// - /// Compares this instance to another. - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(this, obj)) return true; - return Equals(obj as UniqueKey); - } - - /// - /// Returns the hash code for this key. - /// - /// - public override int GetHashCode() - { - return _generatedKey.GetHashCode(); - } - - /// - /// Returns a string representation of this key. - /// - public override string ToString() - { - return _generatedKey; - } - - /// - /// Creates a new key instance unique to the given instance. - /// - /// The instance the key shall be unique to - /// The partial key to be made unique - /// - /// - /// If is of type - public static UniqueKey GetInstanceScoped(object instance, string partialKey) - { - if (instance is Type) - { - throw new ArgumentException( - "please use GetTypeScoped(Type,string) for creating type specific keys", "instance"); - } - return new UniqueKey(GetInstanceScopedString(instance, partialKey)); - } - - /// - /// Creates a new key instance unique to the given type. - /// - /// The type the key shall be unique to - /// The partial key to be made unique - public static UniqueKey GetTypeScoped(Type type, string partialKey) - { - return new UniqueKey(GetTypeScopedString(type, partialKey)); - } - - /// - /// Returns a key unique for the given instance. - /// - /// The instance the key shall be unique to - /// The partial key to be made unique - /// A key formatted as typename[instance-id].partialkey - public static string GetInstanceScopedString(object instance, string partialKey) - { - AssertUtils.ArgumentNotNull(instance, "instance"); - AssertUtils.ArgumentHasText(partialKey, "partialKey"); - - if (instance is Type) - { - throw new ArgumentException( - "please use GetUniqueKey(Type,string) for creating type specific keys", "instance"); - } - return GetUniqueKey(instance.GetType(), instance, partialKey); - } - - /// - /// Returns a key unique for the given type. - /// - /// The type the key shall be unique to - /// The partial key to be made unique - /// A key formatted as typename.partialkey - public static string GetTypeScopedString(Type type, string partialKey) - { - AssertUtils.ArgumentNotNull(type, "type"); - AssertUtils.ArgumentHasText(partialKey, "partialKey"); - - return GetUniqueKey(type, null, partialKey); - } - - private static string GetUniqueKey(Type type, object instance, string partialKey) - { - StringBuilder sb = new StringBuilder(); - sb.Append(type.FullName); - if (instance != null) sb.Append('[').Append(instance.GetHashCode()).Append(']'); - sb.Append('.').Append(partialKey); - return sb.ToString(); - } - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.ComponentModel; +using System.Text; +using Spring.Core.TypeConversion; + +#endregion + +namespace Spring.Util +{ + /// + /// UniqueKey allows for generating keys unique to a type or particular instance and a partial name, + /// that can e.g. be used as keys in . + /// + /// + /// // shows usage type-scoped keys + /// UniqueKey classAKey = UniqueKey.GetTypeScoped(typeof(ClassA), "myKey"); + /// UniqueKey classBKey = UniqueKey.GetTypeScoped(typeof(ClassB), "myKey"); + /// + /// HttpContext.Current.Items.Add( classAKey, "some value unqiue for class A having key 'myKey'"); + /// object value = HttpContext.Current.Items[ UniqueKey.GetTypeScoped(typeof(ClassA), "myKey") ]; + /// Assert.AreEqual( "some value unique for class A having key 'myKey'", value); + /// + /// HttpContext.Current.Items.Add( classBKey, "some value unqiue for class B having key 'myKey'"); + /// object value = HttpContext.Current.Items[ UniqueKey.GetTypeScoped(typeof(ClassB), "myKey") ]; + /// Assert.AreEqual( "some value unique for class B having key 'myKey'", value); + /// + [Serializable] + [TypeConverter(typeof(UniqueKeyConverter))] + public sealed class UniqueKey +#if NET_2_0 + : IEquatable +#endif + { + private readonly string _generatedKey; + + /// + /// Initialize a new instance of from its string representation. + /// See and See for details. + /// + /// The string representation of the new instance. + internal UniqueKey(string key) + { + AssertUtils.ArgumentNotNull(key, "key"); + _generatedKey = key; + } + + /// + /// Compares this instance to another. + /// + public bool Equals(UniqueKey uniqueKey) + { + if (uniqueKey == null) return false; + return Equals(_generatedKey, uniqueKey._generatedKey); + } + + /// + /// Compares this instance to another. + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) return true; + return Equals(obj as UniqueKey); + } + + /// + /// Returns the hash code for this key. + /// + /// + public override int GetHashCode() + { + return _generatedKey.GetHashCode(); + } + + /// + /// Returns a string representation of this key. + /// + public override string ToString() + { + return _generatedKey; + } + + /// + /// Creates a new key instance unique to the given instance. + /// + /// The instance the key shall be unique to + /// The partial key to be made unique + /// + /// + /// If is of type + public static UniqueKey GetInstanceScoped(object instance, string partialKey) + { + if (instance is Type) + { + throw new ArgumentException( + "please use GetTypeScoped(Type,string) for creating type specific keys", "instance"); + } + return new UniqueKey(GetInstanceScopedString(instance, partialKey)); + } + + /// + /// Creates a new key instance unique to the given type. + /// + /// The type the key shall be unique to + /// The partial key to be made unique + public static UniqueKey GetTypeScoped(Type type, string partialKey) + { + return new UniqueKey(GetTypeScopedString(type, partialKey)); + } + + /// + /// Returns a key unique for the given instance. + /// + /// The instance the key shall be unique to + /// The partial key to be made unique + /// A key formatted as typename[instance-id].partialkey + public static string GetInstanceScopedString(object instance, string partialKey) + { + AssertUtils.ArgumentNotNull(instance, "instance"); + AssertUtils.ArgumentHasText(partialKey, "partialKey"); + + if (instance is Type) + { + throw new ArgumentException( + "please use GetUniqueKey(Type,string) for creating type specific keys", "instance"); + } + return GetUniqueKey(instance.GetType(), instance, partialKey); + } + + /// + /// Returns a key unique for the given type. + /// + /// The type the key shall be unique to + /// The partial key to be made unique + /// A key formatted as typename.partialkey + public static string GetTypeScopedString(Type type, string partialKey) + { + AssertUtils.ArgumentNotNull(type, "type"); + AssertUtils.ArgumentHasText(partialKey, "partialKey"); + + return GetUniqueKey(type, null, partialKey); + } + + private static string GetUniqueKey(Type type, object instance, string partialKey) + { + StringBuilder sb = new StringBuilder(); + sb.Append(type.FullName); + if (instance != null) sb.Append('[').Append(instance.GetHashCode()).Append(']'); + sb.Append('.').Append(partialKey); + return sb.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/XmlUtils.cs b/src/Spring/Spring.Core/Util/XmlUtils.cs index 9f2778e4..d974ae72 100644 --- a/src/Spring/Spring.Core/Util/XmlUtils.cs +++ b/src/Spring/Spring.Core/Util/XmlUtils.cs @@ -1,151 +1,150 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Configuration; -using System.Xml; -using System.IO; -using System.Xml.Schema; - -#endregion - -namespace Spring.Util -{ - /// - /// XML utility methods. - /// - /// Aleksandar Seovic - /// $Id: XmlUtils.cs,v 1.5 2007/04/22 00:02:38 oakinger Exp $ - public class XmlUtils - { -#if !NET_2_0 - /// - /// Gets an appropriate implementation - /// for the supplied . - /// - /// The XML that is going to be read. - /// XML schemas that should be used for validation. - /// Validation event handler. - /// - /// A validating implementation. - /// - public static XmlReader CreateValidatingReader(Stream stream, XmlSchemaCollection schemas, ValidationEventHandler eventHandler) - { - return CreateValidatingReader(stream, new XmlUrlResolver(), schemas, eventHandler); - } - - /// - /// Gets an appropriate implementation - /// for the supplied . - /// - /// The XML that is going to be read. - /// to be used for resolving external references - /// XML schemas that should be used for validation. - /// Validation event handler. - /// - /// A validating implementation. - /// - public static XmlReader CreateValidatingReader(Stream stream, XmlResolver xmlResolver, XmlSchemaCollection schemas, ValidationEventHandler eventHandler) - { - XmlValidatingReader reader = new XmlValidatingReader(new XmlTextReader(stream)); - reader.XmlResolver = xmlResolver; - reader.Schemas.Add(schemas); - reader.ValidationType = ValidationType.Schema; - if (eventHandler != null) - { - reader.ValidationEventHandler += eventHandler; - } - return reader; - } -#else - /// - /// Gets an appropriate implementation - /// for the supplied . - /// - /// The XML that is going to be read. - /// XML schemas that should be used for validation. - /// Validation event handler. - /// - /// A validating implementation. - /// - public static XmlReader CreateValidatingReader(Stream stream, XmlSchemaSet schemas, ValidationEventHandler eventHandler) - { - return CreateValidatingReader(stream, new XmlUrlResolver(), schemas, eventHandler); - } - - /// - /// Gets an appropriate implementation - /// for the supplied . - /// - /// The XML that is going to be read. - /// to be used for resolving external references - /// XML schemas that should be used for validation. - /// Validation event handler. - /// - /// A validating implementation. - /// - public static XmlReader CreateValidatingReader(Stream stream, XmlResolver xmlResolver, XmlSchemaSet schemas, ValidationEventHandler eventHandler) - { - XmlReaderSettings settings = new XmlReaderSettings(); - settings.XmlResolver = xmlResolver; - settings.Schemas.Add(schemas); - settings.ValidationType = ValidationType.Schema; - if (eventHandler != null) - { - settings.ValidationEventHandler += eventHandler; - } - - return XmlReader.Create(stream, settings); - } -#endif - - -#if !NET_2_0 - /// - /// Gets an implementation - /// for the supplied . - /// - /// The XML that is going to be read. - /// - /// A non-validating implementation. - /// - public static XmlReader CreateReader(Stream stream) - { - return new XmlTextReader(stream); - } -#else - - /// - /// Gets an appropriate implementation - /// for the supplied . - /// - /// The XML that is going to be read. - /// - /// A non-validating implementation. - /// - public static XmlReader CreateReader(Stream stream) - { - return XmlReader.Create(stream); - } -#endif - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Configuration; +using System.Xml; +using System.IO; +using System.Xml.Schema; + +#endregion + +namespace Spring.Util +{ + /// + /// XML utility methods. + /// + /// Aleksandar Seovic + public class XmlUtils + { +#if !NET_2_0 + /// + /// Gets an appropriate implementation + /// for the supplied . + /// + /// The XML that is going to be read. + /// XML schemas that should be used for validation. + /// Validation event handler. + /// + /// A validating implementation. + /// + public static XmlReader CreateValidatingReader(Stream stream, XmlSchemaCollection schemas, ValidationEventHandler eventHandler) + { + return CreateValidatingReader(stream, new XmlUrlResolver(), schemas, eventHandler); + } + + /// + /// Gets an appropriate implementation + /// for the supplied . + /// + /// The XML that is going to be read. + /// to be used for resolving external references + /// XML schemas that should be used for validation. + /// Validation event handler. + /// + /// A validating implementation. + /// + public static XmlReader CreateValidatingReader(Stream stream, XmlResolver xmlResolver, XmlSchemaCollection schemas, ValidationEventHandler eventHandler) + { + XmlValidatingReader reader = new XmlValidatingReader(new XmlTextReader(stream)); + reader.XmlResolver = xmlResolver; + reader.Schemas.Add(schemas); + reader.ValidationType = ValidationType.Schema; + if (eventHandler != null) + { + reader.ValidationEventHandler += eventHandler; + } + return reader; + } +#else + /// + /// Gets an appropriate implementation + /// for the supplied . + /// + /// The XML that is going to be read. + /// XML schemas that should be used for validation. + /// Validation event handler. + /// + /// A validating implementation. + /// + public static XmlReader CreateValidatingReader(Stream stream, XmlSchemaSet schemas, ValidationEventHandler eventHandler) + { + return CreateValidatingReader(stream, new XmlUrlResolver(), schemas, eventHandler); + } + + /// + /// Gets an appropriate implementation + /// for the supplied . + /// + /// The XML that is going to be read. + /// to be used for resolving external references + /// XML schemas that should be used for validation. + /// Validation event handler. + /// + /// A validating implementation. + /// + public static XmlReader CreateValidatingReader(Stream stream, XmlResolver xmlResolver, XmlSchemaSet schemas, ValidationEventHandler eventHandler) + { + XmlReaderSettings settings = new XmlReaderSettings(); + settings.XmlResolver = xmlResolver; + settings.Schemas.Add(schemas); + settings.ValidationType = ValidationType.Schema; + if (eventHandler != null) + { + settings.ValidationEventHandler += eventHandler; + } + + return XmlReader.Create(stream, settings); + } +#endif + + +#if !NET_2_0 + /// + /// Gets an implementation + /// for the supplied . + /// + /// The XML that is going to be read. + /// + /// A non-validating implementation. + /// + public static XmlReader CreateReader(Stream stream) + { + return new XmlTextReader(stream); + } +#else + + /// + /// Gets an appropriate implementation + /// for the supplied . + /// + /// The XML that is going to be read. + /// + /// A non-validating implementation. + /// + public static XmlReader CreateReader(Stream stream) + { + return XmlReader.Create(stream); + } +#endif + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/Actions/ErrorMessageAction.cs b/src/Spring/Spring.Core/Validation/Actions/ErrorMessageAction.cs index b58f2adc..2c0ad762 100644 --- a/src/Spring/Spring.Core/Validation/Actions/ErrorMessageAction.cs +++ b/src/Spring/Spring.Core/Validation/Actions/ErrorMessageAction.cs @@ -1,121 +1,120 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; - -using Spring.Expressions; -using Spring.Util; - -namespace Spring.Validation.Actions -{ - /// - /// Implementation of that adds error message - /// to the validation errors container. - /// - /// Aleksandar Seovic - /// $Id: ErrorMessageAction.cs,v 1.5 2008/02/05 20:40:25 aseovic Exp $ - public class ErrorMessageAction : BaseValidationAction - { - private string messageId; - private IExpression[] messageParams; - private string[] providers; - - /// - /// Initializes a new instance of the class. - /// - /// Error message resource identifier. - /// Names of the error providers this message should be added to. - public ErrorMessageAction(string messageId, params string[] providers) - { - AssertUtils.ArgumentHasText(messageId, "messageId"); - if (providers == null || providers.Length == 0) - { - throw new ArgumentException("At least one error provider has to be specified.", "providers"); - } - - this.messageId = messageId; - this.providers = providers; - } - - /// - /// Sets the expressions that should be resolved to error message parameters. - /// - /// The expressions that should be resolved to error message parameters. - public IExpression[] Parameters - { - set { messageParams = value; } - } - - /// - /// Called when associated validator is invalid. - /// - /// Validation context. - /// Additional context parameters. - /// Validation errors container. - protected override void OnInvalid(object validationContext, IDictionary contextParams, IValidationErrors errors) - { - ErrorMessage error = CreateErrorMessage(validationContext, contextParams); - foreach (string provider in this.providers) - { - errors.AddError(provider.Trim(), error); - } - } - - /// - /// Resolves the error message. - /// - /// Validation context to resolve message parameters against. - /// Additional context parameters. - /// Resolved error message - private ErrorMessage CreateErrorMessage(object validationContext, IDictionary contextParams) - { - if (messageParams != null && messageParams.Length > 0) - { - object[] parameters = ResolveMessageParameters(messageParams, validationContext, contextParams); - return new ErrorMessage(messageId, parameters); - } - else - { - return new ErrorMessage(messageId, null); - } - } - - /// - /// Resolves the message parameters. - /// - /// List of parameters to resolve. - /// Validation context to resolve parameters against. - /// Additional context parameters. - /// Resolved message parameters. - private object[] ResolveMessageParameters(IList messageParams, object validationContext, IDictionary contextParams) - { - object[] parameters = new object[messageParams.Count]; - for (int i = 0; i < messageParams.Count; i++) - { - parameters[i] = ((IExpression) messageParams[i]).GetValue(validationContext, contextParams); - } - - return parameters; - } - - - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; + +using Spring.Expressions; +using Spring.Util; + +namespace Spring.Validation.Actions +{ + /// + /// Implementation of that adds error message + /// to the validation errors container. + /// + /// Aleksandar Seovic + public class ErrorMessageAction : BaseValidationAction + { + private string messageId; + private IExpression[] messageParams; + private string[] providers; + + /// + /// Initializes a new instance of the class. + /// + /// Error message resource identifier. + /// Names of the error providers this message should be added to. + public ErrorMessageAction(string messageId, params string[] providers) + { + AssertUtils.ArgumentHasText(messageId, "messageId"); + if (providers == null || providers.Length == 0) + { + throw new ArgumentException("At least one error provider has to be specified.", "providers"); + } + + this.messageId = messageId; + this.providers = providers; + } + + /// + /// Sets the expressions that should be resolved to error message parameters. + /// + /// The expressions that should be resolved to error message parameters. + public IExpression[] Parameters + { + set { messageParams = value; } + } + + /// + /// Called when associated validator is invalid. + /// + /// Validation context. + /// Additional context parameters. + /// Validation errors container. + protected override void OnInvalid(object validationContext, IDictionary contextParams, IValidationErrors errors) + { + ErrorMessage error = CreateErrorMessage(validationContext, contextParams); + foreach (string provider in this.providers) + { + errors.AddError(provider.Trim(), error); + } + } + + /// + /// Resolves the error message. + /// + /// Validation context to resolve message parameters against. + /// Additional context parameters. + /// Resolved error message + private ErrorMessage CreateErrorMessage(object validationContext, IDictionary contextParams) + { + if (messageParams != null && messageParams.Length > 0) + { + object[] parameters = ResolveMessageParameters(messageParams, validationContext, contextParams); + return new ErrorMessage(messageId, parameters); + } + else + { + return new ErrorMessage(messageId, null); + } + } + + /// + /// Resolves the message parameters. + /// + /// List of parameters to resolve. + /// Validation context to resolve parameters against. + /// Additional context parameters. + /// Resolved message parameters. + private object[] ResolveMessageParameters(IList messageParams, object validationContext, IDictionary contextParams) + { + object[] parameters = new object[messageParams.Count]; + for (int i = 0; i < messageParams.Count; i++) + { + parameters[i] = ((IExpression) messageParams[i]).GetValue(validationContext, contextParams); + } + + return parameters; + } + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/Actions/ExpressionAction.cs b/src/Spring/Spring.Core/Validation/Actions/ExpressionAction.cs index fc49b5fb..36762ea3 100644 --- a/src/Spring/Spring.Core/Validation/Actions/ExpressionAction.cs +++ b/src/Spring/Spring.Core/Validation/Actions/ExpressionAction.cs @@ -1,113 +1,112 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; - -using Spring.Expressions; - -namespace Spring.Validation.Actions -{ - /// - /// Implementation of that allows you - /// to define Spring.NET expressions that should be evaluated after - /// validation. - /// - /// Aleksandar Seovic - /// $Id: ExpressionAction.cs,v 1.6 2008/02/05 20:40:25 aseovic Exp $ - public class ExpressionAction : BaseValidationAction - { - private IExpression onValid; - private IExpression onInvalid; - - /// - /// Initializes a new instance of the class. - /// - public ExpressionAction() - {} - - /// - /// Initializes a new instance of the class. - /// - /// Expression to execute when validator is valid. - /// Expression to execute when validator is not valid. - public ExpressionAction(string onValid, string onInvalid) - : this((onValid != null ? Expression.Parse(onValid) : null), (onInvalid != null ? Expression.Parse(onInvalid) : null)) - {} - - /// - /// Initializes a new instance of the class. - /// - /// Expression to execute when validator is valid. - /// Expression to execute when validator is not valid. - public ExpressionAction(IExpression onValid, IExpression onInvalid) - { - this.onValid = onValid; - this.onInvalid = onInvalid; - } - - /// - /// Gets or sets the expression to execute when validator is valid. - /// - /// The expression to execute when validator is valid. - public IExpression Valid - { - get { return onValid; } - set { onValid = value; } - } - - /// - /// Gets or sets the expression to execute when validator is not valid. - /// - /// The expression to execute when validator is not valid. - public IExpression Invalid - { - get { return onInvalid; } - set { onInvalid = value; } - } - - /// - /// Called when associated validator is valid. - /// - /// Validation context. - /// Additional context parameters. - /// Validation errors container. - protected override void OnValid(object validationContext, IDictionary contextParams, IValidationErrors errors) - { - if (Valid != null) - { - Valid.GetValue(validationContext, contextParams); - } - } - - /// - /// Called when associated validator is invalid. - /// - /// Validation context. - /// Additional context parameters. - /// Validation errors container. - protected override void OnInvalid(object validationContext, IDictionary contextParams, IValidationErrors errors) - { - if (Invalid != null) - { - Invalid.GetValue(validationContext, contextParams); - } - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; + +using Spring.Expressions; + +namespace Spring.Validation.Actions +{ + /// + /// Implementation of that allows you + /// to define Spring.NET expressions that should be evaluated after + /// validation. + /// + /// Aleksandar Seovic + public class ExpressionAction : BaseValidationAction + { + private IExpression onValid; + private IExpression onInvalid; + + /// + /// Initializes a new instance of the class. + /// + public ExpressionAction() + {} + + /// + /// Initializes a new instance of the class. + /// + /// Expression to execute when validator is valid. + /// Expression to execute when validator is not valid. + public ExpressionAction(string onValid, string onInvalid) + : this((onValid != null ? Expression.Parse(onValid) : null), (onInvalid != null ? Expression.Parse(onInvalid) : null)) + {} + + /// + /// Initializes a new instance of the class. + /// + /// Expression to execute when validator is valid. + /// Expression to execute when validator is not valid. + public ExpressionAction(IExpression onValid, IExpression onInvalid) + { + this.onValid = onValid; + this.onInvalid = onInvalid; + } + + /// + /// Gets or sets the expression to execute when validator is valid. + /// + /// The expression to execute when validator is valid. + public IExpression Valid + { + get { return onValid; } + set { onValid = value; } + } + + /// + /// Gets or sets the expression to execute when validator is not valid. + /// + /// The expression to execute when validator is not valid. + public IExpression Invalid + { + get { return onInvalid; } + set { onInvalid = value; } + } + + /// + /// Called when associated validator is valid. + /// + /// Validation context. + /// Additional context parameters. + /// Validation errors container. + protected override void OnValid(object validationContext, IDictionary contextParams, IValidationErrors errors) + { + if (Valid != null) + { + Valid.GetValue(validationContext, contextParams); + } + } + + /// + /// Called when associated validator is invalid. + /// + /// Validation context. + /// Additional context parameters. + /// Validation errors container. + protected override void OnInvalid(object validationContext, IDictionary contextParams, IValidationErrors errors) + { + if (Invalid != null) + { + Invalid.GetValue(validationContext, contextParams); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/AnyValidatorGroup.cs b/src/Spring/Spring.Core/Validation/AnyValidatorGroup.cs index 0392f047..81e05e82 100644 --- a/src/Spring/Spring.Core/Validation/AnyValidatorGroup.cs +++ b/src/Spring/Spring.Core/Validation/AnyValidatorGroup.cs @@ -39,7 +39,6 @@ namespace Spring.Validation ///

///
/// Aleksandar Seovic - /// $Id: AnyValidatorGroup.cs,v 1.9 2008/02/05 20:40:26 aseovic Exp $ public class AnyValidatorGroup : ValidatorGroup { #region Constructors diff --git a/src/Spring/Spring.Core/Validation/BaseValidationAction.cs b/src/Spring/Spring.Core/Validation/BaseValidationAction.cs index e33265f5..76575e3a 100644 --- a/src/Spring/Spring.Core/Validation/BaseValidationAction.cs +++ b/src/Spring/Spring.Core/Validation/BaseValidationAction.cs @@ -38,7 +38,6 @@ namespace Spring.Validation ///

///
/// Aleksandar Seovic - /// $Id: BaseValidationAction.cs,v 1.6 2008/02/05 20:40:26 aseovic Exp $ public abstract class BaseValidationAction : IValidationAction { #region Fields diff --git a/src/Spring/Spring.Core/Validation/BaseValidator.cs b/src/Spring/Spring.Core/Validation/BaseValidator.cs index 50afd40b..2820d339 100644 --- a/src/Spring/Spring.Core/Validation/BaseValidator.cs +++ b/src/Spring/Spring.Core/Validation/BaseValidator.cs @@ -40,7 +40,6 @@ namespace Spring.Validation ///

/// /// Aleksandar Seovic - /// $Id: BaseValidator.cs,v 1.12 2008/02/05 20:40:26 aseovic Exp $ public abstract class BaseValidator : IValidator { #region Fields diff --git a/src/Spring/Spring.Core/Validation/CollectionValidator.cs b/src/Spring/Spring.Core/Validation/CollectionValidator.cs index 1b5c1e5b..909e16a2 100644 --- a/src/Spring/Spring.Core/Validation/CollectionValidator.cs +++ b/src/Spring/Spring.Core/Validation/CollectionValidator.cs @@ -25,7 +25,6 @@ namespace Spring.Validation /// /// Damjan Tomic /// Aleksandar Seovic - /// $Id: CollectionValidator.cs,v 1.5 2008/02/05 20:40:26 aseovic Exp $ public class CollectionValidator : ValidatorGroup { #region Fields diff --git a/src/Spring/Spring.Core/Validation/Config/ValidationNamespaceParser.cs b/src/Spring/Spring.Core/Validation/Config/ValidationNamespaceParser.cs index 23480a8a..c5eb9ea0 100644 --- a/src/Spring/Spring.Core/Validation/Config/ValidationNamespaceParser.cs +++ b/src/Spring/Spring.Core/Validation/Config/ValidationNamespaceParser.cs @@ -1,383 +1,382 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Xml; - -using Spring.Core.TypeResolution; -using Spring.Context.Support; -using Spring.Expressions; -using Spring.Objects; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Threading; -using Spring.Util; - -#endregion - -namespace Spring.Validation.Config -{ - /// - /// Implementation of the custom configuration parser for validator definitions. - /// - /// Aleksandar Seovic - /// $Id: ValidationNamespaceParser.cs,v 1.2 2007/08/08 00:34:17 bbaia Exp $ - [ - NamespaceParser( - Namespace = "http://www.springframework.net/validation", - SchemaLocationAssemblyHint = typeof(ValidationNamespaceParser), - SchemaLocation = "/Spring.Validation.Config/spring-validation-1.1.xsd") - ] - public sealed class ValidationNamespaceParser : ObjectsNamespaceParser - { - private const string ValidatorTypePrefix = "validator: "; - -// [ThreadStatic] -// private int definitionCount = 0; - private readonly string key_DefinitionCount; - private int definitionCount - { - get - { - object tmp = LogicalThreadContext.GetData(key_DefinitionCount); - if (tmp != null) return (int)tmp; - LogicalThreadContext.SetData(key_DefinitionCount, 0); - return 0; - } - set - { - LogicalThreadContext.SetData(key_DefinitionCount, value); - } - } - - static ValidationNamespaceParser() - { - TypeRegistry.RegisterType(ValidatorTypePrefix + "group", typeof(ValidatorGroup)); - TypeRegistry.RegisterType(ValidatorTypePrefix + "any", typeof(AnyValidatorGroup)); - TypeRegistry.RegisterType(ValidatorTypePrefix + "exclusive", typeof(ExclusiveValidatorGroup)); - - - TypeRegistry.RegisterType(ValidatorTypePrefix + "collection", typeof(CollectionValidator)); - TypeRegistry.RegisterType(ValidatorTypePrefix + "required", typeof(RequiredValidator)); - TypeRegistry.RegisterType(ValidatorTypePrefix + "condition", typeof(ConditionValidator)); - TypeRegistry.RegisterType(ValidatorTypePrefix + "regex", typeof(RegularExpressionValidator)); - } - - /// - /// Initializes a new instance of the class. - /// - public ValidationNamespaceParser() - { - // generate unique key for instance field to be stored in LogicalThreadContext - string FIELDPREFIX = typeof(ValidationNamespaceParser).FullName + base.GetHashCode(); - key_DefinitionCount = FIELDPREFIX + ".definitionCount"; - } - - - /// - /// Parse the specified element and register any resulting - /// IObjectDefinitions with the IObjectDefinitionRegistry that is - /// embedded in the supplied ParserContext. - /// - /// The element to be parsed into one or more IObjectDefinitions - /// The object encapsulating the current state of the parsing - /// process. - /// - /// The primary IObjectDefinition (can be null as explained above) - /// - /// - /// Implementations should return the primary IObjectDefinition - /// that results from the parse phase if they wish to used nested - /// inside (for example) a <property> tag. - /// Implementations may return null if they will not - /// be used in a nested scenario. - /// - /// - public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - if (!element.HasAttribute("id")) - { - throw new ObjectDefinitionStoreException(parserContext.ReaderContext.Resource, "validator", "Top-level validator element must have an 'id' attribute defined."); - } - this.definitionCount = 0; - - //TODO pass down parserContext... - ParseAndRegisterValidator(element, parserContext.ParserHelper); - - return null; - //return definitionCount; - } - - /// - /// Parses the validator definition. - /// - /// Validator's identifier. - /// The element to parse. - /// The parser helper. - /// Validator object definition. - private IObjectDefinition ParseValidator(string id, XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string typeName = GetTypeName(element); - string parent = element.GetAttribute(ObjectDefinitionConstants.ParentAttribute); - string test = element.GetAttribute(ValidatorDefinitionConstants.TestAttribute); - string when = element.GetAttribute(ValidatorDefinitionConstants.WhenAttribute); - string validateAll = element.GetAttribute(ValidatorDefinitionConstants.CollectionValidateAllAttribute); - string context = element.GetAttribute(ValidatorDefinitionConstants.CollectionContextAttribute); - string includeElementsErrors = element.GetAttribute(ValidatorDefinitionConstants.CollectionIncludeElementsErrors); - - string name = "validator: " + (StringUtils.HasText(id) ? id : this.definitionCount.ToString()); - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(test)) - { - properties.Add("Test", test); - } - if (StringUtils.HasText(when)) - { - properties.Add("When", when); - } - if (StringUtils.HasText(validateAll)) - { - properties.Add("ValidateAll", validateAll); - } - if (StringUtils.HasText(validateAll)) - { - properties.Add("Context", context); - } - if (StringUtils.HasText(includeElementsErrors)) - { - properties.Add("IncludeElementErrors", includeElementsErrors); - } - - - ManagedList nestedValidators = new ManagedList(); - ManagedList actions = new ManagedList(); - foreach (XmlNode node in element.ChildNodes) - { - XmlElement child = node as XmlElement; - if (child != null) - { - switch (child.LocalName) - { - case ValidatorDefinitionConstants.PropertyElement: - string propertyName = child.GetAttribute(ValidatorDefinitionConstants.PropertyNameAttribute); - properties.Add(propertyName, base.GetPropertyValue(child, name, parserHelper)); - break; - case ValidatorDefinitionConstants.MessageElement: - actions.Add(ParseErrorMessageAction(child, parserHelper)); - break; - case ValidatorDefinitionConstants.ActionElement: - actions.Add(ParseGenericAction(child, parserHelper)); - break; - case ValidatorDefinitionConstants.ReferenceElement: - nestedValidators.Add(ParseValidatorReference(child, parserHelper)); - break; - default: - nestedValidators.Add(ParseAndRegisterValidator(child, parserHelper)); - break; - } - } - } - if (nestedValidators.Count > 0) - { - properties.Add("Validators", nestedValidators); - } - if (actions.Count > 0) - { - properties.Add("Actions", actions); - } - - IConfigurableObjectDefinition od - = parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, parent, parserHelper.ReaderContext.Reader.Domain); - - od.PropertyValues = properties; - od.IsSingleton = true; - od.IsLazyInit = true; - - return od; - } - - /// - /// Parses and potentially registers a validator. - /// - /// - /// Only validators that have id attribute specified are registered - /// as separate object definitions within application context. - /// - /// Validator XML element. - /// The parser helper. - /// Validator object definition. - private IObjectDefinition ParseAndRegisterValidator(XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); - IObjectDefinition validator = ParseValidator(id, element, parserHelper); - if (StringUtils.HasText(id)) - { - parserHelper.ReaderContext.Registry.RegisterObjectDefinition(id, validator); - this.definitionCount++; - } - return validator; - } - - /// - /// Gets the name of the object type for the specified element. - /// - /// The element. - /// The name of the object type. - private string GetTypeName(XmlElement element) - { - string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - if (StringUtils.IsNullOrEmpty(typeName)) - { - return ValidatorTypePrefix + element.LocalName; - } - return typeName; - } - - /// - /// Creates an error message action based on the specified message element. - /// - /// The message element. - /// The parser helper. - /// The error message action definition. - private static IObjectDefinition ParseErrorMessageAction(XmlElement message, ObjectDefinitionParserHelper parserHelper) - { - string messageId = message.GetAttribute(MessageConstants.IdAttribute); - string[] providers = message.GetAttribute(MessageConstants.ProvidersAttribute).Split(','); - ArrayList parameters = new ArrayList(); - - foreach (XmlElement param in message.ChildNodes) - { - IExpression paramExpression = Expression.Parse(param.GetAttribute(MessageConstants.ParameterValueAttribute)); - parameters.Add(paramExpression); - } - - string typeName = "Spring.Validation.Actions.ErrorMessageAction, Spring.Core"; - ConstructorArgumentValues ctorArgs = new ConstructorArgumentValues(); - ctorArgs.AddGenericArgumentValue(messageId); - ctorArgs.AddGenericArgumentValue(providers); - - string when = message.GetAttribute(ValidatorDefinitionConstants.WhenAttribute); - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(when)) - { - properties.Add("When", when); - } - if (parameters.Count > 0) - { - properties.Add("Parameters", parameters.ToArray(typeof(IExpression))); - } - - IConfigurableObjectDefinition action = - parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserHelper.ReaderContext.Reader.Domain); - action.ConstructorArgumentValues = ctorArgs; - action.PropertyValues = properties; - - return action; - } - - /// - /// Creates a generic action based on the specified element. - /// - /// The action definition element. - /// The parser helper. - /// Generic validation action definition. - private IObjectDefinition ParseGenericAction(XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - string when = element.GetAttribute(ValidatorDefinitionConstants.WhenAttribute); - MutablePropertyValues properties = base.GetPropertyValueSubElements("validator:action", element, parserHelper); - if (StringUtils.HasText(when)) - { - properties.Add("When", when); - } - - IConfigurableObjectDefinition action = - parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserHelper.ReaderContext.Reader.Domain); - action.PropertyValues = properties; - - return action; - } - - /// - /// Creates object definition for the validator reference. - /// - /// The action definition element. - /// The parser helper. - /// Generic validation action definition. - private IObjectDefinition ParseValidatorReference(XmlElement element, ObjectDefinitionParserHelper parserHelper) - { - string typeName = "Spring.Validation.ValidatorReference, Spring.Core"; - string name = element.GetAttribute(ValidatorDefinitionConstants.ReferenceNameAttribute); - string context = element.GetAttribute(ValidatorDefinitionConstants.ReferenceContextAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - properties.Add("Name", name); - if (StringUtils.HasText(context)) - { - properties.Add("Context", context); - } - - IConfigurableObjectDefinition reference = - parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserHelper.ReaderContext.Reader.Domain); - reference.PropertyValues = properties; - return reference; - } - - #region Element & Attribute Name Constants - - private class ValidatorDefinitionConstants - { - public const string PropertyElement = "property"; - public const string MessageElement = "message"; - public const string ActionElement = "action"; - public const string ReferenceElement = "ref"; - - public const string TypeAttribute = "type"; - public const string TestAttribute = "test"; - public const string NameAttribute = "name"; - public const string WhenAttribute = "when"; - - public const string PropertyNameAttribute = "name"; - - public const string ReferenceNameAttribute = "name"; - public const string ReferenceContextAttribute = "context"; - - public const string CollectionValidateAllAttribute = "validate-all"; - public const string CollectionContextAttribute = "context"; - public const string CollectionIncludeElementsErrors = "include-element-errors"; - } - - private class MessageConstants - { - public const string ParamElement = "param"; - - public const string IdAttribute = "id"; - public const string ProvidersAttribute = "providers"; - public const string ParameterValueAttribute = "value"; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Xml; + +using Spring.Core.TypeResolution; +using Spring.Context.Support; +using Spring.Expressions; +using Spring.Objects; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Threading; +using Spring.Util; + +#endregion + +namespace Spring.Validation.Config +{ + /// + /// Implementation of the custom configuration parser for validator definitions. + /// + /// Aleksandar Seovic + [ + NamespaceParser( + Namespace = "http://www.springframework.net/validation", + SchemaLocationAssemblyHint = typeof(ValidationNamespaceParser), + SchemaLocation = "/Spring.Validation.Config/spring-validation-1.1.xsd") + ] + public sealed class ValidationNamespaceParser : ObjectsNamespaceParser + { + private const string ValidatorTypePrefix = "validator: "; + +// [ThreadStatic] +// private int definitionCount = 0; + private readonly string key_DefinitionCount; + private int definitionCount + { + get + { + object tmp = LogicalThreadContext.GetData(key_DefinitionCount); + if (tmp != null) return (int)tmp; + LogicalThreadContext.SetData(key_DefinitionCount, 0); + return 0; + } + set + { + LogicalThreadContext.SetData(key_DefinitionCount, value); + } + } + + static ValidationNamespaceParser() + { + TypeRegistry.RegisterType(ValidatorTypePrefix + "group", typeof(ValidatorGroup)); + TypeRegistry.RegisterType(ValidatorTypePrefix + "any", typeof(AnyValidatorGroup)); + TypeRegistry.RegisterType(ValidatorTypePrefix + "exclusive", typeof(ExclusiveValidatorGroup)); + + + TypeRegistry.RegisterType(ValidatorTypePrefix + "collection", typeof(CollectionValidator)); + TypeRegistry.RegisterType(ValidatorTypePrefix + "required", typeof(RequiredValidator)); + TypeRegistry.RegisterType(ValidatorTypePrefix + "condition", typeof(ConditionValidator)); + TypeRegistry.RegisterType(ValidatorTypePrefix + "regex", typeof(RegularExpressionValidator)); + } + + /// + /// Initializes a new instance of the class. + /// + public ValidationNamespaceParser() + { + // generate unique key for instance field to be stored in LogicalThreadContext + string FIELDPREFIX = typeof(ValidationNamespaceParser).FullName + base.GetHashCode(); + key_DefinitionCount = FIELDPREFIX + ".definitionCount"; + } + + + /// + /// Parse the specified element and register any resulting + /// IObjectDefinitions with the IObjectDefinitionRegistry that is + /// embedded in the supplied ParserContext. + /// + /// The element to be parsed into one or more IObjectDefinitions + /// The object encapsulating the current state of the parsing + /// process. + /// + /// The primary IObjectDefinition (can be null as explained above) + /// + /// + /// Implementations should return the primary IObjectDefinition + /// that results from the parse phase if they wish to used nested + /// inside (for example) a <property> tag. + /// Implementations may return null if they will not + /// be used in a nested scenario. + /// + /// + public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + if (!element.HasAttribute("id")) + { + throw new ObjectDefinitionStoreException(parserContext.ReaderContext.Resource, "validator", "Top-level validator element must have an 'id' attribute defined."); + } + this.definitionCount = 0; + + //TODO pass down parserContext... + ParseAndRegisterValidator(element, parserContext.ParserHelper); + + return null; + //return definitionCount; + } + + /// + /// Parses the validator definition. + /// + /// Validator's identifier. + /// The element to parse. + /// The parser helper. + /// Validator object definition. + private IObjectDefinition ParseValidator(string id, XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string typeName = GetTypeName(element); + string parent = element.GetAttribute(ObjectDefinitionConstants.ParentAttribute); + string test = element.GetAttribute(ValidatorDefinitionConstants.TestAttribute); + string when = element.GetAttribute(ValidatorDefinitionConstants.WhenAttribute); + string validateAll = element.GetAttribute(ValidatorDefinitionConstants.CollectionValidateAllAttribute); + string context = element.GetAttribute(ValidatorDefinitionConstants.CollectionContextAttribute); + string includeElementsErrors = element.GetAttribute(ValidatorDefinitionConstants.CollectionIncludeElementsErrors); + + string name = "validator: " + (StringUtils.HasText(id) ? id : this.definitionCount.ToString()); + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(test)) + { + properties.Add("Test", test); + } + if (StringUtils.HasText(when)) + { + properties.Add("When", when); + } + if (StringUtils.HasText(validateAll)) + { + properties.Add("ValidateAll", validateAll); + } + if (StringUtils.HasText(validateAll)) + { + properties.Add("Context", context); + } + if (StringUtils.HasText(includeElementsErrors)) + { + properties.Add("IncludeElementErrors", includeElementsErrors); + } + + + ManagedList nestedValidators = new ManagedList(); + ManagedList actions = new ManagedList(); + foreach (XmlNode node in element.ChildNodes) + { + XmlElement child = node as XmlElement; + if (child != null) + { + switch (child.LocalName) + { + case ValidatorDefinitionConstants.PropertyElement: + string propertyName = child.GetAttribute(ValidatorDefinitionConstants.PropertyNameAttribute); + properties.Add(propertyName, base.GetPropertyValue(child, name, parserHelper)); + break; + case ValidatorDefinitionConstants.MessageElement: + actions.Add(ParseErrorMessageAction(child, parserHelper)); + break; + case ValidatorDefinitionConstants.ActionElement: + actions.Add(ParseGenericAction(child, parserHelper)); + break; + case ValidatorDefinitionConstants.ReferenceElement: + nestedValidators.Add(ParseValidatorReference(child, parserHelper)); + break; + default: + nestedValidators.Add(ParseAndRegisterValidator(child, parserHelper)); + break; + } + } + } + if (nestedValidators.Count > 0) + { + properties.Add("Validators", nestedValidators); + } + if (actions.Count > 0) + { + properties.Add("Actions", actions); + } + + IConfigurableObjectDefinition od + = parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, parent, parserHelper.ReaderContext.Reader.Domain); + + od.PropertyValues = properties; + od.IsSingleton = true; + od.IsLazyInit = true; + + return od; + } + + /// + /// Parses and potentially registers a validator. + /// + /// + /// Only validators that have id attribute specified are registered + /// as separate object definitions within application context. + /// + /// Validator XML element. + /// The parser helper. + /// Validator object definition. + private IObjectDefinition ParseAndRegisterValidator(XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); + IObjectDefinition validator = ParseValidator(id, element, parserHelper); + if (StringUtils.HasText(id)) + { + parserHelper.ReaderContext.Registry.RegisterObjectDefinition(id, validator); + this.definitionCount++; + } + return validator; + } + + /// + /// Gets the name of the object type for the specified element. + /// + /// The element. + /// The name of the object type. + private string GetTypeName(XmlElement element) + { + string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + if (StringUtils.IsNullOrEmpty(typeName)) + { + return ValidatorTypePrefix + element.LocalName; + } + return typeName; + } + + /// + /// Creates an error message action based on the specified message element. + /// + /// The message element. + /// The parser helper. + /// The error message action definition. + private static IObjectDefinition ParseErrorMessageAction(XmlElement message, ObjectDefinitionParserHelper parserHelper) + { + string messageId = message.GetAttribute(MessageConstants.IdAttribute); + string[] providers = message.GetAttribute(MessageConstants.ProvidersAttribute).Split(','); + ArrayList parameters = new ArrayList(); + + foreach (XmlElement param in message.ChildNodes) + { + IExpression paramExpression = Expression.Parse(param.GetAttribute(MessageConstants.ParameterValueAttribute)); + parameters.Add(paramExpression); + } + + string typeName = "Spring.Validation.Actions.ErrorMessageAction, Spring.Core"; + ConstructorArgumentValues ctorArgs = new ConstructorArgumentValues(); + ctorArgs.AddGenericArgumentValue(messageId); + ctorArgs.AddGenericArgumentValue(providers); + + string when = message.GetAttribute(ValidatorDefinitionConstants.WhenAttribute); + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(when)) + { + properties.Add("When", when); + } + if (parameters.Count > 0) + { + properties.Add("Parameters", parameters.ToArray(typeof(IExpression))); + } + + IConfigurableObjectDefinition action = + parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserHelper.ReaderContext.Reader.Domain); + action.ConstructorArgumentValues = ctorArgs; + action.PropertyValues = properties; + + return action; + } + + /// + /// Creates a generic action based on the specified element. + /// + /// The action definition element. + /// The parser helper. + /// Generic validation action definition. + private IObjectDefinition ParseGenericAction(XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + string when = element.GetAttribute(ValidatorDefinitionConstants.WhenAttribute); + MutablePropertyValues properties = base.GetPropertyValueSubElements("validator:action", element, parserHelper); + if (StringUtils.HasText(when)) + { + properties.Add("When", when); + } + + IConfigurableObjectDefinition action = + parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserHelper.ReaderContext.Reader.Domain); + action.PropertyValues = properties; + + return action; + } + + /// + /// Creates object definition for the validator reference. + /// + /// The action definition element. + /// The parser helper. + /// Generic validation action definition. + private IObjectDefinition ParseValidatorReference(XmlElement element, ObjectDefinitionParserHelper parserHelper) + { + string typeName = "Spring.Validation.ValidatorReference, Spring.Core"; + string name = element.GetAttribute(ValidatorDefinitionConstants.ReferenceNameAttribute); + string context = element.GetAttribute(ValidatorDefinitionConstants.ReferenceContextAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + properties.Add("Name", name); + if (StringUtils.HasText(context)) + { + properties.Add("Context", context); + } + + IConfigurableObjectDefinition reference = + parserHelper.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserHelper.ReaderContext.Reader.Domain); + reference.PropertyValues = properties; + return reference; + } + + #region Element & Attribute Name Constants + + private class ValidatorDefinitionConstants + { + public const string PropertyElement = "property"; + public const string MessageElement = "message"; + public const string ActionElement = "action"; + public const string ReferenceElement = "ref"; + + public const string TypeAttribute = "type"; + public const string TestAttribute = "test"; + public const string NameAttribute = "name"; + public const string WhenAttribute = "when"; + + public const string PropertyNameAttribute = "name"; + + public const string ReferenceNameAttribute = "name"; + public const string ReferenceContextAttribute = "context"; + + public const string CollectionValidateAllAttribute = "validate-all"; + public const string CollectionContextAttribute = "context"; + public const string CollectionIncludeElementsErrors = "include-element-errors"; + } + + private class MessageConstants + { + public const string ParamElement = "param"; + + public const string IdAttribute = "id"; + public const string ProvidersAttribute = "providers"; + public const string ParameterValueAttribute = "value"; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/ErrorMessage.cs b/src/Spring/Spring.Core/Validation/ErrorMessage.cs index 61d2a869..e9bd27f5 100644 --- a/src/Spring/Spring.Core/Validation/ErrorMessage.cs +++ b/src/Spring/Spring.Core/Validation/ErrorMessage.cs @@ -35,7 +35,6 @@ namespace Spring.Validation /// /// Aleksandar Seovic /// Goran Milosavljevic - /// $Id: ErrorMessage.cs,v 1.5 2007/02/19 17:56:42 aseovic Exp $ [Serializable] public class ErrorMessage : IXmlSerializable { diff --git a/src/Spring/Spring.Core/Validation/ExclusiveValidatorGroup.cs b/src/Spring/Spring.Core/Validation/ExclusiveValidatorGroup.cs index d8ef54c8..1a1a2cc5 100644 --- a/src/Spring/Spring.Core/Validation/ExclusiveValidatorGroup.cs +++ b/src/Spring/Spring.Core/Validation/ExclusiveValidatorGroup.cs @@ -38,7 +38,6 @@ namespace Spring.Validation ///

/// /// Aleksandar Seovic - /// $Id: ExclusiveValidatorGroup.cs,v 1.8 2008/02/05 20:40:26 aseovic Exp $ public class ExclusiveValidatorGroup : ValidatorGroup { #region Constructors diff --git a/src/Spring/Spring.Core/Validation/IValidationAction.cs b/src/Spring/Spring.Core/Validation/IValidationAction.cs index 418086bf..a5ab58a1 100644 --- a/src/Spring/Spring.Core/Validation/IValidationAction.cs +++ b/src/Spring/Spring.Core/Validation/IValidationAction.cs @@ -42,7 +42,6 @@ namespace Spring.Validation ///

/// /// Aleksandar Seovic - /// $Id: IValidationAction.cs,v 1.4 2008/02/05 20:40:26 aseovic Exp $ public interface IValidationAction { /// diff --git a/src/Spring/Spring.Core/Validation/IValidationErrors.cs b/src/Spring/Spring.Core/Validation/IValidationErrors.cs index 5c6b2543..b82dc43c 100644 --- a/src/Spring/Spring.Core/Validation/IValidationErrors.cs +++ b/src/Spring/Spring.Core/Validation/IValidationErrors.cs @@ -7,7 +7,6 @@ namespace Spring.Validation /// An interface that validation errors containers have to implement. /// /// Aleksandar Seovic - /// $Id: IValidationErrors.cs,v 1.1 2008/02/05 20:40:26 aseovic Exp $ public interface IValidationErrors { /// diff --git a/src/Spring/Spring.Core/Validation/IValidator.cs b/src/Spring/Spring.Core/Validation/IValidator.cs index 48e0f5f4..5640ca01 100644 --- a/src/Spring/Spring.Core/Validation/IValidator.cs +++ b/src/Spring/Spring.Core/Validation/IValidator.cs @@ -47,7 +47,6 @@ namespace Spring.Validation ///

/// /// Aleksandar Seovic - /// $Id: IValidator.cs,v 1.8 2008/02/05 20:40:26 aseovic Exp $ /// public interface IValidator { diff --git a/src/Spring/Spring.Core/Validation/ValidatedAttribute.cs b/src/Spring/Spring.Core/Validation/ValidatedAttribute.cs index bdd782ad..e72a6d25 100644 --- a/src/Spring/Spring.Core/Validation/ValidatedAttribute.cs +++ b/src/Spring/Spring.Core/Validation/ValidatedAttribute.cs @@ -8,7 +8,6 @@ namespace Spring.Validation ///
/// Damjan Tomic /// Aleksandar Seovic - /// $Id: ValidatedAttribute.cs,v 1.1 2008/04/02 23:02:36 markpollack Exp $ [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true)] [Serializable] public class ValidatedAttribute : Attribute diff --git a/src/Spring/Spring.Core/Validation/ValidationErrors.cs b/src/Spring/Spring.Core/Validation/ValidationErrors.cs index 384d7e30..be4449f3 100644 --- a/src/Spring/Spring.Core/Validation/ValidationErrors.cs +++ b/src/Spring/Spring.Core/Validation/ValidationErrors.cs @@ -44,7 +44,6 @@ namespace Spring.Validation /// /// Aleksandar Seovic /// Goran Milosavljevic - /// $Id: ValidationErrors.cs,v 1.9 2008/02/05 20:40:26 aseovic Exp $ [Serializable] public class ValidationErrors : IValidationErrors, IXmlSerializable { diff --git a/src/Spring/Spring.Core/Validation/ValidationException.cs b/src/Spring/Spring.Core/Validation/ValidationException.cs index 68b1c789..1df8143f 100644 --- a/src/Spring/Spring.Core/Validation/ValidationException.cs +++ b/src/Spring/Spring.Core/Validation/ValidationException.cs @@ -31,7 +31,6 @@ namespace Spring.Validation /// Thrown by the validation advice if the method parameters validation fails. /// /// Aleksandar Seovic - /// $Id: ValidationException.cs,v 1.1 2008/02/05 20:40:26 aseovic Exp $ [Serializable] public class ValidationException : Exception { diff --git a/src/Spring/Spring.Core/Validation/ValidatorGroup.cs b/src/Spring/Spring.Core/Validation/ValidatorGroup.cs index 02154c48..8d845e3f 100644 --- a/src/Spring/Spring.Core/Validation/ValidatorGroup.cs +++ b/src/Spring/Spring.Core/Validation/ValidatorGroup.cs @@ -39,7 +39,6 @@ namespace Spring.Validation ///

/// /// Aleksandar Seovic - /// $Id: ValidatorGroup.cs,v 1.10 2008/02/05 20:40:26 aseovic Exp $ public class ValidatorGroup : BaseValidator { #region Fields diff --git a/src/Spring/Spring.Core/Validation/ValidatorReference.cs b/src/Spring/Spring.Core/Validation/ValidatorReference.cs index a710b11b..b32d6f80 100644 --- a/src/Spring/Spring.Core/Validation/ValidatorReference.cs +++ b/src/Spring/Spring.Core/Validation/ValidatorReference.cs @@ -39,7 +39,6 @@ namespace Spring.Validation ///

/// /// Aleksandar Seovic - /// $Id: ValidatorReference.cs,v 1.5 2008/02/05 20:40:26 aseovic Exp $ public class ValidatorReference : IValidator, IObjectFactoryAware { #region Fields diff --git a/src/Spring/Spring.Core/Validation/Validators/ConditionValidator.cs b/src/Spring/Spring.Core/Validation/Validators/ConditionValidator.cs index 07a98cf6..e62daa5a 100644 --- a/src/Spring/Spring.Core/Validation/Validators/ConditionValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/ConditionValidator.cs @@ -1,88 +1,87 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation -{ - /// - /// Evaluates validator test using condition evaluator. - /// - /// Aleksandar Seovic - /// $Id: ConditionValidator.cs,v 1.5 2006/04/09 07:19:04 markpollack Exp $ - public class ConditionValidator : BaseValidator - { - #region Constructors - - /// - /// Creates a new instance of the class. - /// - public ConditionValidator() - {} - - /// - /// Creates a new instance of the class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public ConditionValidator(string test, string when) : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - } - - /// - /// Creates a new instance of the class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public ConditionValidator(IExpression test, IExpression when) : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - } - - #endregion - - /// - /// Evaluates the test using condition evaluator. - /// - /// - ///

- /// Test can be any logical expression that is supported by the Spring.NET logical - /// expression evaluation engine, and can use any variables that can be resolved - /// by the variable resolver used by the validation engine. - ///

- ///
- /// The object to validate. - /// - /// if the supplied is valid. - /// - protected override bool Validate(object objectToValidate) - { - return Convert.ToBoolean(objectToValidate); - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation +{ + /// + /// Evaluates validator test using condition evaluator. + /// + /// Aleksandar Seovic + public class ConditionValidator : BaseValidator + { + #region Constructors + + /// + /// Creates a new instance of the class. + /// + public ConditionValidator() + {} + + /// + /// Creates a new instance of the class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public ConditionValidator(string test, string when) : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + } + + /// + /// Creates a new instance of the class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public ConditionValidator(IExpression test, IExpression when) : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + } + + #endregion + + /// + /// Evaluates the test using condition evaluator. + /// + /// + ///

+ /// Test can be any logical expression that is supported by the Spring.NET logical + /// expression evaluation engine, and can use any variables that can be resolved + /// by the variable resolver used by the validation engine. + ///

+ ///
+ /// The object to validate. + /// + /// if the supplied is valid. + /// + protected override bool Validate(object objectToValidate) + { + return Convert.ToBoolean(objectToValidate); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/Validators/CreditCardValidator.cs b/src/Spring/Spring.Core/Validation/Validators/CreditCardValidator.cs index e3c3c5f1..6106774a 100644 --- a/src/Spring/Spring.Core/Validation/Validators/CreditCardValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/CreditCardValidator.cs @@ -1,321 +1,321 @@ -#region License - -/* - * Copyright 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation.Validators -{ - /// - /// Perform credit card validations. - /// - /// - /// By default, all supported card types are allowed. You can specify - /// which credit card type validator should be used by setting - /// the value of property to a concrete - /// instance. - /// - public class CreditCardValidator : BaseValidator - { - #region Properties - - /// - /// Credit card type validator to use. - /// - /// - /// Can be concrete implementations of - /// interface. The following are available implementations: - /// , , , - /// . - /// - public ICreditCardType CardType - { - get { return m_cardType; } - set { m_cardType = value; } - } - - #endregion - - #region Constructors - - /// - /// Creates a new instance of the UrlValidator class. - /// - public CreditCardValidator() - {} - - /// - /// Creates a new instance of the UrlValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - /// Credit Card type validator to use. - public CreditCardValidator(string test, string when, ICreditCardType cardType) - : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - this.m_cardType = cardType; - } - - /// - /// Creates a new instance of the UrlValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - /// Credit Card type validator to use. - public CreditCardValidator(IExpression test, IExpression when, ICreditCardType cardType) - : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - this.m_cardType = cardType; - } - - #endregion - - #region BaseValidator methods - - /// - /// Validates the supplied . - /// - /// - /// In the case of the class, - /// the test should be a string variable that will be evaluated and the object - /// obtained as a result of this evaluation will be checked if it is - /// a valid credit card number. - /// - /// The object to validate. - /// - /// if the supplied is valid - /// credit card number. - /// - protected override bool Validate(object objectToValidate) - { - string text = objectToValidate as string; - if (StringUtils.IsNullOrEmpty(text)) - { - return true; - } - - return IsValid(text); - } - - #endregion - - #region CreditCardValidator methods - - /// - /// Checks if the is a valid credit card number. - /// - /// - /// The card number to validate. - /// - /// - /// true if the card number is valid. - /// - public bool IsValid(String card) - { - // check card number length - if ((card == null) || (card.Length < 13) || (card.Length > 19)) - { - return false; - } - - // check if the card is a valid credit card number - if (!LuhnCheck(card)) - { - return false; - } - - // validate card with credit card type validator - if (CardType != null) - { - return ValidateCard(card); - } - else - { - throw new ArgumentException("Property CardType cannot be null."); - } - } - - /// - /// Validates card number with the specified validator. - /// - /// - /// Credit card number to validate. - /// - /// - /// true if credit card number is a valid number of credit card type specified. - /// - private bool ValidateCard(string cardNumber) - { - String card = cardNumber == null ? null : cardNumber.Trim(); - - if (card == null) - { - return false; - } - - return CardType.Matches(card); - } - - /// - /// Checks for a valid credit card number. - /// - /// - /// Credit Card Number. - /// - /// - /// true if the card number passes the LuhnCheck. - /// - private bool LuhnCheck(string cardNumber) - { - // number must be validated as 0..9 numeric first!! - int digits = cardNumber.Length; - int oddOrEven = digits & 1; - long sum = 0; - for (int count = 0; count < digits; count++) - { - int digit; - try - { - digit = Int32.Parse(cardNumber[count] + ""); - } - catch (FormatException) - { - return false; - } - - if (((count & 1) ^ oddOrEven) == 0) - { // not - digit *= 2; - if (digit > 9) - { - digit -= 9; - } - } - sum += digit; - } - - return (sum == 0) ? false : (sum % 10 == 0); - } - - #endregion - - #region Data members - - private ICreditCardType m_cardType; - - #endregion - } - - #region CreditCardType classes - - /// - /// CreditCardType interface defines how validation is performed - /// for one type/brand of credit card. - /// - public interface ICreditCardType - { - /// - /// Returns true if the card number matches this type of - /// credit card. - /// - /// - /// The card number, never null. - /// - /// - /// true if the number matches. - /// - bool Matches(String card); - } - - /// - /// Visa credit card type validation support. - /// - public class Visa : ICreditCardType - { - private static readonly String PREFIX = "4"; - - /// - /// Indicates, wheter the given credit card number matches a visa number. - /// - public bool Matches(String card) - { - return (card.Substring(0, 1).Equals(PREFIX) && (card.Length == 13 || card.Length == 16)); - } - } - - /// - /// American Express credit card type validation support. - /// - public class Amex : ICreditCardType - { - private static readonly String PREFIX = "34,37,"; - - /// - /// Indicates, wheter the given credit card number matches an amex number. - /// - public bool Matches(String card) - { - String prefix2 = card.Substring(0, 2) + ","; - return ((PREFIX.IndexOf(prefix2) != -1) && (card.Length == 15)); - } - } - - /// - /// Discover credit card type validation support. - /// - public class Discover : ICreditCardType - { - private static readonly String PREFIX = "6011"; - - /// - /// Indicates, wheter the given credit card number matches a discover number. - /// - public bool Matches(String card) - { - return (card.Substring(0, 4).Equals(PREFIX) && (card.Length == 16)); - } - } - - /// - /// Mastercard credit card type validation support. - /// - public class Mastercard : ICreditCardType - { - private static readonly String PREFIX = "51,52,53,54,55,"; - - /// - /// Indicates, wheter the given credit card number matches a mastercard number. - /// - public bool Matches(String card) - { - String prefix2 = card.Substring(0, 2) + ","; - return ((PREFIX.IndexOf(prefix2) != -1) && (card.Length == 16)); - } - } - - #endregion -} +#region License + +/* + * Copyright 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation.Validators +{ + /// + /// Perform credit card validations. + /// + /// + /// By default, all supported card types are allowed. You can specify + /// which credit card type validator should be used by setting + /// the value of property to a concrete + /// instance. + /// + public class CreditCardValidator : BaseValidator + { + #region Properties + + /// + /// Credit card type validator to use. + /// + /// + /// Can be concrete implementations of + /// interface. The following are available implementations: + /// , , , + /// . + /// + public ICreditCardType CardType + { + get { return m_cardType; } + set { m_cardType = value; } + } + + #endregion + + #region Constructors + + /// + /// Creates a new instance of the UrlValidator class. + /// + public CreditCardValidator() + {} + + /// + /// Creates a new instance of the UrlValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + /// Credit Card type validator to use. + public CreditCardValidator(string test, string when, ICreditCardType cardType) + : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + this.m_cardType = cardType; + } + + /// + /// Creates a new instance of the UrlValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + /// Credit Card type validator to use. + public CreditCardValidator(IExpression test, IExpression when, ICreditCardType cardType) + : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + this.m_cardType = cardType; + } + + #endregion + + #region BaseValidator methods + + /// + /// Validates the supplied . + /// + /// + /// In the case of the class, + /// the test should be a string variable that will be evaluated and the object + /// obtained as a result of this evaluation will be checked if it is + /// a valid credit card number. + /// + /// The object to validate. + /// + /// if the supplied is valid + /// credit card number. + /// + protected override bool Validate(object objectToValidate) + { + string text = objectToValidate as string; + if (StringUtils.IsNullOrEmpty(text)) + { + return true; + } + + return IsValid(text); + } + + #endregion + + #region CreditCardValidator methods + + /// + /// Checks if the is a valid credit card number. + /// + /// + /// The card number to validate. + /// + /// + /// true if the card number is valid. + /// + public bool IsValid(String card) + { + // check card number length + if ((card == null) || (card.Length < 13) || (card.Length > 19)) + { + return false; + } + + // check if the card is a valid credit card number + if (!LuhnCheck(card)) + { + return false; + } + + // validate card with credit card type validator + if (CardType != null) + { + return ValidateCard(card); + } + else + { + throw new ArgumentException("Property CardType cannot be null."); + } + } + + /// + /// Validates card number with the specified validator. + /// + /// + /// Credit card number to validate. + /// + /// + /// true if credit card number is a valid number of credit card type specified. + /// + private bool ValidateCard(string cardNumber) + { + String card = cardNumber == null ? null : cardNumber.Trim(); + + if (card == null) + { + return false; + } + + return CardType.Matches(card); + } + + /// + /// Checks for a valid credit card number. + /// + /// + /// Credit Card Number. + /// + /// + /// true if the card number passes the LuhnCheck. + /// + private bool LuhnCheck(string cardNumber) + { + // number must be validated as 0..9 numeric first!! + int digits = cardNumber.Length; + int oddOrEven = digits & 1; + long sum = 0; + for (int count = 0; count < digits; count++) + { + int digit; + try + { + digit = Int32.Parse(cardNumber[count] + ""); + } + catch (FormatException) + { + return false; + } + + if (((count & 1) ^ oddOrEven) == 0) + { // not + digit *= 2; + if (digit > 9) + { + digit -= 9; + } + } + sum += digit; + } + + return (sum == 0) ? false : (sum % 10 == 0); + } + + #endregion + + #region Data members + + private ICreditCardType m_cardType; + + #endregion + } + + #region CreditCardType classes + + /// + /// CreditCardType interface defines how validation is performed + /// for one type/brand of credit card. + /// + public interface ICreditCardType + { + /// + /// Returns true if the card number matches this type of + /// credit card. + /// + /// + /// The card number, never null. + /// + /// + /// true if the number matches. + /// + bool Matches(String card); + } + + /// + /// Visa credit card type validation support. + /// + public class Visa : ICreditCardType + { + private static readonly String PREFIX = "4"; + + /// + /// Indicates, wheter the given credit card number matches a visa number. + /// + public bool Matches(String card) + { + return (card.Substring(0, 1).Equals(PREFIX) && (card.Length == 13 || card.Length == 16)); + } + } + + /// + /// American Express credit card type validation support. + /// + public class Amex : ICreditCardType + { + private static readonly String PREFIX = "34,37,"; + + /// + /// Indicates, wheter the given credit card number matches an amex number. + /// + public bool Matches(String card) + { + String prefix2 = card.Substring(0, 2) + ","; + return ((PREFIX.IndexOf(prefix2) != -1) && (card.Length == 15)); + } + } + + /// + /// Discover credit card type validation support. + /// + public class Discover : ICreditCardType + { + private static readonly String PREFIX = "6011"; + + /// + /// Indicates, wheter the given credit card number matches a discover number. + /// + public bool Matches(String card) + { + return (card.Substring(0, 4).Equals(PREFIX) && (card.Length == 16)); + } + } + + /// + /// Mastercard credit card type validation support. + /// + public class Mastercard : ICreditCardType + { + private static readonly String PREFIX = "51,52,53,54,55,"; + + /// + /// Indicates, wheter the given credit card number matches a mastercard number. + /// + public bool Matches(String card) + { + String prefix2 = card.Substring(0, 2) + ","; + return ((PREFIX.IndexOf(prefix2) != -1) && (card.Length == 16)); + } + } + + #endregion +} diff --git a/src/Spring/Spring.Core/Validation/Validators/EmailValidator.cs b/src/Spring/Spring.Core/Validation/Validators/EmailValidator.cs index 691fbb32..c1de00de 100644 --- a/src/Spring/Spring.Core/Validation/Validators/EmailValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/EmailValidator.cs @@ -1,115 +1,115 @@ -#region License - -/* - * Copyright 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text.RegularExpressions; -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation.Validators -{ - /// - /// Perform email validations. - /// - /// - ///

- /// This implementation is not guaranteed to catch all possible errors in an - /// email address. For example, an address like nobody@noplace.nowhere will - /// pass validator, even though there is no TLD "nowhere". - /// - /// Goran Milosavljevic - public class EmailValidator : BaseValidator - { - #region Constructors - - ///

- /// Creates a new instance of the EmailValidator class. - /// - public EmailValidator() - {} - - /// - /// Creates a new instance of the EmailValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public EmailValidator(string test, string when) - : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - } - - /// - /// Creates a new instance of the EmailValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public EmailValidator(IExpression test, IExpression when) - : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - } - - #endregion - - #region BaseValidator methods - - /// - /// Validates the supplied . - /// - /// - /// In the case of the class, - /// the test should be a string variable that will be evaluated and the object - /// obtained as a result of this evaluation will be checked if it is - /// a valid e-mail address. - /// - /// The object to validate. - /// - /// if the supplied is valid - /// e-mail address. - /// - protected override bool Validate(object objectToValidate) - { - string text = objectToValidate as string; - if (StringUtils.IsNullOrEmpty(text)) - { - return true; - } - - Match match = Regex.Match(text, emailCheck); - return match.Success && match.Index == 0 && match.Length == text.Length; - } - - #endregion - - #region Data members - - /// - /// Regular expression used for validation of object passed to this . - /// - private static string emailCheck = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"; - - #endregion - } -} +#region License + +/* + * Copyright 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text.RegularExpressions; +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation.Validators +{ + /// + /// Perform email validations. + /// + /// + ///

+ /// This implementation is not guaranteed to catch all possible errors in an + /// email address. For example, an address like nobody@noplace.nowhere will + /// pass validator, even though there is no TLD "nowhere". + /// + /// Goran Milosavljevic + public class EmailValidator : BaseValidator + { + #region Constructors + + ///

+ /// Creates a new instance of the EmailValidator class. + /// + public EmailValidator() + {} + + /// + /// Creates a new instance of the EmailValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public EmailValidator(string test, string when) + : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + } + + /// + /// Creates a new instance of the EmailValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public EmailValidator(IExpression test, IExpression when) + : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + } + + #endregion + + #region BaseValidator methods + + /// + /// Validates the supplied . + /// + /// + /// In the case of the class, + /// the test should be a string variable that will be evaluated and the object + /// obtained as a result of this evaluation will be checked if it is + /// a valid e-mail address. + /// + /// The object to validate. + /// + /// if the supplied is valid + /// e-mail address. + /// + protected override bool Validate(object objectToValidate) + { + string text = objectToValidate as string; + if (StringUtils.IsNullOrEmpty(text)) + { + return true; + } + + Match match = Regex.Match(text, emailCheck); + return match.Success && match.Index == 0 && match.Length == text.Length; + } + + #endregion + + #region Data members + + /// + /// Regular expression used for validation of object passed to this . + /// + private static string emailCheck = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"; + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Validation/Validators/ISBNValidator.cs b/src/Spring/Spring.Core/Validation/Validators/ISBNValidator.cs index 5c303125..cff00112 100644 --- a/src/Spring/Spring.Core/Validation/Validators/ISBNValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/ISBNValidator.cs @@ -1,167 +1,167 @@ -#region License - -/* - * Copyright 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text.RegularExpressions; -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation.Validators -{ - /// - /// Validates that the object is valid ISBN-10 or ISBN-13 value. - /// - /// Goran Milosavljevic - public class ISBNValidator : BaseValidator - { - #region Constructors - - /// - /// Creates a new instance of the ISBNValidator class. - /// - public ISBNValidator() - {} - - /// - /// Creates a new instance of the ISBNValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public ISBNValidator(string test, string when) - : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - } - - /// - /// Creates a new instance of the ISBNValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public ISBNValidator(IExpression test, IExpression when) - : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - } - - #endregion - - #region BaseValidator methods - - /// - /// Validates the supplied . - /// - /// - /// In the case of the class, - /// the test should be a string variable that will be evaluated and the object - /// obtained as a result of this evaluation will be tested using the ISBN-10 or - /// ISBN-13 validation rules. - /// - /// The object to validate. - /// - /// if the supplied is valid ISBN. - /// - protected override bool Validate(object objectToValidate) - { - String isbn = objectToValidate as String; - if (StringUtils.IsNullOrEmpty(isbn)) - { - return true; - } - - return IsValid(isbn); - } - - #endregion - - #region ISBNValidator methods - - /// - /// Validates against ISBN-10 or ISBN-13 validation - /// rules. - /// - /// - /// ISBN string to validate. - /// - /// - /// true if is a valid ISBN-10 or ISBN-13 code. - /// - private bool IsValid(String isbn) - { - String code = (isbn == null ? null : isbn.Trim().Replace("-", "").Replace(" ", "")); - - // check the length - if ((code == null) || (code.Length < 10 || code.Length>13)) - { - return false; - } - - // validate/reformat using regular expression - Match match; - String pattern; - if (code.Length == 10) - { - pattern = ISBN10_PATTERN; - } - else - { - pattern = ISBN13_PATTERN; - } - - match = Regex.Match(code, pattern); - return match.Success && match.Index == 0 && match.Length == code.Length; - } - - #endregion - - #region Data members - - private static readonly String SEP = "(?:\\-|\\s)"; - private static readonly String GROUP = "(\\d{1,5})"; - private static readonly String PUBLISHER = "(\\d{1,7})"; - private static readonly String TITLE = "(\\d{1,6})"; - - /// - /// ISBN-10 consists of 4 groups of numbers separated by either - /// dashes (-) or spaces. - /// - /// - /// The first group is 1-5 characters, second 1-7, third 1-6, - /// and fourth is 1 digit or an X. - /// - static readonly String ISBN10_PATTERN = "^(?:(\\d{9}[0-9X])|(?:" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9X])))$"; - - /// - /// ISBN-13 consists of 5 groups of numbers separated by either - /// dashes (-) or spaces. - /// - /// - /// The first group is 978 or 979, the second group is - /// 1-5 characters, third 1-7, fourth 1-6, and fifth is 1 digit. - /// - static readonly String ISBN13_PATTERN = "^(978|979)(?:(\\d{10})|(?:" + SEP + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9])))$"; - - #endregion - } -} +#region License + +/* + * Copyright 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text.RegularExpressions; +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation.Validators +{ + /// + /// Validates that the object is valid ISBN-10 or ISBN-13 value. + /// + /// Goran Milosavljevic + public class ISBNValidator : BaseValidator + { + #region Constructors + + /// + /// Creates a new instance of the ISBNValidator class. + /// + public ISBNValidator() + {} + + /// + /// Creates a new instance of the ISBNValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public ISBNValidator(string test, string when) + : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + } + + /// + /// Creates a new instance of the ISBNValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public ISBNValidator(IExpression test, IExpression when) + : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + } + + #endregion + + #region BaseValidator methods + + /// + /// Validates the supplied . + /// + /// + /// In the case of the class, + /// the test should be a string variable that will be evaluated and the object + /// obtained as a result of this evaluation will be tested using the ISBN-10 or + /// ISBN-13 validation rules. + /// + /// The object to validate. + /// + /// if the supplied is valid ISBN. + /// + protected override bool Validate(object objectToValidate) + { + String isbn = objectToValidate as String; + if (StringUtils.IsNullOrEmpty(isbn)) + { + return true; + } + + return IsValid(isbn); + } + + #endregion + + #region ISBNValidator methods + + /// + /// Validates against ISBN-10 or ISBN-13 validation + /// rules. + /// + /// + /// ISBN string to validate. + /// + /// + /// true if is a valid ISBN-10 or ISBN-13 code. + /// + private bool IsValid(String isbn) + { + String code = (isbn == null ? null : isbn.Trim().Replace("-", "").Replace(" ", "")); + + // check the length + if ((code == null) || (code.Length < 10 || code.Length>13)) + { + return false; + } + + // validate/reformat using regular expression + Match match; + String pattern; + if (code.Length == 10) + { + pattern = ISBN10_PATTERN; + } + else + { + pattern = ISBN13_PATTERN; + } + + match = Regex.Match(code, pattern); + return match.Success && match.Index == 0 && match.Length == code.Length; + } + + #endregion + + #region Data members + + private static readonly String SEP = "(?:\\-|\\s)"; + private static readonly String GROUP = "(\\d{1,5})"; + private static readonly String PUBLISHER = "(\\d{1,7})"; + private static readonly String TITLE = "(\\d{1,6})"; + + /// + /// ISBN-10 consists of 4 groups of numbers separated by either + /// dashes (-) or spaces. + /// + /// + /// The first group is 1-5 characters, second 1-7, third 1-6, + /// and fourth is 1 digit or an X. + /// + static readonly String ISBN10_PATTERN = "^(?:(\\d{9}[0-9X])|(?:" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9X])))$"; + + /// + /// ISBN-13 consists of 5 groups of numbers separated by either + /// dashes (-) or spaces. + /// + /// + /// The first group is 978 or 979, the second group is + /// 1-5 characters, third 1-7, fourth 1-6, and fifth is 1 digit. + /// + static readonly String ISBN13_PATTERN = "^(978|979)(?:(\\d{10})|(?:" + SEP + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9])))$"; + + #endregion + } +} diff --git a/src/Spring/Spring.Core/Validation/Validators/RegularExpressionValidator.cs b/src/Spring/Spring.Core/Validation/Validators/RegularExpressionValidator.cs index b20bc2fc..6d45288e 100644 --- a/src/Spring/Spring.Core/Validation/Validators/RegularExpressionValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/RegularExpressionValidator.cs @@ -1,140 +1,139 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text.RegularExpressions; - -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation -{ - /// - /// Validates that object matches specified regular expression. - /// - /// - ///

- /// The test expression must evaluate to a ; - /// otherwise, an exception is thrown. - ///

- ///
- /// Aleksandar Seovic - /// $Id: RegularExpressionValidator.cs,v 1.2 2006/04/09 07:19:04 markpollack Exp $ - public class RegularExpressionValidator : BaseValidator - { - #region Fields - - private string expression = string.Empty; - private RegexOptions options; - - #endregion - - #region Constructors - - /// - /// Creates a new instance of the class. - /// - public RegularExpressionValidator() - { - } - - /// - /// Creates a new instance of the class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - /// The regular expression to match against. - public RegularExpressionValidator(string test, string when, string expression) : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - this.expression = expression; - } - - /// - /// Creates a new instance of the class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - /// The regular expression to match against. - public RegularExpressionValidator(IExpression test, IExpression when, string expression) : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - this.expression = expression; - } - - #endregion - - #region Properties - - /// - /// The regular expression text to match against. - /// - /// The regular expression text. - public string Expression - { - get { return expression; } - set { expression = value; } - } - - /// - /// The for the regular expression evaluation. - /// - /// The regular expression evaluation options. - /// - public RegexOptions Options - { - get { return options; } - set { options = value; } - } - - #endregion - - /// - /// Validates an object. - /// - /// Object to validate. - /// - /// if the supplied - /// object is valid. - /// - /// - /// If the supplied is not a - /// - /// - protected override bool Validate(object objectToValidate) - { - string text = objectToValidate as string; - if (text == null) - { - throw new ArgumentException("Test for RegularExpressionValidator must evaluate to a string."); - } - if (!StringUtils.HasLength(text)) - { - return true; - } - Match match = Regex.Match(text, this.Expression, this.Options); - return match.Success && match.Index == 0 && match.Length == text.Length; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text.RegularExpressions; + +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation +{ + /// + /// Validates that object matches specified regular expression. + /// + /// + ///

+ /// The test expression must evaluate to a ; + /// otherwise, an exception is thrown. + ///

+ ///
+ /// Aleksandar Seovic + public class RegularExpressionValidator : BaseValidator + { + #region Fields + + private string expression = string.Empty; + private RegexOptions options; + + #endregion + + #region Constructors + + /// + /// Creates a new instance of the class. + /// + public RegularExpressionValidator() + { + } + + /// + /// Creates a new instance of the class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + /// The regular expression to match against. + public RegularExpressionValidator(string test, string when, string expression) : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + this.expression = expression; + } + + /// + /// Creates a new instance of the class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + /// The regular expression to match against. + public RegularExpressionValidator(IExpression test, IExpression when, string expression) : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + this.expression = expression; + } + + #endregion + + #region Properties + + /// + /// The regular expression text to match against. + /// + /// The regular expression text. + public string Expression + { + get { return expression; } + set { expression = value; } + } + + /// + /// The for the regular expression evaluation. + /// + /// The regular expression evaluation options. + /// + public RegexOptions Options + { + get { return options; } + set { options = value; } + } + + #endregion + + /// + /// Validates an object. + /// + /// Object to validate. + /// + /// if the supplied + /// object is valid. + /// + /// + /// If the supplied is not a + /// + /// + protected override bool Validate(object objectToValidate) + { + string text = objectToValidate as string; + if (text == null) + { + throw new ArgumentException("Test for RegularExpressionValidator must evaluate to a string."); + } + if (!StringUtils.HasLength(text)) + { + return true; + } + Match match = Regex.Match(text, this.Expression, this.Options); + return match.Success && match.Index == 0 && match.Length == text.Length; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/Validators/RequiredValidator.cs b/src/Spring/Spring.Core/Validation/Validators/RequiredValidator.cs index 173e47dd..d5b046a6 100644 --- a/src/Spring/Spring.Core/Validation/Validators/RequiredValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/RequiredValidator.cs @@ -1,143 +1,142 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation -{ - /// - /// Validates that required value is not empty. - /// - /// - ///

- /// This validator uses following rules to determine if target value is valid: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - ///
Target Valid Value
A .Not or an empty string.
A .Not and not .
One of the number types.Not zero.
A .Not or whitespace.
Any reference type other than .Not .
- ///

- ///

- /// You cannot use this validator to validate any value types other than the ones - /// specified in the table above. - ///

- ///
- /// Aleksandar Seovic - /// $Id: RequiredValidator.cs,v 1.8 2008/03/21 14:12:02 markpollack Exp $ - public class RequiredValidator : BaseValidator - { - #region Constructors - - /// - /// Creates a new instance of the class. - /// - public RequiredValidator() - {} - - /// - /// Creates a new instance of the class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public RequiredValidator(string test, string when) : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - } - - /// - /// Creates a new instance of the class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public RequiredValidator(IExpression test, IExpression when) : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - } - - #endregion - - /// - /// Validates the supplied . - /// - /// - /// In the case of the class, - /// the test should be a variable expression that will be evaluated and the object - /// obtained as a result of this evaluation will be tested using the rules described - /// in the class overview of the - /// class. - /// - /// The object to validate. - /// - /// if the supplied is valid. - /// - protected override bool Validate(object objectToValidate) - { - if (objectToValidate is String && StringUtils.IsNullOrEmpty((string) objectToValidate)) - { - return false; - } - else if (objectToValidate is DateTime && (((DateTime) objectToValidate) == DateTime.MinValue || ((DateTime) objectToValidate) == DateTime.MaxValue)) - { - return false; - } - else if (NumberUtils.IsInteger(objectToValidate) && NumberUtils.IsZero(objectToValidate)) - { - return false; - } - else if (objectToValidate is Char && (((char) objectToValidate) == Char.MinValue || Char.IsWhiteSpace((char) objectToValidate))) - { - return false; - } - else if (NumberUtils.IsDecimal(objectToValidate) && NumberUtils.IsZero(objectToValidate)) - { - return false; - } - return objectToValidate != null; - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation +{ + /// + /// Validates that required value is not empty. + /// + /// + ///

+ /// This validator uses following rules to determine if target value is valid: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + ///
Target Valid Value
A .Not or an empty string.
A .Not and not .
One of the number types.Not zero.
A .Not or whitespace.
Any reference type other than .Not .
+ ///

+ ///

+ /// You cannot use this validator to validate any value types other than the ones + /// specified in the table above. + ///

+ ///
+ /// Aleksandar Seovic + public class RequiredValidator : BaseValidator + { + #region Constructors + + /// + /// Creates a new instance of the class. + /// + public RequiredValidator() + {} + + /// + /// Creates a new instance of the class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public RequiredValidator(string test, string when) : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + } + + /// + /// Creates a new instance of the class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public RequiredValidator(IExpression test, IExpression when) : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + } + + #endregion + + /// + /// Validates the supplied . + /// + /// + /// In the case of the class, + /// the test should be a variable expression that will be evaluated and the object + /// obtained as a result of this evaluation will be tested using the rules described + /// in the class overview of the + /// class. + /// + /// The object to validate. + /// + /// if the supplied is valid. + /// + protected override bool Validate(object objectToValidate) + { + if (objectToValidate is String && StringUtils.IsNullOrEmpty((string) objectToValidate)) + { + return false; + } + else if (objectToValidate is DateTime && (((DateTime) objectToValidate) == DateTime.MinValue || ((DateTime) objectToValidate) == DateTime.MaxValue)) + { + return false; + } + else if (NumberUtils.IsInteger(objectToValidate) && NumberUtils.IsZero(objectToValidate)) + { + return false; + } + else if (objectToValidate is Char && (((char) objectToValidate) == Char.MinValue || Char.IsWhiteSpace((char) objectToValidate))) + { + return false; + } + else if (NumberUtils.IsDecimal(objectToValidate) && NumberUtils.IsZero(objectToValidate)) + { + return false; + } + return objectToValidate != null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Validation/Validators/UrlValidator.cs b/src/Spring/Spring.Core/Validation/Validators/UrlValidator.cs index 018bcd2f..5d8cb670 100644 --- a/src/Spring/Spring.Core/Validation/Validators/UrlValidator.cs +++ b/src/Spring/Spring.Core/Validation/Validators/UrlValidator.cs @@ -1,107 +1,107 @@ -#region License - -/* - * Copyright 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Text.RegularExpressions; -using Spring.Expressions; -using Spring.Util; - -#endregion - -namespace Spring.Validation.Validators -{ - /// - /// Validates that the value is valid URL. - /// - /// Goran Milosavljevic - public class UrlValidator : BaseValidator - { - #region Constructors - - /// - /// Creates a new instance of the UrlValidator class. - /// - public UrlValidator() - {} - - /// - /// Creates a new instance of the UrlValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public UrlValidator(string test, string when) - : base(test, when) - { - AssertUtils.ArgumentHasText(test, "test"); - } - - /// - /// Creates a new instance of the UrlValidator class. - /// - /// The expression to validate. - /// The expression that determines if this validator should be evaluated. - public UrlValidator(IExpression test, IExpression when) - : base(test, when) - { - AssertUtils.ArgumentNotNull(test, "test"); - } - - #endregion - - #region BaseValidator methods - - /// - /// Validates the supplied . - /// - /// - /// In the case of the class, - /// the test should be a string variable that will be evaluated and the object - /// obtained as a result of this evaluation will be tested using the URL validation rules. - /// - /// The object to validate. - /// - /// if the supplied is valid. - /// - protected override bool Validate(object objectToValidate) - { - string text = objectToValidate as string; - if (StringUtils.IsNullOrEmpty(text)) - { - return true; - } - - Match match = Regex.Match(text, urlCheck); - return match.Success && match.Index == 0 && match.Length == text.Length; - } - - #endregion - - #region Data members - - /// - /// Regular expression used for validation of object passed to this . - /// - private static string urlCheck = "((http|https)://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(([0-9]{1,5})?/.*)?"; - - #endregion - } -} +#region License + +/* + * Copyright 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Text.RegularExpressions; +using Spring.Expressions; +using Spring.Util; + +#endregion + +namespace Spring.Validation.Validators +{ + /// + /// Validates that the value is valid URL. + /// + /// Goran Milosavljevic + public class UrlValidator : BaseValidator + { + #region Constructors + + /// + /// Creates a new instance of the UrlValidator class. + /// + public UrlValidator() + {} + + /// + /// Creates a new instance of the UrlValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public UrlValidator(string test, string when) + : base(test, when) + { + AssertUtils.ArgumentHasText(test, "test"); + } + + /// + /// Creates a new instance of the UrlValidator class. + /// + /// The expression to validate. + /// The expression that determines if this validator should be evaluated. + public UrlValidator(IExpression test, IExpression when) + : base(test, when) + { + AssertUtils.ArgumentNotNull(test, "test"); + } + + #endregion + + #region BaseValidator methods + + /// + /// Validates the supplied . + /// + /// + /// In the case of the class, + /// the test should be a string variable that will be evaluated and the object + /// obtained as a result of this evaluation will be tested using the URL validation rules. + /// + /// The object to validate. + /// + /// if the supplied is valid. + /// + protected override bool Validate(object objectToValidate) + { + string text = objectToValidate as string; + if (StringUtils.IsNullOrEmpty(text)) + { + return true; + } + + Match match = Regex.Match(text, urlCheck); + return match.Success && match.Index == 0 && match.Length == text.Length; + } + + #endregion + + #region Data members + + /// + /// Regular expression used for validation of object passed to this . + /// + private static string urlCheck = "((http|https)://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(([0-9]{1,5})?/.*)?"; + + #endregion + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAccessor.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAccessor.cs index 453eb164..ac7c2eb2 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAccessor.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAccessor.cs @@ -1,730 +1,729 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using AopAlliance.Intercept; -using Common.Logging; -using NHibernate; -using NHibernate.Impl; -using NHibernate.Type; -using Spring.Core.TypeResolution; -using Spring.Dao; -using Spring.Data.Support; -using Spring.Objects.Factory; -using IInterceptor=NHibernate.IInterceptor; -using ICriteria=NHibernate.ICriteria; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Base class for HibernateTemplate defining common - /// properties like SessionFactory and flushing behavior. - /// - /// - ///

Not intended to be used directly. See HibernateTemplate. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: HibernateAccessor.cs,v 1.6 2008/01/25 15:04:39 markpollack Exp $ - public abstract class HibernateAccessor : IInitializingObject, IObjectFactoryAware - { - - private Type criteriaType; - - #region Constants - - /// - /// The instance for this class. - /// - private readonly ILog log = LogManager.GetLogger(typeof (HibernateAccessor)); - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public HibernateAccessor() - { - - } - - #endregion - - - #region Properties - - /// - /// Gets or sets if a new Session should be created when no transactional Session - /// can be found for the current thread. - /// - /// - /// true if allowed to create non-transaction session; - /// otherwise, false. - /// - /// - ///

HibernateTemplate is aware of a corresponding Session bound to the - /// current thread, for example when using HibernateTransactionManager. - /// If allowCreate is true, a new non-transactional Session will be created - /// if none found, which needs to be closed at the end of the operation. - /// If false, an InvalidOperationException will get thrown in this case. - ///

- ///
- public abstract bool AllowCreate - { - get; - set; - } - - /// - /// Gets or sets a value indicating whether to always - /// use a new Hibernate Session for this template. - /// - /// true if always use new session; otherwise, false. - /// - ///

- /// Default is "false"; if activated, all operations on this template will - /// work on a new NHibernate ISession even in case of a pre-bound ISession - /// (for example, within a transaction). - ///

- ///

Within a transaction, a new NHibernate ISession used by this template - /// will participate in the transaction through using the same ADO.NET - /// Connection. In such a scenario, multiple Sessions will participate - /// in the same database transaction. - ///

- ///

Turn this on for operations that are supposed to always execute - /// independently, without side effects caused by a shared NHibernate ISession. - ///

- ///
- public abstract bool AlwaysUseNewSession - { - get; - set; - } - - /// - /// Set whether to expose the native Hibernate Session to IHibernateCallback - /// code. Default is "false": a Session proxy will be returned, - /// suppressing close calls and automatically applying - /// query cache settings and transaction timeouts. - /// - /// true if expose native session; otherwise, false. - public abstract bool ExposeNativeSession - { - get; - set; - } - - /// - /// Gets or sets the template flush mode. - /// - /// - /// Default is Auto. Will get applied to any new ISession - /// created by the template. - /// - /// The template flush mode. - public abstract TemplateFlushMode TemplateFlushMode - { - get; - set; - } - - /// - /// Gets or sets the entity interceptor that allows to inspect and change - /// property values before writing to and reading from the database. - /// - /// - /// Will get applied to any new ISession created by this object. - ///

Such an interceptor can either be set at the ISessionFactory level, - /// i.e. on LocalSessionFactoryObject, or at the ISession level, i.e. on - /// HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. - /// It's preferable to set it on LocalSessionFactoryObject or HibernateTransactionManager - /// to avoid repeated configuration and guarantee consistent behavior in transactions. - ///

- ///
- /// The interceptor. - public abstract IInterceptor EntityInterceptor - { - get; - set; - } - - /// - /// Set the object name of a Hibernate entity interceptor that allows to inspect - /// and change property values before writing to and reading from the database. - /// - /// - /// Will get applied to any new Session created by this transaction manager. - ///

Requires the object factory to be known, to be able to resolve the object - /// name to an interceptor instance on session creation. Typically used for - /// prototype interceptors, i.e. a new interceptor instance per session. - ///

- ///

Can also be used for shared interceptor instances, but it is recommended - /// to set the interceptor reference directly in such a scenario. - ///

- ///
- public abstract string EntityInterceptorObjectName - { - set; - } - - /// - /// Gets or sets the session factory that should be used to create - /// NHibernate ISessions. - /// - /// The session factory. - public abstract ISessionFactory SessionFactory - { - get; - set; - } - - /// - /// Set the object factory instance. - /// - public abstract IObjectFactory ObjectFactory - { - set; - } - - /// - /// Gets or sets a value indicating whether to - /// cache all queries executed by this template. - /// - /// - /// If this is true, all IQuery and ICriteria objects created by - /// this template will be marked as cacheable (including all - /// queries through find methods). - ///

To specify the query region to be used for queries cached - /// by this template, set the QueryCacheRegion property. - ///

- ///
- /// true if cache queries; otherwise, false. - public abstract bool CacheQueries - { - get; - set; - } - - /// - /// Gets or sets the name of the cache region for queries executed by this template. - /// - /// - /// If this is specified, it will be applied to all IQuery and ICriteria objects - /// created by this template (including all queries through find methods). - ///

The cache region will not take effect unless queries created by this - /// template are configured to be cached via the CacheQueries property. - ///

- ///
- /// The query cache region. - public abstract string QueryCacheRegion - { - get; - set; - } - - /// - /// Gets or sets the fetch size for this HibernateTemplate. - /// - /// The size of the fetch. - /// This is important for processing - /// large result sets: Setting this higher than the default value will increase - /// processing speed at the cost of memory consumption; setting this lower can - /// avoid transferring row data that will never be read by the application. - ///

Default is 0, indicating to use the driver's default.

- ///
- public abstract int FetchSize - { - get; - set; - } - - /// - /// Gets or sets the maximum number of rows for this HibernateTemplate. - /// - /// The max results. - /// - /// This is important - /// for processing subsets of large result sets, avoiding to read and hold - /// the entire result set in the database or in the ADO.NET driver if we're - /// never interested in the entire result in the first place (for example, - /// when performing searches that might return a large number of matches). - ///

Default is 0, indicating to use the driver's default.

- ///
- public abstract int MaxResults - { - get; - set; - } - - /// - /// Set the ADO.NET exception translator for this instance. - /// Applied to System.Data.Common.DbException (or provider specific exception type - /// in .NET 1.1) thrown by callback code, be it direct - /// DbException or wrapped Hibernate ADOExceptions. - ///

The default exception translator is either a ErrorCodeExceptionTranslator - /// if a DbProvider is available, or a FalbackExceptionTranslator otherwise - ///

- ///
- /// The ADO exception translator. - public abstract IAdoExceptionTranslator AdoExceptionTranslator - { - set; - get; - } - - /// - /// Gets a Session for use by this template. - /// - /// The session. - /// - /// - Returns a new Session in case of "alwaysUseNewSession" (using the same ADO.NET connection as a transaction Session, if applicable) - /// - a pre-bound Session in case of "AllowCreate" is set to false (not the default) - /// - or a pre-bound Session or new Session if no transactional or other pre-bound Session exists. - /// - protected ISession Session - { - get - { - if (AlwaysUseNewSession) - { - return SessionFactoryUtils.GetNewSession(SessionFactory, EntityInterceptor); - } - else if (!AllowCreate) - { - return SessionFactoryUtils.GetSession(SessionFactory, false); - } - else - { - return SessionFactoryUtils.GetSession( - SessionFactory, EntityInterceptor, AdoExceptionTranslator); - } - - } - - } - - #endregion - - #region Methods - - /// - /// Apply the flush mode that's been specified for this accessor - /// to the given Session. - /// - /// The current Hibernate Session. - /// if set to true - /// if executing within an existing transaction. - /// - /// the previous flush mode to restore after the operation, - /// or null if none - /// - protected FlushModeHolder ApplyFlushMode(ISession session, bool existingTransaction) - { - if (TemplateFlushMode == TemplateFlushMode.Never) - { - if (existingTransaction) - { - FlushMode previousFlushMode = session.FlushMode; - if (previousFlushMode != FlushMode.Never) - { - session.FlushMode = FlushMode.Never; - return new FlushModeHolder(previousFlushMode); - } - } - else - { - session.FlushMode = FlushMode.Never; - } - } - else if (TemplateFlushMode == TemplateFlushMode.Eager) - { - if (existingTransaction) - { - FlushMode previousFlushMode = session.FlushMode; - if (previousFlushMode != FlushMode.Auto) - { - session.FlushMode = FlushMode.Auto; - return new FlushModeHolder(previousFlushMode); - } - } - else - { - // rely on default FlushMode.AUTO - } - } - else if (TemplateFlushMode == TemplateFlushMode.Commit) - { - if (existingTransaction) - { - FlushMode previousFlushMode = session.FlushMode; - if (previousFlushMode == FlushMode.Auto) - { - session.FlushMode = FlushMode.Commit; - return new FlushModeHolder(previousFlushMode); - } - } - else - { - session.FlushMode = FlushMode.Commit; - } - } - return new FlushModeHolder(); - } - - - /// - /// Flush the given Hibernate Session if necessary. - /// - /// The current Hibernate Session. - /// if set to true - /// if executing within an existing transaction. - protected void FlushIfNecessary(ISession session, bool existingTransaction) - { - if (TemplateFlushMode == TemplateFlushMode.Eager || - (!existingTransaction && TemplateFlushMode != TemplateFlushMode.Never)) - { - log.Debug("Eagerly flushing Hibernate session"); - session.Flush(); - } - } - - /// - /// Convert the given HibernateException to an appropriate exception from the - /// org.springframework.dao hierarchy. Will automatically detect - /// wrapped ADO.NET Exceptions and convert them accordingly. - /// - /// HibernateException that occured. - /// - /// The corresponding DataAccessException instance - /// - /// - /// The default implementation delegates to SessionFactoryUtils - /// and convertAdoAccessException. Can be overridden in subclasses. - /// - public virtual DataAccessException ConvertHibernateAccessException(HibernateException ex) - { - if (ex is ADOException) - { - return ConvertAdoAccessException((ADOException) ex); - } - return SessionFactoryUtils.ConvertHibernateAccessException(ex); - } - - /// - /// Converts the ADO.NET access exception to an appropriate exception from the - /// org.springframework.dao hierarchy. Can be overridden in subclasses. - /// - /// ADOException that occured, wrapping underlying ADO.NET exception. - /// - /// the corresponding DataAccessException instance - /// - protected virtual DataAccessException ConvertAdoAccessException(ADOException ex) - { - return AdoExceptionTranslator.Translate( - "Hibernate operation: " + ex.Message, null, ex.InnerException); - } - - /// - /// Converts the ADO.NET access exception to an appropriate exception from the - /// org.springframework.dao hierarchy. Can be overridden in subclasses. - /// - /// - /// - /// Note that a direct SQLException can just occur when callback code - /// performs direct ADO.NET access via ISession.Connection(). - /// - /// - /// The ADO.NET exception. - /// The corresponding DataAccessException instance - protected virtual DataAccessException ConvertAdoAccessException(Exception ex) - { - return AdoExceptionTranslator.Translate("Hibernate operation", null, ex); - } - - - /// - /// Prepare the given IQuery object, applying cache settings and/or - /// a transaction timeout. - /// - /// The query object to prepare. - public virtual void PrepareQuery(IQuery queryObject) - { - if (CacheQueries) - { - queryObject.SetCacheable(true); - if (QueryCacheRegion != null) - { - queryObject.SetCacheRegion(QueryCacheRegion); - } - } - - if (FetchSize > 0) - { - AbstractQueryImpl queryImpl = queryObject as AbstractQueryImpl; - if (queryImpl != null) - { - queryImpl.SetFetchSize(FetchSize); - } - else - { - log.Warn("Could not set FetchSize for IQuery. Expected Implemention to be of type AbstractQueryImpl"); - } - } - - if (MaxResults > 0) - { - queryObject.SetMaxResults(MaxResults); - } - - SessionFactoryUtils.ApplyTransactionTimeout(queryObject, SessionFactory); - - } - - /// - /// Apply the given name parameter to the given Query object. - /// - /// The query object. - /// Name of the parameter - /// The value of the parameter - /// The NHibernate type of the parameter (or null if none specified) - public virtual void ApplyNamedParameterToQuery(IQuery queryObject, string paramName, object value, IType type) - { - - if (value is ICollection) - { - if (type != null) - { - queryObject.SetParameterList(paramName, (ICollection)value, type); - } - else - { - queryObject.SetParameterList(paramName, (ICollection)value); - } - } - else if (value is Object[]) - { - - //TODO investigate support for this conversion. - if (type != null) - { - queryObject.SetParameterList(paramName, (Object[])value, type); - } - else - { - queryObject.SetParameterList(paramName, (Object[])value); - } - } - else - { - if (type != null) - { - queryObject.SetParameter(paramName, value, type); - } - else - { - queryObject.SetParameter(paramName, value); - } - } - } - - /// - /// Prepare the given Criteria object, applying cache settings and/or - /// a transaction timeout. - /// - /// - /// Note that for NHibernate 1.2 this only works if the - /// implementation is of the type CriteriaImpl, which should generally - /// be the case. The SetFetchSize method is not available on the - /// ICriteria interface - /// - /// This is a no-op for NHibernate 1.0.x since - /// the SetFetchSize method is not on the ICriteria interface and - /// the implementation class is has internal access. - /// - /// To remove the method completely for Spring's NHibernate 1.0 - /// support while reusing code for NHibernate 1.2 would not be - /// possible. So now this ineffectual operation is left in tact for - /// NHibernate 1.0.2 support. - /// - /// The criteria object to prepare - public void PrepareCriteria(ICriteria criteria) - { - if (CacheQueries) - { - criteria.SetCacheable(true); - if (QueryCacheRegion != null) - { - criteria.SetCacheRegion(QueryCacheRegion); - } - } - - - - if (FetchSize > 0) - { - //TODO see if we can optimize performance. - //CriteriaImpl is internal in NH 1.0.x - object[] args = new object[] { FetchSize }; - try - { - Type t = TypeResolutionUtils.ResolveType("NHibernate.Impl.CriteriaImpl, NHibernate"); - if (t != null) - { - t.InvokeMember("SetFetchSize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance - | BindingFlags.InvokeMethod, - null, criteria, args); - } - } - catch (TypeLoadException e) - { - log.Warn("Can't set FetchSize for ICriteria", e); - } - } - - if (MaxResults > 0) - { - criteria.SetMaxResults(MaxResults); - } - - SessionFactoryUtils.ApplyTransactionTimeout(criteria, SessionFactory); - } - - private void InitCriteriaType() - { - - try - { - criteriaType = TypeResolutionUtils.ResolveType("Hibernate.Impl.CriteriaImpl, NHibernate"); - } - catch (TypeLoadException e) - { - log.Warn("CriteriaImpl not available. FetchSize can not be set on ICriteria objects", e); - } - } - - #endregion - - /// - /// Ensure SessionFactory is not null - /// - public virtual void AfterPropertiesSet() - { - if (SessionFactory == null) - { - throw new ArgumentException("sessionFactory is required"); - } - } - - #region Helper Classes - /// - /// Helper class to determine if the FlushMode enumeration - /// was changed from its default value - /// - protected class FlushModeHolder - { - /// - /// Gets or sets a value indicating whether the FlushMode - /// property was set.. - /// - /// true if FlushMode was set; otherwise, false. - public bool ModeWasSet - { - get { return modeWasSet; } - set { modeWasSet = value; } - } - - /// - /// Gets or sets the FlushMode. - /// - /// The FlushMode. - public FlushMode Mode - { - get { return flushMode; } - set { flushMode = value; } - } - - private bool modeWasSet = false; - private FlushMode flushMode; - - /// - /// Initializes a new instance of the class. - /// - public FlushModeHolder() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The flush mode. - public FlushModeHolder(FlushMode mode) - { - Mode = mode; - ModeWasSet = true; - } - - } - - - #endregion - - - } - - internal class CloseSuppressingMethodInterceptor : IMethodInterceptor - { - private HibernateAccessor hibernateAccessor; - - public CloseSuppressingMethodInterceptor(HibernateAccessor accessor) - { - hibernateAccessor = accessor; - } - - public object Invoke(IMethodInvocation invocation) - { - //anything special for equals/hashcode? - if (invocation.Method.Name.Equals("Close")) - { - return null; - } - else - { - object retValue = invocation.Proceed(); - if (retValue is IQuery) - { - hibernateAccessor.PrepareQuery((IQuery)retValue); - } - if (retValue is ICriteria) - { - hibernateAccessor.PrepareCriteria((ICriteria)retValue); - } - return retValue; - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using AopAlliance.Intercept; +using Common.Logging; +using NHibernate; +using NHibernate.Impl; +using NHibernate.Type; +using Spring.Core.TypeResolution; +using Spring.Dao; +using Spring.Data.Support; +using Spring.Objects.Factory; +using IInterceptor=NHibernate.IInterceptor; +using ICriteria=NHibernate.ICriteria; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Base class for HibernateTemplate defining common + /// properties like SessionFactory and flushing behavior. + /// + /// + ///

Not intended to be used directly. See HibernateTemplate. + ///

+ ///
+ /// Mark Pollack (.NET) + public abstract class HibernateAccessor : IInitializingObject, IObjectFactoryAware + { + + private Type criteriaType; + + #region Constants + + /// + /// The instance for this class. + /// + private readonly ILog log = LogManager.GetLogger(typeof (HibernateAccessor)); + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public HibernateAccessor() + { + + } + + #endregion + + + #region Properties + + /// + /// Gets or sets if a new Session should be created when no transactional Session + /// can be found for the current thread. + /// + /// + /// true if allowed to create non-transaction session; + /// otherwise, false. + /// + /// + ///

HibernateTemplate is aware of a corresponding Session bound to the + /// current thread, for example when using HibernateTransactionManager. + /// If allowCreate is true, a new non-transactional Session will be created + /// if none found, which needs to be closed at the end of the operation. + /// If false, an InvalidOperationException will get thrown in this case. + ///

+ ///
+ public abstract bool AllowCreate + { + get; + set; + } + + /// + /// Gets or sets a value indicating whether to always + /// use a new Hibernate Session for this template. + /// + /// true if always use new session; otherwise, false. + /// + ///

+ /// Default is "false"; if activated, all operations on this template will + /// work on a new NHibernate ISession even in case of a pre-bound ISession + /// (for example, within a transaction). + ///

+ ///

Within a transaction, a new NHibernate ISession used by this template + /// will participate in the transaction through using the same ADO.NET + /// Connection. In such a scenario, multiple Sessions will participate + /// in the same database transaction. + ///

+ ///

Turn this on for operations that are supposed to always execute + /// independently, without side effects caused by a shared NHibernate ISession. + ///

+ ///
+ public abstract bool AlwaysUseNewSession + { + get; + set; + } + + /// + /// Set whether to expose the native Hibernate Session to IHibernateCallback + /// code. Default is "false": a Session proxy will be returned, + /// suppressing close calls and automatically applying + /// query cache settings and transaction timeouts. + /// + /// true if expose native session; otherwise, false. + public abstract bool ExposeNativeSession + { + get; + set; + } + + /// + /// Gets or sets the template flush mode. + /// + /// + /// Default is Auto. Will get applied to any new ISession + /// created by the template. + /// + /// The template flush mode. + public abstract TemplateFlushMode TemplateFlushMode + { + get; + set; + } + + /// + /// Gets or sets the entity interceptor that allows to inspect and change + /// property values before writing to and reading from the database. + /// + /// + /// Will get applied to any new ISession created by this object. + ///

Such an interceptor can either be set at the ISessionFactory level, + /// i.e. on LocalSessionFactoryObject, or at the ISession level, i.e. on + /// HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. + /// It's preferable to set it on LocalSessionFactoryObject or HibernateTransactionManager + /// to avoid repeated configuration and guarantee consistent behavior in transactions. + ///

+ ///
+ /// The interceptor. + public abstract IInterceptor EntityInterceptor + { + get; + set; + } + + /// + /// Set the object name of a Hibernate entity interceptor that allows to inspect + /// and change property values before writing to and reading from the database. + /// + /// + /// Will get applied to any new Session created by this transaction manager. + ///

Requires the object factory to be known, to be able to resolve the object + /// name to an interceptor instance on session creation. Typically used for + /// prototype interceptors, i.e. a new interceptor instance per session. + ///

+ ///

Can also be used for shared interceptor instances, but it is recommended + /// to set the interceptor reference directly in such a scenario. + ///

+ ///
+ public abstract string EntityInterceptorObjectName + { + set; + } + + /// + /// Gets or sets the session factory that should be used to create + /// NHibernate ISessions. + /// + /// The session factory. + public abstract ISessionFactory SessionFactory + { + get; + set; + } + + /// + /// Set the object factory instance. + /// + public abstract IObjectFactory ObjectFactory + { + set; + } + + /// + /// Gets or sets a value indicating whether to + /// cache all queries executed by this template. + /// + /// + /// If this is true, all IQuery and ICriteria objects created by + /// this template will be marked as cacheable (including all + /// queries through find methods). + ///

To specify the query region to be used for queries cached + /// by this template, set the QueryCacheRegion property. + ///

+ ///
+ /// true if cache queries; otherwise, false. + public abstract bool CacheQueries + { + get; + set; + } + + /// + /// Gets or sets the name of the cache region for queries executed by this template. + /// + /// + /// If this is specified, it will be applied to all IQuery and ICriteria objects + /// created by this template (including all queries through find methods). + ///

The cache region will not take effect unless queries created by this + /// template are configured to be cached via the CacheQueries property. + ///

+ ///
+ /// The query cache region. + public abstract string QueryCacheRegion + { + get; + set; + } + + /// + /// Gets or sets the fetch size for this HibernateTemplate. + /// + /// The size of the fetch. + /// This is important for processing + /// large result sets: Setting this higher than the default value will increase + /// processing speed at the cost of memory consumption; setting this lower can + /// avoid transferring row data that will never be read by the application. + ///

Default is 0, indicating to use the driver's default.

+ ///
+ public abstract int FetchSize + { + get; + set; + } + + /// + /// Gets or sets the maximum number of rows for this HibernateTemplate. + /// + /// The max results. + /// + /// This is important + /// for processing subsets of large result sets, avoiding to read and hold + /// the entire result set in the database or in the ADO.NET driver if we're + /// never interested in the entire result in the first place (for example, + /// when performing searches that might return a large number of matches). + ///

Default is 0, indicating to use the driver's default.

+ ///
+ public abstract int MaxResults + { + get; + set; + } + + /// + /// Set the ADO.NET exception translator for this instance. + /// Applied to System.Data.Common.DbException (or provider specific exception type + /// in .NET 1.1) thrown by callback code, be it direct + /// DbException or wrapped Hibernate ADOExceptions. + ///

The default exception translator is either a ErrorCodeExceptionTranslator + /// if a DbProvider is available, or a FalbackExceptionTranslator otherwise + ///

+ ///
+ /// The ADO exception translator. + public abstract IAdoExceptionTranslator AdoExceptionTranslator + { + set; + get; + } + + /// + /// Gets a Session for use by this template. + /// + /// The session. + /// + /// - Returns a new Session in case of "alwaysUseNewSession" (using the same ADO.NET connection as a transaction Session, if applicable) + /// - a pre-bound Session in case of "AllowCreate" is set to false (not the default) + /// - or a pre-bound Session or new Session if no transactional or other pre-bound Session exists. + /// + protected ISession Session + { + get + { + if (AlwaysUseNewSession) + { + return SessionFactoryUtils.GetNewSession(SessionFactory, EntityInterceptor); + } + else if (!AllowCreate) + { + return SessionFactoryUtils.GetSession(SessionFactory, false); + } + else + { + return SessionFactoryUtils.GetSession( + SessionFactory, EntityInterceptor, AdoExceptionTranslator); + } + + } + + } + + #endregion + + #region Methods + + /// + /// Apply the flush mode that's been specified for this accessor + /// to the given Session. + /// + /// The current Hibernate Session. + /// if set to true + /// if executing within an existing transaction. + /// + /// the previous flush mode to restore after the operation, + /// or null if none + /// + protected FlushModeHolder ApplyFlushMode(ISession session, bool existingTransaction) + { + if (TemplateFlushMode == TemplateFlushMode.Never) + { + if (existingTransaction) + { + FlushMode previousFlushMode = session.FlushMode; + if (previousFlushMode != FlushMode.Never) + { + session.FlushMode = FlushMode.Never; + return new FlushModeHolder(previousFlushMode); + } + } + else + { + session.FlushMode = FlushMode.Never; + } + } + else if (TemplateFlushMode == TemplateFlushMode.Eager) + { + if (existingTransaction) + { + FlushMode previousFlushMode = session.FlushMode; + if (previousFlushMode != FlushMode.Auto) + { + session.FlushMode = FlushMode.Auto; + return new FlushModeHolder(previousFlushMode); + } + } + else + { + // rely on default FlushMode.AUTO + } + } + else if (TemplateFlushMode == TemplateFlushMode.Commit) + { + if (existingTransaction) + { + FlushMode previousFlushMode = session.FlushMode; + if (previousFlushMode == FlushMode.Auto) + { + session.FlushMode = FlushMode.Commit; + return new FlushModeHolder(previousFlushMode); + } + } + else + { + session.FlushMode = FlushMode.Commit; + } + } + return new FlushModeHolder(); + } + + + /// + /// Flush the given Hibernate Session if necessary. + /// + /// The current Hibernate Session. + /// if set to true + /// if executing within an existing transaction. + protected void FlushIfNecessary(ISession session, bool existingTransaction) + { + if (TemplateFlushMode == TemplateFlushMode.Eager || + (!existingTransaction && TemplateFlushMode != TemplateFlushMode.Never)) + { + log.Debug("Eagerly flushing Hibernate session"); + session.Flush(); + } + } + + /// + /// Convert the given HibernateException to an appropriate exception from the + /// org.springframework.dao hierarchy. Will automatically detect + /// wrapped ADO.NET Exceptions and convert them accordingly. + /// + /// HibernateException that occured. + /// + /// The corresponding DataAccessException instance + /// + /// + /// The default implementation delegates to SessionFactoryUtils + /// and convertAdoAccessException. Can be overridden in subclasses. + /// + public virtual DataAccessException ConvertHibernateAccessException(HibernateException ex) + { + if (ex is ADOException) + { + return ConvertAdoAccessException((ADOException) ex); + } + return SessionFactoryUtils.ConvertHibernateAccessException(ex); + } + + /// + /// Converts the ADO.NET access exception to an appropriate exception from the + /// org.springframework.dao hierarchy. Can be overridden in subclasses. + /// + /// ADOException that occured, wrapping underlying ADO.NET exception. + /// + /// the corresponding DataAccessException instance + /// + protected virtual DataAccessException ConvertAdoAccessException(ADOException ex) + { + return AdoExceptionTranslator.Translate( + "Hibernate operation: " + ex.Message, null, ex.InnerException); + } + + /// + /// Converts the ADO.NET access exception to an appropriate exception from the + /// org.springframework.dao hierarchy. Can be overridden in subclasses. + /// + /// + /// + /// Note that a direct SQLException can just occur when callback code + /// performs direct ADO.NET access via ISession.Connection(). + /// + /// + /// The ADO.NET exception. + /// The corresponding DataAccessException instance + protected virtual DataAccessException ConvertAdoAccessException(Exception ex) + { + return AdoExceptionTranslator.Translate("Hibernate operation", null, ex); + } + + + /// + /// Prepare the given IQuery object, applying cache settings and/or + /// a transaction timeout. + /// + /// The query object to prepare. + public virtual void PrepareQuery(IQuery queryObject) + { + if (CacheQueries) + { + queryObject.SetCacheable(true); + if (QueryCacheRegion != null) + { + queryObject.SetCacheRegion(QueryCacheRegion); + } + } + + if (FetchSize > 0) + { + AbstractQueryImpl queryImpl = queryObject as AbstractQueryImpl; + if (queryImpl != null) + { + queryImpl.SetFetchSize(FetchSize); + } + else + { + log.Warn("Could not set FetchSize for IQuery. Expected Implemention to be of type AbstractQueryImpl"); + } + } + + if (MaxResults > 0) + { + queryObject.SetMaxResults(MaxResults); + } + + SessionFactoryUtils.ApplyTransactionTimeout(queryObject, SessionFactory); + + } + + /// + /// Apply the given name parameter to the given Query object. + /// + /// The query object. + /// Name of the parameter + /// The value of the parameter + /// The NHibernate type of the parameter (or null if none specified) + public virtual void ApplyNamedParameterToQuery(IQuery queryObject, string paramName, object value, IType type) + { + + if (value is ICollection) + { + if (type != null) + { + queryObject.SetParameterList(paramName, (ICollection)value, type); + } + else + { + queryObject.SetParameterList(paramName, (ICollection)value); + } + } + else if (value is Object[]) + { + + //TODO investigate support for this conversion. + if (type != null) + { + queryObject.SetParameterList(paramName, (Object[])value, type); + } + else + { + queryObject.SetParameterList(paramName, (Object[])value); + } + } + else + { + if (type != null) + { + queryObject.SetParameter(paramName, value, type); + } + else + { + queryObject.SetParameter(paramName, value); + } + } + } + + /// + /// Prepare the given Criteria object, applying cache settings and/or + /// a transaction timeout. + /// + /// + /// Note that for NHibernate 1.2 this only works if the + /// implementation is of the type CriteriaImpl, which should generally + /// be the case. The SetFetchSize method is not available on the + /// ICriteria interface + /// + /// This is a no-op for NHibernate 1.0.x since + /// the SetFetchSize method is not on the ICriteria interface and + /// the implementation class is has internal access. + /// + /// To remove the method completely for Spring's NHibernate 1.0 + /// support while reusing code for NHibernate 1.2 would not be + /// possible. So now this ineffectual operation is left in tact for + /// NHibernate 1.0.2 support. + /// + /// The criteria object to prepare + public void PrepareCriteria(ICriteria criteria) + { + if (CacheQueries) + { + criteria.SetCacheable(true); + if (QueryCacheRegion != null) + { + criteria.SetCacheRegion(QueryCacheRegion); + } + } + + + + if (FetchSize > 0) + { + //TODO see if we can optimize performance. + //CriteriaImpl is internal in NH 1.0.x + object[] args = new object[] { FetchSize }; + try + { + Type t = TypeResolutionUtils.ResolveType("NHibernate.Impl.CriteriaImpl, NHibernate"); + if (t != null) + { + t.InvokeMember("SetFetchSize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance + | BindingFlags.InvokeMethod, + null, criteria, args); + } + } + catch (TypeLoadException e) + { + log.Warn("Can't set FetchSize for ICriteria", e); + } + } + + if (MaxResults > 0) + { + criteria.SetMaxResults(MaxResults); + } + + SessionFactoryUtils.ApplyTransactionTimeout(criteria, SessionFactory); + } + + private void InitCriteriaType() + { + + try + { + criteriaType = TypeResolutionUtils.ResolveType("Hibernate.Impl.CriteriaImpl, NHibernate"); + } + catch (TypeLoadException e) + { + log.Warn("CriteriaImpl not available. FetchSize can not be set on ICriteria objects", e); + } + } + + #endregion + + /// + /// Ensure SessionFactory is not null + /// + public virtual void AfterPropertiesSet() + { + if (SessionFactory == null) + { + throw new ArgumentException("sessionFactory is required"); + } + } + + #region Helper Classes + /// + /// Helper class to determine if the FlushMode enumeration + /// was changed from its default value + /// + protected class FlushModeHolder + { + /// + /// Gets or sets a value indicating whether the FlushMode + /// property was set.. + /// + /// true if FlushMode was set; otherwise, false. + public bool ModeWasSet + { + get { return modeWasSet; } + set { modeWasSet = value; } + } + + /// + /// Gets or sets the FlushMode. + /// + /// The FlushMode. + public FlushMode Mode + { + get { return flushMode; } + set { flushMode = value; } + } + + private bool modeWasSet = false; + private FlushMode flushMode; + + /// + /// Initializes a new instance of the class. + /// + public FlushModeHolder() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The flush mode. + public FlushModeHolder(FlushMode mode) + { + Mode = mode; + ModeWasSet = true; + } + + } + + + #endregion + + + } + + internal class CloseSuppressingMethodInterceptor : IMethodInterceptor + { + private HibernateAccessor hibernateAccessor; + + public CloseSuppressingMethodInterceptor(HibernateAccessor accessor) + { + hibernateAccessor = accessor; + } + + public object Invoke(IMethodInvocation invocation) + { + //anything special for equals/hashcode? + if (invocation.Method.Name.Equals("Close")) + { + return null; + } + else + { + object retValue = invocation.Proceed(); + if (retValue is IQuery) + { + hibernateAccessor.PrepareQuery((IQuery)retValue); + } + if (retValue is ICriteria) + { + hibernateAccessor.PrepareCriteria((ICriteria)retValue); + } + return retValue; + } + } + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAdoException.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAdoException.cs index 6ec61040..599d8be7 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAdoException.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateAdoException.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using NHibernate; -using Spring.Dao; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Hibernate-specific subclass of UncategorizedDataAccessException, - /// for ADO.NET exceptions that Hibernate rethrew and could not be - /// mapped into the DAO exception heirarchy. - /// - /// Mark Pollack (.NET) - /// $Id: HibernateAdoException.cs,v 1.1 2007/05/31 20:25:13 markpollack Exp $ - [Serializable] - public class HibernateAdoException : UncategorizedDataAccessException - { - - #region Constructor (s) - - - /// - /// Initializes a new instance of the class. - /// - public HibernateAdoException() : base() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public HibernateAdoException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception from the underlying data access API - ADO.NET - /// - public HibernateAdoException( string message, ADOException rootCause ) : base( message, rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected HibernateAdoException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - #endregion - - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using NHibernate; +using Spring.Dao; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Hibernate-specific subclass of UncategorizedDataAccessException, + /// for ADO.NET exceptions that Hibernate rethrew and could not be + /// mapped into the DAO exception heirarchy. + /// + /// Mark Pollack (.NET) + [Serializable] + public class HibernateAdoException : UncategorizedDataAccessException + { + + #region Constructor (s) + + + /// + /// Initializes a new instance of the class. + /// + public HibernateAdoException() : base() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public HibernateAdoException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception from the underlying data access API - ADO.NET + /// + public HibernateAdoException( string message, ADOException rootCause ) : base( message, rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected HibernateAdoException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + #endregion + + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateDelegate.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateDelegate.cs index b05380d8..406fb13d 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateDelegate.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateDelegate.cs @@ -1,43 +1,43 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using NHibernate; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public delegate object HibernateDelegate(ISession session); -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using NHibernate; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public delegate object HibernateDelegate(ISession session); +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateObjectRetrievalFailureException.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateObjectRetrievalFailureException.cs index a8953b84..82056179 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateObjectRetrievalFailureException.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateObjectRetrievalFailureException.cs @@ -1,109 +1,108 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using NHibernate; -using Spring.Dao; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Hibernate-specific subclass of ObjectRetrievalFailureException. - /// - /// - /// Converts Hibernate's UnresolvableObjectException, ObjectNotFoundException, - /// ObjectDeletedException, and WrongClassException. - /// - /// Mark Pollack (.NET) - /// $Id: HibernateObjectRetrievalFailureException.cs,v 1.1 2007/05/31 20:25:13 markpollack Exp $ - [Serializable] - public class HibernateObjectRetrievalFailureException : ObjectRetrievalFailureException - { - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public HibernateObjectRetrievalFailureException() - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// The ex. - public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) : base(ex.PersistentClass, ex.Identifier, ex.Message, ex) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The ex. - public HibernateObjectRetrievalFailureException(ObjectNotFoundException ex) : base(ex.PersistentClass, ex.Identifier, ex.Message, ex) - - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The ex. - public HibernateObjectRetrievalFailureException(ObjectDeletedException ex) : base(ex.PersistentClass, ex.Identifier, ex.Message, ex) - { - - } - - //TODO investigate WrongClassException.Type as equivalent to ex.PersistentClass - /// - /// Initializes a new instance of the class. - /// - /// The ex. - public HibernateObjectRetrievalFailureException(WrongClassException ex) : base(ex.Type, ex.Identifier, ex.Message, ex) - { - - } - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected HibernateObjectRetrievalFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using NHibernate; +using Spring.Dao; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Hibernate-specific subclass of ObjectRetrievalFailureException. + /// + /// + /// Converts Hibernate's UnresolvableObjectException, ObjectNotFoundException, + /// ObjectDeletedException, and WrongClassException. + /// + /// Mark Pollack (.NET) + [Serializable] + public class HibernateObjectRetrievalFailureException : ObjectRetrievalFailureException + { + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public HibernateObjectRetrievalFailureException() + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// The ex. + public HibernateObjectRetrievalFailureException(UnresolvableObjectException ex) : base(ex.PersistentClass, ex.Identifier, ex.Message, ex) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The ex. + public HibernateObjectRetrievalFailureException(ObjectNotFoundException ex) : base(ex.PersistentClass, ex.Identifier, ex.Message, ex) + + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The ex. + public HibernateObjectRetrievalFailureException(ObjectDeletedException ex) : base(ex.PersistentClass, ex.Identifier, ex.Message, ex) + { + + } + + //TODO investigate WrongClassException.Type as equivalent to ex.PersistentClass + /// + /// Initializes a new instance of the class. + /// + /// The ex. + public HibernateObjectRetrievalFailureException(WrongClassException ex) : base(ex.Type, ex.Identifier, ex.Message, ex) + { + + } + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected HibernateObjectRetrievalFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + #endregion + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateOptimisticLockingFailureException.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateOptimisticLockingFailureException.cs index f2cac64e..afec84da 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateOptimisticLockingFailureException.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateOptimisticLockingFailureException.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using NHibernate; -using Spring.Dao; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Hibernate-specific subclass of ObjectOptimisticLockingFailureException. - /// - /// - /// Converts Hibernate's StaleObjectStateException. - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: HibernateOptimisticLockingFailureException.cs,v 1.2 2008/04/08 20:26:37 markpollack Exp $ - [Serializable] - public class HibernateOptimisticLockingFailureException : ObjectOptimisticLockingFailureException - { - #region Fields - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public HibernateOptimisticLockingFailureException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The StaleObjectStateException. - public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) : base(ex.PersistentType, ex.Identifier, ex.Message, ex) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected HibernateOptimisticLockingFailureException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using NHibernate; +using Spring.Dao; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Hibernate-specific subclass of ObjectOptimisticLockingFailureException. + /// + /// + /// Converts Hibernate's StaleObjectStateException. + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + [Serializable] + public class HibernateOptimisticLockingFailureException : ObjectOptimisticLockingFailureException + { + #region Fields + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public HibernateOptimisticLockingFailureException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The StaleObjectStateException. + public HibernateOptimisticLockingFailureException(StaleObjectStateException ex) : base(ex.PersistentType, ex.Identifier, ex.Message, ex) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected HibernateOptimisticLockingFailureException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateQueryException.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateQueryException.cs index 9955ff77..3b8d9065 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateQueryException.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateQueryException.cs @@ -1,85 +1,84 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using NHibernate; -using Spring.Dao; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Hibernate-specific subclass of InvalidDataAccessResourceUsageException, - /// thrown on invalid HQL query syntax. - /// - /// Mark Pollack (.NET) - /// $Id: HibernateQueryException.cs,v 1.1 2007/05/31 20:25:13 markpollack Exp $ - [Serializable] - public class HibernateQueryException : InvalidDataAccessResourceUsageException - { - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public HibernateQueryException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The ex. - public HibernateQueryException(QueryException ex) : base(ex.Message, ex) - { - } - - /// - /// Gets the query string that was invalid. - /// - /// The query string that was invalid. - public string QueryString - { - get { return ((QueryException) this.InnerException).QueryString; } - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected HibernateQueryException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using NHibernate; +using Spring.Dao; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Hibernate-specific subclass of InvalidDataAccessResourceUsageException, + /// thrown on invalid HQL query syntax. + /// + /// Mark Pollack (.NET) + [Serializable] + public class HibernateQueryException : InvalidDataAccessResourceUsageException + { + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public HibernateQueryException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The ex. + public HibernateQueryException(QueryException ex) : base(ex.Message, ex) + { + } + + /// + /// Gets the query string that was invalid. + /// + /// The query string that was invalid. + public string QueryString + { + get { return ((QueryException) this.InnerException).QueryString; } + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected HibernateQueryException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateSystemException.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateSystemException.cs index ec1a79ef..f22ae59a 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateSystemException.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateSystemException.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using NHibernate; -using Spring.Dao; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Hibernate-specific subclass of UncategorizedDataAccessException, - /// for Hibernate system errors that do not match any concrete - /// Spring.Dao exceptions. - /// - /// Mark Pollack (.NET) - /// $Id: HibernateSystemException.cs,v 1.1 2007/05/31 20:25:13 markpollack Exp $ - [Serializable] - public class HibernateSystemException : UncategorizedDataAccessException - { - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public HibernateSystemException() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// The cause. - public HibernateSystemException(HibernateException cause) : base(cause != null ? cause.Message : null, cause) - { - - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected HibernateSystemException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using NHibernate; +using Spring.Dao; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Hibernate-specific subclass of UncategorizedDataAccessException, + /// for Hibernate system errors that do not match any concrete + /// Spring.Dao exceptions. + /// + /// Mark Pollack (.NET) + [Serializable] + public class HibernateSystemException : UncategorizedDataAccessException + { + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public HibernateSystemException() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The cause. + public HibernateSystemException(HibernateException cause) : base(cause != null ? cause.Message : null, cause) + { + + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected HibernateSystemException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + + #endregion + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTemplate.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTemplate.cs index 35b962fa..37a8366f 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTemplate.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTemplate.cs @@ -1,2238 +1,2237 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Common.Logging; -using Spring.Aop.Framework; -using Spring.Data.Common; -using Spring.Data.Support; -using IInterceptor = NHibernate.IInterceptor; - -using NHibernate; -using NHibernate.Type; -using Spring.Dao; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Helper class that simplifies NHibernate data access code - /// - /// - ///

Typically used to implement data access or business logic services that - /// use NHibernate within their implementation but are Hibernate-agnostic in their - /// interface. The latter or code calling the latter only have to deal with - /// domain objects.

- /// - ///

The central method is Execute supporting Hibernate access code - /// implementing the HibernateCallback interface. It provides NHibernate Session - /// handling such that neither the IHibernateCallback implementation nor the calling - /// code needs to explicitly care about retrieving/closing NHibernate Sessions, - /// or handling Session lifecycle exceptions. For typical single step actions, - /// there are various convenience methods (Find, Load, SaveOrUpdate, Delete). - ///

- /// - ///

Can be used within a service implementation via direct instantiation - /// with a ISessionFactory reference, or get prepared in an application context - /// and given to services as an object reference. Note: The ISessionFactory should - /// always be configured as an object in the application context, in the first case - /// given to the service directly, in the second case to the prepared template. - ///

- /// - ///

This class can be considered as direct alternative to working with the raw - /// Hibernate Session API (through SessionFactoryUtils.Session). - ///

- /// - ///

LocalSessionFactoryObject is the preferred way of obtaining a reference - /// to a specific NHibernate ISessionFactory. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: HibernateTemplate.cs,v 1.3 2008/01/24 17:29:16 markpollack Exp $ - public class HibernateTemplate : HibernateAccessor, IHibernateOperations - { - #region Fields - - /// - /// The instance for this class. - /// - private readonly ILog log = LogManager.GetLogger(typeof(HibernateTemplate)); - - private bool checkWriteOperations = true; - - - private bool exposeNativeSession = false; - - private bool alwaysUseNewSession = false; - private int maxResults = 0; - private TemplateFlushMode templateFlushMode = TemplateFlushMode.Auto; - private bool allowCreate = true; - private ISessionFactory sessionFactory; - private object entityInterceptor; - private IObjectFactory objectFactory; - private bool cacheQueries = false; - private string queryCacheRegion; - private int fetchSize = 0; - - private IAdoExceptionTranslator adoExceptionTranslator; - - private readonly object syncRoot = new object(); - private ProxyFactory sessionProxyFactory; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public HibernateTemplate() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// The default for creating a new non-transactional - /// session when no transactional Session can be found for the current thread - /// is set to true. - /// The session factory to create sessions. - public HibernateTemplate(ISessionFactory sessionFactory) - { - SessionFactory = sessionFactory; - AfterPropertiesSet(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The session factory to create sessions. - /// if set to true allow creation - /// of a new non-transactional when no transactional Session can be found - /// for the current thread. - public HibernateTemplate(ISessionFactory sessionFactory, bool allowCreate) - { - SessionFactory = sessionFactory; - AllowCreate = allowCreate; - AfterPropertiesSet(); - } - #endregion - - #region Properties - - /// - /// Gets or sets if a new Session should be created when no transactional Session - /// can be found for the current thread. - /// - /// - /// true if allowed to create non-transaction session; - /// otherwise, false. - /// - /// - ///

HibernateTemplate is aware of a corresponding Session bound to the - /// current thread, for example when using HibernateTransactionManager. - /// If allowCreate is true, a new non-transactional Session will be created - /// if none found, which needs to be closed at the end of the operation. - /// If false, an InvalidOperationException will get thrown in this case. - ///

- ///
- public override bool AllowCreate - { - get - { - - return allowCreate; - } - set { allowCreate = value; } - } - - /// - /// Gets or sets a value indicating whether to always - /// use a new Hibernate Session for this template. - /// - /// true if always use new session; otherwise, false. - /// - ///

- /// Default is "false"; if activated, all operations on this template will - /// work on a new NHibernate ISession even in case of a pre-bound ISession - /// (for example, within a transaction). - ///

- ///

Within a transaction, a new NHibernate ISession used by this template - /// will participate in the transaction through using the same ADO.NET - /// Connection. In such a scenario, multiple Sessions will participate - /// in the same database transaction. - ///

- ///

Turn this on for operations that are supposed to always execute - /// independently, without side effects caused by a shared NHibernate ISession. - ///

- ///
- public override bool AlwaysUseNewSession - { - get { return alwaysUseNewSession; } - set { alwaysUseNewSession = value; } - } - - - /// - /// Gets or sets the template flush mode. - /// - /// - /// Default is Auto. Will get applied to any new ISession - /// created by the template. - /// - /// The template flush mode. - public override TemplateFlushMode TemplateFlushMode - { - get { return templateFlushMode; } - set { templateFlushMode = value; } - } - - /// - /// Gets or sets the entity interceptor that allows to inspect and change - /// property values before writing to and reading from the database. - /// - /// - /// Will get applied to any new ISession created by this object. - ///

Such an interceptor can either be set at the ISessionFactory level, - /// i.e. on LocalSessionFactoryObject, or at the ISession level, i.e. on - /// HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. - /// It's preferable to set it on LocalSessionFactoryObject or HibernateTransactionManager - /// to avoid repeated configuration and guarantee consistent behavior in transactions. - ///

- ///
- /// The interceptor. - /// If object factory is not set and need to retrieve entity interceptor by name. - public override IInterceptor EntityInterceptor - { - get - { - if (this.entityInterceptor is string) - { - if (this.objectFactory == null) - { - throw new InvalidOperationException("Cannot get entity interceptor via object name if no object factory set"); - } - return (IInterceptor)this.objectFactory.GetObject((String)this.entityInterceptor, typeof(IInterceptor)); - } - - return (IInterceptor)entityInterceptor; - } - set - { - entityInterceptor = value; - } - } - /// - /// Gets or sets the name of the cache region for queries executed by this template. - /// - /// - /// If this is specified, it will be applied to all IQuery and ICriteria objects - /// created by this template (including all queries through find methods). - ///

The cache region will not take effect unless queries created by this - /// template are configured to be cached via the CacheQueries property. - ///

- ///
- /// The query cache region. - public override string QueryCacheRegion - { - get { return queryCacheRegion; } - set { queryCacheRegion = value; } - } - - - /// - /// Gets or sets a value indicating whether to - /// cache all queries executed by this template. - /// - /// - /// If this is true, all IQuery and ICriteria objects created by - /// this template will be marked as cacheable (including all - /// queries through find methods). - ///

To specify the query region to be used for queries cached - /// by this template, set the QueryCacheRegion property. - ///

- ///
- /// true if cache queries; otherwise, false. - public override bool CacheQueries - { - get { return cacheQueries; } - set { cacheQueries = value; } - } - - /// - /// Gets or sets the maximum number of rows for this HibernateTemplate. - /// - /// The max results. - /// - /// This is important - /// for processing subsets of large result sets, avoiding to read and hold - /// the entire result set in the database or in the ADO.NET driver if we're - /// never interested in the entire result in the first place (for example, - /// when performing searches that might return a large number of matches). - ///

Default is 0, indicating to use the driver's default.

- ///
- public override int MaxResults - { - get { return maxResults; } - set { maxResults = value; } - } - - /// - /// Set whether to expose the native Hibernate Session to IHibernateCallback - /// code. Default is "false": a Session proxy will be returned, - /// suppressing close calls and automatically applying - /// query cache settings and transaction timeouts. - /// - /// true if expose native session; otherwise, false. - public override bool ExposeNativeSession - { - get { return exposeNativeSession; } - set { exposeNativeSession = value; } - } - /// - /// Gets or sets whether to check that the Hibernate Session is not in read-only mode - /// in case of write operations (save/update/delete). - /// - /// - /// true if check that the Hibernate Session is not in read-only mode - /// in case of write operations; otherwise, false. - /// - /// - /// Default is "true", for fail-fast behavior when attempting write operations - /// within a read-only transaction. Turn this off to allow save/update/delete - /// on a Session with flush mode NEVER. - /// - public virtual bool CheckWriteOperations - { - get { return checkWriteOperations; } - set { checkWriteOperations = value; } - } - - /// - /// Set the object name of a Hibernate entity interceptor that allows to inspect - /// and change property values before writing to and reading from the database. - /// - /// - /// Will get applied to any new Session created by this transaction manager. - ///

Requires the object factory to be known, to be able to resolve the object - /// name to an interceptor instance on session creation. Typically used for - /// prototype interceptors, i.e. a new interceptor instance per session. - ///

- ///

Can also be used for shared interceptor instances, but it is recommended - /// to set the interceptor reference directly in such a scenario. - ///

- ///
- /// The name of the entity interceptor in the object factory/application context. - public override string EntityInterceptorObjectName - { - set - { - this.entityInterceptor = value; - } - } - - /// - /// Set the object factory instance. - /// - /// The object factory instance - public override IObjectFactory ObjectFactory - { - set - { - objectFactory = value; - } - } - - /// - /// Gets or sets the session factory that should be used to create - /// NHibernate ISessions. - /// - /// The session factory. - public override ISessionFactory SessionFactory - { - get { return sessionFactory; } - set - { - sessionFactory = value; - } - } - - /// - /// Gets or sets the fetch size for this HibernateTemplate. - /// - /// The size of the fetch. - /// This is important for processing - /// large result sets: Setting this higher than the default value will increase - /// processing speed at the cost of memory consumption; setting this lower can - /// avoid transferring row data that will never be read by the application. - ///

Default is 0, indicating to use the driver's default.

- ///
- public override int FetchSize - { - get { return fetchSize; } - set { fetchSize = value; } - } - - - /// - /// Gets or sets the proxy factory. - /// - /// This may be useful to set if you create many instances of - /// HibernateTemplate and/or HibernateDaoSupport. This allows the same - /// ProxyFactory implementation to be used thereby limiting the - /// number of dynamic proxy types created in the temporary assembly, which - /// are never garbage collected due to .NET runtime semantics. - /// - /// The proxy factory. - public virtual ProxyFactory ProxyFactory - { - get { return sessionProxyFactory; } - set { sessionProxyFactory = value; } - } - - #endregion - - #region IHibernateOperations Members - - /// - /// Set the ADO.NET exception translator for this instance. - /// Applied to System.Data.Common.DbException (or provider specific exception type - /// in .NET 1.1) thrown by callback code, be it direct - /// DbException or wrapped Hibernate ADOExceptions. - ///

The default exception translator is either a ErrorCodeExceptionTranslator - /// if a DbProvider is available, or a FalbackExceptionTranslator otherwise - ///

- ///
- /// The ADO exception translator. - public override IAdoExceptionTranslator AdoExceptionTranslator - { - set { adoExceptionTranslator = value; } - get - { - if (adoExceptionTranslator == null) - { - adoExceptionTranslator = SessionFactoryUtils.NewAdoExceptionTranslator(SessionFactory); - } - return adoExceptionTranslator; - } - } - - - /// - /// Delegate function that clears the session. - /// - /// The hibernate session. - /// null - protected object ClearAction(ISession session) - { - session.Clear(); - return null; - } - - /// - /// Flush all pending saves, updates and deletes to the database. - /// - /// - /// Only invoke this for selective eager flushing, for example when ADO.NET code - /// needs to see certain changes within the same transaction. Else, it's preferable - /// to rely on auto-flushing at transaction completion. - /// - /// In case of Hibernate errors - public void Flush() - { - Execute(new HibernateDelegate(FlushAction), true); - } - - private object FlushAction(ISession session) - { - session.Flush(); - return null; - } - - /// - /// Return the persistent instance of the given entity type - /// with the given identifier, or null if not found. - /// - /// The type. - /// An identifier of the persistent instance. - /// The persistent instance, or null if not found - /// In case of Hibernate errors - public object Get(Type entityType, object id) - { - return Get(entityType, id, null); - } - - /// - /// Return the persistent instance of the given entity type - /// with the given identifier, or null if not found. - /// Obtains the specified lock mode if the instance exists. - /// - /// The type. - /// The lock mode to obtain. - /// The lock mode. - /// the persistent instance, or null if not found - /// the persistent instance, or null if not found - /// In case of Hibernate errors - public object Get(Type type, object id, LockMode lockMode) - { - return Execute(new GetByTypeHibernateCallback(type, id, lockMode),true); - - } - - /// - /// Return the persistent instance of the given entity class - /// with the given identifier, throwing an exception if not found. - /// - /// Type of the entity. - /// An identifier of the persistent instance. - /// The persistent instance - /// If not found - /// In case of Hibernate errors - public object Load(Type entityType, object id) - { - return Load(entityType, id, null); - } - - /// - /// Return the persistent instance of the given entity class - /// with the given identifier, throwing an exception if not found. - /// Obtains the specified lock mode if the instance exists. - /// - /// Type of the entity. - /// An identifier of the persistent instance. - /// The lock mode. - /// The persistent instance - /// If not found - /// In case of Hibernate errors - public object Load(Type entityType, object id, LockMode lockMode) - { - return Execute(new LoadByTypeHibernateCallback(entityType, id, lockMode),true); - - } - - /// - /// Load the persistent instance with the given identifier - /// into the given object, throwing an exception if not found. - /// - /// Entity the object (of the target class) to load into. - /// An identifier of the persistent instance. - /// If object not found. - /// In case of Hibernate errors - public void Load(object entity, object id) - { - Execute(new LoadByEntityHibernateCallback(entity, id),true); - } - - /// - /// Return all persistent instances of the given entity class. - /// Note: Use queries or criteria for retrieving a specific subset. - /// - /// Type of the entity. - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList LoadAll(Type entityType) - { - return (IList)Execute(new LoadAllByTypeHibernateCallback(this, entityType),true); - } - - /// - /// Re-read the state of the given persistent instance. - /// - /// The persistent instance to re-read. - /// In case of Hibernate errors - public void Refresh(object entity) - { - Refresh(entity, null); - } - - /// - /// Re-read the state of the given persistent instance. - /// Obtains the specified lock mode for the instance. - /// - /// The persistent instance to re-read. - /// The lock mode to obtain. - /// In case of Hibernate errors - public void Refresh(object entity, LockMode lockMode) - { - Execute(new RefreshHibernateCallback(entity, lockMode),true); - } - - /// - /// Obtain the specified lock level upon the given object, implicitly - /// checking whether the corresponding database entry still exists - /// (throwing an OptimisticLockingFailureException if not found). - /// - /// The he persistent instance to lock. - /// The lock mode to obtain. - /// If not found - /// In case of Hibernate errors - public void Lock(object entity, LockMode lockMode) - { - Execute(new LockHibernateCallback(entity, lockMode),true); - } - - /// - /// Persist the given transient instance. - /// - /// The transient instance to persist. - /// The generated identifier. - /// In case of Hibernate errors - public object Save(object entity) - { - return Execute(new SaveObjectHibernateCallback(this, entity),true); - } - - /// - /// Persist the given transient instance with the given identifier. - /// - /// The transient instance to persist. - /// The identifier to assign. - /// In case of Hibernate errors - public void Save(object entity, object id) - { - Execute(new SaveObjectWithIdHibernateCallback(this, entity, id),true); - } - - /// - /// Update the given persistent instance. - /// - /// The persistent instance to update. - /// In case of Hibernate errors - public void Update(object entity) - { - Update(entity, null); - } - - /// - /// Update the given persistent instance. - /// Obtains the specified lock mode if the instance exists, implicitly - /// checking whether the corresponding database entry still exists - /// (throwing an OptimisticLockingFailureException if not found). - /// - /// The persistent instance to update. - /// The lock mode to obtain. - /// In case of Hibernate errors - public void Update(object entity, LockMode lockMode) - { - Execute(new UpdateObjectHibernateCallback(this, entity, lockMode),true); - } - - /// - /// Save or update the given persistent instance, - /// according to its id (matching the configured "unsaved-value"?). - /// - /// Tthe persistent instance to save or update - /// (to be associated with the Hibernate Session). - /// In case of Hibernate errors - public void SaveOrUpdate(object entity) - { - Execute(new SaveOrUpdateObjectHibernateCallback(this, entity),true); - } - - /// - /// Save or update all given persistent instances, - /// according to its id (matching the configured "unsaved-value"?). - /// - /// Tthe persistent instances to save or update - /// (to be associated with the Hibernate Session)he entities. - /// In case of Hibernate errors - public void SaveOrUpdateAll(ICollection entities) - { - Execute(new SaveOrUpdateAllHibernateCallback(this, entities), true); - } - - /// - /// Save or update the contents of given persistent object, - /// according to its id (matching the configured "unsaved-value"?). - /// Will copy the contained fields to an already loaded instance - /// with the same id, if appropriate. - /// - /// The persistent object to save or update. - /// (not necessarily to be associated with the Hibernate Session) - /// - /// The actually associated persistent object. - /// (either an already loaded instance with the same id, or the given object) - /// In case of Hibernate errors - public object SaveOrUpdateCopy(object entity) - { - return Execute(new SaveOrUpdateCopyHibernateCallback(this, entity),true); - } - - - /// - /// Remove all objects from the Session cache, and cancel all pending saves, - /// updates and deletes. - /// - public void Clear() - { - Execute(new HibernateDelegate(ClearAction), true); - } - - - - /// - /// Determines whether the given object is in the Session cache. - /// - /// the persistence instance to check. - /// - /// true if session cache contains the specified entity; otherwise, false. - /// - /// In case of Hibernate errors - public bool Contains(object entity) - { - return (bool)Execute(new ContainsHibernateCallback(entity)); - } - - /// - /// Remove the given object from the Session cache. - /// - /// The persistent instance to evict. - /// In case of Hibernate errors - public void Evict(object entity) - { - Execute(new EvictHibernateCallback(entity), true); - - } - - - - /// - /// Delete the given persistent instance. - /// - /// The persistent instance to delete. - /// In case of Hibernate errors - public void Delete(object entity) - { - Delete(entity, null); - } - - - /// - /// Delete the given persistent instance. - /// - /// Tthe persistent instance to delete. - /// The lock mode to obtain. - /// - /// Obtains the specified lock mode if the instance exists, implicitly - /// checking whether the corresponding database entry still exists - /// (throwing an OptimisticLockingFailureException if not found). - /// - /// In case of Hibernate errors - public void Delete(object entity, LockMode lockMode) - { - Execute(new DeleteLockModeHibernateCallback(this, entity, lockMode), true); - } - - /// - /// Delete all objects returned by the query. - /// - /// a query expressed in Hibernate's query language. - /// The number of entity instances deleted. - /// In case of Hibernate errors - public int Delete(string queryString) - { - return Delete(queryString, (Object[]) null, (IType[]) null); - } - - /// - /// Delete all objects returned by the query. - /// - /// a query expressed in Hibernate's query language. - /// The value of the parameter. - /// The Hibernate type of the parameter (or null). - /// The number of entity instances deleted. - /// In case of Hibernate errors - public int Delete(string queryString, object value, IType type) - { - return Delete(queryString, new Object[] {value}, new IType[] {type}); - } - - /// - /// Delete all objects returned by the query. - /// - /// a query expressed in Hibernate's query language. - /// The values of the parameters. - /// Hibernate types of the parameters (or null) - /// The number of entity instances deleted. - /// In case of Hibernate errors - /// If length for argument values and types are not equal. - public int Delete(String queryString, Object[] values, IType[] types) - { - if (values != null && types != null && values.Length != types.Length) - { - throw new ArgumentOutOfRangeException("values", "Length of values array must match length of types array"); - } - return (int)Execute(new DeletebyQueryHibernateCallback(this, queryString, values, types),true); - - } - - - /// - /// Delete all given persistent instances. - /// - /// The persistent instances to delete. - /// - /// This can be combined with any of the find methods to delete by query - /// in two lines of code, similar to Session's delete by query methods. - /// - /// In case of Hibernate errors - public void DeleteAll(ICollection entities) - { - Execute(new DeleteAllHibernateCallback(this, entities),true); - } - - - /// - /// Execute the action specified by the given action object within a Session. - /// - /// - /// Application exceptions thrown by the action object get propagated to the - /// caller (can only be unchecked). Hibernate exceptions are transformed into - /// appropriate DAO ones. Allows for returning a result object, i.e. a domain - /// object or a collection of domain objects. - ///

Note: Callback code is not supposed to handle transactions itself! - /// Use an appropriate transaction manager like HibernateTransactionManager. - /// Generally, callback code must not touch any Session lifecycle methods, - /// like close, disconnect, or reconnect, to let the template do its work. - ///

- ///
- /// The delegate callback object that specifies the Hibernate action. - /// a result object returned by the action, or null - /// - /// In case of Hibernate errors - public object Execute(HibernateDelegate del) - { - return Execute(new ExecuteHibernateCallbackUsingDelegate(del)); - } - - /// - /// Execute the action specified by the delegate within a Session. - /// - /// The HibernateDelegate that specifies the action - /// to perform. - /// if set to true expose the native hibernate session to - /// callback code. - /// a result object returned by the action, or null - /// - public object Execute(HibernateDelegate del, bool exposeNativeSession) - { - return Execute(new ExecuteHibernateCallbackUsingDelegate(del), true); - } - - /// - /// Execute the action specified by the given action object within a Session. - /// - /// The callback object that specifies the Hibernate action. - /// - /// a result object returned by the action, or null - /// - /// - /// Application exceptions thrown by the action object get propagated to the - /// caller (can only be unchecked). Hibernate exceptions are transformed into - /// appropriate DAO ones. Allows for returning a result object, i.e. a domain - /// object or a collection of domain objects. - ///

Note: Callback code is not supposed to handle transactions itself! - /// Use an appropriate transaction manager like HibernateTransactionManager. - /// Generally, callback code must not touch any Session lifecycle methods, - /// like close, disconnect, or reconnect, to let the template do its work. - ///

- ///
- /// In case of Hibernate errors - public object Execute(IHibernateCallback action) - { - return Execute(action, ExposeNativeSession); - } - - /// - /// Execute the specified action assuming that the result object is a List. - /// - /// - /// This is a convenience method for executing Hibernate find calls or - /// queries within an action. - /// - /// The calback object that specifies the Hibernate action. - /// A IList returned by the action, or null - /// - /// In case of Hibernate errors - public IList ExecuteFind(IHibernateCallback action) - { - Object result = Execute(action, ExposeNativeSession); - if (result != null && !(result is IList)) { - throw new InvalidDataAccessApiUsageException( - "Result object returned from HibernateCallback isn't a List: [" + result + "]"); - } - return (IList) result; - } - - /// - /// Execute the action specified by the given action object within a Session. - /// - /// callback object that specifies the Hibernate action. - /// if set to true expose the native hibernate session to - /// callback code. - /// - /// a result object returned by the action, or null - /// - public object Execute(IHibernateCallback action, bool exposeNativeSession) - { - ISession session = Session; - - bool existingTransaction = SessionFactoryUtils.IsSessionTransactional(session, SessionFactory); - if (existingTransaction) - { - if(log.IsDebugEnabled) log.Debug("Found thread-bound Session for HibernateTemplate"); - } - - FlushModeHolder previousFlushModeHolder = new FlushModeHolder(); - try - { - previousFlushModeHolder = ApplyFlushMode(session, existingTransaction); - ISession sessionToExpose = (exposeNativeSession ? session : CreateSessionProxy(session)); - Object result = action.DoInHibernate(sessionToExpose); - FlushIfNecessary(session, existingTransaction); - return result; - } - catch (ADOException ex) - { - IDbProvider dbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); - if (dbProvider != null && dbProvider.IsDataAccessException(ex.InnerException)) - { - throw ConvertAdoAccessException(ex); - } - else - { - throw new HibernateSystemException(ex); - } - } - catch (HibernateException ex) - { - throw ConvertHibernateAccessException(ex); - } - catch (Exception ex) - { - IDbProvider dbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); - if (dbProvider != null && dbProvider.IsDataAccessException(ex)) - { - throw ConvertAdoAccessException(ex); - } - else - { - // Callback code throw application exception or other non DB related exception. - throw; - } - } - finally - { - if (existingTransaction) - { - if (log.IsDebugEnabled) log.Debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); - if (previousFlushModeHolder.ModeWasSet) - { - session.FlushMode = previousFlushModeHolder.Mode; - } - } - else - { - // Never use deferred close for an explicitly new Session. - if (AlwaysUseNewSession) - { - SessionFactoryUtils.CloseSession(session); - } - else - { - SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, SessionFactory); - } - } - } - } - - /// - /// Execute a query for persistent instances. - /// - /// a query expressed in Hibernate's query language - /// - /// a List containing 0 or more persistent instances - /// - /// In case of Hibernate errors - public IList Find(string queryString) - { - return Find(queryString, (object[])null, (IType[])null ); - } - - /// - /// Execute a query for persistent instances, binding - /// one value to a "?" parameter in the query string. - /// - /// a query expressed in Hibernate's query language - /// the value of the parameter - /// - /// a List containing 0 or more persistent instances - /// - /// In case of Hibernate errors - public IList Find(string queryString, object value) - { - return Find(queryString, new object[] {value}, (IType[]) null); - } - - /// - /// Execute a query for persistent instances, binding one value - /// to a "?" parameter of the given type in the query string. - /// - /// a query expressed in Hibernate's query language - /// The value of the parameter. - /// Hibernate type of the parameter (or null) - /// - /// a List containing 0 or more persistent instances - /// - /// In case of Hibernate errors - public IList Find(string queryString, object value, IType type) - { - return Find(queryString, new object[] {value}, new IType[] {type}); - } - - /// - /// Execute a query for persistent instances, binding a - /// number of values to "?" parameters in the query string. - /// - /// a query expressed in Hibernate's query language - /// the values of the parameters - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList Find(string queryString, object[] values) - { - return Find(queryString, values, (IType[]) null); - } - - /// - /// Execute a query for persistent instances, binding a number of - /// values to "?" parameters of the given types in the query string. - /// - /// A query expressed in Hibernate's query language - /// The values of the parameters - /// Hibernate types of the parameters (or null) - /// - /// a List containing 0 or more persistent instances - /// - /// In case of Hibernate errors - /// If values and types are not null and their lengths are not equal - public IList Find(string queryString, object[] values, IType[] types) - { - if (values != null && types != null && values.Length != types.Length) - { - throw new ArgumentException("Length of values array must match length of types array"); - } - return (IList)Execute(new FindHibernateCallback(this, queryString, values, types),true); - } - - /// - /// Execute a query for persistent instances, binding - /// one value to a named parameter in the query string. - /// - /// The name of a Hibernate query in a mapping file - /// The name of the parameter - /// The value of the parameter - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedParam(string queryName, string paramName, object value) - { - return FindByNamedParam(queryName, paramName, value, null); - } - - /// - /// Execute a query for persistent instances, binding - /// one value to a named parameter in the query string. - /// - /// The name of a Hibernate query in a mapping file - /// The name of the parameter - /// The value of the parameter - /// Hibernate type of the parameter (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedParam(string queryName, string paramName, object value, IType type) - { - return FindByNamedParam(queryName, new string[] {paramName}, new object[] {value}, new IType[] {type}); - } - - /// - /// Execute a query for persistent instances, binding a - /// number of values to named parameters in the query string. - /// - /// A query expressed in Hibernate's query language - /// The names of the parameters - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedParam(string queryString, string[] paramNames, object[] values) - { - return FindByNamedParam(queryString, paramNames, values, null); - } - - /// - /// Execute a query for persistent instances, binding a - /// number of values to named parameters in the query string. - /// - /// A query expressed in Hibernate's query language - /// The names of the parameters - /// The values of the parameters - /// Hibernate types of the parameters (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If paramNames length is not equal to values length or - /// if paramNames length is not equal to types length (when types is not null) - public IList FindByNamedParam(string queryString, string[] paramNames, object[] values, IType[] types) - { - if (paramNames.Length != values.Length) - { - throw new ArgumentOutOfRangeException("paramNames","Length of paramNames array must match length of values array"); - } - if (types != null && paramNames.Length != types.Length) - { - throw new ArgumentOutOfRangeException("paramNames","Length of paramNames array must match length of types array"); - } - - return (IList)Execute(new FindByNamedParamHibernateCallback(this, queryString, paramNames, values, types),true); - - } - - /// - /// Execute a named query for persistent instances. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQuery(string queryName) - { - return FindByNamedQuery(queryName, (object[]) null, (IType[]) null); - } - - /// - /// Execute a named query for persistent instances, binding - /// one value to a "?" parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The value of the parameter - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQuery(string queryName, object value) - { - return FindByNamedQuery(queryName, new object[] {value}, (IType[]) null); - } - - /// - /// Execute a named query for persistent instances, binding - /// one value to a "?" parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The value of the parameter - /// Hibernate type of the parameter (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQuery(string queryName, object value, IType type) - { - return FindByNamedQuery(queryName, new object[] { value }, new IType[] { type }); - } - - /// - /// Execute a named query for persistent instances, binding a - /// number of values to "?" parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQuery(string queryName, object[] values) - { - return FindByNamedQuery(queryName, values, (IType[]) null); - } - - /// - /// Execute a named query for persistent instances, binding a - /// number of values to "?" parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The values of the parameters - /// Hibernate types of the parameters (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If values and types are not null and their lengths differ. - public IList FindByNamedQuery(string queryName, object[] values, IType[] types) - { - if (values != null && types != null && values.Length != types.Length) - { - throw new ArgumentOutOfRangeException("Length of values array must match length of types array"); - } - return (IList)Execute(new FindByNamedQueryHibernateCallback(this, queryName, values, types),true); - - - } - - /// - /// Execute a named query for persistent instances, binding - /// one value to a named parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// Name of the parameter - /// The value of the parameter - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value) - { - return FindByNamedQueryAndNamedParam(queryName, paramName, value, null); - - } - - /// - /// Execute a named query for persistent instances, binding - /// one value to a named parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// Name of the parameter - /// The value of the parameter - /// The Hibernate type of the parameter (or null) - /// A List containing 0 or more persistent instances - public IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value, IType type) - { - return FindByNamedQueryAndNamedParam( - queryName, new string[] {paramName}, new object[] {value}, new IType[] {type}); - - } - - /// - /// Execute a named query for persistent instances, binding - /// number of values to named parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The names of the parameters - /// The values of the parameters. - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values) - { - return FindByNamedQueryAndNamedParam(queryName, paramNames, values, null); - - } - - /// - /// Execute a named query for persistent instances, binding - /// number of values to named parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The names of the parameters - /// The values of the parameters. - /// Hibernate types of the parameters (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If paramNames length is not equal to values length or - /// if paramNames length is not equal to types length (when types is not null) - public IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values, IType[] types) - { - if (paramNames != null && values != null && paramNames.Length != values.Length) - { - throw new ArgumentOutOfRangeException("paramNames","Length of paramNames array must match length of values array"); - } - if (paramNames != null && types != null && paramNames.Length != types.Length) - { - throw new ArgumentOutOfRangeException("paramNams","Length of paramNames array must match length of types array"); - } - return (IList)Execute(new FindByNamedQueryAndNamedParamHibernateCallback(this, queryName, paramNames, values, types),true); - - } - - /// - /// Execute a named query for persistent instances, binding the properties - /// of the given object to named parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByNamedQueryAndValueObject(string queryName, object valueObject) - { - return (IList)Execute(new FindByNamedQueryAndValueObjectHibernateCallback(this, queryName, valueObject),true); - - } - - /// - /// Execute a query for persistent instances, binding the properties - /// of the given object to named parameters in the query string. - /// - /// A query expressed in Hibernate's query language - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - public IList FindByValueObject(string queryString, object valueObject) - { - return (IList)Execute(new FindByValueObjectHibernateCallback(this, queryString, valueObject), true); - } - - #endregion - - #region Methods - - - /// - /// Create a close-suppressing proxy for the given Hibernate Session. - /// The proxy also prepares returned Query and Criteria objects. - /// - /// The session. - /// The session proxy. - public virtual ISession CreateSessionProxy(ISession session) - { - //TODO can move to HibernateAccessor and make protected - // if issue reported with AOP+Multiple Threads resolve. - // have not been able to reproduce so added lock as a precaution. - // - lock (syncRoot) - { - if (sessionProxyFactory == null) - { - sessionProxyFactory = new ProxyFactory(); - sessionProxyFactory.AddAdvice(new CloseSuppressingMethodInterceptor(this)); - } - - sessionProxyFactory.Target = session; - - return (ISession)sessionProxyFactory.GetProxy(); - } - } - - /// - /// Check whether write operations are allowed on the given Session. - /// - /// - /// Default implementation throws an InvalidDataAccessApiUsageException - /// in case of FlushMode.Never. Can be overridden in subclasses. - /// - /// The current Hibernate session. - /// If write operation is attempted in read-only mode - /// - public virtual void CheckWriteOperationAllowed(ISession session) - { - if (CheckWriteOperations && TemplateFlushMode != TemplateFlushMode.Eager && - AreEqualFlushMode(TemplateFlushMode.Never, session.FlushMode)) - { - throw new InvalidDataAccessApiUsageException( - "Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session " + - "into FlushMode.AUTO or remove 'readOnly' marker from transaction definition"); - } - } - - - - /// - /// Compares if the flush mode enumerations, Spring's - /// TemplateFlushMode and NHibernates FlushMode have equal - /// settings. - /// - /// The template flush mode. - /// The NHibernate flush mode. - /// - /// Returns true if both are Never, Auto, or Commit, false - /// otherwise. - /// - protected bool AreEqualFlushMode(TemplateFlushMode tfm, FlushMode fm) - { - if ( (tfm ==TemplateFlushMode.Never && fm == FlushMode.Never) || - (tfm ==TemplateFlushMode.Auto && fm == FlushMode.Auto) || - (tfm ==TemplateFlushMode.Commit && fm == FlushMode.Commit) ) - { - return true; - } - else - { - return false; - } - //TODO other combinations. - } - - #endregion - } - - #region Internal Supporting Callback Classes - - //TODO see if can create common base class for some callbacks. - - internal class ContainsHibernateCallback : IHibernateCallback - { - private object entity; - public ContainsHibernateCallback(object entity) - { - this.entity = entity; - } - - public object DoInHibernate(ISession session) - { - return session.Contains(entity); - } - } - - - internal class DeleteLockModeHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private object entity; - private LockMode lockMode; - public DeleteLockModeHibernateCallback(HibernateTemplate template, object entity, LockMode lockMode) - { - this.outer = template; - this.entity = entity; - this.lockMode = lockMode; - } - - public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - if (lockMode != null) - { - session.Lock(entity, lockMode); - } - session.Delete(entity); - return null; - } - } - - - internal class DeletebyQueryHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private string queryString; - private object[] values; - private IType[] types; - - public DeletebyQueryHibernateCallback(HibernateTemplate template, string queryString, object[] values, IType[] types) - { - this.outer = template; - this.queryString = queryString; - this.values = values; - this.types = types; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - if (values != null) - { - return session.Delete(queryString, values, types); - } - else - { - return session.Delete(queryString); - } - } - } - - - - internal class DeleteAllHibernateCallback : IHibernateCallback - { - HibernateTemplate outer; - private ICollection entities; - - public DeleteAllHibernateCallback(HibernateTemplate template, ICollection entities) - { - this.outer = template; - this.entities = entities; - - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - foreach (object entity in entities) - { - session.Delete(entity); - } - return null; - } - - - - } - - - internal class EvictHibernateCallback : IHibernateCallback - { - private object entity; - - public EvictHibernateCallback(object entity) - { - this.entity = entity; - - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - session.Evict(entity); - return null; - } - - - - } - - - internal class FindHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private string queryString; - private object[] values; - private IType[] types; - - public FindHibernateCallback(HibernateTemplate template, string queryString, object[] values, IType[] types) - { - this.outer = template; - this.queryString = queryString; - this.values = values; - this.types = types; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - IQuery queryObject = session.CreateQuery(queryString); - outer.PrepareQuery(queryObject); - if (values != null) - { - for (int i = 0; i < values.Length; i++) - { - if (types != null && types[i] != null) - { - queryObject.SetParameter(i, values[i], types[i]); - } - else - { - queryObject.SetParameter(i, values[i]); - } - } - } - - return queryObject.List(); - } - } - - - internal class FindByNamedParamHibernateCallback : IHibernateCallback - { - HibernateTemplate outer; - private string queryString; - private string[] paramNames; - private object[] values; - private IType[] types; - - public FindByNamedParamHibernateCallback(HibernateTemplate template, string queryString, string[] paramNames, object[] values, IType[] types) - { - this.outer = template; - this.queryString = queryString; - this.paramNames = paramNames; - this.values = values; - this.types = types; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - IQuery queryObject = session.CreateQuery(queryString); - outer.PrepareQuery(queryObject); - if (values != null) - { - for (int i = 0; i < values.Length; i++) - { - outer.ApplyNamedParameterToQuery(queryObject, paramNames[i], values[i], (types != null ? types[i] : null)); - } - } - return queryObject.List(); - - } - } - - - internal class FindByNamedQueryHibernateCallback : IHibernateCallback - { - HibernateTemplate outer; - private string queryName; - private object[] values; - private IType[] types; - - public FindByNamedQueryHibernateCallback(HibernateTemplate template, string queryName, object[] values, IType[] types) - { - this.outer = template; - this.queryName = queryName; - this.values = values; - this.types = types; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - IQuery queryObject = session.GetNamedQuery(queryName); - outer.PrepareQuery(queryObject); - if (values != null) - { - for (int i = 0; i < values.Length; i++) - { - if (types != null && types[i] != null) - { - queryObject.SetParameter(i, values[i], types[i]); - } - else - { - queryObject.SetParameter(i, values[i]); - } - } - } - return queryObject.List(); - - } - } - - - internal class FindByNamedQueryAndNamedParamHibernateCallback : IHibernateCallback - { - HibernateTemplate outer; - private string queryName; - private string[] paramNames; - private object[] values; - private IType[] types; - - public FindByNamedQueryAndNamedParamHibernateCallback(HibernateTemplate template, string queryName, string[] paramNames, object[] values, IType[] types) - { - this.outer = template; - this.queryName = queryName; - this.paramNames = paramNames; - this.values = values; - this.types = types; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - IQuery queryObject = session.GetNamedQuery(queryName); - outer.PrepareQuery(queryObject); - if (values != null) - { - for (int i = 0; i < values.Length; i++) - { - outer.ApplyNamedParameterToQuery(queryObject, paramNames[i], values[i], (types != null ? types[i] : null)); - } - } - return queryObject.List(); - - } - } - - - internal class FindByNamedQueryAndValueObjectHibernateCallback : IHibernateCallback - { - HibernateTemplate outer; - private string queryName; - private object valueObject; - - public FindByNamedQueryAndValueObjectHibernateCallback(HibernateTemplate template, string queryName, object valueObject) - { - this.outer = template; - this.queryName = queryName; - this.valueObject = valueObject; - - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - IQuery queryObject = session.GetNamedQuery(queryName); - outer.PrepareQuery(queryObject); - queryObject.SetProperties(valueObject); - return queryObject.List(); - - } - - - - } - - internal class FindByValueObjectHibernateCallback : IHibernateCallback - { - HibernateTemplate outer; - private string queryString; - private object valueObject; - - public FindByValueObjectHibernateCallback(HibernateTemplate template, string queryString, object valueObject) - { - this.outer = template; - this.queryString = queryString; - this.valueObject = valueObject; - - } - - public object DoInHibernate(ISession session) - { - IQuery queryObject = session.CreateQuery(queryString); - outer.PrepareQuery(queryObject); - queryObject.SetProperties(valueObject); - return queryObject.List(); - - } - - } - - internal class ExecuteHibernateCallbackUsingDelegate : IHibernateCallback - { - private HibernateDelegate del; - - public ExecuteHibernateCallbackUsingDelegate(HibernateDelegate d) - { - del = d; - } - - public object DoInHibernate(ISession session) - { - return del(session); - } - } - - - internal class GetByTypeHibernateCallback : IHibernateCallback - { - private Type entityType; - private object id; - private LockMode lockMode; - - public GetByTypeHibernateCallback(Type entityType, object id, LockMode lockMode) - { - this.entityType = entityType; - this.id = id; - this.lockMode = lockMode; - - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - if (lockMode != null) - { - return session.Get(entityType, id, lockMode); - } - else - { - return session.Get(entityType, id); - } - } - - - - } - - - internal class LoadByTypeHibernateCallback : IHibernateCallback - { - private Type entityType; - private object id; - private LockMode lockMode; - - public LoadByTypeHibernateCallback(Type entityType, object id, LockMode lockMode) - { - this.entityType = entityType; - this.id = id; - this.lockMode = lockMode; - - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - if (lockMode != null) - { - return session.Load(entityType, id, lockMode); - } - else - { - return session.Load(entityType, id); - } - } - - - - } - - - internal class LoadByEntityHibernateCallback : IHibernateCallback - { - private object entity; - private object id; - - public LoadByEntityHibernateCallback(object entity, object id) - { - this.entity = entity; - this.id = id; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - session.Load(entity, id); - return null; - } - - - - } - - - internal class LoadAllByTypeHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private Type entityType; - - public LoadAllByTypeHibernateCallback(HibernateTemplate template, Type entityType) - { - outer = template; - this.entityType = entityType; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - ICriteria criteria = session.CreateCriteria(entityType); - outer.PrepareCriteria(criteria); - return criteria.List(); - } - } - - - internal class LockHibernateCallback : IHibernateCallback - { - private object entity; - private LockMode lockMode; - - public LockHibernateCallback(object entity, LockMode lockMode) - { - this.entity = entity; - this.lockMode = lockMode; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - session.Lock(entity, lockMode); - return null; - } - } - - - internal class RefreshHibernateCallback : IHibernateCallback - { - private object entity; - private LockMode lockMode; - - public RefreshHibernateCallback(object entity, LockMode lockMode) - { - this.entity = entity; - this.lockMode = lockMode; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - if (lockMode != null) - { - session.Refresh(entity, lockMode); - } - else - { - session.Refresh(entity); - } - return null; - } - } - - - internal class SaveObjectHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private object entity; - - public SaveObjectHibernateCallback(HibernateTemplate template, object entity) - { - this.outer = template; - this.entity = entity; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - return session.Save(entity); - } - } - - - internal class SaveObjectWithIdHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private object entity; - private object id; - - public SaveObjectWithIdHibernateCallback(HibernateTemplate template, object entity, object id) - { - this.outer = template; - this.entity = entity; - this.id = id; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - session.Save(entity, id); - return null; - } - } - - - internal class UpdateObjectHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private object entity; - private LockMode lockMode; - - public UpdateObjectHibernateCallback(HibernateTemplate template, object entity, LockMode lockMode) - { - this.outer = template; - this.entity = entity; - this.lockMode = lockMode; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - session.Update(entity); - if (lockMode != null) - { - session.Lock(entity, lockMode); - } - return null; - } - } - - - internal class SaveOrUpdateObjectHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private object entity; - - public SaveOrUpdateObjectHibernateCallback(HibernateTemplate template, object entity) - { - this.outer = template; - this.entity = entity; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - session.SaveOrUpdate(entity); - return null; - } - } - - internal class SaveOrUpdateAllHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private ICollection entities; - - public SaveOrUpdateAllHibernateCallback(HibernateTemplate template, ICollection entities) - { - this.outer = template; - this.entities = entities; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - foreach (object entity in entities) - { - session.SaveOrUpdate(entity); - } - return null; - } - } - internal class SaveOrUpdateCopyHibernateCallback : IHibernateCallback - { - private HibernateTemplate outer; - private object entity; - - public SaveOrUpdateCopyHibernateCallback(HibernateTemplate template, object entity) - { - this.outer = template; - this.entity = entity; - } - - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- public object DoInHibernate(ISession session) - { - outer.CheckWriteOperationAllowed(session); - return session.SaveOrUpdateCopy(entity); - } - } - - - #endregion - - -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Common.Logging; +using Spring.Aop.Framework; +using Spring.Data.Common; +using Spring.Data.Support; +using IInterceptor = NHibernate.IInterceptor; + +using NHibernate; +using NHibernate.Type; +using Spring.Dao; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Helper class that simplifies NHibernate data access code + /// + /// + ///

Typically used to implement data access or business logic services that + /// use NHibernate within their implementation but are Hibernate-agnostic in their + /// interface. The latter or code calling the latter only have to deal with + /// domain objects.

+ /// + ///

The central method is Execute supporting Hibernate access code + /// implementing the HibernateCallback interface. It provides NHibernate Session + /// handling such that neither the IHibernateCallback implementation nor the calling + /// code needs to explicitly care about retrieving/closing NHibernate Sessions, + /// or handling Session lifecycle exceptions. For typical single step actions, + /// there are various convenience methods (Find, Load, SaveOrUpdate, Delete). + ///

+ /// + ///

Can be used within a service implementation via direct instantiation + /// with a ISessionFactory reference, or get prepared in an application context + /// and given to services as an object reference. Note: The ISessionFactory should + /// always be configured as an object in the application context, in the first case + /// given to the service directly, in the second case to the prepared template. + ///

+ /// + ///

This class can be considered as direct alternative to working with the raw + /// Hibernate Session API (through SessionFactoryUtils.Session). + ///

+ /// + ///

LocalSessionFactoryObject is the preferred way of obtaining a reference + /// to a specific NHibernate ISessionFactory. + ///

+ ///
+ /// Mark Pollack (.NET) + public class HibernateTemplate : HibernateAccessor, IHibernateOperations + { + #region Fields + + /// + /// The instance for this class. + /// + private readonly ILog log = LogManager.GetLogger(typeof(HibernateTemplate)); + + private bool checkWriteOperations = true; + + + private bool exposeNativeSession = false; + + private bool alwaysUseNewSession = false; + private int maxResults = 0; + private TemplateFlushMode templateFlushMode = TemplateFlushMode.Auto; + private bool allowCreate = true; + private ISessionFactory sessionFactory; + private object entityInterceptor; + private IObjectFactory objectFactory; + private bool cacheQueries = false; + private string queryCacheRegion; + private int fetchSize = 0; + + private IAdoExceptionTranslator adoExceptionTranslator; + + private readonly object syncRoot = new object(); + private ProxyFactory sessionProxyFactory; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public HibernateTemplate() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The default for creating a new non-transactional + /// session when no transactional Session can be found for the current thread + /// is set to true. + /// The session factory to create sessions. + public HibernateTemplate(ISessionFactory sessionFactory) + { + SessionFactory = sessionFactory; + AfterPropertiesSet(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The session factory to create sessions. + /// if set to true allow creation + /// of a new non-transactional when no transactional Session can be found + /// for the current thread. + public HibernateTemplate(ISessionFactory sessionFactory, bool allowCreate) + { + SessionFactory = sessionFactory; + AllowCreate = allowCreate; + AfterPropertiesSet(); + } + #endregion + + #region Properties + + /// + /// Gets or sets if a new Session should be created when no transactional Session + /// can be found for the current thread. + /// + /// + /// true if allowed to create non-transaction session; + /// otherwise, false. + /// + /// + ///

HibernateTemplate is aware of a corresponding Session bound to the + /// current thread, for example when using HibernateTransactionManager. + /// If allowCreate is true, a new non-transactional Session will be created + /// if none found, which needs to be closed at the end of the operation. + /// If false, an InvalidOperationException will get thrown in this case. + ///

+ ///
+ public override bool AllowCreate + { + get + { + + return allowCreate; + } + set { allowCreate = value; } + } + + /// + /// Gets or sets a value indicating whether to always + /// use a new Hibernate Session for this template. + /// + /// true if always use new session; otherwise, false. + /// + ///

+ /// Default is "false"; if activated, all operations on this template will + /// work on a new NHibernate ISession even in case of a pre-bound ISession + /// (for example, within a transaction). + ///

+ ///

Within a transaction, a new NHibernate ISession used by this template + /// will participate in the transaction through using the same ADO.NET + /// Connection. In such a scenario, multiple Sessions will participate + /// in the same database transaction. + ///

+ ///

Turn this on for operations that are supposed to always execute + /// independently, without side effects caused by a shared NHibernate ISession. + ///

+ ///
+ public override bool AlwaysUseNewSession + { + get { return alwaysUseNewSession; } + set { alwaysUseNewSession = value; } + } + + + /// + /// Gets or sets the template flush mode. + /// + /// + /// Default is Auto. Will get applied to any new ISession + /// created by the template. + /// + /// The template flush mode. + public override TemplateFlushMode TemplateFlushMode + { + get { return templateFlushMode; } + set { templateFlushMode = value; } + } + + /// + /// Gets or sets the entity interceptor that allows to inspect and change + /// property values before writing to and reading from the database. + /// + /// + /// Will get applied to any new ISession created by this object. + ///

Such an interceptor can either be set at the ISessionFactory level, + /// i.e. on LocalSessionFactoryObject, or at the ISession level, i.e. on + /// HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. + /// It's preferable to set it on LocalSessionFactoryObject or HibernateTransactionManager + /// to avoid repeated configuration and guarantee consistent behavior in transactions. + ///

+ ///
+ /// The interceptor. + /// If object factory is not set and need to retrieve entity interceptor by name. + public override IInterceptor EntityInterceptor + { + get + { + if (this.entityInterceptor is string) + { + if (this.objectFactory == null) + { + throw new InvalidOperationException("Cannot get entity interceptor via object name if no object factory set"); + } + return (IInterceptor)this.objectFactory.GetObject((String)this.entityInterceptor, typeof(IInterceptor)); + } + + return (IInterceptor)entityInterceptor; + } + set + { + entityInterceptor = value; + } + } + /// + /// Gets or sets the name of the cache region for queries executed by this template. + /// + /// + /// If this is specified, it will be applied to all IQuery and ICriteria objects + /// created by this template (including all queries through find methods). + ///

The cache region will not take effect unless queries created by this + /// template are configured to be cached via the CacheQueries property. + ///

+ ///
+ /// The query cache region. + public override string QueryCacheRegion + { + get { return queryCacheRegion; } + set { queryCacheRegion = value; } + } + + + /// + /// Gets or sets a value indicating whether to + /// cache all queries executed by this template. + /// + /// + /// If this is true, all IQuery and ICriteria objects created by + /// this template will be marked as cacheable (including all + /// queries through find methods). + ///

To specify the query region to be used for queries cached + /// by this template, set the QueryCacheRegion property. + ///

+ ///
+ /// true if cache queries; otherwise, false. + public override bool CacheQueries + { + get { return cacheQueries; } + set { cacheQueries = value; } + } + + /// + /// Gets or sets the maximum number of rows for this HibernateTemplate. + /// + /// The max results. + /// + /// This is important + /// for processing subsets of large result sets, avoiding to read and hold + /// the entire result set in the database or in the ADO.NET driver if we're + /// never interested in the entire result in the first place (for example, + /// when performing searches that might return a large number of matches). + ///

Default is 0, indicating to use the driver's default.

+ ///
+ public override int MaxResults + { + get { return maxResults; } + set { maxResults = value; } + } + + /// + /// Set whether to expose the native Hibernate Session to IHibernateCallback + /// code. Default is "false": a Session proxy will be returned, + /// suppressing close calls and automatically applying + /// query cache settings and transaction timeouts. + /// + /// true if expose native session; otherwise, false. + public override bool ExposeNativeSession + { + get { return exposeNativeSession; } + set { exposeNativeSession = value; } + } + /// + /// Gets or sets whether to check that the Hibernate Session is not in read-only mode + /// in case of write operations (save/update/delete). + /// + /// + /// true if check that the Hibernate Session is not in read-only mode + /// in case of write operations; otherwise, false. + /// + /// + /// Default is "true", for fail-fast behavior when attempting write operations + /// within a read-only transaction. Turn this off to allow save/update/delete + /// on a Session with flush mode NEVER. + /// + public virtual bool CheckWriteOperations + { + get { return checkWriteOperations; } + set { checkWriteOperations = value; } + } + + /// + /// Set the object name of a Hibernate entity interceptor that allows to inspect + /// and change property values before writing to and reading from the database. + /// + /// + /// Will get applied to any new Session created by this transaction manager. + ///

Requires the object factory to be known, to be able to resolve the object + /// name to an interceptor instance on session creation. Typically used for + /// prototype interceptors, i.e. a new interceptor instance per session. + ///

+ ///

Can also be used for shared interceptor instances, but it is recommended + /// to set the interceptor reference directly in such a scenario. + ///

+ ///
+ /// The name of the entity interceptor in the object factory/application context. + public override string EntityInterceptorObjectName + { + set + { + this.entityInterceptor = value; + } + } + + /// + /// Set the object factory instance. + /// + /// The object factory instance + public override IObjectFactory ObjectFactory + { + set + { + objectFactory = value; + } + } + + /// + /// Gets or sets the session factory that should be used to create + /// NHibernate ISessions. + /// + /// The session factory. + public override ISessionFactory SessionFactory + { + get { return sessionFactory; } + set + { + sessionFactory = value; + } + } + + /// + /// Gets or sets the fetch size for this HibernateTemplate. + /// + /// The size of the fetch. + /// This is important for processing + /// large result sets: Setting this higher than the default value will increase + /// processing speed at the cost of memory consumption; setting this lower can + /// avoid transferring row data that will never be read by the application. + ///

Default is 0, indicating to use the driver's default.

+ ///
+ public override int FetchSize + { + get { return fetchSize; } + set { fetchSize = value; } + } + + + /// + /// Gets or sets the proxy factory. + /// + /// This may be useful to set if you create many instances of + /// HibernateTemplate and/or HibernateDaoSupport. This allows the same + /// ProxyFactory implementation to be used thereby limiting the + /// number of dynamic proxy types created in the temporary assembly, which + /// are never garbage collected due to .NET runtime semantics. + /// + /// The proxy factory. + public virtual ProxyFactory ProxyFactory + { + get { return sessionProxyFactory; } + set { sessionProxyFactory = value; } + } + + #endregion + + #region IHibernateOperations Members + + /// + /// Set the ADO.NET exception translator for this instance. + /// Applied to System.Data.Common.DbException (or provider specific exception type + /// in .NET 1.1) thrown by callback code, be it direct + /// DbException or wrapped Hibernate ADOExceptions. + ///

The default exception translator is either a ErrorCodeExceptionTranslator + /// if a DbProvider is available, or a FalbackExceptionTranslator otherwise + ///

+ ///
+ /// The ADO exception translator. + public override IAdoExceptionTranslator AdoExceptionTranslator + { + set { adoExceptionTranslator = value; } + get + { + if (adoExceptionTranslator == null) + { + adoExceptionTranslator = SessionFactoryUtils.NewAdoExceptionTranslator(SessionFactory); + } + return adoExceptionTranslator; + } + } + + + /// + /// Delegate function that clears the session. + /// + /// The hibernate session. + /// null + protected object ClearAction(ISession session) + { + session.Clear(); + return null; + } + + /// + /// Flush all pending saves, updates and deletes to the database. + /// + /// + /// Only invoke this for selective eager flushing, for example when ADO.NET code + /// needs to see certain changes within the same transaction. Else, it's preferable + /// to rely on auto-flushing at transaction completion. + /// + /// In case of Hibernate errors + public void Flush() + { + Execute(new HibernateDelegate(FlushAction), true); + } + + private object FlushAction(ISession session) + { + session.Flush(); + return null; + } + + /// + /// Return the persistent instance of the given entity type + /// with the given identifier, or null if not found. + /// + /// The type. + /// An identifier of the persistent instance. + /// The persistent instance, or null if not found + /// In case of Hibernate errors + public object Get(Type entityType, object id) + { + return Get(entityType, id, null); + } + + /// + /// Return the persistent instance of the given entity type + /// with the given identifier, or null if not found. + /// Obtains the specified lock mode if the instance exists. + /// + /// The type. + /// The lock mode to obtain. + /// The lock mode. + /// the persistent instance, or null if not found + /// the persistent instance, or null if not found + /// In case of Hibernate errors + public object Get(Type type, object id, LockMode lockMode) + { + return Execute(new GetByTypeHibernateCallback(type, id, lockMode),true); + + } + + /// + /// Return the persistent instance of the given entity class + /// with the given identifier, throwing an exception if not found. + /// + /// Type of the entity. + /// An identifier of the persistent instance. + /// The persistent instance + /// If not found + /// In case of Hibernate errors + public object Load(Type entityType, object id) + { + return Load(entityType, id, null); + } + + /// + /// Return the persistent instance of the given entity class + /// with the given identifier, throwing an exception if not found. + /// Obtains the specified lock mode if the instance exists. + /// + /// Type of the entity. + /// An identifier of the persistent instance. + /// The lock mode. + /// The persistent instance + /// If not found + /// In case of Hibernate errors + public object Load(Type entityType, object id, LockMode lockMode) + { + return Execute(new LoadByTypeHibernateCallback(entityType, id, lockMode),true); + + } + + /// + /// Load the persistent instance with the given identifier + /// into the given object, throwing an exception if not found. + /// + /// Entity the object (of the target class) to load into. + /// An identifier of the persistent instance. + /// If object not found. + /// In case of Hibernate errors + public void Load(object entity, object id) + { + Execute(new LoadByEntityHibernateCallback(entity, id),true); + } + + /// + /// Return all persistent instances of the given entity class. + /// Note: Use queries or criteria for retrieving a specific subset. + /// + /// Type of the entity. + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList LoadAll(Type entityType) + { + return (IList)Execute(new LoadAllByTypeHibernateCallback(this, entityType),true); + } + + /// + /// Re-read the state of the given persistent instance. + /// + /// The persistent instance to re-read. + /// In case of Hibernate errors + public void Refresh(object entity) + { + Refresh(entity, null); + } + + /// + /// Re-read the state of the given persistent instance. + /// Obtains the specified lock mode for the instance. + /// + /// The persistent instance to re-read. + /// The lock mode to obtain. + /// In case of Hibernate errors + public void Refresh(object entity, LockMode lockMode) + { + Execute(new RefreshHibernateCallback(entity, lockMode),true); + } + + /// + /// Obtain the specified lock level upon the given object, implicitly + /// checking whether the corresponding database entry still exists + /// (throwing an OptimisticLockingFailureException if not found). + /// + /// The he persistent instance to lock. + /// The lock mode to obtain. + /// If not found + /// In case of Hibernate errors + public void Lock(object entity, LockMode lockMode) + { + Execute(new LockHibernateCallback(entity, lockMode),true); + } + + /// + /// Persist the given transient instance. + /// + /// The transient instance to persist. + /// The generated identifier. + /// In case of Hibernate errors + public object Save(object entity) + { + return Execute(new SaveObjectHibernateCallback(this, entity),true); + } + + /// + /// Persist the given transient instance with the given identifier. + /// + /// The transient instance to persist. + /// The identifier to assign. + /// In case of Hibernate errors + public void Save(object entity, object id) + { + Execute(new SaveObjectWithIdHibernateCallback(this, entity, id),true); + } + + /// + /// Update the given persistent instance. + /// + /// The persistent instance to update. + /// In case of Hibernate errors + public void Update(object entity) + { + Update(entity, null); + } + + /// + /// Update the given persistent instance. + /// Obtains the specified lock mode if the instance exists, implicitly + /// checking whether the corresponding database entry still exists + /// (throwing an OptimisticLockingFailureException if not found). + /// + /// The persistent instance to update. + /// The lock mode to obtain. + /// In case of Hibernate errors + public void Update(object entity, LockMode lockMode) + { + Execute(new UpdateObjectHibernateCallback(this, entity, lockMode),true); + } + + /// + /// Save or update the given persistent instance, + /// according to its id (matching the configured "unsaved-value"?). + /// + /// Tthe persistent instance to save or update + /// (to be associated with the Hibernate Session). + /// In case of Hibernate errors + public void SaveOrUpdate(object entity) + { + Execute(new SaveOrUpdateObjectHibernateCallback(this, entity),true); + } + + /// + /// Save or update all given persistent instances, + /// according to its id (matching the configured "unsaved-value"?). + /// + /// Tthe persistent instances to save or update + /// (to be associated with the Hibernate Session)he entities. + /// In case of Hibernate errors + public void SaveOrUpdateAll(ICollection entities) + { + Execute(new SaveOrUpdateAllHibernateCallback(this, entities), true); + } + + /// + /// Save or update the contents of given persistent object, + /// according to its id (matching the configured "unsaved-value"?). + /// Will copy the contained fields to an already loaded instance + /// with the same id, if appropriate. + /// + /// The persistent object to save or update. + /// (not necessarily to be associated with the Hibernate Session) + /// + /// The actually associated persistent object. + /// (either an already loaded instance with the same id, or the given object) + /// In case of Hibernate errors + public object SaveOrUpdateCopy(object entity) + { + return Execute(new SaveOrUpdateCopyHibernateCallback(this, entity),true); + } + + + /// + /// Remove all objects from the Session cache, and cancel all pending saves, + /// updates and deletes. + /// + public void Clear() + { + Execute(new HibernateDelegate(ClearAction), true); + } + + + + /// + /// Determines whether the given object is in the Session cache. + /// + /// the persistence instance to check. + /// + /// true if session cache contains the specified entity; otherwise, false. + /// + /// In case of Hibernate errors + public bool Contains(object entity) + { + return (bool)Execute(new ContainsHibernateCallback(entity)); + } + + /// + /// Remove the given object from the Session cache. + /// + /// The persistent instance to evict. + /// In case of Hibernate errors + public void Evict(object entity) + { + Execute(new EvictHibernateCallback(entity), true); + + } + + + + /// + /// Delete the given persistent instance. + /// + /// The persistent instance to delete. + /// In case of Hibernate errors + public void Delete(object entity) + { + Delete(entity, null); + } + + + /// + /// Delete the given persistent instance. + /// + /// Tthe persistent instance to delete. + /// The lock mode to obtain. + /// + /// Obtains the specified lock mode if the instance exists, implicitly + /// checking whether the corresponding database entry still exists + /// (throwing an OptimisticLockingFailureException if not found). + /// + /// In case of Hibernate errors + public void Delete(object entity, LockMode lockMode) + { + Execute(new DeleteLockModeHibernateCallback(this, entity, lockMode), true); + } + + /// + /// Delete all objects returned by the query. + /// + /// a query expressed in Hibernate's query language. + /// The number of entity instances deleted. + /// In case of Hibernate errors + public int Delete(string queryString) + { + return Delete(queryString, (Object[]) null, (IType[]) null); + } + + /// + /// Delete all objects returned by the query. + /// + /// a query expressed in Hibernate's query language. + /// The value of the parameter. + /// The Hibernate type of the parameter (or null). + /// The number of entity instances deleted. + /// In case of Hibernate errors + public int Delete(string queryString, object value, IType type) + { + return Delete(queryString, new Object[] {value}, new IType[] {type}); + } + + /// + /// Delete all objects returned by the query. + /// + /// a query expressed in Hibernate's query language. + /// The values of the parameters. + /// Hibernate types of the parameters (or null) + /// The number of entity instances deleted. + /// In case of Hibernate errors + /// If length for argument values and types are not equal. + public int Delete(String queryString, Object[] values, IType[] types) + { + if (values != null && types != null && values.Length != types.Length) + { + throw new ArgumentOutOfRangeException("values", "Length of values array must match length of types array"); + } + return (int)Execute(new DeletebyQueryHibernateCallback(this, queryString, values, types),true); + + } + + + /// + /// Delete all given persistent instances. + /// + /// The persistent instances to delete. + /// + /// This can be combined with any of the find methods to delete by query + /// in two lines of code, similar to Session's delete by query methods. + /// + /// In case of Hibernate errors + public void DeleteAll(ICollection entities) + { + Execute(new DeleteAllHibernateCallback(this, entities),true); + } + + + /// + /// Execute the action specified by the given action object within a Session. + /// + /// + /// Application exceptions thrown by the action object get propagated to the + /// caller (can only be unchecked). Hibernate exceptions are transformed into + /// appropriate DAO ones. Allows for returning a result object, i.e. a domain + /// object or a collection of domain objects. + ///

Note: Callback code is not supposed to handle transactions itself! + /// Use an appropriate transaction manager like HibernateTransactionManager. + /// Generally, callback code must not touch any Session lifecycle methods, + /// like close, disconnect, or reconnect, to let the template do its work. + ///

+ ///
+ /// The delegate callback object that specifies the Hibernate action. + /// a result object returned by the action, or null + /// + /// In case of Hibernate errors + public object Execute(HibernateDelegate del) + { + return Execute(new ExecuteHibernateCallbackUsingDelegate(del)); + } + + /// + /// Execute the action specified by the delegate within a Session. + /// + /// The HibernateDelegate that specifies the action + /// to perform. + /// if set to true expose the native hibernate session to + /// callback code. + /// a result object returned by the action, or null + /// + public object Execute(HibernateDelegate del, bool exposeNativeSession) + { + return Execute(new ExecuteHibernateCallbackUsingDelegate(del), true); + } + + /// + /// Execute the action specified by the given action object within a Session. + /// + /// The callback object that specifies the Hibernate action. + /// + /// a result object returned by the action, or null + /// + /// + /// Application exceptions thrown by the action object get propagated to the + /// caller (can only be unchecked). Hibernate exceptions are transformed into + /// appropriate DAO ones. Allows for returning a result object, i.e. a domain + /// object or a collection of domain objects. + ///

Note: Callback code is not supposed to handle transactions itself! + /// Use an appropriate transaction manager like HibernateTransactionManager. + /// Generally, callback code must not touch any Session lifecycle methods, + /// like close, disconnect, or reconnect, to let the template do its work. + ///

+ ///
+ /// In case of Hibernate errors + public object Execute(IHibernateCallback action) + { + return Execute(action, ExposeNativeSession); + } + + /// + /// Execute the specified action assuming that the result object is a List. + /// + /// + /// This is a convenience method for executing Hibernate find calls or + /// queries within an action. + /// + /// The calback object that specifies the Hibernate action. + /// A IList returned by the action, or null + /// + /// In case of Hibernate errors + public IList ExecuteFind(IHibernateCallback action) + { + Object result = Execute(action, ExposeNativeSession); + if (result != null && !(result is IList)) { + throw new InvalidDataAccessApiUsageException( + "Result object returned from HibernateCallback isn't a List: [" + result + "]"); + } + return (IList) result; + } + + /// + /// Execute the action specified by the given action object within a Session. + /// + /// callback object that specifies the Hibernate action. + /// if set to true expose the native hibernate session to + /// callback code. + /// + /// a result object returned by the action, or null + /// + public object Execute(IHibernateCallback action, bool exposeNativeSession) + { + ISession session = Session; + + bool existingTransaction = SessionFactoryUtils.IsSessionTransactional(session, SessionFactory); + if (existingTransaction) + { + if(log.IsDebugEnabled) log.Debug("Found thread-bound Session for HibernateTemplate"); + } + + FlushModeHolder previousFlushModeHolder = new FlushModeHolder(); + try + { + previousFlushModeHolder = ApplyFlushMode(session, existingTransaction); + ISession sessionToExpose = (exposeNativeSession ? session : CreateSessionProxy(session)); + Object result = action.DoInHibernate(sessionToExpose); + FlushIfNecessary(session, existingTransaction); + return result; + } + catch (ADOException ex) + { + IDbProvider dbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); + if (dbProvider != null && dbProvider.IsDataAccessException(ex.InnerException)) + { + throw ConvertAdoAccessException(ex); + } + else + { + throw new HibernateSystemException(ex); + } + } + catch (HibernateException ex) + { + throw ConvertHibernateAccessException(ex); + } + catch (Exception ex) + { + IDbProvider dbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); + if (dbProvider != null && dbProvider.IsDataAccessException(ex)) + { + throw ConvertAdoAccessException(ex); + } + else + { + // Callback code throw application exception or other non DB related exception. + throw; + } + } + finally + { + if (existingTransaction) + { + if (log.IsDebugEnabled) log.Debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); + if (previousFlushModeHolder.ModeWasSet) + { + session.FlushMode = previousFlushModeHolder.Mode; + } + } + else + { + // Never use deferred close for an explicitly new Session. + if (AlwaysUseNewSession) + { + SessionFactoryUtils.CloseSession(session); + } + else + { + SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, SessionFactory); + } + } + } + } + + /// + /// Execute a query for persistent instances. + /// + /// a query expressed in Hibernate's query language + /// + /// a List containing 0 or more persistent instances + /// + /// In case of Hibernate errors + public IList Find(string queryString) + { + return Find(queryString, (object[])null, (IType[])null ); + } + + /// + /// Execute a query for persistent instances, binding + /// one value to a "?" parameter in the query string. + /// + /// a query expressed in Hibernate's query language + /// the value of the parameter + /// + /// a List containing 0 or more persistent instances + /// + /// In case of Hibernate errors + public IList Find(string queryString, object value) + { + return Find(queryString, new object[] {value}, (IType[]) null); + } + + /// + /// Execute a query for persistent instances, binding one value + /// to a "?" parameter of the given type in the query string. + /// + /// a query expressed in Hibernate's query language + /// The value of the parameter. + /// Hibernate type of the parameter (or null) + /// + /// a List containing 0 or more persistent instances + /// + /// In case of Hibernate errors + public IList Find(string queryString, object value, IType type) + { + return Find(queryString, new object[] {value}, new IType[] {type}); + } + + /// + /// Execute a query for persistent instances, binding a + /// number of values to "?" parameters in the query string. + /// + /// a query expressed in Hibernate's query language + /// the values of the parameters + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList Find(string queryString, object[] values) + { + return Find(queryString, values, (IType[]) null); + } + + /// + /// Execute a query for persistent instances, binding a number of + /// values to "?" parameters of the given types in the query string. + /// + /// A query expressed in Hibernate's query language + /// The values of the parameters + /// Hibernate types of the parameters (or null) + /// + /// a List containing 0 or more persistent instances + /// + /// In case of Hibernate errors + /// If values and types are not null and their lengths are not equal + public IList Find(string queryString, object[] values, IType[] types) + { + if (values != null && types != null && values.Length != types.Length) + { + throw new ArgumentException("Length of values array must match length of types array"); + } + return (IList)Execute(new FindHibernateCallback(this, queryString, values, types),true); + } + + /// + /// Execute a query for persistent instances, binding + /// one value to a named parameter in the query string. + /// + /// The name of a Hibernate query in a mapping file + /// The name of the parameter + /// The value of the parameter + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedParam(string queryName, string paramName, object value) + { + return FindByNamedParam(queryName, paramName, value, null); + } + + /// + /// Execute a query for persistent instances, binding + /// one value to a named parameter in the query string. + /// + /// The name of a Hibernate query in a mapping file + /// The name of the parameter + /// The value of the parameter + /// Hibernate type of the parameter (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedParam(string queryName, string paramName, object value, IType type) + { + return FindByNamedParam(queryName, new string[] {paramName}, new object[] {value}, new IType[] {type}); + } + + /// + /// Execute a query for persistent instances, binding a + /// number of values to named parameters in the query string. + /// + /// A query expressed in Hibernate's query language + /// The names of the parameters + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedParam(string queryString, string[] paramNames, object[] values) + { + return FindByNamedParam(queryString, paramNames, values, null); + } + + /// + /// Execute a query for persistent instances, binding a + /// number of values to named parameters in the query string. + /// + /// A query expressed in Hibernate's query language + /// The names of the parameters + /// The values of the parameters + /// Hibernate types of the parameters (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If paramNames length is not equal to values length or + /// if paramNames length is not equal to types length (when types is not null) + public IList FindByNamedParam(string queryString, string[] paramNames, object[] values, IType[] types) + { + if (paramNames.Length != values.Length) + { + throw new ArgumentOutOfRangeException("paramNames","Length of paramNames array must match length of values array"); + } + if (types != null && paramNames.Length != types.Length) + { + throw new ArgumentOutOfRangeException("paramNames","Length of paramNames array must match length of types array"); + } + + return (IList)Execute(new FindByNamedParamHibernateCallback(this, queryString, paramNames, values, types),true); + + } + + /// + /// Execute a named query for persistent instances. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQuery(string queryName) + { + return FindByNamedQuery(queryName, (object[]) null, (IType[]) null); + } + + /// + /// Execute a named query for persistent instances, binding + /// one value to a "?" parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The value of the parameter + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQuery(string queryName, object value) + { + return FindByNamedQuery(queryName, new object[] {value}, (IType[]) null); + } + + /// + /// Execute a named query for persistent instances, binding + /// one value to a "?" parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The value of the parameter + /// Hibernate type of the parameter (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQuery(string queryName, object value, IType type) + { + return FindByNamedQuery(queryName, new object[] { value }, new IType[] { type }); + } + + /// + /// Execute a named query for persistent instances, binding a + /// number of values to "?" parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQuery(string queryName, object[] values) + { + return FindByNamedQuery(queryName, values, (IType[]) null); + } + + /// + /// Execute a named query for persistent instances, binding a + /// number of values to "?" parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The values of the parameters + /// Hibernate types of the parameters (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If values and types are not null and their lengths differ. + public IList FindByNamedQuery(string queryName, object[] values, IType[] types) + { + if (values != null && types != null && values.Length != types.Length) + { + throw new ArgumentOutOfRangeException("Length of values array must match length of types array"); + } + return (IList)Execute(new FindByNamedQueryHibernateCallback(this, queryName, values, types),true); + + + } + + /// + /// Execute a named query for persistent instances, binding + /// one value to a named parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// Name of the parameter + /// The value of the parameter + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value) + { + return FindByNamedQueryAndNamedParam(queryName, paramName, value, null); + + } + + /// + /// Execute a named query for persistent instances, binding + /// one value to a named parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// Name of the parameter + /// The value of the parameter + /// The Hibernate type of the parameter (or null) + /// A List containing 0 or more persistent instances + public IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value, IType type) + { + return FindByNamedQueryAndNamedParam( + queryName, new string[] {paramName}, new object[] {value}, new IType[] {type}); + + } + + /// + /// Execute a named query for persistent instances, binding + /// number of values to named parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The names of the parameters + /// The values of the parameters. + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values) + { + return FindByNamedQueryAndNamedParam(queryName, paramNames, values, null); + + } + + /// + /// Execute a named query for persistent instances, binding + /// number of values to named parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The names of the parameters + /// The values of the parameters. + /// Hibernate types of the parameters (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If paramNames length is not equal to values length or + /// if paramNames length is not equal to types length (when types is not null) + public IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values, IType[] types) + { + if (paramNames != null && values != null && paramNames.Length != values.Length) + { + throw new ArgumentOutOfRangeException("paramNames","Length of paramNames array must match length of values array"); + } + if (paramNames != null && types != null && paramNames.Length != types.Length) + { + throw new ArgumentOutOfRangeException("paramNams","Length of paramNames array must match length of types array"); + } + return (IList)Execute(new FindByNamedQueryAndNamedParamHibernateCallback(this, queryName, paramNames, values, types),true); + + } + + /// + /// Execute a named query for persistent instances, binding the properties + /// of the given object to named parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByNamedQueryAndValueObject(string queryName, object valueObject) + { + return (IList)Execute(new FindByNamedQueryAndValueObjectHibernateCallback(this, queryName, valueObject),true); + + } + + /// + /// Execute a query for persistent instances, binding the properties + /// of the given object to named parameters in the query string. + /// + /// A query expressed in Hibernate's query language + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + public IList FindByValueObject(string queryString, object valueObject) + { + return (IList)Execute(new FindByValueObjectHibernateCallback(this, queryString, valueObject), true); + } + + #endregion + + #region Methods + + + /// + /// Create a close-suppressing proxy for the given Hibernate Session. + /// The proxy also prepares returned Query and Criteria objects. + /// + /// The session. + /// The session proxy. + public virtual ISession CreateSessionProxy(ISession session) + { + //TODO can move to HibernateAccessor and make protected + // if issue reported with AOP+Multiple Threads resolve. + // have not been able to reproduce so added lock as a precaution. + // + lock (syncRoot) + { + if (sessionProxyFactory == null) + { + sessionProxyFactory = new ProxyFactory(); + sessionProxyFactory.AddAdvice(new CloseSuppressingMethodInterceptor(this)); + } + + sessionProxyFactory.Target = session; + + return (ISession)sessionProxyFactory.GetProxy(); + } + } + + /// + /// Check whether write operations are allowed on the given Session. + /// + /// + /// Default implementation throws an InvalidDataAccessApiUsageException + /// in case of FlushMode.Never. Can be overridden in subclasses. + /// + /// The current Hibernate session. + /// If write operation is attempted in read-only mode + /// + public virtual void CheckWriteOperationAllowed(ISession session) + { + if (CheckWriteOperations && TemplateFlushMode != TemplateFlushMode.Eager && + AreEqualFlushMode(TemplateFlushMode.Never, session.FlushMode)) + { + throw new InvalidDataAccessApiUsageException( + "Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session " + + "into FlushMode.AUTO or remove 'readOnly' marker from transaction definition"); + } + } + + + + /// + /// Compares if the flush mode enumerations, Spring's + /// TemplateFlushMode and NHibernates FlushMode have equal + /// settings. + /// + /// The template flush mode. + /// The NHibernate flush mode. + /// + /// Returns true if both are Never, Auto, or Commit, false + /// otherwise. + /// + protected bool AreEqualFlushMode(TemplateFlushMode tfm, FlushMode fm) + { + if ( (tfm ==TemplateFlushMode.Never && fm == FlushMode.Never) || + (tfm ==TemplateFlushMode.Auto && fm == FlushMode.Auto) || + (tfm ==TemplateFlushMode.Commit && fm == FlushMode.Commit) ) + { + return true; + } + else + { + return false; + } + //TODO other combinations. + } + + #endregion + } + + #region Internal Supporting Callback Classes + + //TODO see if can create common base class for some callbacks. + + internal class ContainsHibernateCallback : IHibernateCallback + { + private object entity; + public ContainsHibernateCallback(object entity) + { + this.entity = entity; + } + + public object DoInHibernate(ISession session) + { + return session.Contains(entity); + } + } + + + internal class DeleteLockModeHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private object entity; + private LockMode lockMode; + public DeleteLockModeHibernateCallback(HibernateTemplate template, object entity, LockMode lockMode) + { + this.outer = template; + this.entity = entity; + this.lockMode = lockMode; + } + + public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + if (lockMode != null) + { + session.Lock(entity, lockMode); + } + session.Delete(entity); + return null; + } + } + + + internal class DeletebyQueryHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private string queryString; + private object[] values; + private IType[] types; + + public DeletebyQueryHibernateCallback(HibernateTemplate template, string queryString, object[] values, IType[] types) + { + this.outer = template; + this.queryString = queryString; + this.values = values; + this.types = types; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + if (values != null) + { + return session.Delete(queryString, values, types); + } + else + { + return session.Delete(queryString); + } + } + } + + + + internal class DeleteAllHibernateCallback : IHibernateCallback + { + HibernateTemplate outer; + private ICollection entities; + + public DeleteAllHibernateCallback(HibernateTemplate template, ICollection entities) + { + this.outer = template; + this.entities = entities; + + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + foreach (object entity in entities) + { + session.Delete(entity); + } + return null; + } + + + + } + + + internal class EvictHibernateCallback : IHibernateCallback + { + private object entity; + + public EvictHibernateCallback(object entity) + { + this.entity = entity; + + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + session.Evict(entity); + return null; + } + + + + } + + + internal class FindHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private string queryString; + private object[] values; + private IType[] types; + + public FindHibernateCallback(HibernateTemplate template, string queryString, object[] values, IType[] types) + { + this.outer = template; + this.queryString = queryString; + this.values = values; + this.types = types; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + IQuery queryObject = session.CreateQuery(queryString); + outer.PrepareQuery(queryObject); + if (values != null) + { + for (int i = 0; i < values.Length; i++) + { + if (types != null && types[i] != null) + { + queryObject.SetParameter(i, values[i], types[i]); + } + else + { + queryObject.SetParameter(i, values[i]); + } + } + } + + return queryObject.List(); + } + } + + + internal class FindByNamedParamHibernateCallback : IHibernateCallback + { + HibernateTemplate outer; + private string queryString; + private string[] paramNames; + private object[] values; + private IType[] types; + + public FindByNamedParamHibernateCallback(HibernateTemplate template, string queryString, string[] paramNames, object[] values, IType[] types) + { + this.outer = template; + this.queryString = queryString; + this.paramNames = paramNames; + this.values = values; + this.types = types; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + IQuery queryObject = session.CreateQuery(queryString); + outer.PrepareQuery(queryObject); + if (values != null) + { + for (int i = 0; i < values.Length; i++) + { + outer.ApplyNamedParameterToQuery(queryObject, paramNames[i], values[i], (types != null ? types[i] : null)); + } + } + return queryObject.List(); + + } + } + + + internal class FindByNamedQueryHibernateCallback : IHibernateCallback + { + HibernateTemplate outer; + private string queryName; + private object[] values; + private IType[] types; + + public FindByNamedQueryHibernateCallback(HibernateTemplate template, string queryName, object[] values, IType[] types) + { + this.outer = template; + this.queryName = queryName; + this.values = values; + this.types = types; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + IQuery queryObject = session.GetNamedQuery(queryName); + outer.PrepareQuery(queryObject); + if (values != null) + { + for (int i = 0; i < values.Length; i++) + { + if (types != null && types[i] != null) + { + queryObject.SetParameter(i, values[i], types[i]); + } + else + { + queryObject.SetParameter(i, values[i]); + } + } + } + return queryObject.List(); + + } + } + + + internal class FindByNamedQueryAndNamedParamHibernateCallback : IHibernateCallback + { + HibernateTemplate outer; + private string queryName; + private string[] paramNames; + private object[] values; + private IType[] types; + + public FindByNamedQueryAndNamedParamHibernateCallback(HibernateTemplate template, string queryName, string[] paramNames, object[] values, IType[] types) + { + this.outer = template; + this.queryName = queryName; + this.paramNames = paramNames; + this.values = values; + this.types = types; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + IQuery queryObject = session.GetNamedQuery(queryName); + outer.PrepareQuery(queryObject); + if (values != null) + { + for (int i = 0; i < values.Length; i++) + { + outer.ApplyNamedParameterToQuery(queryObject, paramNames[i], values[i], (types != null ? types[i] : null)); + } + } + return queryObject.List(); + + } + } + + + internal class FindByNamedQueryAndValueObjectHibernateCallback : IHibernateCallback + { + HibernateTemplate outer; + private string queryName; + private object valueObject; + + public FindByNamedQueryAndValueObjectHibernateCallback(HibernateTemplate template, string queryName, object valueObject) + { + this.outer = template; + this.queryName = queryName; + this.valueObject = valueObject; + + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + IQuery queryObject = session.GetNamedQuery(queryName); + outer.PrepareQuery(queryObject); + queryObject.SetProperties(valueObject); + return queryObject.List(); + + } + + + + } + + internal class FindByValueObjectHibernateCallback : IHibernateCallback + { + HibernateTemplate outer; + private string queryString; + private object valueObject; + + public FindByValueObjectHibernateCallback(HibernateTemplate template, string queryString, object valueObject) + { + this.outer = template; + this.queryString = queryString; + this.valueObject = valueObject; + + } + + public object DoInHibernate(ISession session) + { + IQuery queryObject = session.CreateQuery(queryString); + outer.PrepareQuery(queryObject); + queryObject.SetProperties(valueObject); + return queryObject.List(); + + } + + } + + internal class ExecuteHibernateCallbackUsingDelegate : IHibernateCallback + { + private HibernateDelegate del; + + public ExecuteHibernateCallbackUsingDelegate(HibernateDelegate d) + { + del = d; + } + + public object DoInHibernate(ISession session) + { + return del(session); + } + } + + + internal class GetByTypeHibernateCallback : IHibernateCallback + { + private Type entityType; + private object id; + private LockMode lockMode; + + public GetByTypeHibernateCallback(Type entityType, object id, LockMode lockMode) + { + this.entityType = entityType; + this.id = id; + this.lockMode = lockMode; + + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + if (lockMode != null) + { + return session.Get(entityType, id, lockMode); + } + else + { + return session.Get(entityType, id); + } + } + + + + } + + + internal class LoadByTypeHibernateCallback : IHibernateCallback + { + private Type entityType; + private object id; + private LockMode lockMode; + + public LoadByTypeHibernateCallback(Type entityType, object id, LockMode lockMode) + { + this.entityType = entityType; + this.id = id; + this.lockMode = lockMode; + + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + if (lockMode != null) + { + return session.Load(entityType, id, lockMode); + } + else + { + return session.Load(entityType, id); + } + } + + + + } + + + internal class LoadByEntityHibernateCallback : IHibernateCallback + { + private object entity; + private object id; + + public LoadByEntityHibernateCallback(object entity, object id) + { + this.entity = entity; + this.id = id; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + session.Load(entity, id); + return null; + } + + + + } + + + internal class LoadAllByTypeHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private Type entityType; + + public LoadAllByTypeHibernateCallback(HibernateTemplate template, Type entityType) + { + outer = template; + this.entityType = entityType; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + ICriteria criteria = session.CreateCriteria(entityType); + outer.PrepareCriteria(criteria); + return criteria.List(); + } + } + + + internal class LockHibernateCallback : IHibernateCallback + { + private object entity; + private LockMode lockMode; + + public LockHibernateCallback(object entity, LockMode lockMode) + { + this.entity = entity; + this.lockMode = lockMode; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + session.Lock(entity, lockMode); + return null; + } + } + + + internal class RefreshHibernateCallback : IHibernateCallback + { + private object entity; + private LockMode lockMode; + + public RefreshHibernateCallback(object entity, LockMode lockMode) + { + this.entity = entity; + this.lockMode = lockMode; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + if (lockMode != null) + { + session.Refresh(entity, lockMode); + } + else + { + session.Refresh(entity); + } + return null; + } + } + + + internal class SaveObjectHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private object entity; + + public SaveObjectHibernateCallback(HibernateTemplate template, object entity) + { + this.outer = template; + this.entity = entity; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + return session.Save(entity); + } + } + + + internal class SaveObjectWithIdHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private object entity; + private object id; + + public SaveObjectWithIdHibernateCallback(HibernateTemplate template, object entity, object id) + { + this.outer = template; + this.entity = entity; + this.id = id; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + session.Save(entity, id); + return null; + } + } + + + internal class UpdateObjectHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private object entity; + private LockMode lockMode; + + public UpdateObjectHibernateCallback(HibernateTemplate template, object entity, LockMode lockMode) + { + this.outer = template; + this.entity = entity; + this.lockMode = lockMode; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + session.Update(entity); + if (lockMode != null) + { + session.Lock(entity, lockMode); + } + return null; + } + } + + + internal class SaveOrUpdateObjectHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private object entity; + + public SaveOrUpdateObjectHibernateCallback(HibernateTemplate template, object entity) + { + this.outer = template; + this.entity = entity; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + session.SaveOrUpdate(entity); + return null; + } + } + + internal class SaveOrUpdateAllHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private ICollection entities; + + public SaveOrUpdateAllHibernateCallback(HibernateTemplate template, ICollection entities) + { + this.outer = template; + this.entities = entities; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + foreach (object entity in entities) + { + session.SaveOrUpdate(entity); + } + return null; + } + } + internal class SaveOrUpdateCopyHibernateCallback : IHibernateCallback + { + private HibernateTemplate outer; + private object entity; + + public SaveOrUpdateCopyHibernateCallback(HibernateTemplate template, object entity) + { + this.outer = template; + this.entity = entity; + } + + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ public object DoInHibernate(ISession session) + { + outer.CheckWriteOperationAllowed(session); + return session.SaveOrUpdateCopy(entity); + } + } + + + #endregion + + +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTransactionManager.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTransactionManager.cs index 6dda6ef1..165bf517 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTransactionManager.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/HibernateTransactionManager.cs @@ -1,916 +1,915 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; -using System.Reflection; - -using NHibernate; -using NHibernate.Transaction; - -using Spring.Core.TypeResolution; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Data.Support; -using Spring.Objects.Factory; -using Spring.Transaction; -using Spring.Transaction.Support; -using Spring.Util; -using HibernateTransactionException = NHibernate.TransactionException; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// PlatformTransactionManager implementation for a single Hibernate SessionFactory. - /// Binds a Hibernate Session from the specified factory to the thread, potentially - /// allowing for one thread Session per factory - /// - /// - /// SessionFactoryUtils and HibernateTemplate are aware of thread-bound Sessions and participate in such - /// transactions automatically. Using either of those is required for Hibernate - /// access code that needs to support this transaction handling mechanism. - /// - /// Supports custom isolation levels at the start of the transaction - /// , and timeouts that get applied as appropriate - /// Hibernate query timeouts. To support the latter, application code must either use - /// HibernateTemplate (which by default applies the timeouts) or call - /// SessionFactoryUtils.applyTransactionTimeout for each created - /// Hibernate Query object. - /// - /// Note that you can specify a Spring IDbProvider instance which if shared with - /// a corresponding instance of AdoTemplate will allow for mixing ADO.NET/NHibernate - /// operations within a single transaction. - /// - /// Mark Pollack (.NET) - /// $Id: HibernateTransactionManager.cs,v 1.7 2007/11/20 14:39:48 markpollack Exp $ - public class HibernateTransactionManager : AbstractPlatformTransactionManager, IObjectFactoryAware, IInitializingObject - { - #region Fields - - private ISessionFactory sessionFactory; - - private IDbProvider dbProvider; - - private bool autodetectDbProvider = true; - - private Object entityInterceptor; - - private IAdoExceptionTranslator adoExceptionTranslator; - - private IAdoExceptionTranslator defaultExceptionTranslator; - - /// - /// Just needed for entityInterceptorBeanName. - /// - private IObjectFactory objectFactory; - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public HibernateTransactionManager() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The session factory. - public HibernateTransactionManager(ISessionFactory sessionFactory) - { - this.sessionFactory = sessionFactory; - AfterPropertiesSet(); - } - - #endregion - - #region Properties - - /// - /// Gets or sets the db provider. - /// - /// The db provider. - public IDbProvider DbProvider - { - get { return dbProvider; } - set { dbProvider = value; } - } - - /// - /// Gets or sets a Hibernate entity interceptor that allows to inspect and change - /// property values before writing to and reading from the database. - /// When getting, return the current Hibernate entity interceptor, or null if none. - /// - /// The entity interceptor. - /// - /// Resolves an entity interceptor object name via the object factory, - /// if necessary. - /// Will get applied to any new Session created by this transaction manager. - /// Such an interceptor can either be set at the SessionFactory level, - /// i.e. on LocalSessionFactoryObject, or at the Session level, i.e. on - /// HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. - /// It's preferable to set it on LocalSessionFactoryObject or HibernateTransactionManager - /// to avoid repeated configuration and guarantee consistent behavior in transactions. - /// - /// If object factory is null and need to get entity interceptor via object name. - public IInterceptor EntityInterceptor - { - get - { - if (this.entityInterceptor is IInterceptor) - { - return (IInterceptor) entityInterceptor; - } - else if (this.entityInterceptor is string) - { - if (this.objectFactory == null) - { - throw new InvalidOperationException ("Cannot get entity interceptor via object name if no object factory set"); - } - String objectName = (String) this.entityInterceptor; - return (IInterceptor) this.objectFactory.GetObject(objectName, typeof(IInterceptor)); - } - else - { - return null; - } - } - set - { - entityInterceptor = value; - } - } - - /// - /// Sets the object name of a Hibernate entity interceptor that - /// allows to inspect and change property values before writing to and reading from the database. - /// - /// The name of the entity interceptor object. - /// - /// Will get applied to any new Session created by this transaction manager. - ///

Requires the object factory to be known, to be able to resolve the object - /// name to an interceptor instance on session creation. Typically used for - /// prototype interceptors, i.e. a new interceptor instance per session. - ///

- ///

Can also be used for shared interceptor instances, but it is recommended - /// to set the interceptor reference directly in such a scenario. - ///

- ///
- public string EntityInterceptorObjectName - { - set - { - entityInterceptor = value; - } - } - - /// - /// Gets or sets the ADO.NET exception translator for this transaction manager. - /// - /// - /// Applied to ADO.NET Exceptions (wrapped by Hibernate's ADOException) - /// - /// The ADO exception translator. - public IAdoExceptionTranslator AdoExceptionTranslator - { - get { return adoExceptionTranslator; } - set { adoExceptionTranslator = value; } - } - - /// - /// Gets the default IAdoException translator, lazily creating it if nece - /// - /// The default IAdoException translator. - public IAdoExceptionTranslator DefaultAdoExceptionTranslator - { - get - { lock(this) - { - if (defaultExceptionTranslator == null) - { - if (dbProvider != null) - { - defaultExceptionTranslator = new ErrorCodeExceptionTranslator(dbProvider); - } - else - { - defaultExceptionTranslator = SessionFactoryUtils.NewAdoExceptionTranslator(SessionFactory); - } - } - return defaultExceptionTranslator; - } - } - } - - /// - /// Gets or sets the SessionFactory that this instance should manage transactions for. - /// - /// The session factory. - public ISessionFactory SessionFactory - { - get { return sessionFactory; } - set { sessionFactory = value; } - } - - /// - /// Set whether to autodetect a ADO.NET connection used by the Hibernate SessionFactory, - /// if set via LocalSessionFactoryObject's DbProvider. Default is "true". - /// - /// - /// true if [autodetect data source]; otherwise, false. - /// - /// - ///

Can be turned off to deliberately ignore an available IDbProvider, - /// to not expose Hibernate transactions as ADO.NET transactions for that IDbProvider. - ///

- ///
- public bool AutodetectDbProvider - { - set { autodetectDbProvider = value; } - } - - #endregion - - #region Methods - - #endregion - - - /// - /// The object factory just needs to be known for resolving entity interceptor - /// It does not need to be set for any other mode of operation. - /// - /// - /// Owning - /// (may not be ). The object can immediately - /// call methods on the factory. - /// - public IObjectFactory ObjectFactory - { - set - { - objectFactory = value; - } - } - - /// - /// Return the current transaction object. - /// - /// The current transaction object. - /// - /// If transaction support is not available. - /// - /// - /// In the case of lookup or system errors. - /// - protected override object DoGetTransaction() - { - HibernateTransactionObject txObject = new HibernateTransactionObject(); - txObject.SavepointAllowed = NestedTransactionsAllowed; - if (TransactionSynchronizationManager.HasResource(SessionFactory)) - { - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.GetResource(SessionFactory); - if (log.IsDebugEnabled) - { - log.Debug("Found thread-bound Session [" + sessionHolder.Session + - "] for Hibernate transaction"); - } - txObject.SetSessionHolder(sessionHolder, false); - if (DbProvider != null) - { - ConnectionHolder conHolder = (ConnectionHolder) - TransactionSynchronizationManager.GetResource(DbProvider); - txObject.ConnectionHolder = conHolder; - } - } - return txObject; - } - - /// - /// Check if the given transaction object indicates an existing, - /// i.e. already begun, transaction. - /// - /// - /// Transaction object returned by - /// . - /// - /// True if there is an existing transaction. - /// - /// In the case of system errors. - /// - protected override bool IsExistingTransaction(object transaction) - { - return ((HibernateTransactionObject) transaction).HasTransaction(); - } - - /// - /// Begin a new transaction with the given transaction definition. - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// instance, describing - /// propagation behavior, isolation level, timeout etc. - /// - /// - /// Does not have to care about applying the propagation behavior, - /// as this has already been handled by this abstract manager. - /// - /// - /// In the case of creation or system errors. - /// - protected override void DoBegin(object transaction, ITransactionDefinition definition) - { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - - if (DbProvider != null && TransactionSynchronizationManager.HasResource(DbProvider) - && !txObject.ConnectionHolder.SynchronizedWithTransaction) - { - throw new IllegalTransactionStateException( - "Pre-bound ADO.NET Connection found - HibernateTransactionManager does not support " + - "running within AdoTransactionManager if told to manage the DbProvider itself. " + - "It is recommended to use a single HibernateTransactionManager for all transactions " + - "on a single DbProvider, no matter whether Hibernate or ADO.NET access."); - } - ISession session = null; - try - { - - if (txObject.SessionHolder == null || txObject.SessionHolder.SynchronizedWithTransaction) - { - IInterceptor interceptor = EntityInterceptor; - ISession newSession = (interceptor != null ? - SessionFactory.OpenSession(interceptor) : SessionFactory.OpenSession()); - - if (log.IsDebugEnabled) - { - log.Debug("Opened new Session [" + newSession + "] for Hibernate transaction"); - } - txObject.SetSessionHolder(new SessionHolder(newSession), true); - - } - txObject.SessionHolder.SynchronizedWithTransaction = true; - session = txObject.SessionHolder.Session; - - IDbConnection con = session.Connection; - //TODO isolation level mgmt - //IsolationLevel previousIsolationLevel = - - if (definition.ReadOnly && txObject.NewSessionHolder) - { - // Just set to NEVER in case of a new Session for this transaction. - session.FlushMode = FlushMode.Never; - } - - if (!definition.ReadOnly && !txObject.NewSessionHolder) - { - // We need AUTO or COMMIT for a non-read-only transaction. - FlushMode flushMode = session.FlushMode; - if (FlushMode.Never == flushMode) - { - session.FlushMode = FlushMode.Auto; - txObject.SessionHolder.PreviousFlushMode = flushMode; - } - } - - // Add the Hibernate transaction to the session holder. - // for now pass in tx options isolation level. - ITransaction hibernateTx = session.BeginTransaction(definition.TransactionIsolationLevel); - IDbTransaction adoTx = GetIDbTransaction(hibernateTx); - - // Add the Hibernate transaction to the session holder. - txObject.SessionHolder.Transaction = hibernateTx; - - // Register transaction timeout. - int timeout = DetermineTimeout(definition); - if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - txObject.SessionHolder.TimeoutInSeconds = timeout; - } - - // Register the Hibernate Session's ADO.NET Connection/TX pair for the DbProvider, if set. - if (DbProvider != null) - { - //investigate passing null for tx. - ConnectionHolder conHolder = new ConnectionHolder(con, adoTx); - if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - conHolder.TimeoutInMillis = definition.TransactionTimeout; - } - if (log.IsDebugEnabled) - { - log.Debug("Exposing Hibernate transaction as ADO transaction [" + con + "]"); - } - TransactionSynchronizationManager.BindResource(DbProvider, conHolder); - txObject.ConnectionHolder = conHolder; - } - - // Bind the session holder to the thread. - if (txObject.NewSessionHolder) - { - TransactionSynchronizationManager.BindResource(SessionFactory, txObject.SessionHolder); - } - - } catch (Exception ex) - { - SessionFactoryUtils.CloseSession(session); - throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex); - } - - - } - - - - - /// - /// Suspend the resources of the current transaction. - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// An object that holds suspended resources (will be kept unexamined for passing it into - /// .) - /// - /// - /// Transaction synchronization will already have been suspended. - /// - /// - /// If suspending is not supported by the transaction manager implementation. - /// - /// - /// in case of system errors. - /// - protected override object DoSuspend(object transaction) - { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - txObject.SetSessionHolder(null, false); - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.UnbindResource(SessionFactory); - ConnectionHolder connectionHolder = null; - if (DbProvider != null) - { - connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.UnbindResource(DbProvider); - } - return new SuspendedResourcesHolder(sessionHolder, connectionHolder); - - } - - /// - /// Resume the resources of the current transaction. - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// The object that holds suspended resources as returned by - /// . - /// - /// - /// Transaction synchronization will be resumed afterwards. - /// - /// - /// If suspending is not supported by the transaction manager implementation. - /// - /// - /// In the case of system errors. - /// - protected override void DoResume(object transaction, object suspendedResources) - { - SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; - if (TransactionSynchronizationManager.HasResource(SessionFactory)) - { - // From non-transactional code running in active transaction synchronization - // -> can be safely removed, will be closed on transaction completion. - TransactionSynchronizationManager.UnbindResource(SessionFactory); - } - TransactionSynchronizationManager.BindResource(SessionFactory, resourcesHolder.SessionHolder); - if (DbProvider != null) - { - TransactionSynchronizationManager.BindResource(DbProvider, resourcesHolder.ConnectionHolder); - } - } - - /// - /// Perform an actual commit on the given transaction. - /// - /// The status representation of the transaction. - /// - ///

- /// An implementation does not need to check the rollback-only flag. - ///

- ///
- /// - /// In the case of system errors. - /// - protected override void DoCommit(DefaultTransactionStatus status) - { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.Transaction; - if (status.Debug) - { - log.Debug("Committing Hibernate transaction on Session [" + - txObject.SessionHolder.Session + "]"); - } - try - { - txObject.SessionHolder.Transaction.Commit(); - } - // Note, unfortunate collision of namespaces/classname for NHibernate.TransactionException - // and Spring.Data.NHibernate requires this wierd construct. - catch (Exception ex) - { - Type nhibTxExceptiontype = TypeResolutionUtils.ResolveType("NHibernate.TransactionException, NHibernate"); - if (ex.GetType().Equals(nhibTxExceptiontype)) - { - // assumably from commit call to the underlying ADO.NET connection - throw new TransactionSystemException("Could not commit Hibernate transaction", ex); - } - HibernateException hibEx = ex as HibernateException; - if (hibEx != null) - { - // assumably failed to flush changes to database - throw ConvertHibernateAccessException(hibEx); - } - throw; - } - } - - /// - /// Perform an actual rollback on the given transaction. - /// - /// The status representation of the transaction. - /// - /// An implementation does not need to check the new transaction flag. - /// - /// - /// In the case of system errors. - /// - protected override void DoRollback(DefaultTransactionStatus status) - { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.Transaction; - if (status.Debug) - { - log.Debug("Rolling back Hibernate transaction on Session [" + - txObject.SessionHolder.Session + "]"); - } - try - { - txObject.SessionHolder.Transaction.Rollback(); - } - catch (HibernateTransactionException ex) - { - throw new TransactionSystemException("Could not roll back Hibernate transaction", ex); - } - catch (HibernateException ex) - { - // Shouldn't really happen, as a rollback doesn't cause a flush. - throw ConvertHibernateAccessException(ex); - } - finally - { - if (!txObject.NewSessionHolder) - { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - txObject.SessionHolder.Session.Clear(); - } - } - - - - } - - - /// - /// Set the given transaction rollback-only. Only called on rollback - /// if the current transaction takes part in an existing one. - /// - /// The status representation of the transaction. - /// - /// In the case of system errors. - /// - protected override void DoSetRollbackOnly(DefaultTransactionStatus status) - { - HibernateTransactionObject txObject = (HibernateTransactionObject) status.Transaction; - if (status.Debug) - { - log.Debug("Setting Hibernate transaction on Session [" + - txObject.SessionHolder.Session + "] rollback-only"); - } - txObject.SetRollbackOnly(); - } - - - /// - /// Gets the ADO.NET IDbTransaction object from the NHibernate ITransaction object. - /// - /// The hibernate transaction. - /// The ADO.NET transaction. Null if could not get the transaction. Warning - /// messages will be logged in that case. - protected IDbTransaction GetIDbTransaction(ITransaction hibernateTx) - { - AdoTransaction hibernateAdoTx = hibernateTx as AdoTransaction; - - IDbTransaction adoTransaction = null; - if (hibernateAdoTx != null) - { - try - { - FieldInfo fi = hibernateAdoTx.GetType().GetField("trans", BindingFlags.Instance | BindingFlags.NonPublic); - adoTransaction = fi.GetValue(hibernateAdoTx) as IDbTransaction; - } - catch (Exception e) - { - log.Warn("Could not extract IDbTransaction from Hibernate AdoTransaction using field name trans.", e); - } - } - else - { - log.Warn("Hibernate ITransaction not of expected type AdoTransaction. Could not extract IDbTransaction from Hibernate AdoTransaction."); - } - return adoTransaction; - } - - /// - /// Convert the given HibernateException to an appropriate exception from - /// the Spring.Dao hierarchy. Can be overridden in subclasses. - /// - /// The HibernateException that occured. - /// The corresponding DataAccessException instance - protected virtual DataAccessException ConvertHibernateAccessException(HibernateException ex) - { - if (AdoExceptionTranslator != null && ex is ADOException) - { - return ConvertAdoAccessException((ADOException) ex, AdoExceptionTranslator); - } - else if (ex is ADOException) - { - return ConvertAdoAccessException((ADOException)ex, DefaultAdoExceptionTranslator); - } - return SessionFactoryUtils.ConvertHibernateAccessException(ex); - } - - /// - /// Convert the given ADOException to an appropriate exception from the - /// the Spring.Dao hierarchy. Can be overridden in subclasses. - /// - /// The ADOException that occured, wrapping the underlying - /// ADO.NET thrown exception. - /// The translator to convert hibernate ADOExceptions. - /// - /// The corresponding DataAccessException instance - /// - protected virtual DataAccessException ConvertAdoAccessException(ADOException ex, IAdoExceptionTranslator translator) - { - return translator.Translate("Hibernate flusing: " + ex.Message, null, ex.InnerException); - } - - /// - /// Cleanup resources after transaction completion. - /// - /// Transaction object returned by - /// . - /// - /// - /// This implemenation unbinds the SessionFactory and - /// DbProvider from thread local storage and closes the - /// ISession. - /// - ///

- /// Called after - /// and - /// - /// execution on any outcome. - ///

- ///

- /// Should not throw any exceptions but just issue warnings on errors. - ///

- ///
- protected override void DoCleanupAfterCompletion( object transaction ) - { - HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; - - // Remove the session holder from the thread. - if (txObject.NewSessionHolder) - { - TransactionSynchronizationManager.UnbindResource(SessionFactory); - } - // Remove the ADO.NET connection holder from the thread, if exposed. - if (DbProvider != null) - { - TransactionSynchronizationManager.UnbindResource(DbProvider); - } - /* - try - { - //TODO investigate isolation level settings... - //IDbConnection con = txObject.SessionHolder.Session.Connection; - //AdoUtils.ResetConnectionAfterTransaction(con, txObject.PreviousIsolationLevel); - } - catch (HibernateException ex) - { - log.Info("Could not access ADO.NET IDbConnection of Hibernate Session", ex); - } - */ - ISession session = txObject.SessionHolder.Session; - if (txObject.NewSessionHolder) - { - if (log.IsDebugEnabled) - { - log.Debug("Closing Hibernate Session [" + session + "] after transaction"); - } - SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, SessionFactory); - } - else - { - if (log.IsDebugEnabled) - { - log.Debug("Not closing pre-bound Hibernate Session [" + session + "] after transaction"); - } - if (txObject.SessionHolder.AssignedPreviousFlushMode) - { - session.FlushMode = txObject.SessionHolder.PreviousFlushMode; - } - } - txObject.SessionHolder.Clear(); - - - } - - private class HibernateTransactionObject : AdoTransactionObjectSupport - { - - private SessionHolder sessionHolder; - - private bool newSessionHolder; - - - public void SetSessionHolder(SessionHolder sessionHolder, bool newSessionHolder) - { - this.sessionHolder = sessionHolder; - this.newSessionHolder = newSessionHolder; - } - - - public SessionHolder SessionHolder - { - get - { - return sessionHolder; - } - } - - public bool NewSessionHolder - { - get - { - return newSessionHolder; - } - } - - public bool HasTransaction() - { - return (this.sessionHolder != null && this.sessionHolder.Transaction != null); - } - - public void SetRollbackOnly() - { - SessionHolder.RollbackOnly = true; - if (ConnectionHolder != null) - { - ConnectionHolder.RollbackOnly = true; - } - } - - /// - /// Return whether the transaction is internally marked as rollback-only. - /// - /// - /// True of the transaction is marked as rollback-only. - public override bool RollbackOnly - { - get - { - return SessionHolder.RollbackOnly || - (ConnectionHolder != null && ConnectionHolder.RollbackOnly); - } - } - } - - private class SuspendedResourcesHolder - { - - private readonly SessionHolder sessionHolder; - - private readonly ConnectionHolder connectionHolder; - - public SuspendedResourcesHolder(SessionHolder sessionHolder, ConnectionHolder conHolder) - { - this.sessionHolder = sessionHolder; - this.connectionHolder = conHolder; - } - - public SessionHolder SessionHolder - { - get - { - return sessionHolder; - } - - } - - public ConnectionHolder ConnectionHolder - { - get - { - return connectionHolder; - } - - } - } - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public void AfterPropertiesSet() - { - if (SessionFactory == null) { - throw new ArgumentException("sessionFactory is required"); - } - if (this.entityInterceptor is string && this.objectFactory == null) { - throw new ArgumentException ("objectFactory is required for entityInterceptorBeanName"); - } - - // Try to derive a DbProvider given the SessionFactory. - if (this.autodetectDbProvider && DbProvider == null) { - IDbProvider sfDbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); - if (sfDbProvider != null) { - // Use the SessionFactory's DataSource for exposing transactions to ADO.NET code. - if (log.IsInfoEnabled) { - log.Info("Derived DbProvider [" + sfDbProvider.DbMetadata.ProductName + - "] of Hibernate SessionFactory for HibernateTransactionManager"); - } - DbProvider = sfDbProvider; - } - else - { - log.Info("Could not auto detect DbProvider from SessionFactory configuration"); - } - - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; +using System.Reflection; + +using NHibernate; +using NHibernate.Transaction; + +using Spring.Core.TypeResolution; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Data.Support; +using Spring.Objects.Factory; +using Spring.Transaction; +using Spring.Transaction.Support; +using Spring.Util; +using HibernateTransactionException = NHibernate.TransactionException; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// PlatformTransactionManager implementation for a single Hibernate SessionFactory. + /// Binds a Hibernate Session from the specified factory to the thread, potentially + /// allowing for one thread Session per factory + /// + /// + /// SessionFactoryUtils and HibernateTemplate are aware of thread-bound Sessions and participate in such + /// transactions automatically. Using either of those is required for Hibernate + /// access code that needs to support this transaction handling mechanism. + /// + /// Supports custom isolation levels at the start of the transaction + /// , and timeouts that get applied as appropriate + /// Hibernate query timeouts. To support the latter, application code must either use + /// HibernateTemplate (which by default applies the timeouts) or call + /// SessionFactoryUtils.applyTransactionTimeout for each created + /// Hibernate Query object. + /// + /// Note that you can specify a Spring IDbProvider instance which if shared with + /// a corresponding instance of AdoTemplate will allow for mixing ADO.NET/NHibernate + /// operations within a single transaction. + /// + /// Mark Pollack (.NET) + public class HibernateTransactionManager : AbstractPlatformTransactionManager, IObjectFactoryAware, IInitializingObject + { + #region Fields + + private ISessionFactory sessionFactory; + + private IDbProvider dbProvider; + + private bool autodetectDbProvider = true; + + private Object entityInterceptor; + + private IAdoExceptionTranslator adoExceptionTranslator; + + private IAdoExceptionTranslator defaultExceptionTranslator; + + /// + /// Just needed for entityInterceptorBeanName. + /// + private IObjectFactory objectFactory; + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public HibernateTransactionManager() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The session factory. + public HibernateTransactionManager(ISessionFactory sessionFactory) + { + this.sessionFactory = sessionFactory; + AfterPropertiesSet(); + } + + #endregion + + #region Properties + + /// + /// Gets or sets the db provider. + /// + /// The db provider. + public IDbProvider DbProvider + { + get { return dbProvider; } + set { dbProvider = value; } + } + + /// + /// Gets or sets a Hibernate entity interceptor that allows to inspect and change + /// property values before writing to and reading from the database. + /// When getting, return the current Hibernate entity interceptor, or null if none. + /// + /// The entity interceptor. + /// + /// Resolves an entity interceptor object name via the object factory, + /// if necessary. + /// Will get applied to any new Session created by this transaction manager. + /// Such an interceptor can either be set at the SessionFactory level, + /// i.e. on LocalSessionFactoryObject, or at the Session level, i.e. on + /// HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager. + /// It's preferable to set it on LocalSessionFactoryObject or HibernateTransactionManager + /// to avoid repeated configuration and guarantee consistent behavior in transactions. + /// + /// If object factory is null and need to get entity interceptor via object name. + public IInterceptor EntityInterceptor + { + get + { + if (this.entityInterceptor is IInterceptor) + { + return (IInterceptor) entityInterceptor; + } + else if (this.entityInterceptor is string) + { + if (this.objectFactory == null) + { + throw new InvalidOperationException ("Cannot get entity interceptor via object name if no object factory set"); + } + String objectName = (String) this.entityInterceptor; + return (IInterceptor) this.objectFactory.GetObject(objectName, typeof(IInterceptor)); + } + else + { + return null; + } + } + set + { + entityInterceptor = value; + } + } + + /// + /// Sets the object name of a Hibernate entity interceptor that + /// allows to inspect and change property values before writing to and reading from the database. + /// + /// The name of the entity interceptor object. + /// + /// Will get applied to any new Session created by this transaction manager. + ///

Requires the object factory to be known, to be able to resolve the object + /// name to an interceptor instance on session creation. Typically used for + /// prototype interceptors, i.e. a new interceptor instance per session. + ///

+ ///

Can also be used for shared interceptor instances, but it is recommended + /// to set the interceptor reference directly in such a scenario. + ///

+ ///
+ public string EntityInterceptorObjectName + { + set + { + entityInterceptor = value; + } + } + + /// + /// Gets or sets the ADO.NET exception translator for this transaction manager. + /// + /// + /// Applied to ADO.NET Exceptions (wrapped by Hibernate's ADOException) + /// + /// The ADO exception translator. + public IAdoExceptionTranslator AdoExceptionTranslator + { + get { return adoExceptionTranslator; } + set { adoExceptionTranslator = value; } + } + + /// + /// Gets the default IAdoException translator, lazily creating it if nece + /// + /// The default IAdoException translator. + public IAdoExceptionTranslator DefaultAdoExceptionTranslator + { + get + { lock(this) + { + if (defaultExceptionTranslator == null) + { + if (dbProvider != null) + { + defaultExceptionTranslator = new ErrorCodeExceptionTranslator(dbProvider); + } + else + { + defaultExceptionTranslator = SessionFactoryUtils.NewAdoExceptionTranslator(SessionFactory); + } + } + return defaultExceptionTranslator; + } + } + } + + /// + /// Gets or sets the SessionFactory that this instance should manage transactions for. + /// + /// The session factory. + public ISessionFactory SessionFactory + { + get { return sessionFactory; } + set { sessionFactory = value; } + } + + /// + /// Set whether to autodetect a ADO.NET connection used by the Hibernate SessionFactory, + /// if set via LocalSessionFactoryObject's DbProvider. Default is "true". + /// + /// + /// true if [autodetect data source]; otherwise, false. + /// + /// + ///

Can be turned off to deliberately ignore an available IDbProvider, + /// to not expose Hibernate transactions as ADO.NET transactions for that IDbProvider. + ///

+ ///
+ public bool AutodetectDbProvider + { + set { autodetectDbProvider = value; } + } + + #endregion + + #region Methods + + #endregion + + + /// + /// The object factory just needs to be known for resolving entity interceptor + /// It does not need to be set for any other mode of operation. + /// + /// + /// Owning + /// (may not be ). The object can immediately + /// call methods on the factory. + /// + public IObjectFactory ObjectFactory + { + set + { + objectFactory = value; + } + } + + /// + /// Return the current transaction object. + /// + /// The current transaction object. + /// + /// If transaction support is not available. + /// + /// + /// In the case of lookup or system errors. + /// + protected override object DoGetTransaction() + { + HibernateTransactionObject txObject = new HibernateTransactionObject(); + txObject.SavepointAllowed = NestedTransactionsAllowed; + if (TransactionSynchronizationManager.HasResource(SessionFactory)) + { + SessionHolder sessionHolder = + (SessionHolder) TransactionSynchronizationManager.GetResource(SessionFactory); + if (log.IsDebugEnabled) + { + log.Debug("Found thread-bound Session [" + sessionHolder.Session + + "] for Hibernate transaction"); + } + txObject.SetSessionHolder(sessionHolder, false); + if (DbProvider != null) + { + ConnectionHolder conHolder = (ConnectionHolder) + TransactionSynchronizationManager.GetResource(DbProvider); + txObject.ConnectionHolder = conHolder; + } + } + return txObject; + } + + /// + /// Check if the given transaction object indicates an existing, + /// i.e. already begun, transaction. + /// + /// + /// Transaction object returned by + /// . + /// + /// True if there is an existing transaction. + /// + /// In the case of system errors. + /// + protected override bool IsExistingTransaction(object transaction) + { + return ((HibernateTransactionObject) transaction).HasTransaction(); + } + + /// + /// Begin a new transaction with the given transaction definition. + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// instance, describing + /// propagation behavior, isolation level, timeout etc. + /// + /// + /// Does not have to care about applying the propagation behavior, + /// as this has already been handled by this abstract manager. + /// + /// + /// In the case of creation or system errors. + /// + protected override void DoBegin(object transaction, ITransactionDefinition definition) + { + HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; + + if (DbProvider != null && TransactionSynchronizationManager.HasResource(DbProvider) + && !txObject.ConnectionHolder.SynchronizedWithTransaction) + { + throw new IllegalTransactionStateException( + "Pre-bound ADO.NET Connection found - HibernateTransactionManager does not support " + + "running within AdoTransactionManager if told to manage the DbProvider itself. " + + "It is recommended to use a single HibernateTransactionManager for all transactions " + + "on a single DbProvider, no matter whether Hibernate or ADO.NET access."); + } + ISession session = null; + try + { + + if (txObject.SessionHolder == null || txObject.SessionHolder.SynchronizedWithTransaction) + { + IInterceptor interceptor = EntityInterceptor; + ISession newSession = (interceptor != null ? + SessionFactory.OpenSession(interceptor) : SessionFactory.OpenSession()); + + if (log.IsDebugEnabled) + { + log.Debug("Opened new Session [" + newSession + "] for Hibernate transaction"); + } + txObject.SetSessionHolder(new SessionHolder(newSession), true); + + } + txObject.SessionHolder.SynchronizedWithTransaction = true; + session = txObject.SessionHolder.Session; + + IDbConnection con = session.Connection; + //TODO isolation level mgmt + //IsolationLevel previousIsolationLevel = + + if (definition.ReadOnly && txObject.NewSessionHolder) + { + // Just set to NEVER in case of a new Session for this transaction. + session.FlushMode = FlushMode.Never; + } + + if (!definition.ReadOnly && !txObject.NewSessionHolder) + { + // We need AUTO or COMMIT for a non-read-only transaction. + FlushMode flushMode = session.FlushMode; + if (FlushMode.Never == flushMode) + { + session.FlushMode = FlushMode.Auto; + txObject.SessionHolder.PreviousFlushMode = flushMode; + } + } + + // Add the Hibernate transaction to the session holder. + // for now pass in tx options isolation level. + ITransaction hibernateTx = session.BeginTransaction(definition.TransactionIsolationLevel); + IDbTransaction adoTx = GetIDbTransaction(hibernateTx); + + // Add the Hibernate transaction to the session holder. + txObject.SessionHolder.Transaction = hibernateTx; + + // Register transaction timeout. + int timeout = DetermineTimeout(definition); + if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + txObject.SessionHolder.TimeoutInSeconds = timeout; + } + + // Register the Hibernate Session's ADO.NET Connection/TX pair for the DbProvider, if set. + if (DbProvider != null) + { + //investigate passing null for tx. + ConnectionHolder conHolder = new ConnectionHolder(con, adoTx); + if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + conHolder.TimeoutInMillis = definition.TransactionTimeout; + } + if (log.IsDebugEnabled) + { + log.Debug("Exposing Hibernate transaction as ADO transaction [" + con + "]"); + } + TransactionSynchronizationManager.BindResource(DbProvider, conHolder); + txObject.ConnectionHolder = conHolder; + } + + // Bind the session holder to the thread. + if (txObject.NewSessionHolder) + { + TransactionSynchronizationManager.BindResource(SessionFactory, txObject.SessionHolder); + } + + } catch (Exception ex) + { + SessionFactoryUtils.CloseSession(session); + throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex); + } + + + } + + + + + /// + /// Suspend the resources of the current transaction. + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// An object that holds suspended resources (will be kept unexamined for passing it into + /// .) + /// + /// + /// Transaction synchronization will already have been suspended. + /// + /// + /// If suspending is not supported by the transaction manager implementation. + /// + /// + /// in case of system errors. + /// + protected override object DoSuspend(object transaction) + { + HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; + txObject.SetSessionHolder(null, false); + SessionHolder sessionHolder = + (SessionHolder) TransactionSynchronizationManager.UnbindResource(SessionFactory); + ConnectionHolder connectionHolder = null; + if (DbProvider != null) + { + connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.UnbindResource(DbProvider); + } + return new SuspendedResourcesHolder(sessionHolder, connectionHolder); + + } + + /// + /// Resume the resources of the current transaction. + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// The object that holds suspended resources as returned by + /// . + /// + /// + /// Transaction synchronization will be resumed afterwards. + /// + /// + /// If suspending is not supported by the transaction manager implementation. + /// + /// + /// In the case of system errors. + /// + protected override void DoResume(object transaction, object suspendedResources) + { + SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; + if (TransactionSynchronizationManager.HasResource(SessionFactory)) + { + // From non-transactional code running in active transaction synchronization + // -> can be safely removed, will be closed on transaction completion. + TransactionSynchronizationManager.UnbindResource(SessionFactory); + } + TransactionSynchronizationManager.BindResource(SessionFactory, resourcesHolder.SessionHolder); + if (DbProvider != null) + { + TransactionSynchronizationManager.BindResource(DbProvider, resourcesHolder.ConnectionHolder); + } + } + + /// + /// Perform an actual commit on the given transaction. + /// + /// The status representation of the transaction. + /// + ///

+ /// An implementation does not need to check the rollback-only flag. + ///

+ ///
+ /// + /// In the case of system errors. + /// + protected override void DoCommit(DefaultTransactionStatus status) + { + HibernateTransactionObject txObject = (HibernateTransactionObject) status.Transaction; + if (status.Debug) + { + log.Debug("Committing Hibernate transaction on Session [" + + txObject.SessionHolder.Session + "]"); + } + try + { + txObject.SessionHolder.Transaction.Commit(); + } + // Note, unfortunate collision of namespaces/classname for NHibernate.TransactionException + // and Spring.Data.NHibernate requires this wierd construct. + catch (Exception ex) + { + Type nhibTxExceptiontype = TypeResolutionUtils.ResolveType("NHibernate.TransactionException, NHibernate"); + if (ex.GetType().Equals(nhibTxExceptiontype)) + { + // assumably from commit call to the underlying ADO.NET connection + throw new TransactionSystemException("Could not commit Hibernate transaction", ex); + } + HibernateException hibEx = ex as HibernateException; + if (hibEx != null) + { + // assumably failed to flush changes to database + throw ConvertHibernateAccessException(hibEx); + } + throw; + } + } + + /// + /// Perform an actual rollback on the given transaction. + /// + /// The status representation of the transaction. + /// + /// An implementation does not need to check the new transaction flag. + /// + /// + /// In the case of system errors. + /// + protected override void DoRollback(DefaultTransactionStatus status) + { + HibernateTransactionObject txObject = (HibernateTransactionObject) status.Transaction; + if (status.Debug) + { + log.Debug("Rolling back Hibernate transaction on Session [" + + txObject.SessionHolder.Session + "]"); + } + try + { + txObject.SessionHolder.Transaction.Rollback(); + } + catch (HibernateTransactionException ex) + { + throw new TransactionSystemException("Could not roll back Hibernate transaction", ex); + } + catch (HibernateException ex) + { + // Shouldn't really happen, as a rollback doesn't cause a flush. + throw ConvertHibernateAccessException(ex); + } + finally + { + if (!txObject.NewSessionHolder) + { + // Clear all pending inserts/updates/deletes in the Session. + // Necessary for pre-bound Sessions, to avoid inconsistent state. + txObject.SessionHolder.Session.Clear(); + } + } + + + + } + + + /// + /// Set the given transaction rollback-only. Only called on rollback + /// if the current transaction takes part in an existing one. + /// + /// The status representation of the transaction. + /// + /// In the case of system errors. + /// + protected override void DoSetRollbackOnly(DefaultTransactionStatus status) + { + HibernateTransactionObject txObject = (HibernateTransactionObject) status.Transaction; + if (status.Debug) + { + log.Debug("Setting Hibernate transaction on Session [" + + txObject.SessionHolder.Session + "] rollback-only"); + } + txObject.SetRollbackOnly(); + } + + + /// + /// Gets the ADO.NET IDbTransaction object from the NHibernate ITransaction object. + /// + /// The hibernate transaction. + /// The ADO.NET transaction. Null if could not get the transaction. Warning + /// messages will be logged in that case. + protected IDbTransaction GetIDbTransaction(ITransaction hibernateTx) + { + AdoTransaction hibernateAdoTx = hibernateTx as AdoTransaction; + + IDbTransaction adoTransaction = null; + if (hibernateAdoTx != null) + { + try + { + FieldInfo fi = hibernateAdoTx.GetType().GetField("trans", BindingFlags.Instance | BindingFlags.NonPublic); + adoTransaction = fi.GetValue(hibernateAdoTx) as IDbTransaction; + } + catch (Exception e) + { + log.Warn("Could not extract IDbTransaction from Hibernate AdoTransaction using field name trans.", e); + } + } + else + { + log.Warn("Hibernate ITransaction not of expected type AdoTransaction. Could not extract IDbTransaction from Hibernate AdoTransaction."); + } + return adoTransaction; + } + + /// + /// Convert the given HibernateException to an appropriate exception from + /// the Spring.Dao hierarchy. Can be overridden in subclasses. + /// + /// The HibernateException that occured. + /// The corresponding DataAccessException instance + protected virtual DataAccessException ConvertHibernateAccessException(HibernateException ex) + { + if (AdoExceptionTranslator != null && ex is ADOException) + { + return ConvertAdoAccessException((ADOException) ex, AdoExceptionTranslator); + } + else if (ex is ADOException) + { + return ConvertAdoAccessException((ADOException)ex, DefaultAdoExceptionTranslator); + } + return SessionFactoryUtils.ConvertHibernateAccessException(ex); + } + + /// + /// Convert the given ADOException to an appropriate exception from the + /// the Spring.Dao hierarchy. Can be overridden in subclasses. + /// + /// The ADOException that occured, wrapping the underlying + /// ADO.NET thrown exception. + /// The translator to convert hibernate ADOExceptions. + /// + /// The corresponding DataAccessException instance + /// + protected virtual DataAccessException ConvertAdoAccessException(ADOException ex, IAdoExceptionTranslator translator) + { + return translator.Translate("Hibernate flusing: " + ex.Message, null, ex.InnerException); + } + + /// + /// Cleanup resources after transaction completion. + /// + /// Transaction object returned by + /// . + /// + /// + /// This implemenation unbinds the SessionFactory and + /// DbProvider from thread local storage and closes the + /// ISession. + /// + ///

+ /// Called after + /// and + /// + /// execution on any outcome. + ///

+ ///

+ /// Should not throw any exceptions but just issue warnings on errors. + ///

+ ///
+ protected override void DoCleanupAfterCompletion( object transaction ) + { + HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; + + // Remove the session holder from the thread. + if (txObject.NewSessionHolder) + { + TransactionSynchronizationManager.UnbindResource(SessionFactory); + } + // Remove the ADO.NET connection holder from the thread, if exposed. + if (DbProvider != null) + { + TransactionSynchronizationManager.UnbindResource(DbProvider); + } + /* + try + { + //TODO investigate isolation level settings... + //IDbConnection con = txObject.SessionHolder.Session.Connection; + //AdoUtils.ResetConnectionAfterTransaction(con, txObject.PreviousIsolationLevel); + } + catch (HibernateException ex) + { + log.Info("Could not access ADO.NET IDbConnection of Hibernate Session", ex); + } + */ + ISession session = txObject.SessionHolder.Session; + if (txObject.NewSessionHolder) + { + if (log.IsDebugEnabled) + { + log.Debug("Closing Hibernate Session [" + session + "] after transaction"); + } + SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, SessionFactory); + } + else + { + if (log.IsDebugEnabled) + { + log.Debug("Not closing pre-bound Hibernate Session [" + session + "] after transaction"); + } + if (txObject.SessionHolder.AssignedPreviousFlushMode) + { + session.FlushMode = txObject.SessionHolder.PreviousFlushMode; + } + } + txObject.SessionHolder.Clear(); + + + } + + private class HibernateTransactionObject : AdoTransactionObjectSupport + { + + private SessionHolder sessionHolder; + + private bool newSessionHolder; + + + public void SetSessionHolder(SessionHolder sessionHolder, bool newSessionHolder) + { + this.sessionHolder = sessionHolder; + this.newSessionHolder = newSessionHolder; + } + + + public SessionHolder SessionHolder + { + get + { + return sessionHolder; + } + } + + public bool NewSessionHolder + { + get + { + return newSessionHolder; + } + } + + public bool HasTransaction() + { + return (this.sessionHolder != null && this.sessionHolder.Transaction != null); + } + + public void SetRollbackOnly() + { + SessionHolder.RollbackOnly = true; + if (ConnectionHolder != null) + { + ConnectionHolder.RollbackOnly = true; + } + } + + /// + /// Return whether the transaction is internally marked as rollback-only. + /// + /// + /// True of the transaction is marked as rollback-only. + public override bool RollbackOnly + { + get + { + return SessionHolder.RollbackOnly || + (ConnectionHolder != null && ConnectionHolder.RollbackOnly); + } + } + } + + private class SuspendedResourcesHolder + { + + private readonly SessionHolder sessionHolder; + + private readonly ConnectionHolder connectionHolder; + + public SuspendedResourcesHolder(SessionHolder sessionHolder, ConnectionHolder conHolder) + { + this.sessionHolder = sessionHolder; + this.connectionHolder = conHolder; + } + + public SessionHolder SessionHolder + { + get + { + return sessionHolder; + } + + } + + public ConnectionHolder ConnectionHolder + { + get + { + return connectionHolder; + } + + } + } + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public void AfterPropertiesSet() + { + if (SessionFactory == null) { + throw new ArgumentException("sessionFactory is required"); + } + if (this.entityInterceptor is string && this.objectFactory == null) { + throw new ArgumentException ("objectFactory is required for entityInterceptorBeanName"); + } + + // Try to derive a DbProvider given the SessionFactory. + if (this.autodetectDbProvider && DbProvider == null) { + IDbProvider sfDbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); + if (sfDbProvider != null) { + // Use the SessionFactory's DataSource for exposing transactions to ADO.NET code. + if (log.IsInfoEnabled) { + log.Info("Derived DbProvider [" + sfDbProvider.DbMetadata.ProductName + + "] of Hibernate SessionFactory for HibernateTransactionManager"); + } + DbProvider = sfDbProvider; + } + else + { + log.Info("Could not auto detect DbProvider from SessionFactory configuration"); + } + + } + } + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/ICommonHibernateOperations.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/ICommonHibernateOperations.cs index 0284b187..a7e4ad38 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/ICommonHibernateOperations.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/ICommonHibernateOperations.cs @@ -1,245 +1,244 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using NHibernate; -using NHibernate.Type; -using Spring.Dao; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Interface that specifies a set of Hibernate operations that - /// are common across versions of Hibernate. - /// - /// - /// Base interface for generic and non generic IHibernateOperations interfaces - /// Not often used, but a useful option - /// to enhance testability, as it can easily be mocked or stubbed. - ///

Provides HibernateTemplate's data access methods that mirror - /// various Session methods. See the NHibernate ISession documentation - /// for details on those methods. - ///

- ///
- /// Mark Pollack (.NET) - /// - /// $Id: ICommonHibernateOperations.cs,v 1.2 2007/09/19 22:58:22 markpollack Exp $ - public interface ICommonHibernateOperations - { - /// - /// Remove all objects from the Session cache, and cancel all pending saves, - /// updates and deletes. - /// - /// In case of Hibernate errors - void Clear(); - - - /// - /// Delete the given persistent instance. - /// - /// The persistent instance to delete. - /// In case of Hibernate errors - void Delete(object entity); - - /// - /// Delete the given persistent instance. - /// - /// - /// Obtains the specified lock mode if the instance exists, implicitly - /// checking whether the corresponding database entry still exists - /// (throwing an OptimisticLockingFailureException if not found). - /// - /// Tthe persistent instance to delete. - /// The lock mode to obtain. - /// In case of Hibernate errors - void Delete(object entity, LockMode lockMode); - - - /// - /// Delete all objects returned by the query. - /// - /// a query expressed in Hibernate's query language. - /// The number of entity instances deleted. - /// In case of Hibernate errors - int Delete(string queryString); - - /// - /// Delete all objects returned by the query. - /// - /// a query expressed in Hibernate's query language. - /// The value of the parameter. - /// The Hibernate type of the parameter (or null). - /// The number of entity instances deleted. - /// In case of Hibernate errors - int Delete(string queryString, object value, IType type); - - - /// - /// Delete all objects returned by the query. - /// - /// a query expressed in Hibernate's query language. - /// The values of the parameters. - /// Hibernate types of the parameters (or null) - /// The number of entity instances deleted. - /// In case of Hibernate errors - int Delete(String queryString, Object[] values, IType[] types); - - - /// - /// Flush all pending saves, updates and deletes to the database. - /// - /// - /// Only invoke this for selective eager flushing, for example when ADO.NET code - /// needs to see certain changes within the same transaction. Else, it's preferable - /// to rely on auto-flushing at transaction completion. - /// - /// In case of Hibernate errors - void Flush(); - - #region Convenience methods for loading individual objects - - /// - /// Load the persistent instance with the given identifier - /// into the given object, throwing an exception if not found. - /// - /// Entity the object (of the target class) to load into. - /// An identifier of the persistent instance. - /// If object not found. - /// In case of Hibernate errors - void Load(object entity, object id); - - - /// - /// Re-read the state of the given persistent instance. - /// - /// The persistent instance to re-read. - /// In case of Hibernate errors - void Refresh(object entity); - - /// - /// Re-read the state of the given persistent instance. - /// Obtains the specified lock mode for the instance. - /// - /// The persistent instance to re-read. - /// The lock mode to obtain. - /// In case of Hibernate errors - void Refresh(object entity, LockMode lockMode); - - /// - /// Determines whether the given object is in the Session cache. - /// - /// the persistence instance to check. - /// - /// true if session cache contains the specified entity; otherwise, false. - /// - /// In case of Hibernate errors - bool Contains(object entity); - - /// - /// Remove the given object from the Session cache. - /// - /// The persistent instance to evict. - /// In case of Hibernate errors - void Evict(object entity); - - #endregion - - #region Convenience methods for storing individual objects - - - /// - /// Obtain the specified lock level upon the given object, implicitly - /// checking whether the corresponding database entry still exists - /// (throwing an OptimisticLockingFailureException if not found). - /// - /// The he persistent instance to lock. - /// The lock mode to obtain. - /// If not found - /// In case of Hibernate errors - void Lock(object entity, LockMode lockMode); - - - /// - /// Persist the given transient instance. - /// - /// The transient instance to persist. - /// The generated identifier. - /// In case of Hibernate errors - object Save(object entity); - - /// - /// Persist the given transient instance with the given identifier. - /// - /// The transient instance to persist. - /// The identifier to assign. - /// In case of Hibernate errors - void Save(object entity, object id); - - /// - /// Update the given persistent instance. - /// - /// The persistent instance to update. - /// In case of Hibernate errors - void Update(object entity); - - /// - /// Update the given persistent instance. - /// Obtains the specified lock mode if the instance exists, implicitly - /// checking whether the corresponding database entry still exists - /// (throwing an OptimisticLockingFailureException if not found). - /// - /// The persistent instance to update. - /// The lock mode to obtain. - /// In case of Hibernate errors - void Update(object entity, LockMode lockMode); - - /// - /// Save or update the given persistent instance, - /// according to its id (matching the configured "unsaved-value"?). - /// - /// Tthe persistent instance to save or update - /// (to be associated with the Hibernate Session). - /// In case of Hibernate errors - void SaveOrUpdate(object entity); - - /// - /// Save or update the contents of given persistent object, - /// according to its id (matching the configured "unsaved-value"?). - /// Will copy the contained fields to an already loaded instance - /// with the same id, if appropriate. - /// - /// The persistent object to save or update. - /// (not necessarily to be associated with the Hibernate Session) - /// - /// The actually associated persistent object. - /// (either an already loaded instance with the same id, or the given object) - /// In case of Hibernate errors - object SaveOrUpdateCopy(object entity); - - - #endregion - - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using NHibernate; +using NHibernate.Type; +using Spring.Dao; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Interface that specifies a set of Hibernate operations that + /// are common across versions of Hibernate. + /// + /// + /// Base interface for generic and non generic IHibernateOperations interfaces + /// Not often used, but a useful option + /// to enhance testability, as it can easily be mocked or stubbed. + ///

Provides HibernateTemplate's data access methods that mirror + /// various Session methods. See the NHibernate ISession documentation + /// for details on those methods. + ///

+ ///
+ /// Mark Pollack (.NET) + /// + public interface ICommonHibernateOperations + { + /// + /// Remove all objects from the Session cache, and cancel all pending saves, + /// updates and deletes. + /// + /// In case of Hibernate errors + void Clear(); + + + /// + /// Delete the given persistent instance. + /// + /// The persistent instance to delete. + /// In case of Hibernate errors + void Delete(object entity); + + /// + /// Delete the given persistent instance. + /// + /// + /// Obtains the specified lock mode if the instance exists, implicitly + /// checking whether the corresponding database entry still exists + /// (throwing an OptimisticLockingFailureException if not found). + /// + /// Tthe persistent instance to delete. + /// The lock mode to obtain. + /// In case of Hibernate errors + void Delete(object entity, LockMode lockMode); + + + /// + /// Delete all objects returned by the query. + /// + /// a query expressed in Hibernate's query language. + /// The number of entity instances deleted. + /// In case of Hibernate errors + int Delete(string queryString); + + /// + /// Delete all objects returned by the query. + /// + /// a query expressed in Hibernate's query language. + /// The value of the parameter. + /// The Hibernate type of the parameter (or null). + /// The number of entity instances deleted. + /// In case of Hibernate errors + int Delete(string queryString, object value, IType type); + + + /// + /// Delete all objects returned by the query. + /// + /// a query expressed in Hibernate's query language. + /// The values of the parameters. + /// Hibernate types of the parameters (or null) + /// The number of entity instances deleted. + /// In case of Hibernate errors + int Delete(String queryString, Object[] values, IType[] types); + + + /// + /// Flush all pending saves, updates and deletes to the database. + /// + /// + /// Only invoke this for selective eager flushing, for example when ADO.NET code + /// needs to see certain changes within the same transaction. Else, it's preferable + /// to rely on auto-flushing at transaction completion. + /// + /// In case of Hibernate errors + void Flush(); + + #region Convenience methods for loading individual objects + + /// + /// Load the persistent instance with the given identifier + /// into the given object, throwing an exception if not found. + /// + /// Entity the object (of the target class) to load into. + /// An identifier of the persistent instance. + /// If object not found. + /// In case of Hibernate errors + void Load(object entity, object id); + + + /// + /// Re-read the state of the given persistent instance. + /// + /// The persistent instance to re-read. + /// In case of Hibernate errors + void Refresh(object entity); + + /// + /// Re-read the state of the given persistent instance. + /// Obtains the specified lock mode for the instance. + /// + /// The persistent instance to re-read. + /// The lock mode to obtain. + /// In case of Hibernate errors + void Refresh(object entity, LockMode lockMode); + + /// + /// Determines whether the given object is in the Session cache. + /// + /// the persistence instance to check. + /// + /// true if session cache contains the specified entity; otherwise, false. + /// + /// In case of Hibernate errors + bool Contains(object entity); + + /// + /// Remove the given object from the Session cache. + /// + /// The persistent instance to evict. + /// In case of Hibernate errors + void Evict(object entity); + + #endregion + + #region Convenience methods for storing individual objects + + + /// + /// Obtain the specified lock level upon the given object, implicitly + /// checking whether the corresponding database entry still exists + /// (throwing an OptimisticLockingFailureException if not found). + /// + /// The he persistent instance to lock. + /// The lock mode to obtain. + /// If not found + /// In case of Hibernate errors + void Lock(object entity, LockMode lockMode); + + + /// + /// Persist the given transient instance. + /// + /// The transient instance to persist. + /// The generated identifier. + /// In case of Hibernate errors + object Save(object entity); + + /// + /// Persist the given transient instance with the given identifier. + /// + /// The transient instance to persist. + /// The identifier to assign. + /// In case of Hibernate errors + void Save(object entity, object id); + + /// + /// Update the given persistent instance. + /// + /// The persistent instance to update. + /// In case of Hibernate errors + void Update(object entity); + + /// + /// Update the given persistent instance. + /// Obtains the specified lock mode if the instance exists, implicitly + /// checking whether the corresponding database entry still exists + /// (throwing an OptimisticLockingFailureException if not found). + /// + /// The persistent instance to update. + /// The lock mode to obtain. + /// In case of Hibernate errors + void Update(object entity, LockMode lockMode); + + /// + /// Save or update the given persistent instance, + /// according to its id (matching the configured "unsaved-value"?). + /// + /// Tthe persistent instance to save or update + /// (to be associated with the Hibernate Session). + /// In case of Hibernate errors + void SaveOrUpdate(object entity); + + /// + /// Save or update the contents of given persistent object, + /// according to its id (matching the configured "unsaved-value"?). + /// Will copy the contained fields to an already loaded instance + /// with the same id, if appropriate. + /// + /// The persistent object to save or update. + /// (not necessarily to be associated with the Hibernate Session) + /// + /// The actually associated persistent object. + /// (either an already loaded instance with the same id, or the given object) + /// In case of Hibernate errors + object SaveOrUpdateCopy(object entity); + + + #endregion + + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateCallback.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateCallback.cs index fcc87154..938c2b8a 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateCallback.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateCallback.cs @@ -1,57 +1,56 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using NHibernate; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Callback interface for NHibernate code. - /// - /// To be used with HibernateTemplate execute - /// method. The typical implementation will call - /// Session.load/find/save/update to perform - /// some operations on persistent objects. - /// - /// Mark Pollack (.NET) - /// $Id: IHibernateCallback.cs,v 1.2 2007/09/19 22:58:22 markpollack Exp $ - public interface IHibernateCallback - { - /// - /// Gets called by HibernateTemplate with an active - /// Hibernate Session. Does not need to care about activating or closing - /// the Session, or handling transactions. - /// - /// - ///

- /// Allows for returning a result object created within the callback, i.e. - /// a domain object or a collection of domain objects. Note that there's - /// special support for single step actions: see HibernateTemplate.find etc. - ///

- ///
- /// A result object, or null if none. - object DoInHibernate(ISession session); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using NHibernate; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Callback interface for NHibernate code. + /// + /// To be used with HibernateTemplate execute + /// method. The typical implementation will call + /// Session.load/find/save/update to perform + /// some operations on persistent objects. + /// + /// Mark Pollack (.NET) + public interface IHibernateCallback + { + /// + /// Gets called by HibernateTemplate with an active + /// Hibernate Session. Does not need to care about activating or closing + /// the Session, or handling transactions. + /// + /// + ///

+ /// Allows for returning a result object created within the callback, i.e. + /// a domain object or a collection of domain objects. Note that there's + /// special support for single step actions: see HibernateTemplate.find etc. + ///

+ ///
+ /// A result object, or null if none. + object DoInHibernate(ISession session); + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateOperations.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateOperations.cs index 231ec17d..25ec5fc5 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateOperations.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/IHibernateOperations.cs @@ -1,438 +1,437 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using NHibernate; -using NHibernate.Type; -using Spring.Dao; -using Spring.Data.NHibernate; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Interface that specifies a basic set of Hibernate operations. - /// - /// - /// Implemented by HibernateTemplate. Not often used, but a useful option - /// to enhance testability, as it can easily be mocked or stubbed. - ///

Provides HibernateTemplate's data access methods that mirror - /// various Session methods. See the NHibernate ISession documentation - /// for details on those methods. - ///

- ///
- /// - /// Mark Pollack (.NET) - /// $Id: IHibernateOperations.cs,v 1.2 2007/09/19 22:58:22 markpollack Exp $ - public interface IHibernateOperations : ICommonHibernateOperations - { - - /// - /// Delete all given persistent instances. - /// - /// The persistent instances to delete. - /// - /// This can be combined with any of the find methods to delete by query - /// in two lines of code, similar to Session's delete by query methods. - /// - /// In case of Hibernate errors - void DeleteAll(ICollection entities); - - /// - /// Execute the action specified by the given action object within a Session. - /// - /// - /// Application exceptions thrown by the action object get propagated to the - /// caller (can only be unchecked). Hibernate exceptions are transformed into - /// appropriate DAO ones. Allows for returning a result object, i.e. a domain - /// object or a collection of domain objects. - ///

Note: Callback code is not supposed to handle transactions itself! - /// Use an appropriate transaction manager like HibernateTransactionManager. - /// Generally, callback code must not touch any Session lifecycle methods, - /// like close, disconnect, or reconnect, to let the template do its work. - ///

- ///
- /// The delegate callback object that specifies the Hibernate action. - /// a result object returned by the action, or null - /// - /// In case of Hibernate errors - object Execute(HibernateDelegate del); - - /// - /// Execute the action specified by the given action object within a Session. - /// - /// - /// Application exceptions thrown by the action object get propagated to the - /// caller (can only be unchecked). Hibernate exceptions are transformed into - /// appropriate DAO ones. Allows for returning a result object, i.e. a domain - /// object or a collection of domain objects. - ///

Note: Callback code is not supposed to handle transactions itself! - /// Use an appropriate transaction manager like HibernateTransactionManager. - /// Generally, callback code must not touch any Session lifecycle methods, - /// like close, disconnect, or reconnect, to let the template do its work. - ///

- ///
- /// The callback object that specifies the Hibernate action. - /// a result object returned by the action, or null - /// - /// In case of Hibernate errors - object Execute(IHibernateCallback action); - - - /// - /// Execute the specified action assuming that the result object is a List. - /// - /// - /// This is a convenience method for executing Hibernate find calls or - /// queries within an action. - /// - /// The calback object that specifies the Hibernate action. - /// A IList returned by the action, or null - /// - /// In case of Hibernate errors - IList ExecuteFind(IHibernateCallback action); - - #region Finder Methods - /// - /// Execute a query for persistent instances. - /// - /// a query expressed in Hibernate's query language - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - IList Find(string queryString); - - - /// - /// Execute a query for persistent instances, binding - /// one value to a "?" parameter in the query string. - /// - /// a query expressed in Hibernate's query language - /// the value of the parameter - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - IList Find(string queryString, object value); - - /// - /// Execute a query for persistent instances, binding one value - /// to a "?" parameter of the given type in the query string. - /// - /// a query expressed in Hibernate's query language - /// The value of the parameter. - /// Hibernate type of the parameter (or null) - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - IList Find(string queryString, object value, IType type); - - - /// - /// Execute a query for persistent instances, binding a - /// number of values to "?" parameters in the query string. - /// - /// a query expressed in Hibernate's query language - /// the values of the parameters - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - IList Find(string queryString, object[] values); - - - - /// - /// Execute a query for persistent instances, binding a number of - /// values to "?" parameters of the given types in the query string. - /// - /// A query expressed in Hibernate's query language - /// The values of the parameters - /// Hibernate types of the parameters (or null) - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If values and types are not null and their lengths are not equal - IList Find(string queryString, object[] values, IType[] types); - - - /// - /// Execute a query for persistent instances, binding - /// one value to a named parameter in the query string. - /// - /// The name of a Hibernate query in a mapping file - /// The name of the parameter - /// The value of the parameter - /// a List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedParam(string queryName, string paramName, object value); - - /// - /// Execute a query for persistent instances, binding - /// one value to a named parameter in the query string. - /// - /// The name of a Hibernate query in a mapping file - /// The name of the parameter - /// The value of the parameter - /// Hibernate type of the parameter (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedParam(string queryName, string paramName, object value, IType type); - - /// - /// Execute a query for persistent instances, binding a - /// number of values to named parameters in the query string. - /// - /// A query expressed in Hibernate's query language - /// The names of the parameters - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedParam(string queryString, string[] paramNames, object[] values); - - - /// - /// Execute a query for persistent instances, binding a - /// number of values to named parameters in the query string. - /// - /// A query expressed in Hibernate's query language - /// The names of the parameters - /// The values of the parameters - /// Hibernate types of the parameters (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If paramNames length is not equal to values length or - /// if paramNames length is not equal to types length (when types is not null) - IList FindByNamedParam(string queryString, string[] paramNames, object[] values, IType[] types); - - /// - /// Execute a named query for persistent instances. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQuery(string queryName); - - /// - /// Execute a named query for persistent instances, binding - /// one value to a "?" parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The value of the parameter - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQuery(string queryName, object value); - - /// - /// Execute a named query for persistent instances, binding - /// one value to a "?" parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The value of the parameter - /// Hibernate type of the parameter (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQuery(string queryName, object value, IType type); - - - /// - /// Execute a named query for persistent instances, binding a - /// number of values to "?" parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQuery(string queryName, object[] values); - - - /// - /// Execute a named query for persistent instances, binding a - /// number of values to "?" parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The values of the parameters - /// Hibernate types of the parameters (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If values and types are not null and their lengths differ. - IList FindByNamedQuery(string queryName, object[] values, IType[] types); - - /// - /// Execute a named query for persistent instances, binding - /// one value to a named parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// Name of the parameter - /// The value of the parameter - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value); - - /// - /// Execute a named query for persistent instances, binding - /// one value to a named parameter in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// Name of the parameter - /// The value of the parameter - /// The Hibernate type of the parameter (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value, IType type); - - /// - /// Execute a named query for persistent instances, binding - /// number of values to named parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The names of the parameters - /// The values of the parameters. - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values); - - - /// - /// Execute a named query for persistent instances, binding - /// number of values to named parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The names of the parameters - /// The values of the parameters. - /// Hibernate types of the parameters (or null) - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - /// If paramNames length is not equal to values length or - /// if paramNames length is not equal to types length (when types is not null) - IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values, IType[] types); - - - /// - /// Execute a named query for persistent instances, binding the properties - /// of the given object to named parameters in the query string. - /// A named query is defined in a Hibernate mapping file. - /// - /// The name of a Hibernate query in a mapping file - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByNamedQueryAndValueObject(string queryName, object valueObject); - - /// - /// Execute a query for persistent instances, binding the properties - /// of the given object to named parameters in the query string. - /// - /// A query expressed in Hibernate's query language - /// The values of the parameters - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList FindByValueObject(string queryString, object valueObject); - - #endregion - - #region Convenience methods for loading individual objects - - /// - /// Return the persistent instance of the given entity type - /// with the given identifier, or null if not found. - /// - /// a persistent type. - /// An identifier of the persistent instance. - /// the persistent instance, or null if not found - /// In case of Hibernate errors - object Get(Type entityType, object id); - - /// - /// Return the persistent instance of the given entity type - /// with the given identifier, or null if not found. - /// Obtains the specified lock mode if the instance exists. - /// - /// A persistent class. - /// An identifier of the persistent instance. - /// The lock mode. - /// the persistent instance, or null if not found - /// the persistent instance, or null if not found - /// In case of Hibernate errors - object Get(Type entityType, object id, LockMode lockMode); - - /// - /// Return the persistent instance of the given entity class - /// with the given identifier, throwing an exception if not found. - /// - /// Type of the entity. - /// An identifier of the persistent instance. - /// The persistent instance - /// If not found - /// In case of Hibernate errors - object Load(Type entityType, object id); - - /// - /// Return the persistent instance of the given entity class - /// with the given identifier, throwing an exception if not found. - /// Obtains the specified lock mode if the instance exists. - /// - /// Type of the entity. - /// An identifier of the persistent instance. - /// The lock mode. - /// The persistent instance - /// If not found - /// In case of Hibernate errors - object Load(Type entityType, object id, LockMode lockMode); - - - - /// - /// Return all persistent instances of the given entity class. - /// Note: Use queries or criteria for retrieving a specific subset. - /// - /// Type of the entity. - /// A List containing 0 or more persistent instances - /// In case of Hibernate errors - IList LoadAll(Type entityType); - - - - - - #endregion - - #region Convenience methods for storing individual objects - - /// - /// Save or update all given persistent instances, - /// according to its id (matching the configured "unsaved-value"?). - /// - /// Tthe persistent instances to save or update - /// (to be associated with the Hibernate Session)he entities. - /// In case of Hibernate errors - void SaveOrUpdateAll(ICollection entities); - - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using NHibernate; +using NHibernate.Type; +using Spring.Dao; +using Spring.Data.NHibernate; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Interface that specifies a basic set of Hibernate operations. + /// + /// + /// Implemented by HibernateTemplate. Not often used, but a useful option + /// to enhance testability, as it can easily be mocked or stubbed. + ///

Provides HibernateTemplate's data access methods that mirror + /// various Session methods. See the NHibernate ISession documentation + /// for details on those methods. + ///

+ ///
+ /// + /// Mark Pollack (.NET) + public interface IHibernateOperations : ICommonHibernateOperations + { + + /// + /// Delete all given persistent instances. + /// + /// The persistent instances to delete. + /// + /// This can be combined with any of the find methods to delete by query + /// in two lines of code, similar to Session's delete by query methods. + /// + /// In case of Hibernate errors + void DeleteAll(ICollection entities); + + /// + /// Execute the action specified by the given action object within a Session. + /// + /// + /// Application exceptions thrown by the action object get propagated to the + /// caller (can only be unchecked). Hibernate exceptions are transformed into + /// appropriate DAO ones. Allows for returning a result object, i.e. a domain + /// object or a collection of domain objects. + ///

Note: Callback code is not supposed to handle transactions itself! + /// Use an appropriate transaction manager like HibernateTransactionManager. + /// Generally, callback code must not touch any Session lifecycle methods, + /// like close, disconnect, or reconnect, to let the template do its work. + ///

+ ///
+ /// The delegate callback object that specifies the Hibernate action. + /// a result object returned by the action, or null + /// + /// In case of Hibernate errors + object Execute(HibernateDelegate del); + + /// + /// Execute the action specified by the given action object within a Session. + /// + /// + /// Application exceptions thrown by the action object get propagated to the + /// caller (can only be unchecked). Hibernate exceptions are transformed into + /// appropriate DAO ones. Allows for returning a result object, i.e. a domain + /// object or a collection of domain objects. + ///

Note: Callback code is not supposed to handle transactions itself! + /// Use an appropriate transaction manager like HibernateTransactionManager. + /// Generally, callback code must not touch any Session lifecycle methods, + /// like close, disconnect, or reconnect, to let the template do its work. + ///

+ ///
+ /// The callback object that specifies the Hibernate action. + /// a result object returned by the action, or null + /// + /// In case of Hibernate errors + object Execute(IHibernateCallback action); + + + /// + /// Execute the specified action assuming that the result object is a List. + /// + /// + /// This is a convenience method for executing Hibernate find calls or + /// queries within an action. + /// + /// The calback object that specifies the Hibernate action. + /// A IList returned by the action, or null + /// + /// In case of Hibernate errors + IList ExecuteFind(IHibernateCallback action); + + #region Finder Methods + /// + /// Execute a query for persistent instances. + /// + /// a query expressed in Hibernate's query language + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + IList Find(string queryString); + + + /// + /// Execute a query for persistent instances, binding + /// one value to a "?" parameter in the query string. + /// + /// a query expressed in Hibernate's query language + /// the value of the parameter + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + IList Find(string queryString, object value); + + /// + /// Execute a query for persistent instances, binding one value + /// to a "?" parameter of the given type in the query string. + /// + /// a query expressed in Hibernate's query language + /// The value of the parameter. + /// Hibernate type of the parameter (or null) + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + IList Find(string queryString, object value, IType type); + + + /// + /// Execute a query for persistent instances, binding a + /// number of values to "?" parameters in the query string. + /// + /// a query expressed in Hibernate's query language + /// the values of the parameters + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + IList Find(string queryString, object[] values); + + + + /// + /// Execute a query for persistent instances, binding a number of + /// values to "?" parameters of the given types in the query string. + /// + /// A query expressed in Hibernate's query language + /// The values of the parameters + /// Hibernate types of the parameters (or null) + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If values and types are not null and their lengths are not equal + IList Find(string queryString, object[] values, IType[] types); + + + /// + /// Execute a query for persistent instances, binding + /// one value to a named parameter in the query string. + /// + /// The name of a Hibernate query in a mapping file + /// The name of the parameter + /// The value of the parameter + /// a List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedParam(string queryName, string paramName, object value); + + /// + /// Execute a query for persistent instances, binding + /// one value to a named parameter in the query string. + /// + /// The name of a Hibernate query in a mapping file + /// The name of the parameter + /// The value of the parameter + /// Hibernate type of the parameter (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedParam(string queryName, string paramName, object value, IType type); + + /// + /// Execute a query for persistent instances, binding a + /// number of values to named parameters in the query string. + /// + /// A query expressed in Hibernate's query language + /// The names of the parameters + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedParam(string queryString, string[] paramNames, object[] values); + + + /// + /// Execute a query for persistent instances, binding a + /// number of values to named parameters in the query string. + /// + /// A query expressed in Hibernate's query language + /// The names of the parameters + /// The values of the parameters + /// Hibernate types of the parameters (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If paramNames length is not equal to values length or + /// if paramNames length is not equal to types length (when types is not null) + IList FindByNamedParam(string queryString, string[] paramNames, object[] values, IType[] types); + + /// + /// Execute a named query for persistent instances. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQuery(string queryName); + + /// + /// Execute a named query for persistent instances, binding + /// one value to a "?" parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The value of the parameter + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQuery(string queryName, object value); + + /// + /// Execute a named query for persistent instances, binding + /// one value to a "?" parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The value of the parameter + /// Hibernate type of the parameter (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQuery(string queryName, object value, IType type); + + + /// + /// Execute a named query for persistent instances, binding a + /// number of values to "?" parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQuery(string queryName, object[] values); + + + /// + /// Execute a named query for persistent instances, binding a + /// number of values to "?" parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The values of the parameters + /// Hibernate types of the parameters (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If values and types are not null and their lengths differ. + IList FindByNamedQuery(string queryName, object[] values, IType[] types); + + /// + /// Execute a named query for persistent instances, binding + /// one value to a named parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// Name of the parameter + /// The value of the parameter + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value); + + /// + /// Execute a named query for persistent instances, binding + /// one value to a named parameter in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// Name of the parameter + /// The value of the parameter + /// The Hibernate type of the parameter (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQueryAndNamedParam(string queryName, string paramName, object value, IType type); + + /// + /// Execute a named query for persistent instances, binding + /// number of values to named parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The names of the parameters + /// The values of the parameters. + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values); + + + /// + /// Execute a named query for persistent instances, binding + /// number of values to named parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The names of the parameters + /// The values of the parameters. + /// Hibernate types of the parameters (or null) + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + /// If paramNames length is not equal to values length or + /// if paramNames length is not equal to types length (when types is not null) + IList FindByNamedQueryAndNamedParam(string queryName, string[] paramNames, object[] values, IType[] types); + + + /// + /// Execute a named query for persistent instances, binding the properties + /// of the given object to named parameters in the query string. + /// A named query is defined in a Hibernate mapping file. + /// + /// The name of a Hibernate query in a mapping file + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByNamedQueryAndValueObject(string queryName, object valueObject); + + /// + /// Execute a query for persistent instances, binding the properties + /// of the given object to named parameters in the query string. + /// + /// A query expressed in Hibernate's query language + /// The values of the parameters + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList FindByValueObject(string queryString, object valueObject); + + #endregion + + #region Convenience methods for loading individual objects + + /// + /// Return the persistent instance of the given entity type + /// with the given identifier, or null if not found. + /// + /// a persistent type. + /// An identifier of the persistent instance. + /// the persistent instance, or null if not found + /// In case of Hibernate errors + object Get(Type entityType, object id); + + /// + /// Return the persistent instance of the given entity type + /// with the given identifier, or null if not found. + /// Obtains the specified lock mode if the instance exists. + /// + /// A persistent class. + /// An identifier of the persistent instance. + /// The lock mode. + /// the persistent instance, or null if not found + /// the persistent instance, or null if not found + /// In case of Hibernate errors + object Get(Type entityType, object id, LockMode lockMode); + + /// + /// Return the persistent instance of the given entity class + /// with the given identifier, throwing an exception if not found. + /// + /// Type of the entity. + /// An identifier of the persistent instance. + /// The persistent instance + /// If not found + /// In case of Hibernate errors + object Load(Type entityType, object id); + + /// + /// Return the persistent instance of the given entity class + /// with the given identifier, throwing an exception if not found. + /// Obtains the specified lock mode if the instance exists. + /// + /// Type of the entity. + /// An identifier of the persistent instance. + /// The lock mode. + /// The persistent instance + /// If not found + /// In case of Hibernate errors + object Load(Type entityType, object id, LockMode lockMode); + + + + /// + /// Return all persistent instances of the given entity class. + /// Note: Use queries or criteria for retrieving a specific subset. + /// + /// Type of the entity. + /// A List containing 0 or more persistent instances + /// In case of Hibernate errors + IList LoadAll(Type entityType); + + + + + + #endregion + + #region Convenience methods for storing individual objects + + /// + /// Save or update all given persistent instances, + /// according to its id (matching the configured "unsaved-value"?). + /// + /// Tthe persistent instances to save or update + /// (to be associated with the Hibernate Session)he entities. + /// In case of Hibernate errors + void SaveOrUpdateAll(ICollection entities); + + + #endregion + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/LocalSessionFactoryObject.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/LocalSessionFactoryObject.cs index 78c62118..a9d3cad8 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/LocalSessionFactoryObject.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/LocalSessionFactoryObject.cs @@ -1,391 +1,390 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Data; -using Common.Logging; -using NHibernate; -using NHibernate.Cfg; -using NHibernate.Connection; -using Spring.Core.IO; -using Spring.Data.Common; -using Spring.Objects.Factory; -using Environment = NHibernate.Cfg.Environment; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// An IFactoryObject that creates a local Hibernate SessionFactory instance. - /// Behaves like a SessionFactory instance when used as bean reference, - /// e.g. for HibernateTemplate's "SessionFactory" property. - /// - /// - /// The typical usage will be to register this as singleton factory - /// in an application context and give objects references to application services - /// that need it. - /// - /// Hibernate configuration settings can be set using the IDictionary property 'HibernateProperties'. - /// - /// - /// - /// Mark Pollack (.NET) - /// $Id: LocalSessionFactoryObject.cs,v 1.7 2008/03/21 14:12:16 markpollack Exp $ - public class LocalSessionFactoryObject : IFactoryObject, IInitializingObject, System.IDisposable - { - #region Fields - - private Configuration configuration; - - private ISessionFactory sessionFactory; - - private string[] mappingAssemblies; - - private string[] mappingResources; - - private string[] configFilenames; - - /// - /// TODO: consider changing to NamevalueCollection for easier - /// cut-n-paste from existing App.config based configurations. - /// - private IDictionary hibernateProperties; - - private IDbProvider dbProvider; - - #endregion - - #region Constants - - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (LocalSessionFactoryObject)); - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public LocalSessionFactoryObject() - { - - } - - #endregion - - #region Properties - - /// - /// Sets the assemblies to load that contain mapping files. - /// - /// The mapping assemblies. - public string[] MappingAssemblies - { - set { mappingAssemblies = value; } - } - - /// - /// Sets the hibernate configuration files to load, i.e. hibernate.cfg.xml. - /// - public string[] ConfigFilenames - { - set { configFilenames = value; } - } - - /// - /// Sets the locations of Spring IResources that contain mapping - /// files. - /// - /// The location of mapping resources. - public string[] MappingResources - { - set { mappingResources = value;} - } - - /// - /// Return the Configuration object used to build the SessionFactory. - /// Allows access to configuration metadata stored there (rarely needed). - /// - /// The hibernate configuration. - public Configuration Configuration - { - get { return configuration; } - } - - /// - /// Set NHibernate configuration properties, like "hibernate.dialect". - /// - /// The hibernate properties. - /// - ///

Can be used to override values in a NHibernate XML config file, - /// or to specify all necessary properties locally. - ///

- ///

Note: Do not specify a transaction provider here when using - /// Spring-driven transactions. It is also advisable to omit connection - /// provider settings and use a Spring-set IDbProvider instead. - ///

- ///
- public IDictionary HibernateProperties - { - get - { - if (hibernateProperties == null) - { - hibernateProperties = new Hashtable(); - } - return hibernateProperties; - } - set - { - hibernateProperties = value; - } - } - - /// - /// Get or set the DataSource to be used by the SessionFactory. - /// - /// The db provider. - /// - /// If set, this will override corresponding settings in Hibernate properties. - /// Note: If this is set, the Hibernate settings should not define - /// a connection string - /// (hibernate.connection.connection_string) to avoid meaningless double configuration. - /// - /// - public IDbProvider DbProvider - { - set { dbProvider = value; } - get { return dbProvider; } - } - - - #endregion - - #region Methods - - #endregion - - /// - /// Return the singleon session factory. - /// - public object GetObject() - { - return sessionFactory; - } - - /// - /// Return the type or subclass. - /// - /// The type created by this factory - public System.Type ObjectType - { - get - { - return (sessionFactory != null) ? sessionFactory.GetType() : typeof(ISessionFactory); - } - } - - /// - /// Returns true - /// - /// true - public bool IsSingleton - { - get - { - return true; - } - } - - /// - /// Initialize the SessionFactory for the given or the - /// default location. - /// - public void AfterPropertiesSet() - { - // Create Configuration instance. - Configuration config = NewConfiguration(); - - - if (this.dbProvider != null) - { - config.SetProperty(Environment.ConnectionString, dbProvider.ConnectionString); - config.SetProperty(Environment.ConnectionProvider, typeof(DbProviderWrapper).AssemblyQualifiedName); - } - - if (this.hibernateProperties != null) - { - if (config.GetProperty(Environment.ConnectionProvider) != null && - hibernateProperties.Contains(Environment.ConnectionProvider)) - { - #region Logging - if (log.IsWarnEnabled) - { - log.Warn("Overriding use of Spring's Hibernate Connection Provider with [" + - hibernateProperties[Environment.ConnectionProvider] + "]"); - } - #endregion - config.Properties.Remove(Environment.ConnectionProvider); - } - config.AddProperties(hibernateProperties); - } - if (this.mappingAssemblies != null) - { - foreach (string assemblyName in mappingAssemblies) - { - config.AddAssembly(assemblyName); - } - } - - IResourceLoader resourceLoader = new ConfigurableResourceLoader(); - - if (this.mappingResources != null) - { - foreach (string resourceName in mappingResources) - { - config.AddInputStream(resourceLoader.GetResource(resourceName).InputStream); - } - } - - if (configFilenames != null) - { - foreach (string configFilename in configFilenames) - { - config.Configure(configFilename); - } - } - - // Perform custom post-processing in subclasses. - PostProcessConfiguration(config); - - // Build SessionFactory instance. - log.Info("Building new Hibernate SessionFactory"); - this.configuration = config; - this.sessionFactory = NewSessionFactory(config); - - - } - - /// - /// Close the SessionFactory on application context shutdown. - /// - public void Dispose() - { - if (sessionFactory != null) - { - #region Instrumentation - if (log.IsInfoEnabled) - { - log.Info("Closing Hibernate SessionFactory"); - } - #endregion - sessionFactory.Close(); - } - } - - /// - /// Subclasses can override this method to perform custom initialization - /// of the Configuration instance used for ISessionFactory creation. - /// - /// - /// The properties of this LocalSessionFactoryObject will be applied to - /// the Configuration object that gets returned here. - ///

The default implementation creates a new Configuration instance. - /// A custom implementation could prepare the instance in a specific way, - /// or use a custom Configuration subclass. - ///

- ///
- protected virtual Configuration NewConfiguration() - { - return new Configuration(); - } - - /// - /// To be implemented by subclasses that want to to perform custom - /// post-processing of the Configuration object after this FactoryObject - /// performed its default initialization. - /// - /// The current configuration object. - protected virtual void PostProcessConfiguration(Configuration config) - { - } - - /// - /// Subclasses can override this method to perform custom initialization - /// of the SessionFactory instance, creating it via the given Configuration - /// object that got prepared by this LocalSessionFactoryObject. - /// - /// - ///

The default implementation invokes Configuration's BuildSessionFactory. - /// A custom implementation could prepare the instance in a specific way, - /// or use a custom ISessionFactory subclass. - ///

- ///
- protected virtual ISessionFactory NewSessionFactory(Configuration config) - { - ISessionFactory sf = config.BuildSessionFactory(); - DbProviderWrapper dbProviderWrapper = sf.ConnectionProvider as DbProviderWrapper; - if (dbProviderWrapper != null) - { - dbProviderWrapper.DbProvider = dbProvider; - } - return sf; - } - - #region DbProviderWrapper Helper class - - internal class DbProviderWrapper : ConnectionProvider - { - private IDbProvider _dbProvider; - - public DbProviderWrapper() - { - } - - public IDbProvider DbProvider - { - get { return _dbProvider; } - set { _dbProvider = value; } - } - - public override void CloseConnection(IDbConnection conn) - { - base.CloseConnection(conn); - conn.Dispose(); - } - - public override IDbConnection GetConnection() - { - IDbConnection dbCon = _dbProvider.CreateConnection(); - dbCon.Open(); - return dbCon; - } - } - - #endregion // DbProviderWrapper Helper class - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Data; +using Common.Logging; +using NHibernate; +using NHibernate.Cfg; +using NHibernate.Connection; +using Spring.Core.IO; +using Spring.Data.Common; +using Spring.Objects.Factory; +using Environment = NHibernate.Cfg.Environment; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// An IFactoryObject that creates a local Hibernate SessionFactory instance. + /// Behaves like a SessionFactory instance when used as bean reference, + /// e.g. for HibernateTemplate's "SessionFactory" property. + /// + /// + /// The typical usage will be to register this as singleton factory + /// in an application context and give objects references to application services + /// that need it. + /// + /// Hibernate configuration settings can be set using the IDictionary property 'HibernateProperties'. + /// + /// + /// + /// Mark Pollack (.NET) + public class LocalSessionFactoryObject : IFactoryObject, IInitializingObject, System.IDisposable + { + #region Fields + + private Configuration configuration; + + private ISessionFactory sessionFactory; + + private string[] mappingAssemblies; + + private string[] mappingResources; + + private string[] configFilenames; + + /// + /// TODO: consider changing to NamevalueCollection for easier + /// cut-n-paste from existing App.config based configurations. + /// + private IDictionary hibernateProperties; + + private IDbProvider dbProvider; + + #endregion + + #region Constants + + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (LocalSessionFactoryObject)); + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public LocalSessionFactoryObject() + { + + } + + #endregion + + #region Properties + + /// + /// Sets the assemblies to load that contain mapping files. + /// + /// The mapping assemblies. + public string[] MappingAssemblies + { + set { mappingAssemblies = value; } + } + + /// + /// Sets the hibernate configuration files to load, i.e. hibernate.cfg.xml. + /// + public string[] ConfigFilenames + { + set { configFilenames = value; } + } + + /// + /// Sets the locations of Spring IResources that contain mapping + /// files. + /// + /// The location of mapping resources. + public string[] MappingResources + { + set { mappingResources = value;} + } + + /// + /// Return the Configuration object used to build the SessionFactory. + /// Allows access to configuration metadata stored there (rarely needed). + /// + /// The hibernate configuration. + public Configuration Configuration + { + get { return configuration; } + } + + /// + /// Set NHibernate configuration properties, like "hibernate.dialect". + /// + /// The hibernate properties. + /// + ///

Can be used to override values in a NHibernate XML config file, + /// or to specify all necessary properties locally. + ///

+ ///

Note: Do not specify a transaction provider here when using + /// Spring-driven transactions. It is also advisable to omit connection + /// provider settings and use a Spring-set IDbProvider instead. + ///

+ ///
+ public IDictionary HibernateProperties + { + get + { + if (hibernateProperties == null) + { + hibernateProperties = new Hashtable(); + } + return hibernateProperties; + } + set + { + hibernateProperties = value; + } + } + + /// + /// Get or set the DataSource to be used by the SessionFactory. + /// + /// The db provider. + /// + /// If set, this will override corresponding settings in Hibernate properties. + /// Note: If this is set, the Hibernate settings should not define + /// a connection string + /// (hibernate.connection.connection_string) to avoid meaningless double configuration. + /// + /// + public IDbProvider DbProvider + { + set { dbProvider = value; } + get { return dbProvider; } + } + + + #endregion + + #region Methods + + #endregion + + /// + /// Return the singleon session factory. + /// + public object GetObject() + { + return sessionFactory; + } + + /// + /// Return the type or subclass. + /// + /// The type created by this factory + public System.Type ObjectType + { + get + { + return (sessionFactory != null) ? sessionFactory.GetType() : typeof(ISessionFactory); + } + } + + /// + /// Returns true + /// + /// true + public bool IsSingleton + { + get + { + return true; + } + } + + /// + /// Initialize the SessionFactory for the given or the + /// default location. + /// + public void AfterPropertiesSet() + { + // Create Configuration instance. + Configuration config = NewConfiguration(); + + + if (this.dbProvider != null) + { + config.SetProperty(Environment.ConnectionString, dbProvider.ConnectionString); + config.SetProperty(Environment.ConnectionProvider, typeof(DbProviderWrapper).AssemblyQualifiedName); + } + + if (this.hibernateProperties != null) + { + if (config.GetProperty(Environment.ConnectionProvider) != null && + hibernateProperties.Contains(Environment.ConnectionProvider)) + { + #region Logging + if (log.IsWarnEnabled) + { + log.Warn("Overriding use of Spring's Hibernate Connection Provider with [" + + hibernateProperties[Environment.ConnectionProvider] + "]"); + } + #endregion + config.Properties.Remove(Environment.ConnectionProvider); + } + config.AddProperties(hibernateProperties); + } + if (this.mappingAssemblies != null) + { + foreach (string assemblyName in mappingAssemblies) + { + config.AddAssembly(assemblyName); + } + } + + IResourceLoader resourceLoader = new ConfigurableResourceLoader(); + + if (this.mappingResources != null) + { + foreach (string resourceName in mappingResources) + { + config.AddInputStream(resourceLoader.GetResource(resourceName).InputStream); + } + } + + if (configFilenames != null) + { + foreach (string configFilename in configFilenames) + { + config.Configure(configFilename); + } + } + + // Perform custom post-processing in subclasses. + PostProcessConfiguration(config); + + // Build SessionFactory instance. + log.Info("Building new Hibernate SessionFactory"); + this.configuration = config; + this.sessionFactory = NewSessionFactory(config); + + + } + + /// + /// Close the SessionFactory on application context shutdown. + /// + public void Dispose() + { + if (sessionFactory != null) + { + #region Instrumentation + if (log.IsInfoEnabled) + { + log.Info("Closing Hibernate SessionFactory"); + } + #endregion + sessionFactory.Close(); + } + } + + /// + /// Subclasses can override this method to perform custom initialization + /// of the Configuration instance used for ISessionFactory creation. + /// + /// + /// The properties of this LocalSessionFactoryObject will be applied to + /// the Configuration object that gets returned here. + ///

The default implementation creates a new Configuration instance. + /// A custom implementation could prepare the instance in a specific way, + /// or use a custom Configuration subclass. + ///

+ ///
+ protected virtual Configuration NewConfiguration() + { + return new Configuration(); + } + + /// + /// To be implemented by subclasses that want to to perform custom + /// post-processing of the Configuration object after this FactoryObject + /// performed its default initialization. + /// + /// The current configuration object. + protected virtual void PostProcessConfiguration(Configuration config) + { + } + + /// + /// Subclasses can override this method to perform custom initialization + /// of the SessionFactory instance, creating it via the given Configuration + /// object that got prepared by this LocalSessionFactoryObject. + /// + /// + ///

The default implementation invokes Configuration's BuildSessionFactory. + /// A custom implementation could prepare the instance in a specific way, + /// or use a custom ISessionFactory subclass. + ///

+ ///
+ protected virtual ISessionFactory NewSessionFactory(Configuration config) + { + ISessionFactory sf = config.BuildSessionFactory(); + DbProviderWrapper dbProviderWrapper = sf.ConnectionProvider as DbProviderWrapper; + if (dbProviderWrapper != null) + { + dbProviderWrapper.DbProvider = dbProvider; + } + return sf; + } + + #region DbProviderWrapper Helper class + + internal class DbProviderWrapper : ConnectionProvider + { + private IDbProvider _dbProvider; + + public DbProviderWrapper() + { + } + + public IDbProvider DbProvider + { + get { return _dbProvider; } + set { _dbProvider = value; } + } + + public override void CloseConnection(IDbConnection conn) + { + base.CloseConnection(conn); + conn.Dispose(); + } + + public override IDbConnection GetConnection() + { + IDbConnection dbCon = _dbProvider.CreateConnection(); + dbCon.Open(); + return dbCon; + } + } + + #endregion // DbProviderWrapper Helper class + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionFactoryUtils.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionFactoryUtils.cs index 343347a4..63f1a242 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionFactoryUtils.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionFactoryUtils.cs @@ -1,713 +1,712 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Common.Logging; -using NHibernate; -using NHibernate.Connection; -using NHibernate.Driver; -using NHibernate.Engine; -using Spring.Collections; -using Spring.Context; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Data.Support; -using Spring.Objects.Factory.Config; -using Spring.Threading; -using Spring.Transaction.Support; -using Spring.Util; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Helper class featuring methods for Hibernate Session handling, - /// allowing for reuse of Hibernate Session instances within transactions. - /// Also provides support for exception translation. - /// - /// Mark Pollack (.NET) - /// $Id: SessionFactoryUtils.cs,v 1.5 2008/04/08 20:26:37 markpollack Exp $ - public abstract class SessionFactoryUtils - { - #region Fields - - /// - /// The instance for this class. - /// - private static readonly ILog log = LogManager.GetLogger(typeof(SessionFactoryUtils)); - - #endregion - - #region Constants - - /// - /// The ordering value for synchronizaiton this session resources. - /// Set to be lower than ADO.NET synchronization. - /// - public static readonly int SESSION_SYNCHRONIZATION_ORDER = - AdoUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100; - - private static readonly string DeferredCloseHolderDataSlotName = "Spring.Data.NHibernate:deferredCloseHolder"; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public SessionFactoryUtils() - { - - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - /// - /// Get a new Hibernate Session from the given SessionFactory. - /// Will return a new Session even if there already is a pre-bound - /// Session for the given SessionFactory. - /// - /// - /// Within a transaction, this method will create a new Session - /// that shares the transaction's ADO.NET Connection. More specifically, - /// it will use the same ADO.NET Connection as the pre-bound Hibernate Session. - /// - /// The session factory to create the session with. - /// The Hibernate entity interceptor, or null if none. - /// The new session. - /// If could not open Hibernate session - public static ISession GetNewSession(ISessionFactory sessionFactory, IInterceptor interceptor) - { - try - { - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); - if (sessionHolder != null && !sessionHolder.IsEmpty) - { - if (interceptor != null) - { - return sessionFactory.OpenSession(sessionHolder.AnySession.Connection, interceptor); - } - else - { - return sessionFactory.OpenSession(sessionHolder.AnySession.Connection); - } - } - else - { - if (interceptor != null) - { - return sessionFactory.OpenSession(interceptor); - } - else - { - return sessionFactory.OpenSession(); - } - } - } - catch (HibernateException ex) - { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - /// - /// Get a Hibernate Session for the given SessionFactory. Is aware of and will - /// return any existing corresponding Session bound to the current thread, for - /// example when using HibernateTransactionManager. Will always create a new - /// Session otherwise. - /// - /// - /// Supports setting a Session-level Hibernate entity interceptor that allows - /// to inspect and change property values before writing to and reading from the - /// database. Such an interceptor can also be set at the SessionFactory level - /// (i.e. on LocalSessionFactoryObject), on HibernateTransactionManager, or on - /// HibernateInterceptor/HibernateTemplate. - /// - /// The session factory to create the - /// session with. - /// Hibernate entity interceptor, or null if none. - /// AdoExceptionTranslator to use for flushing the - /// Session on transaction synchronization (can be null; only used when actually - /// registering a transaction synchronization). - /// The Hibernate Session - /// - /// If the session couldn't be created. - /// - /// - /// If no thread-bound Session found and allowCreate is false. - /// - public static ISession GetSession( - ISessionFactory sessionFactory, IInterceptor entityInterceptor, - IAdoExceptionTranslator adoExceptionTranslator) - { - try - { - return GetSession(sessionFactory, entityInterceptor, adoExceptionTranslator, true); - } - catch (HibernateException ex) - { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - /// - /// Get a Hibernate Session for the given SessionFactory. Is aware of and will - /// return any existing corresponding Session bound to the current thread, for - /// example when using . Will create a new Session - /// otherwise, if allowCreate is true. - /// - /// The session factory to create the session with. - /// if set to true create a non-transactional Session when no - /// transactional Session can be found for the current thread. - /// The hibernate session - /// - /// If the session couldn't be created. - /// - /// - /// If no thread-bound Session found and allowCreate is false. - /// - public static ISession GetSession(ISessionFactory sessionFactory, bool allowCreate) - { - try - { - return GetSession(sessionFactory, null, null, allowCreate); - } - catch (HibernateException ex) - { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - /// - /// Get a Hibernate Session for the given SessionFactory. - /// - /// Is aware of and will return any existing corresponding - /// Session bound to the current thread, for example whenusing - /// . Will create a new - /// Session otherwise, if "allowCreate" is true. - ///

Throws the orginal HibernateException, in contrast to - /// . - ///

- /// The session factory. - /// if set to true [allow create]. - /// The Hibernate Session - /// - /// if the Session couldn't be created - /// - /// - /// If no thread-bound Session found and allowCreate is false. - /// - public static ISession DoGetSession(ISessionFactory sessionFactory, bool allowCreate) - { - return DoGetSession(sessionFactory, null, null, allowCreate); - } - - private static ISession GetSession( - ISessionFactory sessionFactory, IInterceptor entityInterceptor, - IAdoExceptionTranslator adoExceptionTranslator, bool allowCreate) - { - try - { - return DoGetSession(sessionFactory, entityInterceptor, adoExceptionTranslator, allowCreate); - } - catch (HibernateException ex) - { - throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); - } - } - - - private static ISession DoGetSession( - ISessionFactory sessionFactory, IInterceptor entityInterceptor, - IAdoExceptionTranslator adoExceptionTranslator, bool allowCreate) - { - AssertUtils.ArgumentNotNull(sessionFactory, "sessionFactory", "SessionFactory can not be null"); - - SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); - if (sessionHolder != null && !sessionHolder.IsEmpty) - { - // pre-bound Hibernate Session - ISession session = null; - if (TransactionSynchronizationManager.SynchronizationActive && - sessionHolder.DoesNotHoldNonDefaultSession) - { - // Spring transaction management is active -> - // register pre-bound Session with it for transactional flushing. - session = sessionHolder.ValidatedSession; - if (!sessionHolder.SynchronizedWithTransaction) - { - log.Debug("Registering Spring transaction synchronization for existing Hibernate Session"); - TransactionSynchronizationManager.RegisterSynchronization( - new SpringSessionSynchronization(sessionHolder, sessionFactory, adoExceptionTranslator, false)); - sessionHolder.SynchronizedWithTransaction = true; - // Switch to FlushMode.AUTO if we're not within a read-only transaction. - FlushMode flushMode = session.FlushMode; - if (FlushMode.Never == flushMode && - !TransactionSynchronizationManager.CurrentTransactionReadOnly) - { - session.FlushMode = FlushMode.Auto; - sessionHolder.PreviousFlushMode = flushMode; - } - } - } - else - { - // No Spring transaction management active -> simply return default thread-bound Session, if any - // (possibly from OpenSessionInViewModule) - session = sessionHolder.ValidatedSession; - } - - if (session != null) - { - return session; - } - - } - - - ISession sess = OpenSession(sessionFactory, entityInterceptor); - // Set Session to FlushMode.Never if we're within a read-only transaction. - // Use same Session for further Hibernate actions within the transaction. - // Thread object will get removed by synchronization at transaction completion. - if (TransactionSynchronizationManager.SynchronizationActive) - { - log.Debug("Registering Spring transaction synchronization for new Hibernate Session"); - SessionHolder holderToUse = sessionHolder; - if (holderToUse == null) - { - holderToUse = new SessionHolder(sess); - } - else - { - holderToUse.AddSession(sess); - } - if (TransactionSynchronizationManager.CurrentTransactionReadOnly) - { - sess.FlushMode = FlushMode.Never; - } - TransactionSynchronizationManager.RegisterSynchronization( - new SpringSessionSynchronization(holderToUse, sessionFactory, adoExceptionTranslator, true)); - holderToUse.SynchronizedWithTransaction = true; - if (holderToUse != sessionHolder) - { - TransactionSynchronizationManager.BindResource(sessionFactory, holderToUse); - } - } - - - - // Check whether we are allowed to return the Session. - if (!allowCreate && !IsSessionTransactional(sess, sessionFactory)) - { - CloseSession(sess); - throw new InvalidOperationException ("No Hibernate Session bound to thread, " + - "and configuration does not allow creation of non-transactional one here"); - } - - return sess; - - - } - - /// - /// Open a new Session from the factory. - /// - /// The session factory to create the session with. - /// Hibernate entity interceptor, or null if none. - /// the newly opened session - internal static ISession OpenSession(ISessionFactory sessionFactory, IInterceptor entityInterceptor) - { - log.Debug("Opening Hibernate Session"); - ISession session = ( - (entityInterceptor != null) - ? sessionFactory.OpenSession(entityInterceptor) - : sessionFactory.OpenSession() - ); - - return session; - } - - /// - /// Perform the actual closing of the Hibernate Session - /// catching and logging any cleanup exceptions thrown. - /// - /// The hibernate session to close - public static void CloseSession(ISession session) - { - if (session != null) - { - log.Debug("Closing Hibernate Session"); - try - { - session.Close(); - } - catch (HibernateException ex) - { - log.Error("Could not close Hibernate Session", ex); - } - catch (Exception ex) - { - log.Error("Unexpected exception on closing Hibernate Session", ex); - } - } - } - - /// - /// Return whether the given Hibernate Session is transactional, that is, - /// bound to the current thread by Spring's transaction facilities. - /// - /// The hibernate session to check - /// The session factory that the session - /// was created with, can be null. - /// - /// true if the session transactional; otherwise, false. - /// - public static bool IsSessionTransactional(ISession session, ISessionFactory sessionFactory) - { - if (sessionFactory == null) - { - return false; - } - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); - return (sessionHolder != null && sessionHolder.ContainsSession(session)); - } - - #endregion - - /// - /// Convert the given HibernateException to an appropriate exception from the - /// Spring.Dao hierarchy. Note that it is advisable to - /// handle AdoException specifically by using a AdoExceptionTranslator for the - /// underlying ADO.NET exception. - /// - /// The Hibernate exception that occured. - /// DataAccessException instance - public static DataAccessException ConvertHibernateAccessException(HibernateException ex) - { - if (ex is ADOException) - { - // ADOException during Hibernate access: only passed in here from custom code, - // as HibernateTemplate etc will use AdoExceptionTranslator-based handling. - return new HibernateAdoException("Ado Exception", (ADOException) ex); - } - if (ex is UnresolvableObjectException) - { - return new HibernateObjectRetrievalFailureException((UnresolvableObjectException) ex); - } - if (ex is ObjectDeletedException) - { - return new InvalidDataAccessApiUsageException(ex.Message, ex); - } - if (ex is WrongClassException) - { - return new HibernateObjectRetrievalFailureException((WrongClassException) ex); - } - if (ex is StaleObjectStateException) - { - return new HibernateOptimisticLockingFailureException((StaleObjectStateException) ex); - } - if (ex is QueryException) - { - return new HibernateQueryException((QueryException) ex); - } - if (ex is PersistentObjectException) - { - return new InvalidDataAccessApiUsageException(ex.Message, ex); - } - if (ex is TransientObjectException) - { - return new InvalidDataAccessApiUsageException(ex.Message, ex); - } - - if (ex is PropertyValueException) - { - return new DataIntegrityViolationException(ex.Message, ex); - } - if (ex is PersistentObjectException) - { - return new InvalidDataAccessApiUsageException(ex.Message, ex); - } - if (ex is NonUniqueResultException) - { - return new IncorrectResultSizeDataAccessException(ex.Message, 1); - } - // fallback - return new HibernateSystemException(ex); - } - - /// - /// Close the given Session, created via the given factory, - /// if it is not managed externally (i.e. not bound to the thread). - /// - /// The hibernate session to close - /// The hibernate SessionFactory that - /// the session was created with. - public static void ReleaseSession(ISession session, ISessionFactory sessionFactory) - { - if (session == null) - { - return; - } - // Only close non-transactional Sessions. - if (!IsSessionTransactional(session, sessionFactory)) - { - CloseSessionOrRegisterDeferredClose(session, sessionFactory); - } - } - - /// - /// Close the given Session or register it for deferred close. - /// - /// The session. - /// The session factory. - internal static void CloseSessionOrRegisterDeferredClose(ISession session, ISessionFactory sessionFactory) - { - IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; - - if (holderDictionary != null && sessionFactory != null && holderDictionary.Contains(sessionFactory)) - { - log.Debug("Registering Hibernate Session for deferred close"); - // Switch Session to FlushMode.NEVER for remaining lifetime. - session.FlushMode = FlushMode.Never; - Set sessions = (Set) holderDictionary[sessionFactory]; - sessions.Add(session); - } - else - { - CloseSession(session); - } - } - - /// - ///Initialize deferred close for the current thread and the given SessionFactory. - /// Sessions will not be actually closed on close calls then, but rather at a - /// processDeferredClose call at a finishing point (like request completion). - /// - /// The session factory. - public static void InitDeferredClose(ISessionFactory sessionFactory) - { - AssertUtils.ArgumentNotNull(sessionFactory, "No SessionFactory specified"); - - log.Debug("Initializing deferred close of Hibernate Sessions"); - - IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; - - if (holderDictionary == null) - { - holderDictionary = new Hashtable(); - LogicalThreadContext.SetData(DeferredCloseHolderDataSlotName, holderDictionary); - } - holderDictionary.Add(sessionFactory, new ListSet()); - } - - /// - /// Return if deferred close is active for the current thread - /// and the given SessionFactory. - /// The session factory. - /// - /// true if [is deferred close active] [the specified session factory]; otherwise, false. - /// - /// If SessionFactory argument is null. - public static bool IsDeferredCloseActive(ISessionFactory sessionFactory) - { - if (sessionFactory == null) - { - throw new ArgumentNullException("sessionFactory", "No SessionFactory specified"); - } - IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; - return (holderDictionary != null && holderDictionary.Contains(sessionFactory)); - } - - /// - /// Process Sessions that have been registered for deferred close - /// for the given SessionFactory. - /// - /// The session factory. - /// If there is no session factory associated with the thread. - public static void ProcessDeferredClose(ISessionFactory sessionFactory) - { - AssertUtils.ArgumentNotNull(sessionFactory, "No SessionFactory specified"); - - IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; - - if (holderDictionary == null || !holderDictionary.Contains(sessionFactory)) - { - throw new InvalidOperationException("Deferred close not active for SessionFactory [" + sessionFactory + "]"); - } - log.Debug("Processing deferred close of Hibernate Sessions"); - Set sessions = (Set) holderDictionary[sessionFactory]; - holderDictionary.Remove(sessionFactory); - foreach (ISession session in sessions) - { - CloseSession(session); - } - - if (holderDictionary.Count == 0) - { - LogicalThreadContext.FreeNamedDataSlot(DeferredCloseHolderDataSlotName); - } - - - } - - /// - /// Applies the current transaction timeout, if any, to the given - /// criteria object - /// - /// The Hibernate Criteria object. - /// Hibernate SessionFactory that the Criteria was created for - /// (can be null). - /// If criteria argument is null. - public static void ApplyTransactionTimeout(ICriteria criteria, ISessionFactory sessionFactory) - { - if (criteria == null) - { - throw new ArgumentNullException("criteria", "No Criteria object specified"); - } - - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); - if (sessionHolder != null && sessionHolder.HasTimeout) - { - criteria.SetTimeout(sessionHolder.TimeToLiveInSeconds); - } - } - - /// - /// Applies the current transaction timeout, if any, to the given - /// Hibenrate query object. - /// - /// The Hibernate Query object. - /// Hibernate SessionFactory that the Query was created for - /// (can be null). - /// If query argument is null. - public static void ApplyTransactionTimeout(IQuery query, ISessionFactory sessionFactory) - { - if (query == null) - { - throw new ArgumentNullException("queryObject", "No query object specified"); - } - if (sessionFactory != null) - { - SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); - if (sessionHolder != null && sessionHolder.HasTimeout) - { - query.SetTimeout(sessionHolder.TimeToLiveInSeconds); - } - } - } - /// - /// Gets the Spring IDbProvider given the ISessionFactory. - /// - /// The matching is performed by comparing the assembly qualified - /// name string of the hibernate Driver.ConnectionType to those in - /// the DbProviderFactory definitions. No connections are created - /// in performing this comparison. - /// The session factory. - /// The corresponding IDbProvider, null if no mapping was found. - /// If DbProviderFactory's ApplicaitonContext is not - /// an instance of IConfigurableApplicaitonContext. - public static IDbProvider GetDbProvider(ISessionFactory sessionFactory) - { - ISessionFactoryImplementor sfi = sessionFactory as ISessionFactoryImplementor; - if (sfi != null) - { - - ConnectionProvider cp = sfi.ConnectionProvider as ConnectionProvider; - if (cp != null) - { - IConfigurableApplicationContext ctx = - Spring.Data.Common.DbProviderFactory.ApplicationContext as IConfigurableApplicationContext; - if (ctx == null) - { - throw new InvalidOperationException( - "Implementations of IApplicationContext must also implement IConfigurableApplicationContext"); - } - - - DriverBase db = cp.Driver as DriverBase; - if (db != null) - { - Type hibCommandType = db.CreateCommand().GetType(); - //Type hibConnectionType = cp.Driver.ConnectionType; - - string[] providerNames = ctx.GetObjectNamesForType(typeof(DbProvider), true, false); - string hibCommandAQN = hibCommandType.AssemblyQualifiedName; - foreach (string providerName in providerNames) - { - IObjectDefinition objectdef = ctx.ObjectFactory.GetObjectDefinition(providerName); - ConstructorArgumentValues ctorArgs = objectdef.ConstructorArgumentValues; - ConstructorArgumentValues.ValueHolder vh = ctorArgs.NamedArgumentValues["dbmetadata"] as ConstructorArgumentValues.ValueHolder; - IObjectDefinition od = vh.Value as IObjectDefinition; - ConstructorArgumentValues dbmdCtorArgs = od.ConstructorArgumentValues; - string commandType = dbmdCtorArgs.GetArgumentValue("commandType", typeof(string)).Value as string; - string assemblyName = dbmdCtorArgs.GetArgumentValue("assemblyName", typeof(string)).Value as string; - - - if (hibCommandAQN.Equals(commandType)) - { - IDbProvider prov = Spring.Data.Common.DbProviderFactory.GetDbProvider(providerName); - return prov; - } - } - } - else - { - log.Info("Could not derive IDbProvider from SessionFactory"); - } - } - - - } - return null; - } - - /// - /// Create a IAdoExceptionTranslator from the given SessionFactory. - /// - /// If a corresponding IDbProvider is found, a ErrorcodeExceptionTranslator - /// for the IDbProvider is created. Otherwise, a FallbackException is created. - /// The session factory to create the translator for - /// An IAdoExceptionTranslator - public static IAdoExceptionTranslator NewAdoExceptionTranslator(ISessionFactory sessionFactory) - { - IDbProvider dbProvider = GetDbProvider(sessionFactory); - if (dbProvider != null) - { - return new ErrorCodeExceptionTranslator(dbProvider); - } - log.Warn("Using FallbackException Translator. Could not translate from ISessionFactory to IDbProvider"); - return new FallbackExceptionTranslator(); - - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Common.Logging; +using NHibernate; +using NHibernate.Connection; +using NHibernate.Driver; +using NHibernate.Engine; +using Spring.Collections; +using Spring.Context; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Data.Support; +using Spring.Objects.Factory.Config; +using Spring.Threading; +using Spring.Transaction.Support; +using Spring.Util; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Helper class featuring methods for Hibernate Session handling, + /// allowing for reuse of Hibernate Session instances within transactions. + /// Also provides support for exception translation. + /// + /// Mark Pollack (.NET) + public abstract class SessionFactoryUtils + { + #region Fields + + /// + /// The instance for this class. + /// + private static readonly ILog log = LogManager.GetLogger(typeof(SessionFactoryUtils)); + + #endregion + + #region Constants + + /// + /// The ordering value for synchronizaiton this session resources. + /// Set to be lower than ADO.NET synchronization. + /// + public static readonly int SESSION_SYNCHRONIZATION_ORDER = + AdoUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100; + + private static readonly string DeferredCloseHolderDataSlotName = "Spring.Data.NHibernate:deferredCloseHolder"; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public SessionFactoryUtils() + { + + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + /// + /// Get a new Hibernate Session from the given SessionFactory. + /// Will return a new Session even if there already is a pre-bound + /// Session for the given SessionFactory. + /// + /// + /// Within a transaction, this method will create a new Session + /// that shares the transaction's ADO.NET Connection. More specifically, + /// it will use the same ADO.NET Connection as the pre-bound Hibernate Session. + /// + /// The session factory to create the session with. + /// The Hibernate entity interceptor, or null if none. + /// The new session. + /// If could not open Hibernate session + public static ISession GetNewSession(ISessionFactory sessionFactory, IInterceptor interceptor) + { + try + { + SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); + if (sessionHolder != null && !sessionHolder.IsEmpty) + { + if (interceptor != null) + { + return sessionFactory.OpenSession(sessionHolder.AnySession.Connection, interceptor); + } + else + { + return sessionFactory.OpenSession(sessionHolder.AnySession.Connection); + } + } + else + { + if (interceptor != null) + { + return sessionFactory.OpenSession(interceptor); + } + else + { + return sessionFactory.OpenSession(); + } + } + } + catch (HibernateException ex) + { + throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); + } + } + + /// + /// Get a Hibernate Session for the given SessionFactory. Is aware of and will + /// return any existing corresponding Session bound to the current thread, for + /// example when using HibernateTransactionManager. Will always create a new + /// Session otherwise. + /// + /// + /// Supports setting a Session-level Hibernate entity interceptor that allows + /// to inspect and change property values before writing to and reading from the + /// database. Such an interceptor can also be set at the SessionFactory level + /// (i.e. on LocalSessionFactoryObject), on HibernateTransactionManager, or on + /// HibernateInterceptor/HibernateTemplate. + /// + /// The session factory to create the + /// session with. + /// Hibernate entity interceptor, or null if none. + /// AdoExceptionTranslator to use for flushing the + /// Session on transaction synchronization (can be null; only used when actually + /// registering a transaction synchronization). + /// The Hibernate Session + /// + /// If the session couldn't be created. + /// + /// + /// If no thread-bound Session found and allowCreate is false. + /// + public static ISession GetSession( + ISessionFactory sessionFactory, IInterceptor entityInterceptor, + IAdoExceptionTranslator adoExceptionTranslator) + { + try + { + return GetSession(sessionFactory, entityInterceptor, adoExceptionTranslator, true); + } + catch (HibernateException ex) + { + throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); + } + } + + /// + /// Get a Hibernate Session for the given SessionFactory. Is aware of and will + /// return any existing corresponding Session bound to the current thread, for + /// example when using . Will create a new Session + /// otherwise, if allowCreate is true. + /// + /// The session factory to create the session with. + /// if set to true create a non-transactional Session when no + /// transactional Session can be found for the current thread. + /// The hibernate session + /// + /// If the session couldn't be created. + /// + /// + /// If no thread-bound Session found and allowCreate is false. + /// + public static ISession GetSession(ISessionFactory sessionFactory, bool allowCreate) + { + try + { + return GetSession(sessionFactory, null, null, allowCreate); + } + catch (HibernateException ex) + { + throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); + } + } + + /// + /// Get a Hibernate Session for the given SessionFactory. + /// + /// Is aware of and will return any existing corresponding + /// Session bound to the current thread, for example whenusing + /// . Will create a new + /// Session otherwise, if "allowCreate" is true. + ///

Throws the orginal HibernateException, in contrast to + /// . + ///

+ /// The session factory. + /// if set to true [allow create]. + /// The Hibernate Session + /// + /// if the Session couldn't be created + /// + /// + /// If no thread-bound Session found and allowCreate is false. + /// + public static ISession DoGetSession(ISessionFactory sessionFactory, bool allowCreate) + { + return DoGetSession(sessionFactory, null, null, allowCreate); + } + + private static ISession GetSession( + ISessionFactory sessionFactory, IInterceptor entityInterceptor, + IAdoExceptionTranslator adoExceptionTranslator, bool allowCreate) + { + try + { + return DoGetSession(sessionFactory, entityInterceptor, adoExceptionTranslator, allowCreate); + } + catch (HibernateException ex) + { + throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); + } + } + + + private static ISession DoGetSession( + ISessionFactory sessionFactory, IInterceptor entityInterceptor, + IAdoExceptionTranslator adoExceptionTranslator, bool allowCreate) + { + AssertUtils.ArgumentNotNull(sessionFactory, "sessionFactory", "SessionFactory can not be null"); + + SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); + if (sessionHolder != null && !sessionHolder.IsEmpty) + { + // pre-bound Hibernate Session + ISession session = null; + if (TransactionSynchronizationManager.SynchronizationActive && + sessionHolder.DoesNotHoldNonDefaultSession) + { + // Spring transaction management is active -> + // register pre-bound Session with it for transactional flushing. + session = sessionHolder.ValidatedSession; + if (!sessionHolder.SynchronizedWithTransaction) + { + log.Debug("Registering Spring transaction synchronization for existing Hibernate Session"); + TransactionSynchronizationManager.RegisterSynchronization( + new SpringSessionSynchronization(sessionHolder, sessionFactory, adoExceptionTranslator, false)); + sessionHolder.SynchronizedWithTransaction = true; + // Switch to FlushMode.AUTO if we're not within a read-only transaction. + FlushMode flushMode = session.FlushMode; + if (FlushMode.Never == flushMode && + !TransactionSynchronizationManager.CurrentTransactionReadOnly) + { + session.FlushMode = FlushMode.Auto; + sessionHolder.PreviousFlushMode = flushMode; + } + } + } + else + { + // No Spring transaction management active -> simply return default thread-bound Session, if any + // (possibly from OpenSessionInViewModule) + session = sessionHolder.ValidatedSession; + } + + if (session != null) + { + return session; + } + + } + + + ISession sess = OpenSession(sessionFactory, entityInterceptor); + // Set Session to FlushMode.Never if we're within a read-only transaction. + // Use same Session for further Hibernate actions within the transaction. + // Thread object will get removed by synchronization at transaction completion. + if (TransactionSynchronizationManager.SynchronizationActive) + { + log.Debug("Registering Spring transaction synchronization for new Hibernate Session"); + SessionHolder holderToUse = sessionHolder; + if (holderToUse == null) + { + holderToUse = new SessionHolder(sess); + } + else + { + holderToUse.AddSession(sess); + } + if (TransactionSynchronizationManager.CurrentTransactionReadOnly) + { + sess.FlushMode = FlushMode.Never; + } + TransactionSynchronizationManager.RegisterSynchronization( + new SpringSessionSynchronization(holderToUse, sessionFactory, adoExceptionTranslator, true)); + holderToUse.SynchronizedWithTransaction = true; + if (holderToUse != sessionHolder) + { + TransactionSynchronizationManager.BindResource(sessionFactory, holderToUse); + } + } + + + + // Check whether we are allowed to return the Session. + if (!allowCreate && !IsSessionTransactional(sess, sessionFactory)) + { + CloseSession(sess); + throw new InvalidOperationException ("No Hibernate Session bound to thread, " + + "and configuration does not allow creation of non-transactional one here"); + } + + return sess; + + + } + + /// + /// Open a new Session from the factory. + /// + /// The session factory to create the session with. + /// Hibernate entity interceptor, or null if none. + /// the newly opened session + internal static ISession OpenSession(ISessionFactory sessionFactory, IInterceptor entityInterceptor) + { + log.Debug("Opening Hibernate Session"); + ISession session = ( + (entityInterceptor != null) + ? sessionFactory.OpenSession(entityInterceptor) + : sessionFactory.OpenSession() + ); + + return session; + } + + /// + /// Perform the actual closing of the Hibernate Session + /// catching and logging any cleanup exceptions thrown. + /// + /// The hibernate session to close + public static void CloseSession(ISession session) + { + if (session != null) + { + log.Debug("Closing Hibernate Session"); + try + { + session.Close(); + } + catch (HibernateException ex) + { + log.Error("Could not close Hibernate Session", ex); + } + catch (Exception ex) + { + log.Error("Unexpected exception on closing Hibernate Session", ex); + } + } + } + + /// + /// Return whether the given Hibernate Session is transactional, that is, + /// bound to the current thread by Spring's transaction facilities. + /// + /// The hibernate session to check + /// The session factory that the session + /// was created with, can be null. + /// + /// true if the session transactional; otherwise, false. + /// + public static bool IsSessionTransactional(ISession session, ISessionFactory sessionFactory) + { + if (sessionFactory == null) + { + return false; + } + SessionHolder sessionHolder = + (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); + return (sessionHolder != null && sessionHolder.ContainsSession(session)); + } + + #endregion + + /// + /// Convert the given HibernateException to an appropriate exception from the + /// Spring.Dao hierarchy. Note that it is advisable to + /// handle AdoException specifically by using a AdoExceptionTranslator for the + /// underlying ADO.NET exception. + /// + /// The Hibernate exception that occured. + /// DataAccessException instance + public static DataAccessException ConvertHibernateAccessException(HibernateException ex) + { + if (ex is ADOException) + { + // ADOException during Hibernate access: only passed in here from custom code, + // as HibernateTemplate etc will use AdoExceptionTranslator-based handling. + return new HibernateAdoException("Ado Exception", (ADOException) ex); + } + if (ex is UnresolvableObjectException) + { + return new HibernateObjectRetrievalFailureException((UnresolvableObjectException) ex); + } + if (ex is ObjectDeletedException) + { + return new InvalidDataAccessApiUsageException(ex.Message, ex); + } + if (ex is WrongClassException) + { + return new HibernateObjectRetrievalFailureException((WrongClassException) ex); + } + if (ex is StaleObjectStateException) + { + return new HibernateOptimisticLockingFailureException((StaleObjectStateException) ex); + } + if (ex is QueryException) + { + return new HibernateQueryException((QueryException) ex); + } + if (ex is PersistentObjectException) + { + return new InvalidDataAccessApiUsageException(ex.Message, ex); + } + if (ex is TransientObjectException) + { + return new InvalidDataAccessApiUsageException(ex.Message, ex); + } + + if (ex is PropertyValueException) + { + return new DataIntegrityViolationException(ex.Message, ex); + } + if (ex is PersistentObjectException) + { + return new InvalidDataAccessApiUsageException(ex.Message, ex); + } + if (ex is NonUniqueResultException) + { + return new IncorrectResultSizeDataAccessException(ex.Message, 1); + } + // fallback + return new HibernateSystemException(ex); + } + + /// + /// Close the given Session, created via the given factory, + /// if it is not managed externally (i.e. not bound to the thread). + /// + /// The hibernate session to close + /// The hibernate SessionFactory that + /// the session was created with. + public static void ReleaseSession(ISession session, ISessionFactory sessionFactory) + { + if (session == null) + { + return; + } + // Only close non-transactional Sessions. + if (!IsSessionTransactional(session, sessionFactory)) + { + CloseSessionOrRegisterDeferredClose(session, sessionFactory); + } + } + + /// + /// Close the given Session or register it for deferred close. + /// + /// The session. + /// The session factory. + internal static void CloseSessionOrRegisterDeferredClose(ISession session, ISessionFactory sessionFactory) + { + IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; + + if (holderDictionary != null && sessionFactory != null && holderDictionary.Contains(sessionFactory)) + { + log.Debug("Registering Hibernate Session for deferred close"); + // Switch Session to FlushMode.NEVER for remaining lifetime. + session.FlushMode = FlushMode.Never; + Set sessions = (Set) holderDictionary[sessionFactory]; + sessions.Add(session); + } + else + { + CloseSession(session); + } + } + + /// + ///Initialize deferred close for the current thread and the given SessionFactory. + /// Sessions will not be actually closed on close calls then, but rather at a + /// processDeferredClose call at a finishing point (like request completion). + /// + /// The session factory. + public static void InitDeferredClose(ISessionFactory sessionFactory) + { + AssertUtils.ArgumentNotNull(sessionFactory, "No SessionFactory specified"); + + log.Debug("Initializing deferred close of Hibernate Sessions"); + + IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; + + if (holderDictionary == null) + { + holderDictionary = new Hashtable(); + LogicalThreadContext.SetData(DeferredCloseHolderDataSlotName, holderDictionary); + } + holderDictionary.Add(sessionFactory, new ListSet()); + } + + /// + /// Return if deferred close is active for the current thread + /// and the given SessionFactory. + /// The session factory. + /// + /// true if [is deferred close active] [the specified session factory]; otherwise, false. + /// + /// If SessionFactory argument is null. + public static bool IsDeferredCloseActive(ISessionFactory sessionFactory) + { + if (sessionFactory == null) + { + throw new ArgumentNullException("sessionFactory", "No SessionFactory specified"); + } + IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; + return (holderDictionary != null && holderDictionary.Contains(sessionFactory)); + } + + /// + /// Process Sessions that have been registered for deferred close + /// for the given SessionFactory. + /// + /// The session factory. + /// If there is no session factory associated with the thread. + public static void ProcessDeferredClose(ISessionFactory sessionFactory) + { + AssertUtils.ArgumentNotNull(sessionFactory, "No SessionFactory specified"); + + IDictionary holderDictionary = LogicalThreadContext.GetData(DeferredCloseHolderDataSlotName) as IDictionary; + + if (holderDictionary == null || !holderDictionary.Contains(sessionFactory)) + { + throw new InvalidOperationException("Deferred close not active for SessionFactory [" + sessionFactory + "]"); + } + log.Debug("Processing deferred close of Hibernate Sessions"); + Set sessions = (Set) holderDictionary[sessionFactory]; + holderDictionary.Remove(sessionFactory); + foreach (ISession session in sessions) + { + CloseSession(session); + } + + if (holderDictionary.Count == 0) + { + LogicalThreadContext.FreeNamedDataSlot(DeferredCloseHolderDataSlotName); + } + + + } + + /// + /// Applies the current transaction timeout, if any, to the given + /// criteria object + /// + /// The Hibernate Criteria object. + /// Hibernate SessionFactory that the Criteria was created for + /// (can be null). + /// If criteria argument is null. + public static void ApplyTransactionTimeout(ICriteria criteria, ISessionFactory sessionFactory) + { + if (criteria == null) + { + throw new ArgumentNullException("criteria", "No Criteria object specified"); + } + + SessionHolder sessionHolder = + (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); + if (sessionHolder != null && sessionHolder.HasTimeout) + { + criteria.SetTimeout(sessionHolder.TimeToLiveInSeconds); + } + } + + /// + /// Applies the current transaction timeout, if any, to the given + /// Hibenrate query object. + /// + /// The Hibernate Query object. + /// Hibernate SessionFactory that the Query was created for + /// (can be null). + /// If query argument is null. + public static void ApplyTransactionTimeout(IQuery query, ISessionFactory sessionFactory) + { + if (query == null) + { + throw new ArgumentNullException("queryObject", "No query object specified"); + } + if (sessionFactory != null) + { + SessionHolder sessionHolder = + (SessionHolder) TransactionSynchronizationManager.GetResource(sessionFactory); + if (sessionHolder != null && sessionHolder.HasTimeout) + { + query.SetTimeout(sessionHolder.TimeToLiveInSeconds); + } + } + } + /// + /// Gets the Spring IDbProvider given the ISessionFactory. + /// + /// The matching is performed by comparing the assembly qualified + /// name string of the hibernate Driver.ConnectionType to those in + /// the DbProviderFactory definitions. No connections are created + /// in performing this comparison. + /// The session factory. + /// The corresponding IDbProvider, null if no mapping was found. + /// If DbProviderFactory's ApplicaitonContext is not + /// an instance of IConfigurableApplicaitonContext. + public static IDbProvider GetDbProvider(ISessionFactory sessionFactory) + { + ISessionFactoryImplementor sfi = sessionFactory as ISessionFactoryImplementor; + if (sfi != null) + { + + ConnectionProvider cp = sfi.ConnectionProvider as ConnectionProvider; + if (cp != null) + { + IConfigurableApplicationContext ctx = + Spring.Data.Common.DbProviderFactory.ApplicationContext as IConfigurableApplicationContext; + if (ctx == null) + { + throw new InvalidOperationException( + "Implementations of IApplicationContext must also implement IConfigurableApplicationContext"); + } + + + DriverBase db = cp.Driver as DriverBase; + if (db != null) + { + Type hibCommandType = db.CreateCommand().GetType(); + //Type hibConnectionType = cp.Driver.ConnectionType; + + string[] providerNames = ctx.GetObjectNamesForType(typeof(DbProvider), true, false); + string hibCommandAQN = hibCommandType.AssemblyQualifiedName; + foreach (string providerName in providerNames) + { + IObjectDefinition objectdef = ctx.ObjectFactory.GetObjectDefinition(providerName); + ConstructorArgumentValues ctorArgs = objectdef.ConstructorArgumentValues; + ConstructorArgumentValues.ValueHolder vh = ctorArgs.NamedArgumentValues["dbmetadata"] as ConstructorArgumentValues.ValueHolder; + IObjectDefinition od = vh.Value as IObjectDefinition; + ConstructorArgumentValues dbmdCtorArgs = od.ConstructorArgumentValues; + string commandType = dbmdCtorArgs.GetArgumentValue("commandType", typeof(string)).Value as string; + string assemblyName = dbmdCtorArgs.GetArgumentValue("assemblyName", typeof(string)).Value as string; + + + if (hibCommandAQN.Equals(commandType)) + { + IDbProvider prov = Spring.Data.Common.DbProviderFactory.GetDbProvider(providerName); + return prov; + } + } + } + else + { + log.Info("Could not derive IDbProvider from SessionFactory"); + } + } + + + } + return null; + } + + /// + /// Create a IAdoExceptionTranslator from the given SessionFactory. + /// + /// If a corresponding IDbProvider is found, a ErrorcodeExceptionTranslator + /// for the IDbProvider is created. Otherwise, a FallbackException is created. + /// The session factory to create the translator for + /// An IAdoExceptionTranslator + public static IAdoExceptionTranslator NewAdoExceptionTranslator(ISessionFactory sessionFactory) + { + IDbProvider dbProvider = GetDbProvider(sessionFactory); + if (dbProvider != null) + { + return new ErrorCodeExceptionTranslator(dbProvider); + } + log.Warn("Using FallbackException Translator. Could not translate from ISessionFactory to IDbProvider"); + return new FallbackExceptionTranslator(); + + } + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionHolder.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionHolder.cs index b821b6d7..8401b745 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionHolder.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SessionHolder.cs @@ -1,375 +1,374 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using Common.Logging; -using NHibernate; -using Spring.Collections; -using Spring.Transaction.Support; -using Spring.Util; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// Session holder, wrapping a NHibernate ISession and a NHibernate Transaction. - /// HibernateTransactionManager binds instances of this class - /// to the thread, for a given ISessionFactory. - /// - /// - /// Note: This is an SPI class, not intended to be used by applications. - /// - /// Mark Pollack (.NET) - /// $Id: SessionHolder.cs,v 1.1 2007/05/31 20:25:13 markpollack Exp $ - public class SessionHolder : ResourceHolderSupport - { - #region Fields - - private static readonly object DEFAULT_KEY = new object(); - - private readonly Hashtable sessionDictionary = new Hashtable(1); - - private IDbConnection connection; - - private ITransaction transaction; - - private FlushMode flushMode; - - //needed to see if we actually assigned the enum value... - private bool assignedPreviousFlushMode = false; - - #endregion - - #region Logging Definition - - private static readonly ILog log = LogManager.GetLogger(typeof (SessionHolder)); - - #endregion - - #region Constructor (s) - - /// - /// May be used by derived classes to create an empty SessionHolder. - /// - /// - /// When using this ctor in your derived class, you MUST override ! - /// - protected SessionHolder() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The session. - public SessionHolder(ISession session) - { - AddSession(session); - } - - /// - /// Initializes a new instance of the class. - /// - /// The key to store the session under. - /// The hibernate session. - public SessionHolder(object key, ISession session) - { - AddSession(key, session); - } - - /// - /// May be overridden in a derived class to e.g. lazily create a session - /// - protected virtual void EnsureInitialized() - { - // noop here - but may be overridden to lazily create a session - } - - #endregion - - #region Properties - - /// - /// Gets the session using the default key - /// - /// The hibernate session. - public ISession Session - { - get - { - lock (sessionDictionary.SyncRoot) - { - EnsureInitialized(); - return sessionDictionary[DEFAULT_KEY] as ISession; - } - } - } - - /// - /// Gets the first session based on iteration over - /// the IDictionary storage. - /// - /// Any hibernate session. - public ISession AnySession - { - get - { - lock(sessionDictionary.SyncRoot) - { - EnsureInitialized(); - if (sessionDictionary.Count > 0) - { - IEnumerator enumerator = sessionDictionary.Values.GetEnumerator(); - enumerator.MoveNext(); - return (ISession)enumerator.Current; - } - return null; - } - } - } - - /// - /// Gets a value indicating whether dictionary of - /// hibernate sessions is empty. - /// - /// - /// true if this session holder is empty; otherwise, false. - /// - public bool IsEmpty - { - get - { - lock(sessionDictionary.SyncRoot) - { - EnsureInitialized(); - return (sessionDictionary.Count > 0 ? false : true); - } - } - } - - /// - /// Gets a value indicating whether this SessionHolder - /// does not hold non default session. - /// - /// - /// true if does not hold non default session; otherwise, false. - /// - public bool DoesNotHoldNonDefaultSession - { - get - { - lock (sessionDictionary.SyncRoot) - { - EnsureInitialized(); - return ( - sessionDictionary.Count == 0 || - (sessionDictionary.Count == 1 && sessionDictionary.Contains(DEFAULT_KEY)) - ); - - } - } - } - - /// - /// Gets or sets the hibernate transaction. - /// - /// The transaction. - public ITransaction Transaction - { - get { return transaction; } - set { transaction = value; } - } - - /// - /// Gets or sets the ADO.NET Connection used to create the session. - /// - /// The ADO.NET connection. - public IDbConnection Connection - { - get { return connection; } - set { connection = value; } - } - - /// - /// Gets or sets the previous flush mode. - /// - /// The previous flush mode. - public FlushMode PreviousFlushMode - { - get { return flushMode; } - set - { - flushMode = value; - assignedPreviousFlushMode = true; - } - } - - /// - /// Gets a value indicating whether the PreviousFlushMode property - /// was set. - /// - /// - /// true if assigned PreviousFlushMode property; otherwise, false. - /// - public bool AssignedPreviousFlushMode - { - get - { - return assignedPreviousFlushMode; - } - } - - /// - /// Gets the validated session. - /// - /// The validated session. - public ISession ValidatedSession - { - get - { - return GetValidatedSession(DEFAULT_KEY); - } - } - - #endregion - - #region Methods - - /// - /// Gets the session given key identifier - /// - /// The key. - /// A hibernate session - public ISession GetSession(object key) - { - lock (sessionDictionary.SyncRoot) - { - EnsureInitialized(); - return sessionDictionary[key] as ISession; - } - } - - - /// - /// Gets the session given the key and removes the session from - /// the dictionary storage. - /// - /// The key. - /// A hibernate session - public ISession GetValidatedSession(object key) - { - lock (sessionDictionary.SyncRoot) - { - EnsureInitialized(); - ISession session = sessionDictionary[key] as ISession; - // Check for dangling Session that's around but already closed. - // Effectively an assertion: that should never happen in practice. - // We'll seamlessly remove the Session here, to not let it cause - // any side effects. - if (session != null && !session.IsOpen) - { - sessionDictionary.Remove(key); - session = null; - } - return session; - } - } - /// - /// Adds the session to the dictionary storage using the default key. - /// - /// The hibernate session. - public void AddSession(ISession session) - { - AddSession(DEFAULT_KEY, session); - } - - /// - /// Adds the session to the dictionary storage using the supplied key. - /// - /// The key. - /// The hibernate session. - public void AddSession(object key, ISession session) - { - AssertUtils.ArgumentNotNull(key, "key", "Key must not be null"); - AssertUtils.ArgumentNotNull(session, "session", "Session must not be null"); - - lock (sessionDictionary.SyncRoot) - { - if (sessionDictionary.ContainsKey(key)) - { - log.Debug("Overwriting Session in SessionHolder with key = "+ key); - } - - sessionDictionary[key] = session; - } - } - - /// - /// Removes the session from the dictionary storage for the given key. - /// - /// The key. - /// The session that was previously contained in the - /// dictionary storage. - public ISession RemoveSession(object key) - { - lock(sessionDictionary.SyncRoot) - { - ISession oldSession = sessionDictionary[key] as ISession; - sessionDictionary.Remove(key); - return oldSession; - } - } - - /// - /// Determines whether the holder the specified session. - /// - /// The session. - /// - /// true if the holder contains the specified session; otherwise, false. - /// - public bool ContainsSession(object session) - { - lock (sessionDictionary.SyncRoot) - { - EnsureInitialized(); - return sessionDictionary.ContainsValue(session); - } - } - - /// - /// Clear the transaction state of this resource holder. - /// - public override void Clear() - { - base.Clear(); - Transaction = null; - assignedPreviousFlushMode = false; - Connection = null; - } - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using Common.Logging; +using NHibernate; +using Spring.Collections; +using Spring.Transaction.Support; +using Spring.Util; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// Session holder, wrapping a NHibernate ISession and a NHibernate Transaction. + /// HibernateTransactionManager binds instances of this class + /// to the thread, for a given ISessionFactory. + /// + /// + /// Note: This is an SPI class, not intended to be used by applications. + /// + /// Mark Pollack (.NET) + public class SessionHolder : ResourceHolderSupport + { + #region Fields + + private static readonly object DEFAULT_KEY = new object(); + + private readonly Hashtable sessionDictionary = new Hashtable(1); + + private IDbConnection connection; + + private ITransaction transaction; + + private FlushMode flushMode; + + //needed to see if we actually assigned the enum value... + private bool assignedPreviousFlushMode = false; + + #endregion + + #region Logging Definition + + private static readonly ILog log = LogManager.GetLogger(typeof (SessionHolder)); + + #endregion + + #region Constructor (s) + + /// + /// May be used by derived classes to create an empty SessionHolder. + /// + /// + /// When using this ctor in your derived class, you MUST override ! + /// + protected SessionHolder() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The session. + public SessionHolder(ISession session) + { + AddSession(session); + } + + /// + /// Initializes a new instance of the class. + /// + /// The key to store the session under. + /// The hibernate session. + public SessionHolder(object key, ISession session) + { + AddSession(key, session); + } + + /// + /// May be overridden in a derived class to e.g. lazily create a session + /// + protected virtual void EnsureInitialized() + { + // noop here - but may be overridden to lazily create a session + } + + #endregion + + #region Properties + + /// + /// Gets the session using the default key + /// + /// The hibernate session. + public ISession Session + { + get + { + lock (sessionDictionary.SyncRoot) + { + EnsureInitialized(); + return sessionDictionary[DEFAULT_KEY] as ISession; + } + } + } + + /// + /// Gets the first session based on iteration over + /// the IDictionary storage. + /// + /// Any hibernate session. + public ISession AnySession + { + get + { + lock(sessionDictionary.SyncRoot) + { + EnsureInitialized(); + if (sessionDictionary.Count > 0) + { + IEnumerator enumerator = sessionDictionary.Values.GetEnumerator(); + enumerator.MoveNext(); + return (ISession)enumerator.Current; + } + return null; + } + } + } + + /// + /// Gets a value indicating whether dictionary of + /// hibernate sessions is empty. + /// + /// + /// true if this session holder is empty; otherwise, false. + /// + public bool IsEmpty + { + get + { + lock(sessionDictionary.SyncRoot) + { + EnsureInitialized(); + return (sessionDictionary.Count > 0 ? false : true); + } + } + } + + /// + /// Gets a value indicating whether this SessionHolder + /// does not hold non default session. + /// + /// + /// true if does not hold non default session; otherwise, false. + /// + public bool DoesNotHoldNonDefaultSession + { + get + { + lock (sessionDictionary.SyncRoot) + { + EnsureInitialized(); + return ( + sessionDictionary.Count == 0 || + (sessionDictionary.Count == 1 && sessionDictionary.Contains(DEFAULT_KEY)) + ); + + } + } + } + + /// + /// Gets or sets the hibernate transaction. + /// + /// The transaction. + public ITransaction Transaction + { + get { return transaction; } + set { transaction = value; } + } + + /// + /// Gets or sets the ADO.NET Connection used to create the session. + /// + /// The ADO.NET connection. + public IDbConnection Connection + { + get { return connection; } + set { connection = value; } + } + + /// + /// Gets or sets the previous flush mode. + /// + /// The previous flush mode. + public FlushMode PreviousFlushMode + { + get { return flushMode; } + set + { + flushMode = value; + assignedPreviousFlushMode = true; + } + } + + /// + /// Gets a value indicating whether the PreviousFlushMode property + /// was set. + /// + /// + /// true if assigned PreviousFlushMode property; otherwise, false. + /// + public bool AssignedPreviousFlushMode + { + get + { + return assignedPreviousFlushMode; + } + } + + /// + /// Gets the validated session. + /// + /// The validated session. + public ISession ValidatedSession + { + get + { + return GetValidatedSession(DEFAULT_KEY); + } + } + + #endregion + + #region Methods + + /// + /// Gets the session given key identifier + /// + /// The key. + /// A hibernate session + public ISession GetSession(object key) + { + lock (sessionDictionary.SyncRoot) + { + EnsureInitialized(); + return sessionDictionary[key] as ISession; + } + } + + + /// + /// Gets the session given the key and removes the session from + /// the dictionary storage. + /// + /// The key. + /// A hibernate session + public ISession GetValidatedSession(object key) + { + lock (sessionDictionary.SyncRoot) + { + EnsureInitialized(); + ISession session = sessionDictionary[key] as ISession; + // Check for dangling Session that's around but already closed. + // Effectively an assertion: that should never happen in practice. + // We'll seamlessly remove the Session here, to not let it cause + // any side effects. + if (session != null && !session.IsOpen) + { + sessionDictionary.Remove(key); + session = null; + } + return session; + } + } + /// + /// Adds the session to the dictionary storage using the default key. + /// + /// The hibernate session. + public void AddSession(ISession session) + { + AddSession(DEFAULT_KEY, session); + } + + /// + /// Adds the session to the dictionary storage using the supplied key. + /// + /// The key. + /// The hibernate session. + public void AddSession(object key, ISession session) + { + AssertUtils.ArgumentNotNull(key, "key", "Key must not be null"); + AssertUtils.ArgumentNotNull(session, "session", "Session must not be null"); + + lock (sessionDictionary.SyncRoot) + { + if (sessionDictionary.ContainsKey(key)) + { + log.Debug("Overwriting Session in SessionHolder with key = "+ key); + } + + sessionDictionary[key] = session; + } + } + + /// + /// Removes the session from the dictionary storage for the given key. + /// + /// The key. + /// The session that was previously contained in the + /// dictionary storage. + public ISession RemoveSession(object key) + { + lock(sessionDictionary.SyncRoot) + { + ISession oldSession = sessionDictionary[key] as ISession; + sessionDictionary.Remove(key); + return oldSession; + } + } + + /// + /// Determines whether the holder the specified session. + /// + /// The session. + /// + /// true if the holder contains the specified session; otherwise, false. + /// + public bool ContainsSession(object session) + { + lock (sessionDictionary.SyncRoot) + { + EnsureInitialized(); + return sessionDictionary.ContainsValue(session); + } + } + + /// + /// Clear the transaction state of this resource holder. + /// + public override void Clear() + { + base.Clear(); + Transaction = null; + assignedPreviousFlushMode = false; + Connection = null; + } + + #endregion + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SpringSessionSynchronization.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SpringSessionSynchronization.cs index f95b4362..31d9dcdb 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SpringSessionSynchronization.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/SpringSessionSynchronization.cs @@ -1,275 +1,274 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using Common.Logging; -using NHibernate; -using NHibernate.Engine; -using Spring.Core; -using Spring.Data.Support; -using Spring.Transaction.Support; - -#endregion - -namespace Spring.Data.NHibernate -{ - /// - /// NHibnerations actions taken during the transaction lifecycle. - /// - /// Mark Pollack (.NET) - /// $Id: SpringSessionSynchronization.cs,v 1.2 2007/08/29 03:42:06 markpollack Exp $ - public class SpringSessionSynchronization : TransactionSynchronizationAdapter, IOrdered - { - #region Fields - - /// - /// The instance for this class. - /// - private readonly ILog log = LogManager.GetLogger(typeof(SpringSessionSynchronization)); - - private readonly SessionHolder sessionHolder; - - private readonly ISessionFactory sessionFactory; - - private readonly IAdoExceptionTranslator adoExceptionTranslator; - - private readonly bool newSession; - - private bool holderActive = true; - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public SpringSessionSynchronization(SessionHolder sessionHolder, ISessionFactory sessionFactory, - IAdoExceptionTranslator adoExceptionTranslator, bool newSession) - { - this.sessionHolder = sessionHolder; - this.sessionFactory = sessionFactory; - this.adoExceptionTranslator = adoExceptionTranslator; - this.newSession = newSession; - } - - #endregion - - #region Properties - - /// - /// Return the order value of this object, where a higher value means greater in - /// terms of sorting. - /// - /// - ///

- /// Normally starting with 0 or 1, with indicating - /// greatest. Same order values will result in arbitrary positions for the affected - /// objects. - ///

- ///

- /// Higher value can be interpreted as lower priority, consequently the first object - /// has highest priority. - ///

- ///
- /// The order value. - public int Order - { - get - { - return SessionFactoryUtils.SESSION_SYNCHRONIZATION_ORDER; - } - } - - #endregion - - #region Methods - - /// - /// Suspend this synchronization. - /// - /// - ///

- /// Unbind Hibernate resources (SessionHolder) from - /// - /// if managing any. - ///

- ///
- public override void Suspend() - { - if (this.holderActive) - { - TransactionSynchronizationManager.UnbindResource(this.sessionFactory); - } - } - - /// - /// Resume this synchronization. - /// - /// - ///

- /// Rebind Hibernate resources from - /// - /// if managing any. - ///

- ///
- public override void Resume() - { - if (this.holderActive) - { - TransactionSynchronizationManager.BindResource(this.sessionFactory, this.sessionHolder); - } - } - - /// - /// Invoked before transaction commit (before - /// ) - /// - /// - /// If the transaction is defined as a read-only transaction. - /// - /// - ///

- /// Can flush transactional sessions to the database. - ///

- ///

- /// Note that exceptions will get propagated to the commit caller and - /// cause a rollback of the transaction. - ///

- ///
- public override void BeforeCommit(bool readOnly) - { - if (!readOnly) - { - // read-write transaction -> flush the Hibernate Session - log.Debug("Flushing Hibernate Session on transaction synchronization"); - ISession session = this.sessionHolder.Session; - //Further check: only flush when not FlushMode.NEVER - if (session.FlushMode != FlushMode.Never) - { - try - { - session.Flush(); - //TODO can throw System.ObjectDisposedException... - } - catch (ADOException ex) - { - if (this.adoExceptionTranslator != null) - { - //TODO investigate how ADOException wraps inner exception. - throw this.adoExceptionTranslator.Translate( - "Hibernate transaction synchronization: " + ex.Message, null, ex.InnerException); - } - else - { - throw new HibernateAdoException("ADO.NET Exception", ex); - } - } - catch (HibernateException ex) - { - throw SessionFactoryUtils.ConvertHibernateAccessException(ex); - } - } - - } - } - - /// - /// Invoked before transaction commit (before - /// ) - /// Can e.g. flush transactional O/R Mapping sessions to the database - /// - /// - /// - /// This callback does not mean that the transaction will actually be - /// commited. A rollback decision can still occur after this method - /// has been called. This callback is rather meant to perform work - /// that's only relevant if a commit still has a chance - /// to happen, such as flushing SQL statements to the database. - /// - /// - /// Note that exceptions will get propagated to the commit caller and cause a - /// rollback of the transaction. - /// - /// (note: do not throw TransactionException subclasses here!) - /// - /// - public override void BeforeCompletion() - { - if (this.newSession) - { - // Default behavior: unbind and close the thread-bound Hibernate Session. - TransactionSynchronizationManager.UnbindResource(this.sessionFactory); - this.holderActive = false; - } - else if (this.sessionHolder.AssignedPreviousFlushMode == true) - { - // In case of pre-bound Session, restore previous flush mode. - this.sessionHolder.Session.FlushMode = (this.sessionHolder.PreviousFlushMode); - } - } - - /// - /// Invoked after transaction commit/rollback. - /// - /// - /// Status according to - /// - /// - /// Can e.g. perform resource cleanup, in this case after transaction completion. - ///

- /// Note that exceptions will get propagated to the commit or rollback - /// caller, although they will not influence the outcome of the transaction. - ///

- ///
- public override void AfterCompletion(TransactionSynchronizationStatus status) - { - - ISession session = sessionHolder.Session; - - // Provide correct transaction status for releasing the Session's cache locks, - // if possible. Else, closing will release all cache locks assuming a rollback. - ISessionImplementor sessionImplementor = session as ISessionImplementor; - if (sessionImplementor != null) - { - sessionImplementor.AfterTransactionCompletion(status == TransactionSynchronizationStatus.Committed); - } - - if (newSession) - { - SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, sessionFactory); - } - - if (!newSession && status != TransactionSynchronizationStatus.Committed) - { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - sessionHolder.Session.Clear(); - } - - if (this.sessionHolder.DoesNotHoldNonDefaultSession) { - sessionHolder.SynchronizedWithTransaction = false; - } - - } - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using Common.Logging; +using NHibernate; +using NHibernate.Engine; +using Spring.Core; +using Spring.Data.Support; +using Spring.Transaction.Support; + +#endregion + +namespace Spring.Data.NHibernate +{ + /// + /// NHibnerations actions taken during the transaction lifecycle. + /// + /// Mark Pollack (.NET) + public class SpringSessionSynchronization : TransactionSynchronizationAdapter, IOrdered + { + #region Fields + + /// + /// The instance for this class. + /// + private readonly ILog log = LogManager.GetLogger(typeof(SpringSessionSynchronization)); + + private readonly SessionHolder sessionHolder; + + private readonly ISessionFactory sessionFactory; + + private readonly IAdoExceptionTranslator adoExceptionTranslator; + + private readonly bool newSession; + + private bool holderActive = true; + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public SpringSessionSynchronization(SessionHolder sessionHolder, ISessionFactory sessionFactory, + IAdoExceptionTranslator adoExceptionTranslator, bool newSession) + { + this.sessionHolder = sessionHolder; + this.sessionFactory = sessionFactory; + this.adoExceptionTranslator = adoExceptionTranslator; + this.newSession = newSession; + } + + #endregion + + #region Properties + + /// + /// Return the order value of this object, where a higher value means greater in + /// terms of sorting. + /// + /// + ///

+ /// Normally starting with 0 or 1, with indicating + /// greatest. Same order values will result in arbitrary positions for the affected + /// objects. + ///

+ ///

+ /// Higher value can be interpreted as lower priority, consequently the first object + /// has highest priority. + ///

+ ///
+ /// The order value. + public int Order + { + get + { + return SessionFactoryUtils.SESSION_SYNCHRONIZATION_ORDER; + } + } + + #endregion + + #region Methods + + /// + /// Suspend this synchronization. + /// + /// + ///

+ /// Unbind Hibernate resources (SessionHolder) from + /// + /// if managing any. + ///

+ ///
+ public override void Suspend() + { + if (this.holderActive) + { + TransactionSynchronizationManager.UnbindResource(this.sessionFactory); + } + } + + /// + /// Resume this synchronization. + /// + /// + ///

+ /// Rebind Hibernate resources from + /// + /// if managing any. + ///

+ ///
+ public override void Resume() + { + if (this.holderActive) + { + TransactionSynchronizationManager.BindResource(this.sessionFactory, this.sessionHolder); + } + } + + /// + /// Invoked before transaction commit (before + /// ) + /// + /// + /// If the transaction is defined as a read-only transaction. + /// + /// + ///

+ /// Can flush transactional sessions to the database. + ///

+ ///

+ /// Note that exceptions will get propagated to the commit caller and + /// cause a rollback of the transaction. + ///

+ ///
+ public override void BeforeCommit(bool readOnly) + { + if (!readOnly) + { + // read-write transaction -> flush the Hibernate Session + log.Debug("Flushing Hibernate Session on transaction synchronization"); + ISession session = this.sessionHolder.Session; + //Further check: only flush when not FlushMode.NEVER + if (session.FlushMode != FlushMode.Never) + { + try + { + session.Flush(); + //TODO can throw System.ObjectDisposedException... + } + catch (ADOException ex) + { + if (this.adoExceptionTranslator != null) + { + //TODO investigate how ADOException wraps inner exception. + throw this.adoExceptionTranslator.Translate( + "Hibernate transaction synchronization: " + ex.Message, null, ex.InnerException); + } + else + { + throw new HibernateAdoException("ADO.NET Exception", ex); + } + } + catch (HibernateException ex) + { + throw SessionFactoryUtils.ConvertHibernateAccessException(ex); + } + } + + } + } + + /// + /// Invoked before transaction commit (before + /// ) + /// Can e.g. flush transactional O/R Mapping sessions to the database + /// + /// + /// + /// This callback does not mean that the transaction will actually be + /// commited. A rollback decision can still occur after this method + /// has been called. This callback is rather meant to perform work + /// that's only relevant if a commit still has a chance + /// to happen, such as flushing SQL statements to the database. + /// + /// + /// Note that exceptions will get propagated to the commit caller and cause a + /// rollback of the transaction. + /// + /// (note: do not throw TransactionException subclasses here!) + /// + /// + public override void BeforeCompletion() + { + if (this.newSession) + { + // Default behavior: unbind and close the thread-bound Hibernate Session. + TransactionSynchronizationManager.UnbindResource(this.sessionFactory); + this.holderActive = false; + } + else if (this.sessionHolder.AssignedPreviousFlushMode == true) + { + // In case of pre-bound Session, restore previous flush mode. + this.sessionHolder.Session.FlushMode = (this.sessionHolder.PreviousFlushMode); + } + } + + /// + /// Invoked after transaction commit/rollback. + /// + /// + /// Status according to + /// + /// + /// Can e.g. perform resource cleanup, in this case after transaction completion. + ///

+ /// Note that exceptions will get propagated to the commit or rollback + /// caller, although they will not influence the outcome of the transaction. + ///

+ ///
+ public override void AfterCompletion(TransactionSynchronizationStatus status) + { + + ISession session = sessionHolder.Session; + + // Provide correct transaction status for releasing the Session's cache locks, + // if possible. Else, closing will release all cache locks assuming a rollback. + ISessionImplementor sessionImplementor = session as ISessionImplementor; + if (sessionImplementor != null) + { + sessionImplementor.AfterTransactionCompletion(status == TransactionSynchronizationStatus.Committed); + } + + if (newSession) + { + SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, sessionFactory); + } + + if (!newSession && status != TransactionSynchronizationStatus.Committed) + { + // Clear all pending inserts/updates/deletes in the Session. + // Necessary for pre-bound Sessions, to avoid inconsistent state. + sessionHolder.Session.Clear(); + } + + if (this.sessionHolder.DoesNotHoldNonDefaultSession) { + sessionHolder.SynchronizedWithTransaction = false; + } + + } + + #endregion + + } +} diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/HibernateDaoSupport.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/HibernateDaoSupport.cs index 16d3e748..ee2f40db 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/HibernateDaoSupport.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/HibernateDaoSupport.cs @@ -47,7 +47,6 @@ namespace Spring.Data.NHibernate.Support /// ///
/// Mark Pollack (.NET) - /// $Id: HibernateDaoSupport.cs,v 1.2 2007/08/28 15:26:37 markpollack Exp $ public abstract class HibernateDaoSupport : DaoSupport { #region Fields diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/OpenSessionInViewModule.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/OpenSessionInViewModule.cs index be321e60..4fc7731b 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/OpenSessionInViewModule.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/Support/OpenSessionInViewModule.cs @@ -35,7 +35,6 @@ namespace Spring.Data.NHibernate.Support /// Mark Pollack (.NET) /// Erich Eichinger /// Harald Radi - /// $Id: OpenSessionInViewModule.cs,v 1.7 2008/01/21 06:39:12 oakinger Exp $ public class OpenSessionInViewModule : SessionScope, IHttpModule { /// diff --git a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/TemplateFlushMode.cs b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/TemplateFlushMode.cs index 2f1ee184..70224942 100644 --- a/src/Spring/Spring.Data.NHibernate/Data/NHibernate/TemplateFlushMode.cs +++ b/src/Spring/Spring.Data.NHibernate/Data/NHibernate/TemplateFlushMode.cs @@ -1,98 +1,97 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - - -namespace Spring.Data.NHibernate -{ - /// - /// Enumeration for the various Hibernate flush modes. - /// - /// Mark Pollack (.NET) - /// $Id: TemplateFlushMode.cs,v 1.1 2007/05/31 20:25:13 markpollack Exp $ - public enum TemplateFlushMode - { - /// Never flush is a good strategy for read-only units of work. - /// - /// - /// Hibernate will not track and look for changes in this case, - /// avoiding any overhead of modification detection. - ///

In case of an existing ISession, TemplateFlushMode.Never will turn - /// the hibenrate flush mode - /// to FlushMode.Never for the scope of the current operation, resetting the previous - /// flush mode afterwards. - ///

- ///
- Never, - - /// Automatic flushing is the default mode for a Hibernate Session. - /// - /// - /// A session will get flushed on transaction commit, and on certain find - /// operations that might involve already modified instances, but not - /// after each unit of work like with eager flushing. - ///

In case of an existing Session, TemplateFlushMode.Auto - /// will participate in the existing flush mode, not modifying - /// it for the current operation. - /// This in particular means that this setting will not modify an existing - /// hibernate flush mode FlushMode.Never, in contrast to TemplateFlushMode.Eager. - ///

- ///
- Auto, - - /// - /// Eager flushing leads to immediate synchronization with the database, - /// even if in a transaction. - /// - /// - /// This causes inconsistencies to show up and throw - /// a respective exception immediately, and ADO access code that participates - /// in the same transaction will see the changes as the database is already - /// aware of them then. But the drawbacks are: - ///
    - ///
  • additional communication roundtrips with the database, instead of a - /// single batch at transaction commit;
  • - ///
  • the fact that an actual database rollback is needed if the Hibernate - /// transaction rolls back (due to already submitted SQL statements).
  • - ///
- ///

In case of an existing Session, TemplateFlushMode.Eager - /// will turn the NHibernate flush mode - /// to FlushMode.Auto for the scope of the current operation and issue a flush at the - /// end, resetting the previous flush mode afterwards. - ///

- ///
- Eager, - - /// - /// Flushing at commit only is intended for units of work where no - /// intermediate flushing is desired, not even for find operations - /// that might involve already modified instances. - /// - /// - ///

In case of an existing Session, TemplateFlushMode.Commit - /// will turn the NHibernate flush mode - /// to FlushMode.Commit for the scope of the current operation, resetting the previous - /// flush mode afterwards. The only exception is an existing flush mode - /// FlushMode.Never, which will not be modified through this setting. - ///

- ///
- Commit - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + + +namespace Spring.Data.NHibernate +{ + /// + /// Enumeration for the various Hibernate flush modes. + /// + /// Mark Pollack (.NET) + public enum TemplateFlushMode + { + /// Never flush is a good strategy for read-only units of work. + /// + /// + /// Hibernate will not track and look for changes in this case, + /// avoiding any overhead of modification detection. + ///

In case of an existing ISession, TemplateFlushMode.Never will turn + /// the hibenrate flush mode + /// to FlushMode.Never for the scope of the current operation, resetting the previous + /// flush mode afterwards. + ///

+ ///
+ Never, + + /// Automatic flushing is the default mode for a Hibernate Session. + /// + /// + /// A session will get flushed on transaction commit, and on certain find + /// operations that might involve already modified instances, but not + /// after each unit of work like with eager flushing. + ///

In case of an existing Session, TemplateFlushMode.Auto + /// will participate in the existing flush mode, not modifying + /// it for the current operation. + /// This in particular means that this setting will not modify an existing + /// hibernate flush mode FlushMode.Never, in contrast to TemplateFlushMode.Eager. + ///

+ ///
+ Auto, + + /// + /// Eager flushing leads to immediate synchronization with the database, + /// even if in a transaction. + /// + /// + /// This causes inconsistencies to show up and throw + /// a respective exception immediately, and ADO access code that participates + /// in the same transaction will see the changes as the database is already + /// aware of them then. But the drawbacks are: + ///
    + ///
  • additional communication roundtrips with the database, instead of a + /// single batch at transaction commit;
  • + ///
  • the fact that an actual database rollback is needed if the Hibernate + /// transaction rolls back (due to already submitted SQL statements).
  • + ///
+ ///

In case of an existing Session, TemplateFlushMode.Eager + /// will turn the NHibernate flush mode + /// to FlushMode.Auto for the scope of the current operation and issue a flush at the + /// end, resetting the previous flush mode afterwards. + ///

+ ///
+ Eager, + + /// + /// Flushing at commit only is intended for units of work where no + /// intermediate flushing is desired, not even for find operations + /// that might involve already modified instances. + /// + /// + ///

In case of an existing Session, TemplateFlushMode.Commit + /// will turn the NHibernate flush mode + /// to FlushMode.Commit for the scope of the current operation, resetting the previous + /// flush mode afterwards. The only exception is an existing flush mode + /// FlushMode.Never, which will not be modified through this setting. + ///

+ ///
+ Commit + + } +} diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/FindHibernateDelegate.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/FindHibernateDelegate.cs index bc229e6a..ec4c683c 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/FindHibernateDelegate.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/FindHibernateDelegate.cs @@ -41,6 +41,5 @@ namespace Spring.Data.NHibernate.Generic /// /// The type of result object /// Sree Nivask (.NET) - /// $Id: FindHibernateDelegate.cs,v 1.2 2007/09/19 22:58:10 markpollack Exp $ public delegate IList FindHibernateDelegate(ISession session); } diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDaoSupport.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDaoSupport.cs index 3d210f3b..769d1c8b 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDaoSupport.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDaoSupport.cs @@ -48,7 +48,6 @@ namespace Spring.Data.NHibernate.Generic.Support /// /// Sree Nivask (.NET) /// Mark Pollack (.NET) - /// $Id: HibernateDaoSupport.cs,v 1.3 2007/09/19 22:58:10 markpollack Exp $ public abstract class HibernateDaoSupport : DaoSupport { #region Fields diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDelegate.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDelegate.cs index fb8b49c0..57a762f8 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDelegate.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateDelegate.cs @@ -40,6 +40,5 @@ namespace Spring.Data.NHibernate.Generic /// /// The type of result object /// Sree Nivask (.NET) - /// $Id: HibernateDelegate.cs,v 1.2 2007/09/19 22:58:10 markpollack Exp $ public delegate T HibernateDelegate(ISession session); } diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateTemplate.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateTemplate.cs index 5b994ab8..1638ee69 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateTemplate.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/HibernateTemplate.cs @@ -68,7 +68,6 @@ namespace Spring.Data.NHibernate.Generic /// /// Sree Nivask (.NET) /// Mark Pollack (.NET) - /// $Id: HibernateTemplate.cs,v 1.3 2008/01/24 17:29:09 markpollack Exp $ public class HibernateTemplate : HibernateAccessor, IHibernateOperations { #region Fields diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IFindHibernateCallback.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IFindHibernateCallback.cs index b84c65f4..113fd5c2 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IFindHibernateCallback.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IFindHibernateCallback.cs @@ -35,7 +35,6 @@ namespace Spring.Data.NHibernate.Generic /// /// Sree Nivask (.NET) /// Mark Pollack (.NET) - /// $Id: IFindHibernateCallback.cs,v 1.2 2007/09/19 22:58:10 markpollack Exp $ public interface IFindHibernateCallback { /// diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateCallback.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateCallback.cs index 6fd97f3f..4bb7c560 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateCallback.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateCallback.cs @@ -37,7 +37,6 @@ namespace Spring.Data.NHibernate.Generic /// /// /// Sree Nivask (.NET) - /// $Id: IHibernateCallback.cs,v 1.2 2007/09/19 22:58:10 markpollack Exp $ public interface IHibernateCallback { /// diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateOperations.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateOperations.cs index 899c88bc..26925613 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateOperations.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/Generic/IHibernateOperations.cs @@ -40,7 +40,6 @@ namespace Spring.Data.NHibernate.Generic /// /// Sree Nivask (.NET) /// Mark Pollack (.NET) - /// $Id: IHibernateOperations.cs,v 1.2 2007/09/19 22:58:10 markpollack Exp $ public interface IHibernateOperations : ICommonHibernateOperations { diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateAccessor.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateAccessor.cs index eb2f24c0..b7e0b6ee 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateAccessor.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateAccessor.cs @@ -48,7 +48,6 @@ namespace Spring.Data.NHibernate ///

/// /// Mark Pollack (.NET) - /// $Id: HibernateAccessor.cs,v 1.7 2008/01/25 15:04:28 markpollack Exp $ public abstract class HibernateAccessor : IInitializingObject, IObjectFactoryAware { diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateOptimisticLockingFailureException.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateOptimisticLockingFailureException.cs index a196d416..2478d50d 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateOptimisticLockingFailureException.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/HibernateOptimisticLockingFailureException.cs @@ -37,7 +37,6 @@ namespace Spring.Data.NHibernate /// /// Juergen Hoeller /// Mark Pollack (.NET) - /// $Id: HibernateOptimisticLockingFailureException.cs,v 1.1 2008/04/08 20:26:30 markpollack Exp $ [Serializable] public class HibernateOptimisticLockingFailureException : ObjectOptimisticLockingFailureException { diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/LocalSessionFactoryObject.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/LocalSessionFactoryObject.cs index e3232651..647c8aac 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/LocalSessionFactoryObject.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/LocalSessionFactoryObject.cs @@ -50,7 +50,6 @@ namespace Spring.Data.NHibernate /// /// /// Mark Pollack (.NET) - /// $Id: LocalSessionFactoryObject.cs,v 1.11 2008/03/21 14:12:08 markpollack Exp $ public class LocalSessionFactoryObject : IFactoryObject, IInitializingObject, System.IDisposable { #region Fields diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SessionFactoryUtils.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SessionFactoryUtils.cs index 9361bbb4..0e13824b 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SessionFactoryUtils.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SessionFactoryUtils.cs @@ -47,7 +47,6 @@ namespace Spring.Data.NHibernate /// Also provides support for exception translation. ///
/// Mark Pollack (.NET) - /// $Id: SessionFactoryUtils.cs,v 1.1 2008/04/08 20:26:30 markpollack Exp $ public abstract class SessionFactoryUtils { #region Fields diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionContext.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionContext.cs index c0ab893e..d45d948a 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionContext.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionContext.cs @@ -38,7 +38,6 @@ namespace Spring.Data.NHibernate /// qualified name of this class as value.

/// Juergen Hoeller /// Mark Pollack (.NET) - /// $Id: SpringSessionContext.cs,v 1.2 2007/09/19 22:58:11 markpollack Exp $ /// public class SpringSessionContext : ICurrentSessionContext { diff --git a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionSynchronization.cs b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionSynchronization.cs index 78ca458b..1dac6449 100644 --- a/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionSynchronization.cs +++ b/src/Spring/Spring.Data.NHibernate12/Data/NHibernate/SpringSessionSynchronization.cs @@ -35,7 +35,6 @@ namespace Spring.Data.NHibernate /// NHibnerations actions taken during the transaction lifecycle. ///
/// Mark Pollack (.NET) - /// $Id: SpringSessionSynchronization.cs,v 1.1 2007/06/01 02:34:12 markpollack Exp $ public class SpringSessionSynchronization : TransactionSynchronizationAdapter, IOrdered { #region Fields diff --git a/src/Spring/Spring.Data/Dao/CannotAcquireLockException.cs b/src/Spring/Spring.Data/Dao/CannotAcquireLockException.cs index a73c4ef4..73d247bc 100644 --- a/src/Spring/Spring.Data/Dao/CannotAcquireLockException.cs +++ b/src/Spring/Spring.Data/Dao/CannotAcquireLockException.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on failure to aquire a lock during an update i.e a select for - /// update statement. - /// - /// - ///

- /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: CannotAcquireLockException.cs,v 1.6 2008/04/08 20:26:43 markpollack Exp $ - [Serializable] - public class CannotAcquireLockException : PessimisticLockingFailureException - { - /// - /// Creates a new instance of the - /// class. - /// - public CannotAcquireLockException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public CannotAcquireLockException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public CannotAcquireLockException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected CannotAcquireLockException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on failure to aquire a lock during an update i.e a select for + /// update statement. + /// + /// + ///

+ /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class CannotAcquireLockException : PessimisticLockingFailureException + { + /// + /// Creates a new instance of the + /// class. + /// + public CannotAcquireLockException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public CannotAcquireLockException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public CannotAcquireLockException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected CannotAcquireLockException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/CannotSerializeTransactionException.cs b/src/Spring/Spring.Data/Dao/CannotSerializeTransactionException.cs index bdfcf15e..776975b4 100644 --- a/src/Spring/Spring.Data/Dao/CannotSerializeTransactionException.cs +++ b/src/Spring/Spring.Data/Dao/CannotSerializeTransactionException.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on failure to complete a transaction in serialized mode due to - /// update conflicts. - /// - /// - ///

- /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: CannotSerializeTransactionException.cs,v 1.6 2008/04/08 20:26:43 markpollack Exp $ - [Serializable] - public class CannotSerializeTransactionException : PessimisticLockingFailureException - { - /// - /// Creates a new instance of the - /// class. - /// - public CannotSerializeTransactionException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public CannotSerializeTransactionException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public CannotSerializeTransactionException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected CannotSerializeTransactionException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on failure to complete a transaction in serialized mode due to + /// update conflicts. + /// + /// + ///

+ /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class CannotSerializeTransactionException : PessimisticLockingFailureException + { + /// + /// Creates a new instance of the + /// class. + /// + public CannotSerializeTransactionException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public CannotSerializeTransactionException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public CannotSerializeTransactionException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected CannotSerializeTransactionException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/CleanupFailureDataAccessException.cs b/src/Spring/Spring.Data/Dao/CleanupFailureDataAccessException.cs index 5c344dab..de9ea026 100644 --- a/src/Spring/Spring.Data/Dao/CleanupFailureDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/CleanupFailureDataAccessException.cs @@ -1,94 +1,93 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown when we couldn't cleanup after a data access operation, - /// but the actual operation went OK. - /// - /// - ///

- /// For example, this exception or a subclass might be thrown if an ADO.NET - /// connection couldn't be closed after it had been used successfully. - ///

- ///

- /// Note that data access code might perform resource cleanup in a - /// finally block and therefore log cleanup failure rather than rethrow it, - /// to keep the original data access exception, if any. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: CleanupFailureDataAccessException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class CleanupFailureDataAccessException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public CleanupFailureDataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public CleanupFailureDataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public CleanupFailureDataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected CleanupFailureDataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown when we couldn't cleanup after a data access operation, + /// but the actual operation went OK. + /// + /// + ///

+ /// For example, this exception or a subclass might be thrown if an ADO.NET + /// connection couldn't be closed after it had been used successfully. + ///

+ ///

+ /// Note that data access code might perform resource cleanup in a + /// finally block and therefore log cleanup failure rather than rethrow it, + /// to keep the original data access exception, if any. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class CleanupFailureDataAccessException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public CleanupFailureDataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public CleanupFailureDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public CleanupFailureDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected CleanupFailureDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs b/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs index 2c6ffc71..e499fc80 100644 --- a/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs +++ b/src/Spring/Spring.Data/Dao/ConcurrencyFailureException.cs @@ -1,90 +1,89 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on concurrency failure. This exception should be - /// sublassed to indicate the type of failure - optimistic locking, - /// failure to acquire lock, etc. - /// - /// - ///

- /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - ///

- ///
- /// Thomas Risberg - /// Griffin Caprio (.NET) - /// $Id: ConcurrencyFailureException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class ConcurrencyFailureException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public ConcurrencyFailureException() : base("No Exception Message") {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public ConcurrencyFailureException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public ConcurrencyFailureException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ConcurrencyFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on concurrency failure. This exception should be + /// sublassed to indicate the type of failure - optimistic locking, + /// failure to acquire lock, etc. + /// + /// + ///

+ /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + ///

+ ///
+ /// Thomas Risberg + /// Griffin Caprio (.NET) + [Serializable] + public class ConcurrencyFailureException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public ConcurrencyFailureException() : base("No Exception Message") {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public ConcurrencyFailureException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public ConcurrencyFailureException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ConcurrencyFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/DataAccessException.cs b/src/Spring/Spring.Data/Dao/DataAccessException.cs index 66b84c64..0b4769e1 100644 --- a/src/Spring/Spring.Data/Dao/DataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/DataAccessException.cs @@ -1,81 +1,81 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Root of the hierarchy of data access exceptions - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - [Serializable] - public abstract class DataAccessException : Exception - { - /// - /// Creates a new instance of the - /// class. - /// - protected DataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - protected DataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - protected DataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected DataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Root of the hierarchy of data access exceptions + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public abstract class DataAccessException : Exception + { + /// + /// Creates a new instance of the + /// class. + /// + protected DataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + protected DataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + protected DataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected DataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } +} diff --git a/src/Spring/Spring.Data/Dao/DataAccessResourceFailureException.cs b/src/Spring/Spring.Data/Dao/DataAccessResourceFailureException.cs index e762cbdd..95144925 100644 --- a/src/Spring/Spring.Data/Dao/DataAccessResourceFailureException.cs +++ b/src/Spring/Spring.Data/Dao/DataAccessResourceFailureException.cs @@ -1,83 +1,82 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Data access exception thrown when a resource fails completely: - /// for example, if we can't connect to a database using ADO.NET. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: DataAccessResourceFailureException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class DataAccessResourceFailureException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public DataAccessResourceFailureException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public DataAccessResourceFailureException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public DataAccessResourceFailureException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected DataAccessResourceFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Data access exception thrown when a resource fails completely: + /// for example, if we can't connect to a database using ADO.NET. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class DataAccessResourceFailureException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public DataAccessResourceFailureException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public DataAccessResourceFailureException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public DataAccessResourceFailureException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected DataAccessResourceFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/DataIntegrityViolationException.cs b/src/Spring/Spring.Data/Dao/DataIntegrityViolationException.cs index 86c77d3c..7a1f3d2d 100644 --- a/src/Spring/Spring.Data/Dao/DataIntegrityViolationException.cs +++ b/src/Spring/Spring.Data/Dao/DataIntegrityViolationException.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown when an attempt to insert or update data - /// results in violation of an integrity constraint. - /// - /// - ///

- /// Note that this is not purely a relational concept; unique primary keys are - /// required by most database types. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: DataIntegrityViolationException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class DataIntegrityViolationException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public DataIntegrityViolationException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public DataIntegrityViolationException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public DataIntegrityViolationException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected DataIntegrityViolationException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown when an attempt to insert or update data + /// results in violation of an integrity constraint. + /// + /// + ///

+ /// Note that this is not purely a relational concept; unique primary keys are + /// required by most database types. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class DataIntegrityViolationException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public DataIntegrityViolationException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public DataIntegrityViolationException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public DataIntegrityViolationException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected DataIntegrityViolationException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/DataRetrievalFailureException.cs b/src/Spring/Spring.Data/Dao/DataRetrievalFailureException.cs index 0c5c8238..e84ea780 100644 --- a/src/Spring/Spring.Data/Dao/DataRetrievalFailureException.cs +++ b/src/Spring/Spring.Data/Dao/DataRetrievalFailureException.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown if certain expected data could not be retrieved, e.g. - /// when looking up specific data via a known identifier. - /// - /// - ///

- /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: DataRetrievalFailureException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class DataRetrievalFailureException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public DataRetrievalFailureException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public DataRetrievalFailureException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public DataRetrievalFailureException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected DataRetrievalFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown if certain expected data could not be retrieved, e.g. + /// when looking up specific data via a known identifier. + /// + /// + ///

+ /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class DataRetrievalFailureException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public DataRetrievalFailureException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public DataRetrievalFailureException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public DataRetrievalFailureException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected DataRetrievalFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/DeadlockLoserDataAccessException.cs b/src/Spring/Spring.Data/Dao/DeadlockLoserDataAccessException.cs index ae62ad45..18611b2e 100644 --- a/src/Spring/Spring.Data/Dao/DeadlockLoserDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/DeadlockLoserDataAccessException.cs @@ -1,83 +1,82 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Generic exception thrown when the current process was - /// a deadlock loser, and its transaction rolled back. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: DeadlockLoserDataAccessException.cs,v 1.6 2008/04/08 20:26:43 markpollack Exp $ - [Serializable] - public class DeadlockLoserDataAccessException : PessimisticLockingFailureException - { - /// - /// Creates a new instance of the - /// class. - /// - public DeadlockLoserDataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public DeadlockLoserDataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public DeadlockLoserDataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected DeadlockLoserDataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Generic exception thrown when the current process was + /// a deadlock loser, and its transaction rolled back. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class DeadlockLoserDataAccessException : PessimisticLockingFailureException + { + /// + /// Creates a new instance of the + /// class. + /// + public DeadlockLoserDataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public DeadlockLoserDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public DeadlockLoserDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected DeadlockLoserDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/EmptyResultDataAccessException.cs b/src/Spring/Spring.Data/Dao/EmptyResultDataAccessException.cs index fb83d4f0..35da8dbe 100644 --- a/src/Spring/Spring.Data/Dao/EmptyResultDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/EmptyResultDataAccessException.cs @@ -1,94 +1,93 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Data access exception thrown when a result was not of the expected size, - /// for example when expecting a single row but getting 0 or more than 1 rows. - /// - /// Mark Pollack (.NET) - /// Juergen Hoeller - /// $Id: EmptyResultDataAccessException.cs,v 1.2 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class EmptyResultDataAccessException : IncorrectResultSizeDataAccessException - { - - /// - /// Initializes a new instance of the class. - /// - public EmptyResultDataAccessException() : base () - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message. - public EmptyResultDataAccessException(string message) : base (message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message. - /// The inner exception. - public EmptyResultDataAccessException(string message, Exception innerException) : base (message, innerException) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The expected size. - public EmptyResultDataAccessException(int expectedSize) : base (expectedSize, 0) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// A message about the exception. - /// The expected size. - public EmptyResultDataAccessException( string message, int expectedSize ) : base( message, expectedSize, 0 ) {} - - - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is . - /// The class name is or is zero (0). - protected EmptyResultDataAccessException( SerializationInfo info, StreamingContext context ) : base( info, context ) - { - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Data access exception thrown when a result was not of the expected size, + /// for example when expecting a single row but getting 0 or more than 1 rows. + /// + /// Mark Pollack (.NET) + /// Juergen Hoeller + [Serializable] + public class EmptyResultDataAccessException : IncorrectResultSizeDataAccessException + { + + /// + /// Initializes a new instance of the class. + /// + public EmptyResultDataAccessException() : base () + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The message. + public EmptyResultDataAccessException(string message) : base (message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner exception. + public EmptyResultDataAccessException(string message, Exception innerException) : base (message, innerException) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The expected size. + public EmptyResultDataAccessException(int expectedSize) : base (expectedSize, 0) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// A message about the exception. + /// The expected size. + public EmptyResultDataAccessException( string message, int expectedSize ) : base( message, expectedSize, 0 ) {} + + + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is . + /// The class name is or is zero (0). + protected EmptyResultDataAccessException( SerializationInfo info, StreamingContext context ) : base( info, context ) + { + } + } +} diff --git a/src/Spring/Spring.Data/Dao/IncorrectResultSizeDataAccessException.cs b/src/Spring/Spring.Data/Dao/IncorrectResultSizeDataAccessException.cs index c0064c19..61422c73 100644 --- a/src/Spring/Spring.Data/Dao/IncorrectResultSizeDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/IncorrectResultSizeDataAccessException.cs @@ -1,173 +1,172 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Data access exception thrown when a result was not of the expected size, - /// for example when expecting a single row but getting 0 or more than 1 rows. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: IncorrectResultSizeDataAccessException.cs,v 1.6 2007/11/20 04:03:48 markpollack Exp $ - [Serializable] - public class IncorrectResultSizeDataAccessException : InvalidDataAccessApiUsageException, ISerializable - { - private int _expectedSize; - private int _actualSize; - - /// Return the expected result size. - public virtual int ExpectedSize - { - get - { - return _expectedSize; - } - } - - /// Return the actual result size (or -1 if unknown). - public virtual int ActualSize - { - get - { - return _actualSize; - } - } - - /// - /// Creates a new instance of the - /// class. - /// - public IncorrectResultSizeDataAccessException() : this( -1, -1 ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public IncorrectResultSizeDataAccessException( string message ) : this( message, -1, -1 ) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public IncorrectResultSizeDataAccessException( string message, Exception rootCause ) - : base( message, rootCause ) - { - _expectedSize = -1; - _actualSize = -1; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// The expected result size. - /// The actual result size (or -1 if unknown). - public IncorrectResultSizeDataAccessException( int expectedSize, int actualSize ) - : this ( "Incorrect result size: expected " + expectedSize + ", actual " + actualSize, expectedSize, actualSize) - { - } - - /// - /// Creates a new instance of the - /// class. - /// > - /// - /// A message about the exception. - /// - /// The expected result size. - /// The actual result size (or -1 if unknown). - public IncorrectResultSizeDataAccessException( string message, int expectedSize, int actualSize ) - : base( message ) - { - this._expectedSize = expectedSize; - this._actualSize = actualSize; - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception - /// The expected result size. - public IncorrectResultSizeDataAccessException(string message, int expectedSize) - : base(message) - { - this._expectedSize = expectedSize; - this._actualSize = -1; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected IncorrectResultSizeDataAccessException( SerializationInfo info, StreamingContext context ) : base( info, context ) - { - _expectedSize = info.GetInt32( "expectedSize" ); - _actualSize = info.GetInt32( "actualSize" ); - } - - #region ISerializable Members - /// - /// Override of - /// to allow for private serialization. - /// - /// - /// The - /// that holds the serialized object data about the exception. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "expectedSize", _expectedSize ); - info.AddValue( "actualSize", _actualSize ); - base.GetObjectData( info, context ); - } - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Data access exception thrown when a result was not of the expected size, + /// for example when expecting a single row but getting 0 or more than 1 rows. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class IncorrectResultSizeDataAccessException : InvalidDataAccessApiUsageException, ISerializable + { + private int _expectedSize; + private int _actualSize; + + /// Return the expected result size. + public virtual int ExpectedSize + { + get + { + return _expectedSize; + } + } + + /// Return the actual result size (or -1 if unknown). + public virtual int ActualSize + { + get + { + return _actualSize; + } + } + + /// + /// Creates a new instance of the + /// class. + /// + public IncorrectResultSizeDataAccessException() : this( -1, -1 ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public IncorrectResultSizeDataAccessException( string message ) : this( message, -1, -1 ) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public IncorrectResultSizeDataAccessException( string message, Exception rootCause ) + : base( message, rootCause ) + { + _expectedSize = -1; + _actualSize = -1; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// The expected result size. + /// The actual result size (or -1 if unknown). + public IncorrectResultSizeDataAccessException( int expectedSize, int actualSize ) + : this ( "Incorrect result size: expected " + expectedSize + ", actual " + actualSize, expectedSize, actualSize) + { + } + + /// + /// Creates a new instance of the + /// class. + /// > + /// + /// A message about the exception. + /// + /// The expected result size. + /// The actual result size (or -1 if unknown). + public IncorrectResultSizeDataAccessException( string message, int expectedSize, int actualSize ) + : base( message ) + { + this._expectedSize = expectedSize; + this._actualSize = actualSize; + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception + /// The expected result size. + public IncorrectResultSizeDataAccessException(string message, int expectedSize) + : base(message) + { + this._expectedSize = expectedSize; + this._actualSize = -1; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected IncorrectResultSizeDataAccessException( SerializationInfo info, StreamingContext context ) : base( info, context ) + { + _expectedSize = info.GetInt32( "expectedSize" ); + _actualSize = info.GetInt32( "actualSize" ); + } + + #region ISerializable Members + /// + /// Override of + /// to allow for private serialization. + /// + /// + /// The + /// that holds the serialized object data about the exception. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "expectedSize", _expectedSize ); + info.AddValue( "actualSize", _actualSize ); + base.GetObjectData( info, context ); + } + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/IncorrectUpdateSemanticsDataAccessException.cs b/src/Spring/Spring.Data/Dao/IncorrectUpdateSemanticsDataAccessException.cs index e50c3834..607ae1b9 100644 --- a/src/Spring/Spring.Data/Dao/IncorrectUpdateSemanticsDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/IncorrectUpdateSemanticsDataAccessException.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Data access exception thrown when something unintended appears to have - /// happened with an update, but the transaction hasn't already been rolled back. - /// - /// - ///

- /// Thrown, for example, when we wanted to update 1 row in an RDBMS but actually - /// updated 3. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: IncorrectUpdateSemanticsDataAccessException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public abstract class IncorrectUpdateSemanticsDataAccessException - : InvalidDataAccessResourceUsageException - { - /// Return whether or not data was updated. - /// - /// True if data was updated (as opposed to being incorrectly - /// updated). If this property returns false, there's nothing to roll back. - /// - public abstract bool DataWasUpdated { get; } - - /// - /// Creates a new instance of the - /// class. - /// - protected IncorrectUpdateSemanticsDataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - protected IncorrectUpdateSemanticsDataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - protected IncorrectUpdateSemanticsDataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected IncorrectUpdateSemanticsDataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Data access exception thrown when something unintended appears to have + /// happened with an update, but the transaction hasn't already been rolled back. + /// + /// + ///

+ /// Thrown, for example, when we wanted to update 1 row in an RDBMS but actually + /// updated 3. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public abstract class IncorrectUpdateSemanticsDataAccessException + : InvalidDataAccessResourceUsageException + { + /// Return whether or not data was updated. + /// + /// True if data was updated (as opposed to being incorrectly + /// updated). If this property returns false, there's nothing to roll back. + /// + public abstract bool DataWasUpdated { get; } + + /// + /// Creates a new instance of the + /// class. + /// + protected IncorrectUpdateSemanticsDataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + protected IncorrectUpdateSemanticsDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + protected IncorrectUpdateSemanticsDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected IncorrectUpdateSemanticsDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/InvalidDataAccessApiUsageException.cs b/src/Spring/Spring.Data/Dao/InvalidDataAccessApiUsageException.cs index f7f27c01..eb4c1714 100644 --- a/src/Spring/Spring.Data/Dao/InvalidDataAccessApiUsageException.cs +++ b/src/Spring/Spring.Data/Dao/InvalidDataAccessApiUsageException.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on incorrect usage of the API, such as failing to "compile" a query - /// object that needed compilation before execution. - /// - /// - ///

- /// This represents a problem in our data access framework, not the underlying data access - /// infrastructure. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: InvalidDataAccessApiUsageException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class InvalidDataAccessApiUsageException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public InvalidDataAccessApiUsageException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public InvalidDataAccessApiUsageException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public InvalidDataAccessApiUsageException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected InvalidDataAccessApiUsageException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on incorrect usage of the API, such as failing to "compile" a query + /// object that needed compilation before execution. + /// + /// + ///

+ /// This represents a problem in our data access framework, not the underlying data access + /// infrastructure. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class InvalidDataAccessApiUsageException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public InvalidDataAccessApiUsageException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public InvalidDataAccessApiUsageException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public InvalidDataAccessApiUsageException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected InvalidDataAccessApiUsageException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/InvalidDataAccessResourceUsageException.cs b/src/Spring/Spring.Data/Dao/InvalidDataAccessResourceUsageException.cs index 65cec5ef..3d8958c1 100644 --- a/src/Spring/Spring.Data/Dao/InvalidDataAccessResourceUsageException.cs +++ b/src/Spring/Spring.Data/Dao/InvalidDataAccessResourceUsageException.cs @@ -1,88 +1,87 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Root for exceptions thrown when we use a data access resource incorrectly. - /// - /// - ///

- /// Thrown for example on specifying bad SQL when using a RDBMS. - /// Resource-specific subclasses will probably be supplied by data access packages. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: InvalidDataAccessResourceUsageException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class InvalidDataAccessResourceUsageException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public InvalidDataAccessResourceUsageException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public InvalidDataAccessResourceUsageException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public InvalidDataAccessResourceUsageException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected InvalidDataAccessResourceUsageException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Root for exceptions thrown when we use a data access resource incorrectly. + /// + /// + ///

+ /// Thrown for example on specifying bad SQL when using a RDBMS. + /// Resource-specific subclasses will probably be supplied by data access packages. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class InvalidDataAccessResourceUsageException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public InvalidDataAccessResourceUsageException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public InvalidDataAccessResourceUsageException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public InvalidDataAccessResourceUsageException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected InvalidDataAccessResourceUsageException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/ObjectOptimisticLockingFailureException.cs b/src/Spring/Spring.Data/Dao/ObjectOptimisticLockingFailureException.cs index 39fd8b0c..29ca35c4 100644 --- a/src/Spring/Spring.Data/Dao/ObjectOptimisticLockingFailureException.cs +++ b/src/Spring/Spring.Data/Dao/ObjectOptimisticLockingFailureException.cs @@ -1,176 +1,175 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on an optimistic locking violation for a mapped object. - /// Provides information about the persistent class and the identifier. - /// - /// Mark Pollack (.NET) - /// $Id: ObjectOptimisticLockingFailureException.cs,v 1.1 2006/12/13 18:40:11 markpollack Exp $ - [Serializable] - public class ObjectOptimisticLockingFailureException : OptimisticLockingFailureException, ISerializable - { - #region Fields - - private object persistentClass; - - private object identifier; - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public ObjectOptimisticLockingFailureException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception.. - public ObjectOptimisticLockingFailureException(string message) : base(message) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception from the underlying data access API - /// - public ObjectOptimisticLockingFailureException(string message, Exception rootCause) : base(message, rootCause) - { - } - - public ObjectOptimisticLockingFailureException(Type persistentClass, Object identifier) : this(persistentClass, identifier, - "Object of class [" + persistentClass.Name + "] with identifier [" + identifier + - "]: optimistic locking failed", null) - { - - } - - public ObjectOptimisticLockingFailureException( - Type persistentClass, Object identifier, String msg, Exception ex) : base(msg, ex) - { - this.persistentClass = persistentClass; - this.identifier = identifier; - } - - public ObjectOptimisticLockingFailureException(String persistentClassName, Object identifier) : this(persistentClassName, identifier, - "Object of class [" + persistentClassName + "] with identifier [" + identifier + - "]: optimistic locking failed", null) - { - - } - - public ObjectOptimisticLockingFailureException( - String persistentClassName, Object identifier, String msg, Exception ex) : base(msg, ex) - { - this.persistentClass = persistentClassName; - this.identifier = identifier; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectOptimisticLockingFailureException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - #endregion - - public Type PersistentClass - { - get { return persistentClass as Type;} - } - - public object Identifier - { - get { return identifier; } - } - - public string PersistentClassName - { - get - { - if (this.persistentClass is Type) - { - return ((Type) this.persistentClass).Name; - } - return (this.persistentClass != null ? this.persistentClass.ToString() : null); - - } - } - - - - - #region Properties - - #endregion - - #region Methods - - #endregion - - #region ISerializable Members - - /// - /// When overridden in a derived class, sets the - /// with information about the exception. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is a null reference ( in Visual Basic). - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "persistentClass", persistentClass ); - info.AddValue( "identifier", identifier ); - base.GetObjectData( info, context ); - } - - #endregion - } +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on an optimistic locking violation for a mapped object. + /// Provides information about the persistent class and the identifier. + /// + /// Mark Pollack (.NET) + [Serializable] + public class ObjectOptimisticLockingFailureException : OptimisticLockingFailureException, ISerializable + { + #region Fields + + private object persistentClass; + + private object identifier; + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public ObjectOptimisticLockingFailureException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception.. + public ObjectOptimisticLockingFailureException(string message) : base(message) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception from the underlying data access API + /// + public ObjectOptimisticLockingFailureException(string message, Exception rootCause) : base(message, rootCause) + { + } + + public ObjectOptimisticLockingFailureException(Type persistentClass, Object identifier) : this(persistentClass, identifier, + "Object of class [" + persistentClass.Name + "] with identifier [" + identifier + + "]: optimistic locking failed", null) + { + + } + + public ObjectOptimisticLockingFailureException( + Type persistentClass, Object identifier, String msg, Exception ex) : base(msg, ex) + { + this.persistentClass = persistentClass; + this.identifier = identifier; + } + + public ObjectOptimisticLockingFailureException(String persistentClassName, Object identifier) : this(persistentClassName, identifier, + "Object of class [" + persistentClassName + "] with identifier [" + identifier + + "]: optimistic locking failed", null) + { + + } + + public ObjectOptimisticLockingFailureException( + String persistentClassName, Object identifier, String msg, Exception ex) : base(msg, ex) + { + this.persistentClass = persistentClassName; + this.identifier = identifier; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectOptimisticLockingFailureException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + #endregion + + public Type PersistentClass + { + get { return persistentClass as Type;} + } + + public object Identifier + { + get { return identifier; } + } + + public string PersistentClassName + { + get + { + if (this.persistentClass is Type) + { + return ((Type) this.persistentClass).Name; + } + return (this.persistentClass != null ? this.persistentClass.ToString() : null); + + } + } + + + + + #region Properties + + #endregion + + #region Methods + + #endregion + + #region ISerializable Members + + /// + /// When overridden in a derived class, sets the + /// with information about the exception. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is a null reference ( in Visual Basic). + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "persistentClass", persistentClass ); + info.AddValue( "identifier", identifier ); + base.GetObjectData( info, context ); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/ObjectRetrievalFailureException.cs b/src/Spring/Spring.Data/Dao/ObjectRetrievalFailureException.cs index 42c37439..15d326e2 100644 --- a/src/Spring/Spring.Data/Dao/ObjectRetrievalFailureException.cs +++ b/src/Spring/Spring.Data/Dao/ObjectRetrievalFailureException.cs @@ -1,157 +1,156 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown if a mapped object could not be retrieved via its identifier. - /// Provides information about the persistent class and the identifier. - /// - /// Mark Pollack (.NET) - /// $Id: ObjectRetrievalFailureException.cs,v 1.1 2006/12/13 18:40:11 markpollack Exp $ - [Serializable] - public class ObjectRetrievalFailureException : DataRetrievalFailureException, ISerializable - { - private object persistentClass; - - private object identifier; - - #region Constructor (s) - - /// - /// Creates a new instance of the - /// class. - /// - public ObjectRetrievalFailureException() {} - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - public ObjectRetrievalFailureException(string message) : base(message) - { - - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception from the underlying data access API - /// - public ObjectRetrievalFailureException(string message, Exception rootCause) : base(message, rootCause) - { - } - - - public ObjectRetrievalFailureException(Type persistentClass, object identifier) : this(persistentClass, identifier, "Object of class [" + persistentClass.Name + "] with identifier [" + identifier + "]: not found", null) - { - } - - - public ObjectRetrievalFailureException( - Type persistentClass, Object identifier, String msg, Exception ex) : base(msg, ex) - { - this.persistentClass = persistentClass; - this.identifier = identifier; - } - - public ObjectRetrievalFailureException(String persistentClassName, Object identifier) : this(persistentClassName, identifier, - "Object of class [" + persistentClassName + "] with identifier [" + identifier + "]: not found", - null) - { - - } - - public ObjectRetrievalFailureException( - String persistentClassName, Object identifier, String msg, Exception ex) : base(msg, ex) - { - this.persistentClass = persistentClassName; - this.identifier = identifier; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected ObjectRetrievalFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - #endregion - - public object PersistentClass - { - get { return persistentClass; } - } - - public object Identifier - { - get { return identifier; } - } - - public string PersistentClassName - { - get - { - if (this.persistentClass is Type) - { - return ((Type) this.persistentClass).Name; - } - return (this.persistentClass != null ? this.persistentClass.ToString() : null); - - } - } - - /// - /// When overridden in a derived class, sets the - /// with information about the exception. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is a null reference ( in Visual Basic). - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "persistentClass", persistentClass ); - info.AddValue( "identifier", identifier ); - base.GetObjectData( info, context ); - } - - } +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown if a mapped object could not be retrieved via its identifier. + /// Provides information about the persistent class and the identifier. + /// + /// Mark Pollack (.NET) + [Serializable] + public class ObjectRetrievalFailureException : DataRetrievalFailureException, ISerializable + { + private object persistentClass; + + private object identifier; + + #region Constructor (s) + + /// + /// Creates a new instance of the + /// class. + /// + public ObjectRetrievalFailureException() {} + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + public ObjectRetrievalFailureException(string message) : base(message) + { + + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception from the underlying data access API + /// + public ObjectRetrievalFailureException(string message, Exception rootCause) : base(message, rootCause) + { + } + + + public ObjectRetrievalFailureException(Type persistentClass, object identifier) : this(persistentClass, identifier, "Object of class [" + persistentClass.Name + "] with identifier [" + identifier + "]: not found", null) + { + } + + + public ObjectRetrievalFailureException( + Type persistentClass, Object identifier, String msg, Exception ex) : base(msg, ex) + { + this.persistentClass = persistentClass; + this.identifier = identifier; + } + + public ObjectRetrievalFailureException(String persistentClassName, Object identifier) : this(persistentClassName, identifier, + "Object of class [" + persistentClassName + "] with identifier [" + identifier + "]: not found", + null) + { + + } + + public ObjectRetrievalFailureException( + String persistentClassName, Object identifier, String msg, Exception ex) : base(msg, ex) + { + this.persistentClass = persistentClassName; + this.identifier = identifier; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected ObjectRetrievalFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + #endregion + + public object PersistentClass + { + get { return persistentClass; } + } + + public object Identifier + { + get { return identifier; } + } + + public string PersistentClassName + { + get + { + if (this.persistentClass is Type) + { + return ((Type) this.persistentClass).Name; + } + return (this.persistentClass != null ? this.persistentClass.ToString() : null); + + } + } + + /// + /// When overridden in a derived class, sets the + /// with information about the exception. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is a null reference ( in Visual Basic). + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "persistentClass", persistentClass ); + info.AddValue( "identifier", identifier ); + base.GetObjectData( info, context ); + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/OptimisticLockingFailureException.cs b/src/Spring/Spring.Data/Dao/OptimisticLockingFailureException.cs index a77e3044..75fb334e 100644 --- a/src/Spring/Spring.Data/Dao/OptimisticLockingFailureException.cs +++ b/src/Spring/Spring.Data/Dao/OptimisticLockingFailureException.cs @@ -1,88 +1,87 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on an optimistic locking violation. - /// - /// - ///

- /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: OptimisticLockingFailureException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class OptimisticLockingFailureException : ConcurrencyFailureException - { - /// - /// Creates a new instance of the - /// class. - /// - public OptimisticLockingFailureException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public OptimisticLockingFailureException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public OptimisticLockingFailureException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected OptimisticLockingFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on an optimistic locking violation. + /// + /// + ///

+ /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class OptimisticLockingFailureException : ConcurrencyFailureException + { + /// + /// Creates a new instance of the + /// class. + /// + public OptimisticLockingFailureException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public OptimisticLockingFailureException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public OptimisticLockingFailureException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected OptimisticLockingFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/PermissionDeniedDataAccessException.cs b/src/Spring/Spring.Data/Dao/PermissionDeniedDataAccessException.cs index 9d91eb92..f505d31a 100644 --- a/src/Spring/Spring.Data/Dao/PermissionDeniedDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/PermissionDeniedDataAccessException.cs @@ -1,83 +1,82 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown when the underlyingresource denied a permission to - /// access a specific element, such as a specific database table. - /// - /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: PermissionDeniedDataAccessException.cs,v 1.1 2006/06/12 10:39:19 markpollack Exp $ - [Serializable] - public class PermissionDeniedDataAccessException : InvalidDataAccessResourceUsageException - { - /// - /// Creates a new instance of the - /// class. - /// - public PermissionDeniedDataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public PermissionDeniedDataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public PermissionDeniedDataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected PermissionDeniedDataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown when the underlyingresource denied a permission to + /// access a specific element, such as a specific database table. + /// + /// Juergen Hoeller + /// Mark Pollack (.NET) + [Serializable] + public class PermissionDeniedDataAccessException : InvalidDataAccessResourceUsageException + { + /// + /// Creates a new instance of the + /// class. + /// + public PermissionDeniedDataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public PermissionDeniedDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public PermissionDeniedDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected PermissionDeniedDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/PessimisticLockingFailureException.cs b/src/Spring/Spring.Data/Dao/PessimisticLockingFailureException.cs index 901ab619..708f36b3 100644 --- a/src/Spring/Spring.Data/Dao/PessimisticLockingFailureException.cs +++ b/src/Spring/Spring.Data/Dao/PessimisticLockingFailureException.cs @@ -1,91 +1,90 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on a pessimistic locking violation. - /// - /// - /// Serves as a superclass for more specific exceptions, like - /// CannotAcquireLockException and DeadlockLoserDataAccessException - /// - /// - /// This exception will be thrown either by O/R mapping tools or by custom DAO - /// implementations. - /// - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: PessimisticLockingFailureException.cs,v 1.1 2008/04/08 20:26:43 markpollack Exp $ - [Serializable] - public class PessimisticLockingFailureException : ConcurrencyFailureException - { - /// - /// Creates a new instance of the - /// class. - /// - public PessimisticLockingFailureException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public PessimisticLockingFailureException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public PessimisticLockingFailureException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected PessimisticLockingFailureException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on a pessimistic locking violation. + /// + /// + /// Serves as a superclass for more specific exceptions, like + /// CannotAcquireLockException and DeadlockLoserDataAccessException + /// + /// + /// This exception will be thrown either by O/R mapping tools or by custom DAO + /// implementations. + /// + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class PessimisticLockingFailureException : ConcurrencyFailureException + { + /// + /// Creates a new instance of the + /// class. + /// + public PessimisticLockingFailureException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public PessimisticLockingFailureException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public PessimisticLockingFailureException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected PessimisticLockingFailureException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/Support/DaoSupport.cs b/src/Spring/Spring.Data/Dao/Support/DaoSupport.cs index e547f7ac..0913d441 100644 --- a/src/Spring/Spring.Data/Dao/Support/DaoSupport.cs +++ b/src/Spring/Spring.Data/Dao/Support/DaoSupport.cs @@ -1,115 +1,114 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Common.Logging; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Dao.Support -{ - /// - /// Generic base class for DAOs, defining template methods for DAO initialization. - /// - /// - /// Extended by Spring's specific DAO support classes, such as: - /// AdoDaoSupport, HibernateDaoSupport, etc. - /// - /// Mark Pollack (.NET) - /// $Id: DaoSupport.cs,v 1.3 2006/11/13 07:04:45 markpollack Exp $ - public abstract class DaoSupport : IInitializingObject - { - #region Fields - - #endregion - - #region Constants - - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (DaoSupport)); - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public DaoSupport() - { - - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - /// - /// Abstract subclasses must override this to check their configuration. - /// - /// - ///

Implementors should be marked as sealed, to make it clear that - /// concrete subclasses are not supposed to override this template method themselves. - ///

- ///
- protected abstract void CheckDaoConfig(); - - /// - /// Concrete subclasses can override this for custom initialization behavior. - /// - /// - /// Gets called after population of this instance's object properties. - /// Exception thrown if InitDao fails will be rethrown as - /// a ObjectInitializationException. - /// - protected virtual void InitDao() - { - - } - - - #endregion - - public void AfterPropertiesSet() - { - // Let abstract subclasses check their configuration. - CheckDaoConfig(); - - // Let concrete implementations initialize themselves. - try - { - InitDao(); - } - catch (Exception ex) - { - throw new ObjectInitializationException("Initialization of DAO failed: " + ex.Message, ex); - } - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Common.Logging; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Dao.Support +{ + /// + /// Generic base class for DAOs, defining template methods for DAO initialization. + /// + /// + /// Extended by Spring's specific DAO support classes, such as: + /// AdoDaoSupport, HibernateDaoSupport, etc. + /// + /// Mark Pollack (.NET) + public abstract class DaoSupport : IInitializingObject + { + #region Fields + + #endregion + + #region Constants + + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (DaoSupport)); + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public DaoSupport() + { + + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + /// + /// Abstract subclasses must override this to check their configuration. + /// + /// + ///

Implementors should be marked as sealed, to make it clear that + /// concrete subclasses are not supposed to override this template method themselves. + ///

+ ///
+ protected abstract void CheckDaoConfig(); + + /// + /// Concrete subclasses can override this for custom initialization behavior. + /// + /// + /// Gets called after population of this instance's object properties. + /// Exception thrown if InitDao fails will be rethrown as + /// a ObjectInitializationException. + /// + protected virtual void InitDao() + { + + } + + + #endregion + + public void AfterPropertiesSet() + { + // Let abstract subclasses check their configuration. + CheckDaoConfig(); + + // Let concrete implementations initialize themselves. + try + { + InitDao(); + } + catch (Exception ex) + { + throw new ObjectInitializationException("Initialization of DAO failed: " + ex.Message, ex); + } + } + } +} diff --git a/src/Spring/Spring.Data/Dao/Support/DataAccessUtils.cs b/src/Spring/Spring.Data/Dao/Support/DataAccessUtils.cs index c93e984d..92001585 100644 --- a/src/Spring/Spring.Data/Dao/Support/DataAccessUtils.cs +++ b/src/Spring/Spring.Data/Dao/Support/DataAccessUtils.cs @@ -1,72 +1,71 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Util; - -#endregion - -namespace Spring.Dao.Support -{ - /// - /// Miscellaneous utility methods for DAO implementations. - /// Useful with any data access technology. - /// - /// Mark Pollack (.NET) - /// $Id: DataAccessUtils.cs,v 1.3 2006/12/02 07:35:23 markpollack Exp $ - public class DataAccessUtils - { - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public DataAccessUtils() - { - - } - - #endregion - - #region Methods - - public static object RequiredUniqueResultSet(IList results) - { - int size = (results != null ? results.Count : 0); - if (size == 0) - { - throw new EmptyResultDataAccessException(1); - } - if ( ! CollectionUtils.HasUniqueObject(results)) - { - throw new IncorrectResultSizeDataAccessException(1, size); - } - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - return enumerator.Current; - } - - #endregion - } - -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Util; + +#endregion + +namespace Spring.Dao.Support +{ + /// + /// Miscellaneous utility methods for DAO implementations. + /// Useful with any data access technology. + /// + /// Mark Pollack (.NET) + public class DataAccessUtils + { + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public DataAccessUtils() + { + + } + + #endregion + + #region Methods + + public static object RequiredUniqueResultSet(IList results) + { + int size = (results != null ? results.Count : 0); + if (size == 0) + { + throw new EmptyResultDataAccessException(1); + } + if ( ! CollectionUtils.HasUniqueObject(results)) + { + throw new IncorrectResultSizeDataAccessException(1, size); + } + IEnumerator enumerator = results.GetEnumerator(); + enumerator.MoveNext(); + return enumerator.Current; + } + + #endregion + } + +} diff --git a/src/Spring/Spring.Data/Dao/Support/Generic/DataAccessUtils.cs b/src/Spring/Spring.Data/Dao/Support/Generic/DataAccessUtils.cs index 99b53f48..6126c59b 100644 --- a/src/Spring/Spring.Data/Dao/Support/Generic/DataAccessUtils.cs +++ b/src/Spring/Spring.Data/Dao/Support/Generic/DataAccessUtils.cs @@ -1,76 +1,75 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System; -using System.Collections; -using System.Collections.Generic; -using Spring.Util.Generic; - -#endregion - -namespace Spring.Dao.Support.Generic -{ - /// - /// Miscellaneous utility methods for DAO implementations. - /// Useful with any data access technology. - /// - /// Mark Pollack (.NET) - /// $Id: DataAccessUtils.cs,v 1.1 2006/12/02 20:50:21 markpollack Exp $ - public class DataAccessUtils - { - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public DataAccessUtils() - { - - } - - #endregion - - #region Methods - - public static T RequiredUniqueResultSet(IList results) - { - int size = (results != null ? results.Count : 0); - if (size == 0) - { - throw new EmptyResultDataAccessException(1); - } - if ( ! CollectionUtils.HasUniqueObject(results)) - { - throw new IncorrectResultSizeDataAccessException(1, size); - } - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - return enumerator.Current; - } - - #endregion - } - -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System; +using System.Collections; +using System.Collections.Generic; +using Spring.Util.Generic; + +#endregion + +namespace Spring.Dao.Support.Generic +{ + /// + /// Miscellaneous utility methods for DAO implementations. + /// Useful with any data access technology. + /// + /// Mark Pollack (.NET) + public class DataAccessUtils + { + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public DataAccessUtils() + { + + } + + #endregion + + #region Methods + + public static T RequiredUniqueResultSet(IList results) + { + int size = (results != null ? results.Count : 0); + if (size == 0) + { + throw new EmptyResultDataAccessException(1); + } + if ( ! CollectionUtils.HasUniqueObject(results)) + { + throw new IncorrectResultSizeDataAccessException(1, size); + } + IEnumerator enumerator = results.GetEnumerator(); + enumerator.MoveNext(); + return enumerator.Current; + } + + #endregion + } + +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/TypeMismatchDataAccessException.cs b/src/Spring/Spring.Data/Dao/TypeMismatchDataAccessException.cs index b74c8fa7..3edd6517 100644 --- a/src/Spring/Spring.Data/Dao/TypeMismatchDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/TypeMismatchDataAccessException.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Exception thrown on mismatch between CLS type and database type: - /// for example on an attempt to set an object of the wrong type - /// in an RDBMS column. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: TypeMismatchDataAccessException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public class TypeMismatchDataAccessException : InvalidDataAccessResourceUsageException - { - /// - /// Creates a new instance of the - /// class. - /// - public TypeMismatchDataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public TypeMismatchDataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public TypeMismatchDataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TypeMismatchDataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Exception thrown on mismatch between CLS type and database type: + /// for example on an attempt to set an object of the wrong type + /// in an RDBMS column. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class TypeMismatchDataAccessException : InvalidDataAccessResourceUsageException + { + /// + /// Creates a new instance of the + /// class. + /// + public TypeMismatchDataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TypeMismatchDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public TypeMismatchDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TypeMismatchDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Dao/UncategorizedDataAccessException.cs b/src/Spring/Spring.Data/Dao/UncategorizedDataAccessException.cs index 1ea9397e..9b9169de 100644 --- a/src/Spring/Spring.Data/Dao/UncategorizedDataAccessException.cs +++ b/src/Spring/Spring.Data/Dao/UncategorizedDataAccessException.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; - -#endregion - -namespace Spring.Dao -{ - /// - /// Normal superclass when we can't distinguish anything more specific - /// than "something went wrong with the underlying resource": for example, - /// a SQLException from Sql Server that we can't pinpoint more precisely. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: UncategorizedDataAccessException.cs,v 1.5 2006/05/18 21:37:50 markpollack Exp $ - [Serializable] - public abstract class UncategorizedDataAccessException : DataAccessException - { - /// - /// Creates a new instance of the - /// class. - /// - public UncategorizedDataAccessException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public UncategorizedDataAccessException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception (from the underlying data access API, such as ADO.NET). - /// - public UncategorizedDataAccessException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected UncategorizedDataAccessException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; + +#endregion + +namespace Spring.Dao +{ + /// + /// Normal superclass when we can't distinguish anything more specific + /// than "something went wrong with the underlying resource": for example, + /// a SQLException from Sql Server that we can't pinpoint more precisely. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public abstract class UncategorizedDataAccessException : DataAccessException + { + /// + /// Creates a new instance of the + /// class. + /// + public UncategorizedDataAccessException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public UncategorizedDataAccessException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception (from the underlying data access API, such as ADO.NET). + /// + public UncategorizedDataAccessException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected UncategorizedDataAccessException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/BadSqlGrammarException.cs b/src/Spring/Spring.Data/Data/BadSqlGrammarException.cs index 80f0d98a..5f05c0c2 100644 --- a/src/Spring/Spring.Data/Data/BadSqlGrammarException.cs +++ b/src/Spring/Spring.Data/Data/BadSqlGrammarException.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Dao; - -#endregion - -namespace Spring.Data -{ - /// - /// Exception thrown when SQL specified is invalid. - /// - /// Mark Pollack (.NET) - /// $Id: BadSqlGrammarException.cs,v 1.3 2006/11/29 07:18:45 markpollack Exp $ - [Serializable] - public class BadSqlGrammarException : InvalidDataAccessResourceUsageException, ISerializable - { - #region Fields - - /// - /// SQL that led to the problem - /// - private string sql; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public BadSqlGrammarException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - public BadSqlGrammarException(string message): base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - /// The inner exception. - public BadSqlGrammarException(string message, Exception inner): base(message, inner) - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// name of the current task. - /// The offending SQL statment - /// The root cause. - public BadSqlGrammarException(string task, String sql, Exception ex) : base(task + "; bad SQL grammar [" + sql + "]; " + ex.Message, ex) - { - this.sql = sql; - } - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected BadSqlGrammarException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - - #endregion - - #region Properties - - public string Sql - { - get - { - return sql; - } - } - #endregion - - - #region ISerializable Members - - /// - /// When overridden in a derived class, sets the - /// with information about the exception. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is a null reference ( in Visual Basic). - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "sql", sql ); - base.GetObjectData( info, context ); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Dao; + +#endregion + +namespace Spring.Data +{ + /// + /// Exception thrown when SQL specified is invalid. + /// + /// Mark Pollack (.NET) + [Serializable] + public class BadSqlGrammarException : InvalidDataAccessResourceUsageException, ISerializable + { + #region Fields + + /// + /// SQL that led to the problem + /// + private string sql; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public BadSqlGrammarException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + public BadSqlGrammarException(string message): base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + /// The inner exception. + public BadSqlGrammarException(string message, Exception inner): base(message, inner) + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// name of the current task. + /// The offending SQL statment + /// The root cause. + public BadSqlGrammarException(string task, String sql, Exception ex) : base(task + "; bad SQL grammar [" + sql + "]; " + ex.Message, ex) + { + this.sql = sql; + } + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected BadSqlGrammarException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + + #endregion + + #region Properties + + public string Sql + { + get + { + return sql; + } + } + #endregion + + + #region ISerializable Members + + /// + /// When overridden in a derived class, sets the + /// with information about the exception. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is a null reference ( in Visual Basic). + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "sql", sql ); + base.GetObjectData( info, context ); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Data/CannotGetAdoConnectionException.cs b/src/Spring/Spring.Data/Data/CannotGetAdoConnectionException.cs index 649cda4e..93308924 100644 --- a/src/Spring/Spring.Data/Data/CannotGetAdoConnectionException.cs +++ b/src/Spring/Spring.Data/Data/CannotGetAdoConnectionException.cs @@ -1,89 +1,88 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Dao; - -#endregion - -namespace Spring.Data -{ - /// - /// Fatal exception thrown when we can't connect to an RDBMS using ADO.NET - /// - /// Rod Johnson - /// Mark Pollack (.NET) - /// $Id: CannotGetAdoConnectionException.cs,v 1.1 2006/11/24 05:57:46 markpollack Exp $ - [Serializable] - public class CannotGetAdoConnectionException : InvalidDataAccessResourceUsageException, ISerializable - { - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public CannotGetAdoConnectionException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - public CannotGetAdoConnectionException(string message): base(message) - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - /// The inner exception. - public CannotGetAdoConnectionException(string message, Exception inner) - : base(message, inner) - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected CannotGetAdoConnectionException(SerializationInfo info, StreamingContext context) : base(info, context) { } - - - - #endregion - - - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Dao; + +#endregion + +namespace Spring.Data +{ + /// + /// Fatal exception thrown when we can't connect to an RDBMS using ADO.NET + /// + /// Rod Johnson + /// Mark Pollack (.NET) + [Serializable] + public class CannotGetAdoConnectionException : InvalidDataAccessResourceUsageException, ISerializable + { + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public CannotGetAdoConnectionException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + public CannotGetAdoConnectionException(string message): base(message) + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + /// The inner exception. + public CannotGetAdoConnectionException(string message, Exception inner) + : base(message, inner) + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected CannotGetAdoConnectionException(SerializationInfo info, StreamingContext context) : base(info, context) { } + + + + #endregion + + + + } +} diff --git a/src/Spring/Spring.Data/Data/CommandDelegate.cs b/src/Spring/Spring.Data/Data/CommandDelegate.cs index 5031e919..b8d195f1 100644 --- a/src/Spring/Spring.Data/Data/CommandDelegate.cs +++ b/src/Spring/Spring.Data/Data/CommandDelegate.cs @@ -1,42 +1,42 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; - -namespace Spring.Data -{ - /// - /// Callback delegate for code that operates on a IDbCommand. - /// - /// the ADO.NET command object. - /// - ///

Allows you to execute any number of operations - /// on a single IDbCommand, for example a single ExecuteScalar - /// call or repeated execute calls with varying parameters. - ///

- ///

Used internally by AdoTemplate, but also useful for - /// application code. Note that the passed in IDbCommand - /// has been created by the framework and will have its - /// Connection property set and the Transaction property - /// set based on the transaction context.

- ///
- /// Mark Pollack - public delegate object CommandDelegate(IDbCommand command); -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; + +namespace Spring.Data +{ + /// + /// Callback delegate for code that operates on a IDbCommand. + /// + /// the ADO.NET command object. + /// + ///

Allows you to execute any number of operations + /// on a single IDbCommand, for example a single ExecuteScalar + /// call or repeated execute calls with varying parameters. + ///

+ ///

Used internally by AdoTemplate, but also useful for + /// application code. Note that the passed in IDbCommand + /// has been created by the framework and will have its + /// Connection property set and the Transaction property + /// set based on the transaction context.

+ ///
+ /// Mark Pollack + public delegate object CommandDelegate(IDbCommand command); +} diff --git a/src/Spring/Spring.Data/Data/CommandSetterDelegate.cs b/src/Spring/Spring.Data/Data/CommandSetterDelegate.cs index 6427eec5..6315cd29 100644 --- a/src/Spring/Spring.Data/Data/CommandSetterDelegate.cs +++ b/src/Spring/Spring.Data/Data/CommandSetterDelegate.cs @@ -1,34 +1,34 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; - -namespace Spring.Data -{ - /// - /// Callback delegate to set any necessary parameters or other - /// properties on the command object. The CommandType and - /// CommandText properties will have already been supplied - /// - /// The database command object. - /// Mark Pollack - public delegate void CommandSetterDelegate(IDbCommand dbCommand); - -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; + +namespace Spring.Data +{ + /// + /// Callback delegate to set any necessary parameters or other + /// properties on the command object. The CommandType and + /// CommandText properties will have already been supplied + /// + /// The database command object. + /// Mark Pollack + public delegate void CommandSetterDelegate(IDbCommand dbCommand); + +} diff --git a/src/Spring/Spring.Data/Data/Common/DbMetadata.cs b/src/Spring/Spring.Data/Data/Common/DbMetadata.cs index 69cf20c7..c9a215b1 100644 --- a/src/Spring/Spring.Data/Data/Common/DbMetadata.cs +++ b/src/Spring/Spring.Data/Data/Common/DbMetadata.cs @@ -1,420 +1,419 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using Spring.Util; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// Provides database metdata information. - /// - /// Mark Pollack (.NET) - /// $Id: DbMetadata.cs,v 1.13 2007/11/21 18:01:45 markpollack Exp $ - public class DbMetadata : IDbMetadata - { - #region Fields - - private bool supportsDeriveParametersMethod = true; - - private string productName; - private string assemblyName; - private Type connectionType; - private Type commandType; - private Type parameterType; - private Type dataAdapterType; - - - private Type parameterDbType; - private PropertyInfo parameterDbTypeProperty; - private PropertyInfo parameterIsNullableProperty; - private string parameterNamePrefix; - - private Type exceptionType; - private bool useParameterNamePrefixInParameterCollection; - private bool useParameterPrefixInSql; - private bool bindByName; - - - - - private Type commandBuilderType; - private MethodInfo commandBuilderDeriveParametersMethod; - - private string errorCodeExceptionExpression = string.Empty; - - private ErrorCodes errorCodes; - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - /// Name of the product. - /// Name of the assembly. - /// Type of the connection. - /// Type of the command. - /// Type of the parameter. - /// Type of the data adapter. - /// Type of the command builder. - /// The command builder derive parameters method. - /// Type of the parameter db. - /// The parameter db type property. - /// The parameter is nullable property. - /// The parameter name prefix. - /// Type of the exception. - /// if set to true [use parameter name prefix in parameter collection]. - /// if set to true [use parameter prefix in SQL]. - /// if set to true [bind by name]. - /// The error code exception expression. - public DbMetadata(string productName, - string assemblyName, - Type connectionType, - Type commandType, - Type parameterType, - Type dataAdapterType, - Type commandBuilderType, - string commandBuilderDeriveParametersMethod, - Type parameterDbType, - string parameterDbTypeProperty, - string parameterIsNullableProperty, - string parameterNamePrefix, - Type exceptionType, - bool useParameterNamePrefixInParameterCollection, - bool useParameterPrefixInSql, - bool bindByName, - string errorCodeExceptionExpression - - ) - { - - AssertUtils.ArgumentHasText(productName, "ProductName"); - this.productName = productName; - AssertUtils.ArgumentHasText(assemblyName, "assemblyName", GetErrorMessage() ); - AssertUtils.ArgumentNotNull(connectionType, "connectionType", GetErrorMessage() ); - AssertUtils.ArgumentNotNull(commandType, "commandType", GetErrorMessage()); - AssertUtils.ArgumentNotNull(parameterType, "parameterType", GetErrorMessage()); - AssertUtils.ArgumentNotNull(dataAdapterType, "dataAdapterType", GetErrorMessage()); - AssertUtils.ArgumentNotNull(commandBuilderType, "commandBuilderType", GetErrorMessage()); - AssertUtils.ArgumentHasText(commandBuilderDeriveParametersMethod, "commandBuilderDeriveParametersMethod", GetErrorMessage()); - AssertUtils.ArgumentNotNull(parameterDbType, "parameterDbType", GetErrorMessage()); - AssertUtils.ArgumentHasText(parameterDbTypeProperty, "parameterDbTypeProperty", GetErrorMessage()); - AssertUtils.ArgumentHasText(parameterIsNullableProperty, "parameterIsNullableProperty", GetErrorMessage()); - AssertUtils.ArgumentHasText(parameterNamePrefix, "parameterNamePrefix", GetErrorMessage()); - AssertUtils.ArgumentNotNull(exceptionType, "exceptionType", GetErrorMessage()); - - this.assemblyName = assemblyName; - - this.connectionType = connectionType; - this.commandType = commandType; - this.parameterType = parameterType; - this.dataAdapterType = dataAdapterType; - this.commandBuilderType = commandBuilderType; - - //TODO consider support for derive parameters via a stored procedure. - if (commandBuilderDeriveParametersMethod.ToLower().Trim().Equals("not supported")) - { - supportsDeriveParametersMethod = false; - } - - if (supportsDeriveParametersMethod) - { - this.commandBuilderDeriveParametersMethod = - ReflectionUtils.GetMethod(this.commandBuilderType, commandBuilderDeriveParametersMethod, - new Type[] {this.commandType}); - - AssertUtils.ArgumentNotNull(this.commandBuilderDeriveParametersMethod, - "commandBuilderDeriveParametersMethod", GetErrorMessage() + - ", could not resolve commandBuilderDeriveParametersMethod " + - commandBuilderDeriveParametersMethod + - " to MethodInfo. Please check dbproviders.xml entry for correct metadata listing."); - } - - this.commandType = commandType; - - this.parameterDbType = parameterDbType; - - this.parameterDbTypeProperty = this.parameterType.GetProperty(parameterDbTypeProperty, - BindingFlags.Instance | BindingFlags.Public); - AssertUtils.ArgumentNotNull(this.parameterDbTypeProperty, "parameterDbTypeProperty", GetErrorMessage() + - ", could not resolve parameterDbTypeProperty " + - parameterDbTypeProperty + - " to PropertyInfo. Please check dbproviders.xml entry for correct metadata listing."); - - this.parameterIsNullableProperty = this.parameterType.GetProperty(parameterIsNullableProperty, - BindingFlags.Instance | BindingFlags.Public); - - AssertUtils.ArgumentNotNull(this.parameterIsNullableProperty, "parameterIsNullableProperty", GetErrorMessage() + - ", could not resolve parameterIsNullableProperty " + - parameterIsNullableProperty + - " to PropertyInfo. Please check dbproviders.xml entry for correct metadata listing."); - - this.parameterNamePrefix = parameterNamePrefix; - this.exceptionType = exceptionType; - - this.useParameterNamePrefixInParameterCollection = useParameterNamePrefixInParameterCollection; - this.useParameterPrefixInSql = useParameterPrefixInSql; - this.bindByName = bindByName; - - this.errorCodeExceptionExpression = errorCodeExceptionExpression; - - - errorCodes = new ErrorCodes(); - - - } - - private string GetErrorMessage() - { - return "DbProvider product name = " + productName; - } - - - #endregion - - #region IDbMetadata Members - - /// - /// Gets a value indicating whether to use param name prefix in parameter collection. - /// - /// - /// true if should use param name prefix in parameter collection; otherwise, false. - /// - public bool UseParamNamePrefixInParameterCollection - { - get { return useParameterNamePrefixInParameterCollection; } - } - - /// - /// Gets the name of the assembly. - /// - /// Example: System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The name of the assembly. - public string AssemblyName - { - get { return assemblyName; } - } - - /// - /// Gets a descriptive name of the product. - /// - /// Example: Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0 - /// The name of the product. - public string ProductName - { - get { return productName; } - } - - /// - /// Gets the type of the connection. The fully qualified type name is given since some providers, - /// notably for SqlServerCe, do not use the same namespace for all data access types. - /// - /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the connection. - public Type ConnectionType - { - get { return connectionType; } - } - - /// - /// Gets the type of the command. - /// - /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the command. - public Type CommandType - { - get { return commandType; } - } - - /// - /// Gets the type of the parameter. - /// - /// Example: System.Data.SqlClient.SqlParameter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the parameter. - public Type ParameterType - { - get { return parameterType; } - } - - /// - /// Gets the type of the data adapter. - /// - /// Example: System.Data.SqlClient.SqlDataAdapter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the data adapter. - public Type DataAdapterType - { - get { return dataAdapterType; } - } - - /// - /// Gets the type of the command builder. - /// - /// Example: System.Data.SqlClient.SqlCommandBuilder, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the command builder. - public Type CommandBuilderType - { - get { return commandBuilderType; } - } - - /// - /// Gets the command builder derive parameters method. - /// - /// If the value 'not supported' is specified then this method will throw an ArgumentException - /// Example: DeriveParameters - /// The command builder derive parameters method. - public MethodInfo CommandBuilderDeriveParametersMethod - { - get - { - if (supportsDeriveParametersMethod) - { - return commandBuilderDeriveParametersMethod; - } else - { - throw new ArgumentException("This provider does not support the DeriveParameters functionality"); - } - } - } - - /// - /// Provide the prefix used to indentify named parameters in SQL text. - /// - /// @ for Sql Server - public string ParameterNamePrefix - { - get { return parameterNamePrefix; } - } - - /// - /// Gets the type of the exception. - /// - /// Example: System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the exception. - public Type ExceptionType - { - get { return exceptionType; } - } - - /// - /// Does the driver require the use of the parameter prefix when - /// specifying the name of the parameter in the Command's - /// Parameter collection. - /// - /// - /// If true, then commamd.Parameters["@parameterName"] is - /// used, otherwise, command.Parameters["parameterName"]. - /// - public bool UseParameterNamePrefixInParameterCollection - { - get { return useParameterNamePrefixInParameterCollection; } - } - - - /// - /// Gets a value indicating whether the Provider requires - /// the use of a named prefix in the SQL string. - /// - /// - /// true if use parameter prefix in SQL; otherwise, false. - /// - /// - /// The OLE DB/ODBC .NET Provider does not support named parameters for - /// passing parameters to an SQL Statement or a stored procedure called - /// by an IDbCommand when CommandType is set to Text. - /// - public bool UseParameterPrefixInSql - { - get { return useParameterPrefixInSql; } - } - - /// - /// For providers that allow you to choose between binding parameters - /// to a command by name (true) or by position (false). - /// - /// - public bool BindByName - { - get { return bindByName; } - set { bindByName = value; } - } - - /// - /// Gets the type of the parameter db. - /// - /// Example: System.Data.SqlDbType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the parameter db. - public Type ParameterDbType - { - get { return parameterDbType; } - } - - /// - /// Gets the parameter db type property. - /// - /// Example: SqlDbType for SqlServer - /// The parameter db type property. - public PropertyInfo ParameterDbTypeProperty - { - get { return parameterDbTypeProperty; } - } - - /// - /// Gets the parameter is nullable property. - /// - /// Example: IsNullable for Sql Server - /// The parameter is nullable property. - public PropertyInfo ParameterIsNullableProperty - { - get { return parameterIsNullableProperty; } - } - - /// - /// Gets or sets the error codes. - /// - /// The collection of error codes to map error code integer values to Spring's DAO exception hierarchy - /// The error codes. - public ErrorCodes ErrorCodes - { - get { return errorCodes; } - set { errorCodes = value;} - } - - /// - /// Gets the error code exception expression. - /// - /// Example Errors[0].Number.ToString() for Sql Server - /// The error code exception expression. - public string ErrorCodeExceptionExpression - { - get { return errorCodeExceptionExpression; } - } - - #endregion - - - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using Spring.Util; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// Provides database metdata information. + /// + /// Mark Pollack (.NET) + public class DbMetadata : IDbMetadata + { + #region Fields + + private bool supportsDeriveParametersMethod = true; + + private string productName; + private string assemblyName; + private Type connectionType; + private Type commandType; + private Type parameterType; + private Type dataAdapterType; + + + private Type parameterDbType; + private PropertyInfo parameterDbTypeProperty; + private PropertyInfo parameterIsNullableProperty; + private string parameterNamePrefix; + + private Type exceptionType; + private bool useParameterNamePrefixInParameterCollection; + private bool useParameterPrefixInSql; + private bool bindByName; + + + + + private Type commandBuilderType; + private MethodInfo commandBuilderDeriveParametersMethod; + + private string errorCodeExceptionExpression = string.Empty; + + private ErrorCodes errorCodes; + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + /// Name of the product. + /// Name of the assembly. + /// Type of the connection. + /// Type of the command. + /// Type of the parameter. + /// Type of the data adapter. + /// Type of the command builder. + /// The command builder derive parameters method. + /// Type of the parameter db. + /// The parameter db type property. + /// The parameter is nullable property. + /// The parameter name prefix. + /// Type of the exception. + /// if set to true [use parameter name prefix in parameter collection]. + /// if set to true [use parameter prefix in SQL]. + /// if set to true [bind by name]. + /// The error code exception expression. + public DbMetadata(string productName, + string assemblyName, + Type connectionType, + Type commandType, + Type parameterType, + Type dataAdapterType, + Type commandBuilderType, + string commandBuilderDeriveParametersMethod, + Type parameterDbType, + string parameterDbTypeProperty, + string parameterIsNullableProperty, + string parameterNamePrefix, + Type exceptionType, + bool useParameterNamePrefixInParameterCollection, + bool useParameterPrefixInSql, + bool bindByName, + string errorCodeExceptionExpression + + ) + { + + AssertUtils.ArgumentHasText(productName, "ProductName"); + this.productName = productName; + AssertUtils.ArgumentHasText(assemblyName, "assemblyName", GetErrorMessage() ); + AssertUtils.ArgumentNotNull(connectionType, "connectionType", GetErrorMessage() ); + AssertUtils.ArgumentNotNull(commandType, "commandType", GetErrorMessage()); + AssertUtils.ArgumentNotNull(parameterType, "parameterType", GetErrorMessage()); + AssertUtils.ArgumentNotNull(dataAdapterType, "dataAdapterType", GetErrorMessage()); + AssertUtils.ArgumentNotNull(commandBuilderType, "commandBuilderType", GetErrorMessage()); + AssertUtils.ArgumentHasText(commandBuilderDeriveParametersMethod, "commandBuilderDeriveParametersMethod", GetErrorMessage()); + AssertUtils.ArgumentNotNull(parameterDbType, "parameterDbType", GetErrorMessage()); + AssertUtils.ArgumentHasText(parameterDbTypeProperty, "parameterDbTypeProperty", GetErrorMessage()); + AssertUtils.ArgumentHasText(parameterIsNullableProperty, "parameterIsNullableProperty", GetErrorMessage()); + AssertUtils.ArgumentHasText(parameterNamePrefix, "parameterNamePrefix", GetErrorMessage()); + AssertUtils.ArgumentNotNull(exceptionType, "exceptionType", GetErrorMessage()); + + this.assemblyName = assemblyName; + + this.connectionType = connectionType; + this.commandType = commandType; + this.parameterType = parameterType; + this.dataAdapterType = dataAdapterType; + this.commandBuilderType = commandBuilderType; + + //TODO consider support for derive parameters via a stored procedure. + if (commandBuilderDeriveParametersMethod.ToLower().Trim().Equals("not supported")) + { + supportsDeriveParametersMethod = false; + } + + if (supportsDeriveParametersMethod) + { + this.commandBuilderDeriveParametersMethod = + ReflectionUtils.GetMethod(this.commandBuilderType, commandBuilderDeriveParametersMethod, + new Type[] {this.commandType}); + + AssertUtils.ArgumentNotNull(this.commandBuilderDeriveParametersMethod, + "commandBuilderDeriveParametersMethod", GetErrorMessage() + + ", could not resolve commandBuilderDeriveParametersMethod " + + commandBuilderDeriveParametersMethod + + " to MethodInfo. Please check dbproviders.xml entry for correct metadata listing."); + } + + this.commandType = commandType; + + this.parameterDbType = parameterDbType; + + this.parameterDbTypeProperty = this.parameterType.GetProperty(parameterDbTypeProperty, + BindingFlags.Instance | BindingFlags.Public); + AssertUtils.ArgumentNotNull(this.parameterDbTypeProperty, "parameterDbTypeProperty", GetErrorMessage() + + ", could not resolve parameterDbTypeProperty " + + parameterDbTypeProperty + + " to PropertyInfo. Please check dbproviders.xml entry for correct metadata listing."); + + this.parameterIsNullableProperty = this.parameterType.GetProperty(parameterIsNullableProperty, + BindingFlags.Instance | BindingFlags.Public); + + AssertUtils.ArgumentNotNull(this.parameterIsNullableProperty, "parameterIsNullableProperty", GetErrorMessage() + + ", could not resolve parameterIsNullableProperty " + + parameterIsNullableProperty + + " to PropertyInfo. Please check dbproviders.xml entry for correct metadata listing."); + + this.parameterNamePrefix = parameterNamePrefix; + this.exceptionType = exceptionType; + + this.useParameterNamePrefixInParameterCollection = useParameterNamePrefixInParameterCollection; + this.useParameterPrefixInSql = useParameterPrefixInSql; + this.bindByName = bindByName; + + this.errorCodeExceptionExpression = errorCodeExceptionExpression; + + + errorCodes = new ErrorCodes(); + + + } + + private string GetErrorMessage() + { + return "DbProvider product name = " + productName; + } + + + #endregion + + #region IDbMetadata Members + + /// + /// Gets a value indicating whether to use param name prefix in parameter collection. + /// + /// + /// true if should use param name prefix in parameter collection; otherwise, false. + /// + public bool UseParamNamePrefixInParameterCollection + { + get { return useParameterNamePrefixInParameterCollection; } + } + + /// + /// Gets the name of the assembly. + /// + /// Example: System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The name of the assembly. + public string AssemblyName + { + get { return assemblyName; } + } + + /// + /// Gets a descriptive name of the product. + /// + /// Example: Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0 + /// The name of the product. + public string ProductName + { + get { return productName; } + } + + /// + /// Gets the type of the connection. The fully qualified type name is given since some providers, + /// notably for SqlServerCe, do not use the same namespace for all data access types. + /// + /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the connection. + public Type ConnectionType + { + get { return connectionType; } + } + + /// + /// Gets the type of the command. + /// + /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the command. + public Type CommandType + { + get { return commandType; } + } + + /// + /// Gets the type of the parameter. + /// + /// Example: System.Data.SqlClient.SqlParameter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the parameter. + public Type ParameterType + { + get { return parameterType; } + } + + /// + /// Gets the type of the data adapter. + /// + /// Example: System.Data.SqlClient.SqlDataAdapter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the data adapter. + public Type DataAdapterType + { + get { return dataAdapterType; } + } + + /// + /// Gets the type of the command builder. + /// + /// Example: System.Data.SqlClient.SqlCommandBuilder, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the command builder. + public Type CommandBuilderType + { + get { return commandBuilderType; } + } + + /// + /// Gets the command builder derive parameters method. + /// + /// If the value 'not supported' is specified then this method will throw an ArgumentException + /// Example: DeriveParameters + /// The command builder derive parameters method. + public MethodInfo CommandBuilderDeriveParametersMethod + { + get + { + if (supportsDeriveParametersMethod) + { + return commandBuilderDeriveParametersMethod; + } else + { + throw new ArgumentException("This provider does not support the DeriveParameters functionality"); + } + } + } + + /// + /// Provide the prefix used to indentify named parameters in SQL text. + /// + /// @ for Sql Server + public string ParameterNamePrefix + { + get { return parameterNamePrefix; } + } + + /// + /// Gets the type of the exception. + /// + /// Example: System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the exception. + public Type ExceptionType + { + get { return exceptionType; } + } + + /// + /// Does the driver require the use of the parameter prefix when + /// specifying the name of the parameter in the Command's + /// Parameter collection. + /// + /// + /// If true, then commamd.Parameters["@parameterName"] is + /// used, otherwise, command.Parameters["parameterName"]. + /// + public bool UseParameterNamePrefixInParameterCollection + { + get { return useParameterNamePrefixInParameterCollection; } + } + + + /// + /// Gets a value indicating whether the Provider requires + /// the use of a named prefix in the SQL string. + /// + /// + /// true if use parameter prefix in SQL; otherwise, false. + /// + /// + /// The OLE DB/ODBC .NET Provider does not support named parameters for + /// passing parameters to an SQL Statement or a stored procedure called + /// by an IDbCommand when CommandType is set to Text. + /// + public bool UseParameterPrefixInSql + { + get { return useParameterPrefixInSql; } + } + + /// + /// For providers that allow you to choose between binding parameters + /// to a command by name (true) or by position (false). + /// + /// + public bool BindByName + { + get { return bindByName; } + set { bindByName = value; } + } + + /// + /// Gets the type of the parameter db. + /// + /// Example: System.Data.SqlDbType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the parameter db. + public Type ParameterDbType + { + get { return parameterDbType; } + } + + /// + /// Gets the parameter db type property. + /// + /// Example: SqlDbType for SqlServer + /// The parameter db type property. + public PropertyInfo ParameterDbTypeProperty + { + get { return parameterDbTypeProperty; } + } + + /// + /// Gets the parameter is nullable property. + /// + /// Example: IsNullable for Sql Server + /// The parameter is nullable property. + public PropertyInfo ParameterIsNullableProperty + { + get { return parameterIsNullableProperty; } + } + + /// + /// Gets or sets the error codes. + /// + /// The collection of error codes to map error code integer values to Spring's DAO exception hierarchy + /// The error codes. + public ErrorCodes ErrorCodes + { + get { return errorCodes; } + set { errorCodes = value;} + } + + /// + /// Gets the error code exception expression. + /// + /// Example Errors[0].Number.ToString() for Sql Server + /// The error code exception expression. + public string ErrorCodeExceptionExpression + { + get { return errorCodeExceptionExpression; } + } + + #endregion + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/DbParameter.cs b/src/Spring/Spring.Data/Data/Common/DbParameter.cs index 819e9049..2d54ad2e 100644 --- a/src/Spring/Spring.Data/Data/Common/DbParameter.cs +++ b/src/Spring/Spring.Data/Data/Common/DbParameter.cs @@ -1,194 +1,193 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// A parameter class used by - /// - /// Mark Pollack (.NET) - /// $Id: DbParameter.cs,v 1.6 2008/05/30 21:09:22 markpollack Exp $ - public class DbParameter : Spring.Data.Common.IDbParameter - { - #region Fields - private Enum dbType; - private ParameterDirection direction; - private bool isNullable; - private string name; - private string sourceColumn; - private DataRowVersion sourceVersion; - private object val; - private byte precision; - private byte scale; - private int size; - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - /// - /// Sets the SourceVersion to be Default and the ParameterDirection to be Input. - /// - public DbParameter() - { - sourceVersion = DataRowVersion.Default; - direction = ParameterDirection.Input; - } - - #endregion - - #region IDbParameter Members - - public Enum DbType - { - set - { - dbType = value; - } - } - - #endregion - - public IDbParameter Type(Enum dbType) - { - this.dbType = dbType; - return this; - } - - public IDbParameter Type(Enum dbType, int size) - { - this.dbType = dbType; - this.size = size; - return this; - } - - public Enum GetDbType() - { - return dbType; - } - - public IDbParameter Direction(ParameterDirection direction) - { - this.direction = direction; - return this; - } - - public ParameterDirection GetDirection() - { - return direction; - } - - public IDbParameter IsNullable(bool isNullable) - { - this.isNullable = isNullable; - return this; - } - - public bool GetIsNullable() - { - return isNullable; - } - - public IDbParameter Name(string name) - { - this.name = name; - return this; - } - - public string GetName() - { - return name; - } - - public IDbParameter SourceColumn(string sourceColumn) - { - this.sourceColumn = sourceColumn; - return this; - } - - public string GetSourceColumn() - { - return sourceColumn; - } - - public IDbParameter SourceVersion(DataRowVersion sourceVersion) - { - this.sourceVersion = sourceVersion; - return this; - } - - public DataRowVersion GetSourceVersion() - { - return sourceVersion; - } - - public IDbParameter Value(object val) - { - this.val = val; - return this; - } - - public object GetValue() - { - return val; - } - - public IDbParameter Precision(byte precision) - { - this.precision = precision; - return this; - } - - public byte GetPrecision() - { - return precision; - } - - public IDbParameter Scale(byte scale) - { - this.scale = scale; - return this; - } - - public byte GetScale() - { - return scale; - } - - public IDbParameter Size(int size) - { - this.size = size; - return this; - } - - public int GetSize() - { - return size; - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// A parameter class used by + /// + /// Mark Pollack (.NET) + public class DbParameter : Spring.Data.Common.IDbParameter + { + #region Fields + private Enum dbType; + private ParameterDirection direction; + private bool isNullable; + private string name; + private string sourceColumn; + private DataRowVersion sourceVersion; + private object val; + private byte precision; + private byte scale; + private int size; + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + /// + /// Sets the SourceVersion to be Default and the ParameterDirection to be Input. + /// + public DbParameter() + { + sourceVersion = DataRowVersion.Default; + direction = ParameterDirection.Input; + } + + #endregion + + #region IDbParameter Members + + public Enum DbType + { + set + { + dbType = value; + } + } + + #endregion + + public IDbParameter Type(Enum dbType) + { + this.dbType = dbType; + return this; + } + + public IDbParameter Type(Enum dbType, int size) + { + this.dbType = dbType; + this.size = size; + return this; + } + + public Enum GetDbType() + { + return dbType; + } + + public IDbParameter Direction(ParameterDirection direction) + { + this.direction = direction; + return this; + } + + public ParameterDirection GetDirection() + { + return direction; + } + + public IDbParameter IsNullable(bool isNullable) + { + this.isNullable = isNullable; + return this; + } + + public bool GetIsNullable() + { + return isNullable; + } + + public IDbParameter Name(string name) + { + this.name = name; + return this; + } + + public string GetName() + { + return name; + } + + public IDbParameter SourceColumn(string sourceColumn) + { + this.sourceColumn = sourceColumn; + return this; + } + + public string GetSourceColumn() + { + return sourceColumn; + } + + public IDbParameter SourceVersion(DataRowVersion sourceVersion) + { + this.sourceVersion = sourceVersion; + return this; + } + + public DataRowVersion GetSourceVersion() + { + return sourceVersion; + } + + public IDbParameter Value(object val) + { + this.val = val; + return this; + } + + public object GetValue() + { + return val; + } + + public IDbParameter Precision(byte precision) + { + this.precision = precision; + return this; + } + + public byte GetPrecision() + { + return precision; + } + + public IDbParameter Scale(byte scale) + { + this.scale = scale; + return this; + } + + public byte GetScale() + { + return scale; + } + + public IDbParameter Size(int size) + { + this.size = size; + return this; + } + + public int GetSize() + { + return size; + } + } +} diff --git a/src/Spring/Spring.Data/Data/Common/DbParameters.cs b/src/Spring/Spring.Data/Data/Common/DbParameters.cs index 7a1a6bda..a4e6ae0a 100644 --- a/src/Spring/Spring.Data/Data/Common/DbParameters.cs +++ b/src/Spring/Spring.Data/Data/Common/DbParameters.cs @@ -1,302 +1,301 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; -using System.Reflection; -using Spring.Dao; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// A more portable means to create a collection of ADO.NET - /// parameters. - /// - /// Mark Pollack (.NET) - /// $Id: DbParameters.cs,v 1.14 2007/12/06 22:34:56 markpollack Exp $ - public class DbParameters : IDbParameters - { - - #region Fields - - private IDbProvider dbProvider; - - //Just used as a container for the underlying parameter collection. - private IDbCommand dbCommand; - private IDataParameterCollection dataParameterCollection; - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public DbParameters(IDbProvider dbProvider) - { - this.dbProvider = dbProvider; - dbCommand = dbProvider.CreateCommand(); - dataParameterCollection = dbCommand.Parameters; - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - #endregion - - public IDataParameter this[string parameterName] - { - get { return (IDbDataParameter) dataParameterCollection[parameterName]; } - set { dataParameterCollection[parameterName] = value; } - } - - public IDataParameter this[int index] - { - get { return (IDbDataParameter) dataParameterCollection[index]; } - set { dataParameterCollection[index] = value; } - } - - public IDataParameterCollection DataParameterCollection - { - get { return dataParameterCollection; } - } - - public int Count - { - get - { - return dataParameterCollection.Count; - } - } - public bool Contains(string parameterName) - { - return dataParameterCollection.Contains(parameterName); - } - - public void AddParameter(IDataParameter dbParameter) - { - dataParameterCollection.Add(dbParameter); - } - - - public IDbDataParameter AddParameter(string name, - Enum parameterType, - int size, - ParameterDirection direction, - bool isNullable, - byte precision, - byte scale, - string sourceColumn, - DataRowVersion sourceVersion, - object parameterValue) - { - IDbDataParameter parameter = dbCommand.CreateParameter(); - - parameter.ParameterName = dbProvider.CreateParameterNameForCollection(name); - - AssignParameterType(parameter, parameterType); - - if (size > 0) - { - parameter.Size = size; - } - parameter.Direction = direction; - - if (isNullable) - { - AssignIsNullable(isNullable, parameter); - } - - parameter.Precision = precision; - - if (scale > 0) - { - parameter.Scale = scale; - } - - if (sourceColumn != null && sourceColumn != string.Empty) - { - parameter.SourceColumn = sourceColumn; - } - - parameter.SourceVersion = sourceVersion; - - parameter.Value = (parameterValue == null) ? DBNull.Value : parameterValue; - - dataParameterCollection.Add(parameter); - - return parameter; - } - - public IDbDataParameter AddParameter(string name, - Enum parameterType, - ParameterDirection direction, - bool isNullable, - byte precision, - byte scale, - string sourceColumn, - DataRowVersion sourceVersion, - object parameterValue) - { - return AddParameter(name, parameterType, 0, direction, isNullable, precision, scale, sourceColumn, sourceVersion, - parameterValue); - } - - - public int Add(object parameterValue) - { - IDbDataParameter parameter = dbCommand.CreateParameter(); - //TODO investigate default behavior of values. - parameter.Value = (parameterValue == null) ? DBNull.Value : parameterValue; - dataParameterCollection.Add(parameter); - return dataParameterCollection.Count - 1; - } - - public void AddRange(Array values) - { - foreach (Array value in values) - { - Add(value); - } - } - - public IDbDataParameter AddWithValue(string name, object parameterValue) - { - return AddParameter(name, null, -1, ParameterDirection.Input, false, - 0, 0, null, DataRowVersion.Default, parameterValue); - } - - public IDbDataParameter Add(string name, Enum parameterType) - { - return AddParameter(name, parameterType, -1, ParameterDirection.Input, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter Add(string name, Enum parameterType, int size) - { - return AddParameter(name, parameterType, size, ParameterDirection.Input, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter Add(string name, Enum parameterType, int size, string sourceColumn) - { - return AddParameter(name, parameterType, size, ParameterDirection.Input, - false, 0, 0, sourceColumn, DataRowVersion.Default, null); - } - - public IDbDataParameter AddOut(string name, Enum parameterType) - { - return AddParameter(name, parameterType, -1, ParameterDirection.Output, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter AddOut(string name, Enum parameterType, int size) - { - return AddParameter(name, parameterType, size, ParameterDirection.Output, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter AddInOut(string name, Enum parameterType) - { - return AddParameter(name, parameterType, -1, ParameterDirection.InputOutput, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter AddInOut(string name, Enum parameterType, int size) - { - return AddParameter(name, parameterType, size, ParameterDirection.InputOutput, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter AddReturn(string name, Enum parameterType) - { - return AddParameter(name, parameterType, -1, ParameterDirection.ReturnValue, - false, 0, 0, null, DataRowVersion.Default, null); - } - - public IDbDataParameter AddReturn(string name, Enum parameterType, int size) - { - return AddParameter(name, parameterType, size, ParameterDirection.ReturnValue, - false, 0, 0, null, DataRowVersion.Default, null); - } - - - public object GetValue(string name) - { - return dataParameterCollection[dbProvider.CreateParameterNameForCollection(name)]; - } - - public void SetValue(string name, object parameterValue) - { - IDbDataParameter parameter = dataParameterCollection[dbProvider.CreateParameterNameForCollection(name)] as IDbDataParameter; - if (parameter != null) - { - parameter.Value = (parameterValue == null) ? DBNull.Value : parameterValue; - } - } - - - protected void AssignParameterType(IDbDataParameter parameter, Enum parameterType) - { - if (parameterType != null) - { - if (parameterType is DbType) - { - parameter.DbType = (DbType) parameterType; - } - else - { - if (parameterType.GetType() != dbProvider.DbMetadata.ParameterDbType) - { - throw new TypeMismatchDataAccessException("Invalid parameter type specified for parameter name [" - + parameter.ParameterName + "]. [" - + parameterType.GetType().AssemblyQualifiedName + "] is not of expected type [" - + dbProvider.DbMetadata.ParameterDbType.AssemblyQualifiedName + "]"); - } - dbProvider.DbMetadata.ParameterDbTypeProperty.SetValue(parameter, parameterType, null); - } - } - } - - protected void AssignIsNullable(bool isNullable, IDbDataParameter parameter) - { - PropertyInfo propertyInfo = dbProvider.DbMetadata.ParameterIsNullableProperty; - if (propertyInfo != null) - { - propertyInfo.SetValue(parameter, isNullable, null); - } - //TODO investigate default behavior. - if (parameter.Value == null) - { - parameter.Value = DBNull.Value; - } - } - - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; +using System.Reflection; +using Spring.Dao; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// A more portable means to create a collection of ADO.NET + /// parameters. + /// + /// Mark Pollack (.NET) + public class DbParameters : IDbParameters + { + + #region Fields + + private IDbProvider dbProvider; + + //Just used as a container for the underlying parameter collection. + private IDbCommand dbCommand; + private IDataParameterCollection dataParameterCollection; + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public DbParameters(IDbProvider dbProvider) + { + this.dbProvider = dbProvider; + dbCommand = dbProvider.CreateCommand(); + dataParameterCollection = dbCommand.Parameters; + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + #endregion + + public IDataParameter this[string parameterName] + { + get { return (IDbDataParameter) dataParameterCollection[parameterName]; } + set { dataParameterCollection[parameterName] = value; } + } + + public IDataParameter this[int index] + { + get { return (IDbDataParameter) dataParameterCollection[index]; } + set { dataParameterCollection[index] = value; } + } + + public IDataParameterCollection DataParameterCollection + { + get { return dataParameterCollection; } + } + + public int Count + { + get + { + return dataParameterCollection.Count; + } + } + public bool Contains(string parameterName) + { + return dataParameterCollection.Contains(parameterName); + } + + public void AddParameter(IDataParameter dbParameter) + { + dataParameterCollection.Add(dbParameter); + } + + + public IDbDataParameter AddParameter(string name, + Enum parameterType, + int size, + ParameterDirection direction, + bool isNullable, + byte precision, + byte scale, + string sourceColumn, + DataRowVersion sourceVersion, + object parameterValue) + { + IDbDataParameter parameter = dbCommand.CreateParameter(); + + parameter.ParameterName = dbProvider.CreateParameterNameForCollection(name); + + AssignParameterType(parameter, parameterType); + + if (size > 0) + { + parameter.Size = size; + } + parameter.Direction = direction; + + if (isNullable) + { + AssignIsNullable(isNullable, parameter); + } + + parameter.Precision = precision; + + if (scale > 0) + { + parameter.Scale = scale; + } + + if (sourceColumn != null && sourceColumn != string.Empty) + { + parameter.SourceColumn = sourceColumn; + } + + parameter.SourceVersion = sourceVersion; + + parameter.Value = (parameterValue == null) ? DBNull.Value : parameterValue; + + dataParameterCollection.Add(parameter); + + return parameter; + } + + public IDbDataParameter AddParameter(string name, + Enum parameterType, + ParameterDirection direction, + bool isNullable, + byte precision, + byte scale, + string sourceColumn, + DataRowVersion sourceVersion, + object parameterValue) + { + return AddParameter(name, parameterType, 0, direction, isNullable, precision, scale, sourceColumn, sourceVersion, + parameterValue); + } + + + public int Add(object parameterValue) + { + IDbDataParameter parameter = dbCommand.CreateParameter(); + //TODO investigate default behavior of values. + parameter.Value = (parameterValue == null) ? DBNull.Value : parameterValue; + dataParameterCollection.Add(parameter); + return dataParameterCollection.Count - 1; + } + + public void AddRange(Array values) + { + foreach (Array value in values) + { + Add(value); + } + } + + public IDbDataParameter AddWithValue(string name, object parameterValue) + { + return AddParameter(name, null, -1, ParameterDirection.Input, false, + 0, 0, null, DataRowVersion.Default, parameterValue); + } + + public IDbDataParameter Add(string name, Enum parameterType) + { + return AddParameter(name, parameterType, -1, ParameterDirection.Input, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter Add(string name, Enum parameterType, int size) + { + return AddParameter(name, parameterType, size, ParameterDirection.Input, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter Add(string name, Enum parameterType, int size, string sourceColumn) + { + return AddParameter(name, parameterType, size, ParameterDirection.Input, + false, 0, 0, sourceColumn, DataRowVersion.Default, null); + } + + public IDbDataParameter AddOut(string name, Enum parameterType) + { + return AddParameter(name, parameterType, -1, ParameterDirection.Output, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter AddOut(string name, Enum parameterType, int size) + { + return AddParameter(name, parameterType, size, ParameterDirection.Output, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter AddInOut(string name, Enum parameterType) + { + return AddParameter(name, parameterType, -1, ParameterDirection.InputOutput, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter AddInOut(string name, Enum parameterType, int size) + { + return AddParameter(name, parameterType, size, ParameterDirection.InputOutput, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter AddReturn(string name, Enum parameterType) + { + return AddParameter(name, parameterType, -1, ParameterDirection.ReturnValue, + false, 0, 0, null, DataRowVersion.Default, null); + } + + public IDbDataParameter AddReturn(string name, Enum parameterType, int size) + { + return AddParameter(name, parameterType, size, ParameterDirection.ReturnValue, + false, 0, 0, null, DataRowVersion.Default, null); + } + + + public object GetValue(string name) + { + return dataParameterCollection[dbProvider.CreateParameterNameForCollection(name)]; + } + + public void SetValue(string name, object parameterValue) + { + IDbDataParameter parameter = dataParameterCollection[dbProvider.CreateParameterNameForCollection(name)] as IDbDataParameter; + if (parameter != null) + { + parameter.Value = (parameterValue == null) ? DBNull.Value : parameterValue; + } + } + + + protected void AssignParameterType(IDbDataParameter parameter, Enum parameterType) + { + if (parameterType != null) + { + if (parameterType is DbType) + { + parameter.DbType = (DbType) parameterType; + } + else + { + if (parameterType.GetType() != dbProvider.DbMetadata.ParameterDbType) + { + throw new TypeMismatchDataAccessException("Invalid parameter type specified for parameter name [" + + parameter.ParameterName + "]. [" + + parameterType.GetType().AssemblyQualifiedName + "] is not of expected type [" + + dbProvider.DbMetadata.ParameterDbType.AssemblyQualifiedName + "]"); + } + dbProvider.DbMetadata.ParameterDbTypeProperty.SetValue(parameter, parameterType, null); + } + } + } + + protected void AssignIsNullable(bool isNullable, IDbDataParameter parameter) + { + PropertyInfo propertyInfo = dbProvider.DbMetadata.ParameterIsNullableProperty; + if (propertyInfo != null) + { + propertyInfo.SetValue(parameter, isNullable, null); + } + //TODO investigate default behavior. + if (parameter.Value == null) + { + parameter.Value = DBNull.Value; + } + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/DbParametersBuilder.cs b/src/Spring/Spring.Data/Data/Common/DbParametersBuilder.cs index a5b6f769..b3be0f24 100644 --- a/src/Spring/Spring.Data/Data/Common/DbParametersBuilder.cs +++ b/src/Spring/Spring.Data/Data/Common/DbParametersBuilder.cs @@ -1,111 +1,110 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using Common.Logging; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// Assists in creating a collection of parameters by keeping track of all - /// IDbParameters its creates. After creating a number of parameters ask for the collection - /// with the GetParameters methods. - /// - /// This builder is stateful, you must create a new one for each collection - /// of parameters you would like to create. - /// Mark Pollack (.NET) - /// $Id: DbParametersBuilder.cs,v 1.2 2007/05/01 00:37:10 markpollack Exp $ - public class DbParametersBuilder : IDbParametersBuilder - { - #region Fields - - private IDbProvider dbProvider; - private IList parameterList; - - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (DbParametersBuilder)); - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public DbParametersBuilder(IDbProvider dbProvider) - { - this.dbProvider = dbProvider; - parameterList = new ArrayList(); - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - public IDbParameter Create() - { - IDbParameter p = new DbParameter(); - parameterList.Add(p); - return p; - } - - public IDbParameters GetParameters() - { - IDbParameters dbParameters = CreateDbParameters(); - foreach (IDbParameter parameter in parameterList) - { - dbParameters.AddParameter(parameter.GetName(), - parameter.GetDbType(), - parameter.GetSize(), - parameter.GetDirection(), - parameter.GetIsNullable(), - parameter.GetPrecision(), - parameter.GetScale(), - parameter.GetSourceColumn(), - parameter.GetSourceVersion(), - parameter.GetValue()); - } - return dbParameters; - } - - - protected IDbParameters CreateDbParameters() - { - return new DbParameters(dbProvider); - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using Common.Logging; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// Assists in creating a collection of parameters by keeping track of all + /// IDbParameters its creates. After creating a number of parameters ask for the collection + /// with the GetParameters methods. + /// + /// This builder is stateful, you must create a new one for each collection + /// of parameters you would like to create. + /// Mark Pollack (.NET) + public class DbParametersBuilder : IDbParametersBuilder + { + #region Fields + + private IDbProvider dbProvider; + private IList parameterList; + + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (DbParametersBuilder)); + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public DbParametersBuilder(IDbProvider dbProvider) + { + this.dbProvider = dbProvider; + parameterList = new ArrayList(); + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + public IDbParameter Create() + { + IDbParameter p = new DbParameter(); + parameterList.Add(p); + return p; + } + + public IDbParameters GetParameters() + { + IDbParameters dbParameters = CreateDbParameters(); + foreach (IDbParameter parameter in parameterList) + { + dbParameters.AddParameter(parameter.GetName(), + parameter.GetDbType(), + parameter.GetSize(), + parameter.GetDirection(), + parameter.GetIsNullable(), + parameter.GetPrecision(), + parameter.GetScale(), + parameter.GetSourceColumn(), + parameter.GetSourceVersion(), + parameter.GetValue()); + } + return dbParameters; + } + + + protected IDbParameters CreateDbParameters() + { + return new DbParameters(dbProvider); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/DbProvider.cs b/src/Spring/Spring.Data/Data/Common/DbProvider.cs index c4d07e54..3cef76c8 100644 --- a/src/Spring/Spring.Data/Data/Common/DbProvider.cs +++ b/src/Spring/Spring.Data/Data/Common/DbProvider.cs @@ -1,250 +1,249 @@ -#region Licence - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using Spring.Expressions; -using Spring.Reflection.Dynamic; -using Spring.Util; - -namespace Spring.Data.Common -{ - /// - /// Implemenation of of DbProvider that uses metadata to create provider specific ADO.NET objects. - /// - /// $Id: - public class DbProvider : IDbProvider - { - private string connectionString; - private IDbMetadata dbMetadata; - private IDynamicConstructor newCommand; - private IDynamicConstructor newConnection; - private IDynamicConstructor newCommandBuilder; - private IDynamicConstructor newDataAdapter; - private IDynamicConstructor newParameter; - - /// - /// Initializes a new instance of the class. - /// - /// The db metadata. - public DbProvider(IDbMetadata dbMetadata) - { - this.dbMetadata = dbMetadata; - newCommand = DynamicConstructor.Create(dbMetadata.CommandType.GetConstructor(Type.EmptyTypes)); - newConnection = DynamicConstructor.Create(dbMetadata.ConnectionType.GetConstructor(Type.EmptyTypes)); - newCommandBuilder = DynamicConstructor.Create(dbMetadata.CommandBuilderType.GetConstructor(Type.EmptyTypes)); - newDataAdapter = DynamicConstructor.Create(dbMetadata.DataAdapterType.GetConstructor(Type.EmptyTypes)); - newParameter = DynamicConstructor.Create(dbMetadata.ParameterType.GetConstructor(Type.EmptyTypes)); - } - - /// - /// Returns a new command object for executing SQL statments/Stored Procedures - /// against the database. - /// - /// An new - public IDbCommand CreateCommand() - { - return newCommand.Invoke(ObjectUtils.EmptyObjects) as IDbCommand; - } - - /// - /// Returns a new instance of the providers CommandBuilder class. - /// - /// A new Command Builder - /// In .NET 1.1 there was no common base class or interface - /// for command builders, hence the return signature is object to - /// be portable (but more loosely typed) across .NET 1.1/2.0 - public object CreateCommandBuilder() - { - return newCommandBuilder.Invoke(ObjectUtils.EmptyObjects); - } - - /// - /// Returns a new connection object to communicate with the database. - /// - /// A new - public IDbConnection CreateConnection() - { - IDbConnection conn = newConnection.Invoke(ObjectUtils.EmptyObjects) as IDbConnection; - if (conn != null) - { - conn.ConnectionString = ConnectionString; - } - return conn; - } - - /// - /// Returns a new adapter objects for use with offline DataSets. - /// - /// A new - public IDbDataAdapter CreateDataAdapter() - { - return newDataAdapter.Invoke(ObjectUtils.EmptyObjects) as IDbDataAdapter; - } - - /// - /// Returns a new parameter object for binding values to parameter - /// placeholders in SQL statements or Stored Procedure variables. - /// - /// A new - public IDbDataParameter CreateParameter() - { - return newParameter.Invoke(ObjectUtils.EmptyObjects) as IDbDataParameter; - } - - /// - /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. - /// - /// The unformatted name of the parameter. - /// - /// The parameter name formatted foran IDbCommand.CommandText. - /// - /// In most cases this adds the parameter prefix to the name passed into this method. - public string CreateParameterName(string name) - { - if (dbMetadata.BindByName) - { - if (DbMetadata.UseParameterPrefixInSql) - { - return DbMetadata.ParameterNamePrefix + name; - } - else - { - return name; - } - } - else - { - return DbMetadata.ParameterNamePrefix; - } - } - - /// - /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be - /// part of a IDataParameterCollection. - /// - /// The unformatted name of the parameter. - /// - /// The parameter name formatted for an IDataParameter - /// - public string CreateParameterNameForCollection(string name) - { - if (dbMetadata.BindByName) - { - if (DbMetadata.UseParameterNamePrefixInParameterCollection) - { - return DbMetadata.ParameterNamePrefix + name; - } - else - { - return name; - } - } - else - { - return DbMetadata.ParameterNamePrefix; - } - } - - /// - /// Return metadata information about the database provider - /// - /// - public IDbMetadata DbMetadata - { - get { return dbMetadata; } - } - - /// - /// Connection string used to create connections. - /// - /// - public string ConnectionString - { - get { return connectionString; } - set { connectionString = value; } - } - - /// - /// Extracts the provider specific error code as a string. - /// - /// The data access exception. - /// The provider specific error code - public string ExtractError(Exception e) - { - - if (!StringUtils.IsNullOrEmpty(dbMetadata.ErrorCodeExceptionExpression)) - { - return ExpressionEvaluator.GetValue(e, dbMetadata.ErrorCodeExceptionExpression).ToString(); - } - else - { - return "Could not extract error code exception type." + e.GetType(); - } - - } - - - - /// - /// Determines whether the provided exception is in fact related - /// to database access. This can be provider dependent in .NET 1.1 since - /// there isn't a common base class for ADO.NET exceptions. - /// - /// The exception thrown when performing data access - /// operations. - /// - /// true if is a valid data access exception for the specified - /// exception; otherwise, false. - /// - public bool IsDataAccessException(Exception e) - { - -#if NET_2_0 - if (e is System.Data.Common.DbException) - { - return true; - } - else - { - return false; - } -#else - return IsDataAccessExceptionBCL11(e); -#endif - } - - /// - /// Determines whether is data access exception in .NET 1.1 for the specified exception. - /// - /// The candidate exception. - /// - /// true if is data access exception in .NET 1.1 for the specified exception; otherwise, false. - /// - private bool IsDataAccessExceptionBCL11(Exception e) - { - if (e == null) - { - return false; - } - return e.GetType().IsAssignableFrom(DbMetadata.ExceptionType); - } - } -} +#region Licence + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using Spring.Expressions; +using Spring.Reflection.Dynamic; +using Spring.Util; + +namespace Spring.Data.Common +{ + /// + /// Implemenation of of DbProvider that uses metadata to create provider specific ADO.NET objects. + /// + public class DbProvider : IDbProvider + { + private string connectionString; + private IDbMetadata dbMetadata; + private IDynamicConstructor newCommand; + private IDynamicConstructor newConnection; + private IDynamicConstructor newCommandBuilder; + private IDynamicConstructor newDataAdapter; + private IDynamicConstructor newParameter; + + /// + /// Initializes a new instance of the class. + /// + /// The db metadata. + public DbProvider(IDbMetadata dbMetadata) + { + this.dbMetadata = dbMetadata; + newCommand = DynamicConstructor.Create(dbMetadata.CommandType.GetConstructor(Type.EmptyTypes)); + newConnection = DynamicConstructor.Create(dbMetadata.ConnectionType.GetConstructor(Type.EmptyTypes)); + newCommandBuilder = DynamicConstructor.Create(dbMetadata.CommandBuilderType.GetConstructor(Type.EmptyTypes)); + newDataAdapter = DynamicConstructor.Create(dbMetadata.DataAdapterType.GetConstructor(Type.EmptyTypes)); + newParameter = DynamicConstructor.Create(dbMetadata.ParameterType.GetConstructor(Type.EmptyTypes)); + } + + /// + /// Returns a new command object for executing SQL statments/Stored Procedures + /// against the database. + /// + /// An new + public IDbCommand CreateCommand() + { + return newCommand.Invoke(ObjectUtils.EmptyObjects) as IDbCommand; + } + + /// + /// Returns a new instance of the providers CommandBuilder class. + /// + /// A new Command Builder + /// In .NET 1.1 there was no common base class or interface + /// for command builders, hence the return signature is object to + /// be portable (but more loosely typed) across .NET 1.1/2.0 + public object CreateCommandBuilder() + { + return newCommandBuilder.Invoke(ObjectUtils.EmptyObjects); + } + + /// + /// Returns a new connection object to communicate with the database. + /// + /// A new + public IDbConnection CreateConnection() + { + IDbConnection conn = newConnection.Invoke(ObjectUtils.EmptyObjects) as IDbConnection; + if (conn != null) + { + conn.ConnectionString = ConnectionString; + } + return conn; + } + + /// + /// Returns a new adapter objects for use with offline DataSets. + /// + /// A new + public IDbDataAdapter CreateDataAdapter() + { + return newDataAdapter.Invoke(ObjectUtils.EmptyObjects) as IDbDataAdapter; + } + + /// + /// Returns a new parameter object for binding values to parameter + /// placeholders in SQL statements or Stored Procedure variables. + /// + /// A new + public IDbDataParameter CreateParameter() + { + return newParameter.Invoke(ObjectUtils.EmptyObjects) as IDbDataParameter; + } + + /// + /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. + /// + /// The unformatted name of the parameter. + /// + /// The parameter name formatted foran IDbCommand.CommandText. + /// + /// In most cases this adds the parameter prefix to the name passed into this method. + public string CreateParameterName(string name) + { + if (dbMetadata.BindByName) + { + if (DbMetadata.UseParameterPrefixInSql) + { + return DbMetadata.ParameterNamePrefix + name; + } + else + { + return name; + } + } + else + { + return DbMetadata.ParameterNamePrefix; + } + } + + /// + /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be + /// part of a IDataParameterCollection. + /// + /// The unformatted name of the parameter. + /// + /// The parameter name formatted for an IDataParameter + /// + public string CreateParameterNameForCollection(string name) + { + if (dbMetadata.BindByName) + { + if (DbMetadata.UseParameterNamePrefixInParameterCollection) + { + return DbMetadata.ParameterNamePrefix + name; + } + else + { + return name; + } + } + else + { + return DbMetadata.ParameterNamePrefix; + } + } + + /// + /// Return metadata information about the database provider + /// + /// + public IDbMetadata DbMetadata + { + get { return dbMetadata; } + } + + /// + /// Connection string used to create connections. + /// + /// + public string ConnectionString + { + get { return connectionString; } + set { connectionString = value; } + } + + /// + /// Extracts the provider specific error code as a string. + /// + /// The data access exception. + /// The provider specific error code + public string ExtractError(Exception e) + { + + if (!StringUtils.IsNullOrEmpty(dbMetadata.ErrorCodeExceptionExpression)) + { + return ExpressionEvaluator.GetValue(e, dbMetadata.ErrorCodeExceptionExpression).ToString(); + } + else + { + return "Could not extract error code exception type." + e.GetType(); + } + + } + + + + /// + /// Determines whether the provided exception is in fact related + /// to database access. This can be provider dependent in .NET 1.1 since + /// there isn't a common base class for ADO.NET exceptions. + /// + /// The exception thrown when performing data access + /// operations. + /// + /// true if is a valid data access exception for the specified + /// exception; otherwise, false. + /// + public bool IsDataAccessException(Exception e) + { + +#if NET_2_0 + if (e is System.Data.Common.DbException) + { + return true; + } + else + { + return false; + } +#else + return IsDataAccessExceptionBCL11(e); +#endif + } + + /// + /// Determines whether is data access exception in .NET 1.1 for the specified exception. + /// + /// The candidate exception. + /// + /// true if is data access exception in .NET 1.1 for the specified exception; otherwise, false. + /// + private bool IsDataAccessExceptionBCL11(Exception e) + { + if (e == null) + { + return false; + } + return e.GetType().IsAssignableFrom(DbMetadata.ExceptionType); + } + } +} diff --git a/src/Spring/Spring.Data/Data/Common/DbProviderFactory.cs b/src/Spring/Spring.Data/Data/Common/DbProviderFactory.cs index 90089610..682228d6 100644 --- a/src/Spring/Spring.Data/Data/Common/DbProviderFactory.cs +++ b/src/Spring/Spring.Data/Data/Common/DbProviderFactory.cs @@ -1,165 +1,164 @@ -#region Licence - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Common.Logging; -using Spring.Context; -using Spring.Context.Support; -using Spring.Core.IO; -using Spring.Util; - -namespace Spring.Data.Common -{ - /// - /// Create DbProviders based on configuration information in assembly resource - /// dbproviders.xml - /// - /// - /// - /// - /// TODO: Provide over-ride resource location. - /// TODO: Add error codes to provider. - /// - /// Mark Pollack (.NET) - /// $Id: DbProviderFactory.cs,v 1.12 2007/08/16 20:38:43 markpollack Exp $ - public class DbProviderFactory - { - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static ILog log = LogManager.GetLogger(typeof(DbProviderFactory)); - - private static readonly string DBPROVIDER_DEFAULT_RESOURCE_NAME = - "assembly://" + typeof(DbProviderFactory).Assembly.FullName + "/Spring.Data.Common/dbproviders.xml"; - - public static string DBPROVIDER_ADDITIONAL_RESOURCE_NAME = - "file://dbProviders.xml"; - - private static readonly string DBPROVIDER_CONTEXTNAME = "DBPROVIDERFACTORY_CONTEXT"; - - #endregion - - #region Fields - - private volatile static XmlApplicationContext ctx; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - static DbProviderFactory() - { - } - - #endregion - - - /// - /// Gets the DbProvider given an identifying name. - /// - /// - /// Familiar names for the .NET 2.0 provider model are supported, i.e. - /// System.Data.SqlClient. Refer to the documentation for a complete - /// listing of supported DbProviders and their names. You may - /// also use the method GetDbProviderClasses or obtain the - /// underlying IApplicationContext to progammatically obtain information - /// about supported providers. - /// - /// Name of the provider invariant. - /// - public static IDbProvider GetDbProvider(string providerInvariantName) - { - InitializeDbProviderFactoryIfNeeded(); - - return ctx.GetObject(providerInvariantName, typeof(IDbProvider)) as IDbProvider; - - } - - /// - /// Gets the application context that contains the definitions of the - /// various providers. - /// - /// This method should rarely, if ever, be used in - /// application code. It is used by the framework itself - /// to map other data access products abstractions for a 'DbProvider/DataSource' - /// onto Spring's model. - /// The application context. - public static IApplicationContext ApplicationContext - { - get - { - InitializeDbProviderFactoryIfNeeded(); - return ctx; - } - } - - //TODO GetDbProviderClasses - private static void InitializeDbProviderFactoryIfNeeded() - { - if (ctx == null) - { - lock(typeof(DbProviderFactory)) - { - if (ctx == null) - { - try - { - - //TODO get from well know location in app.config.... - ConfigurableResourceLoader loader = new ConfigurableResourceLoader(DBPROVIDER_ADDITIONAL_RESOURCE_NAME); - - - if (loader.GetResource(DBPROVIDER_ADDITIONAL_RESOURCE_NAME).Exists) - { - #region Instrumentation - if (log.IsDebugEnabled) - { - log.Debug("Loading additional DbProviders from " + DBPROVIDER_ADDITIONAL_RESOURCE_NAME); - } - #endregion - ctx = new XmlApplicationContext(DBPROVIDER_CONTEXTNAME, true, new string[] { DBPROVIDER_DEFAULT_RESOURCE_NAME, - DBPROVIDER_ADDITIONAL_RESOURCE_NAME}); - } - else - { - ctx = new XmlApplicationContext(DBPROVIDER_CONTEXTNAME, true, new string[] { DBPROVIDER_DEFAULT_RESOURCE_NAME }); - } - - string[] dbProviderNames = ctx.GetObjectNamesForType(typeof(IDbProvider)); - if (log.IsInfoEnabled) - { - log.Info(String.Format("{0} DbProviders Available. [{1}]", dbProviderNames.Length, StringUtils.ArrayToCommaDelimitedString(dbProviderNames))); - } - } - catch (Exception e) - { - log.Error("Error processing " + DBPROVIDER_DEFAULT_RESOURCE_NAME, e); - throw; - } - } - } - } - } - } -} +#region Licence + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Common.Logging; +using Spring.Context; +using Spring.Context.Support; +using Spring.Core.IO; +using Spring.Util; + +namespace Spring.Data.Common +{ + /// + /// Create DbProviders based on configuration information in assembly resource + /// dbproviders.xml + /// + /// + /// + /// + /// TODO: Provide over-ride resource location. + /// TODO: Add error codes to provider. + /// + /// Mark Pollack (.NET) + public class DbProviderFactory + { + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static ILog log = LogManager.GetLogger(typeof(DbProviderFactory)); + + private static readonly string DBPROVIDER_DEFAULT_RESOURCE_NAME = + "assembly://" + typeof(DbProviderFactory).Assembly.FullName + "/Spring.Data.Common/dbproviders.xml"; + + public static string DBPROVIDER_ADDITIONAL_RESOURCE_NAME = + "file://dbProviders.xml"; + + private static readonly string DBPROVIDER_CONTEXTNAME = "DBPROVIDERFACTORY_CONTEXT"; + + #endregion + + #region Fields + + private volatile static XmlApplicationContext ctx; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + static DbProviderFactory() + { + } + + #endregion + + + /// + /// Gets the DbProvider given an identifying name. + /// + /// + /// Familiar names for the .NET 2.0 provider model are supported, i.e. + /// System.Data.SqlClient. Refer to the documentation for a complete + /// listing of supported DbProviders and their names. You may + /// also use the method GetDbProviderClasses or obtain the + /// underlying IApplicationContext to progammatically obtain information + /// about supported providers. + /// + /// Name of the provider invariant. + /// + public static IDbProvider GetDbProvider(string providerInvariantName) + { + InitializeDbProviderFactoryIfNeeded(); + + return ctx.GetObject(providerInvariantName, typeof(IDbProvider)) as IDbProvider; + + } + + /// + /// Gets the application context that contains the definitions of the + /// various providers. + /// + /// This method should rarely, if ever, be used in + /// application code. It is used by the framework itself + /// to map other data access products abstractions for a 'DbProvider/DataSource' + /// onto Spring's model. + /// The application context. + public static IApplicationContext ApplicationContext + { + get + { + InitializeDbProviderFactoryIfNeeded(); + return ctx; + } + } + + //TODO GetDbProviderClasses + private static void InitializeDbProviderFactoryIfNeeded() + { + if (ctx == null) + { + lock(typeof(DbProviderFactory)) + { + if (ctx == null) + { + try + { + + //TODO get from well know location in app.config.... + ConfigurableResourceLoader loader = new ConfigurableResourceLoader(DBPROVIDER_ADDITIONAL_RESOURCE_NAME); + + + if (loader.GetResource(DBPROVIDER_ADDITIONAL_RESOURCE_NAME).Exists) + { + #region Instrumentation + if (log.IsDebugEnabled) + { + log.Debug("Loading additional DbProviders from " + DBPROVIDER_ADDITIONAL_RESOURCE_NAME); + } + #endregion + ctx = new XmlApplicationContext(DBPROVIDER_CONTEXTNAME, true, new string[] { DBPROVIDER_DEFAULT_RESOURCE_NAME, + DBPROVIDER_ADDITIONAL_RESOURCE_NAME}); + } + else + { + ctx = new XmlApplicationContext(DBPROVIDER_CONTEXTNAME, true, new string[] { DBPROVIDER_DEFAULT_RESOURCE_NAME }); + } + + string[] dbProviderNames = ctx.GetObjectNamesForType(typeof(IDbProvider)); + if (log.IsInfoEnabled) + { + log.Info(String.Format("{0} DbProviders Available. [{1}]", dbProviderNames.Length, StringUtils.ArrayToCommaDelimitedString(dbProviderNames))); + } + } + catch (Exception e) + { + log.Error("Error processing " + DBPROVIDER_DEFAULT_RESOURCE_NAME, e); + throw; + } + } + } + } + } + } +} diff --git a/src/Spring/Spring.Data/Data/Common/DbProviderFactoryObject.cs b/src/Spring/Spring.Data/Data/Common/DbProviderFactoryObject.cs index 848d0563..38e9ddf5 100644 --- a/src/Spring/Spring.Data/Data/Common/DbProviderFactoryObject.cs +++ b/src/Spring/Spring.Data/Data/Common/DbProviderFactoryObject.cs @@ -1,153 +1,153 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Objects.Factory; -using Spring.Util; - -namespace Spring.Data.Common -{ - /// - /// A implementation that - /// creates instances of the class. - /// - /// Typically used as a convenience for retrieving shared - /// in a Spring XML configuration file as compared to - /// using explict factory method support. - /// - public class DbProviderFactoryObject : IFactoryObject, IInitializingObject - { - private string provider; - private string connectionString; - private IDbProvider dbProvider; - - /// - /// Creates a new instance of the class. - /// - public DbProviderFactoryObject() - { - } - - /// - /// Return an instance of and IDbProvider as configured by this factory - /// managed by this factory. - /// - /// - /// The same (singleton) instance of the IDbProvider managed by - /// this factory. - /// - /// - /// - /// If this method is being called in the context of an enclosing IoC container and - /// returns , the IoC container will consider this factory - /// object as not being fully initialized and throw a corresponding (and most - /// probably fatal) exception. - /// - /// - public object GetObject() - { - lock (this) - { - if (dbProvider == null) - { - ValidateProperties(); - dbProvider = DbProviderFactory.GetDbProvider(Provider); - if (connectionString != null) - { - dbProvider.ConnectionString = this.connectionString; - } - } - - return dbProvider; - } - } - - /// - /// Return the type of - /// - public Type ObjectType - { - get { return typeof (IDbProvider); } - } - - /// - /// Returns true, as the the object managed by this factory is a singleton. - /// - /// - public bool IsSingleton - { - get { return true; } - } - - /// - /// Validates that the provider name is specified. - /// - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - /// In the event of not setting the ProviderName. - /// - public void AfterPropertiesSet() - { - ValidateProperties(); - } - - /// - /// Gets or sets the name of the database provider. - /// - /// The name of the database provider. - public string Provider - { - get { return provider; } - set - { - AssertUtils.ArgumentHasText(value, "The 'ProviderName' property must have a value."); - provider = value.Trim(); - } - } - - /// - /// Gets or sets the connection string. - /// - /// The connection string. - public string ConnectionString - { - get { return connectionString; } - set - { - AssertUtils.ArgumentHasText(value, "The 'ConnectionString' property must have a value."); - connectionString = value.Trim(); - } - } - - /// - /// Validates the properties. - /// - private void ValidateProperties() - { - if (StringUtils.IsNullOrEmpty(Provider)) - { - throw new ArgumentException("The 'DbProviderName' property has not been set."); - } - } - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Objects.Factory; +using Spring.Util; + +namespace Spring.Data.Common +{ + /// + /// A implementation that + /// creates instances of the class. + /// + /// Typically used as a convenience for retrieving shared + /// in a Spring XML configuration file as compared to + /// using explict factory method support. + /// + public class DbProviderFactoryObject : IFactoryObject, IInitializingObject + { + private string provider; + private string connectionString; + private IDbProvider dbProvider; + + /// + /// Creates a new instance of the class. + /// + public DbProviderFactoryObject() + { + } + + /// + /// Return an instance of and IDbProvider as configured by this factory + /// managed by this factory. + /// + /// + /// The same (singleton) instance of the IDbProvider managed by + /// this factory. + /// + /// + /// + /// If this method is being called in the context of an enclosing IoC container and + /// returns , the IoC container will consider this factory + /// object as not being fully initialized and throw a corresponding (and most + /// probably fatal) exception. + /// + /// + public object GetObject() + { + lock (this) + { + if (dbProvider == null) + { + ValidateProperties(); + dbProvider = DbProviderFactory.GetDbProvider(Provider); + if (connectionString != null) + { + dbProvider.ConnectionString = this.connectionString; + } + } + + return dbProvider; + } + } + + /// + /// Return the type of + /// + public Type ObjectType + { + get { return typeof (IDbProvider); } + } + + /// + /// Returns true, as the the object managed by this factory is a singleton. + /// + /// + public bool IsSingleton + { + get { return true; } + } + + /// + /// Validates that the provider name is specified. + /// + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + /// In the event of not setting the ProviderName. + /// + public void AfterPropertiesSet() + { + ValidateProperties(); + } + + /// + /// Gets or sets the name of the database provider. + /// + /// The name of the database provider. + public string Provider + { + get { return provider; } + set + { + AssertUtils.ArgumentHasText(value, "The 'ProviderName' property must have a value."); + provider = value.Trim(); + } + } + + /// + /// Gets or sets the connection string. + /// + /// The connection string. + public string ConnectionString + { + get { return connectionString; } + set + { + AssertUtils.ArgumentHasText(value, "The 'ConnectionString' property must have a value."); + connectionString = value.Trim(); + } + } + + /// + /// Validates the properties. + /// + private void ValidateProperties() + { + if (StringUtils.IsNullOrEmpty(Provider)) + { + throw new ArgumentException("The 'DbProviderName' property has not been set."); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/DelegatingDbProvider.cs b/src/Spring/Spring.Data/Data/Common/DelegatingDbProvider.cs index 133b1c1f..6637da3f 100644 --- a/src/Spring/Spring.Data/Data/Common/DelegatingDbProvider.cs +++ b/src/Spring/Spring.Data/Data/Common/DelegatingDbProvider.cs @@ -1,228 +1,227 @@ -#region Licence - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using Spring.Objects.Factory; -using Spring.Util; - -namespace Spring.Data.Common -{ - /// - /// IDbProvider implementation that delegates all calls to a given target - /// IDbProvider - /// - /// Mark Pollack - /// $Id: DelegatingDbProvider.cs,v 1.1 2008/01/29 22:19:20 markpollack Exp $ - public class DelegatingDbProvider : IDbProvider, IInitializingObject - { - private IDbProvider targetDbProvider; - - - /// - /// Initializes a new instance of the class. - /// - public DelegatingDbProvider() - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// The target db provider. - public DelegatingDbProvider(IDbProvider targetDbProvider) - { - this.targetDbProvider = targetDbProvider; - } - - - /// - /// Gets or sets the target IDbProvider that this IDbProvider should delegate to - /// - /// The target db provider. - public IDbProvider TargetDbProvider - { - get { return targetDbProvider; } - set - { - AssertUtils.ArgumentNotNull(value,"TargetDbProvider"); - targetDbProvider = value; - } - } - - #region IDbProvider Members - - /// - /// Returns a new command object for executing SQL statments/Stored Procedures - /// against the database. - /// - /// An new - public virtual IDbCommand CreateCommand() - { - return TargetDbProvider.CreateCommand(); - } - - /// - /// Returns a new instance of the providers CommandBuilder class. - /// - /// In .NET 1.1 there was no common base class or interface - /// for command builders, hence the return signature is object to - /// be portable (but more loosely typed) across .NET 1.1/2.0 - /// A new Command Builder - public virtual object CreateCommandBuilder() - { - return TargetDbProvider.CreateCommandBuilder(); - } - - /// - /// Returns a new connection object to communicate with the database. - /// - /// A new - public virtual IDbConnection CreateConnection() - { - return TargetDbProvider.CreateConnection(); - } - - /// - /// Returns a new adapter objects for use with offline DataSets. - /// - /// A new - public virtual IDbDataAdapter CreateDataAdapter() - { - return TargetDbProvider.CreateDataAdapter(); - } - - /// - /// Returns a new parameter object for binding values to parameter - /// placeholders in SQL statements or Stored Procedure variables. - /// - /// A new - public virtual IDbDataParameter CreateParameter() - { - return TargetDbProvider.CreateParameter(); - } - - /// - /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. - /// - /// In most cases this adds the parameter prefix to the name passed into this method. - /// The unformatted name of the parameter. - /// The parameter name formatted foran IDbCommand.CommandText. - public virtual string CreateParameterName(string name) - { - return TargetDbProvider.CreateParameterName(name); - } - - /// - /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be - /// part of a IDataParameterCollection. - /// - /// The unformatted name of the parameter. - /// The parameter name formatted for an IDataParameter - public virtual string CreateParameterNameForCollection(string name) - { - return TargetDbProvider.CreateParameterNameForCollection(name); - } - - /// - /// Return metadata information about the database provider - /// - public virtual IDbMetadata DbMetadata - { - get { return TargetDbProvider.DbMetadata; } - } - - /// - /// Connection string used to create connections. - /// - public virtual string ConnectionString - { - get { return TargetDbProvider.ConnectionString; } - set { TargetDbProvider.ConnectionString = value; } - } - - /// - /// Extracts the provider specific error code as a string. - /// - /// The data access exception. - /// The provider specific error code - public virtual string ExtractError(Exception e) - { - return TargetDbProvider.ExtractError(e); - } - - /// - /// Determines whether the provided exception is in fact related - /// to database access. This can be provider dependent in .NET 1.1 since - /// there isn't a common base class for ADO.NET exceptions. - /// - /// The exception thrown when performing data access - /// operations. - /// - /// true if is a valid data access exception for the specified - /// exception; otherwise, false. - /// - public virtual bool IsDataAccessException(Exception e) - { - return TargetDbProvider.IsDataAccessException(e); - } - - #endregion - - #region IInitializingObject Members - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public virtual void AfterPropertiesSet() - { - if (TargetDbProvider == null) - { - throw new ArgumentNullException("Property 'TargetDbProvider' is required."); - } - } - - #endregion - } +#region Licence + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using Spring.Objects.Factory; +using Spring.Util; + +namespace Spring.Data.Common +{ + /// + /// IDbProvider implementation that delegates all calls to a given target + /// IDbProvider + /// + /// Mark Pollack + public class DelegatingDbProvider : IDbProvider, IInitializingObject + { + private IDbProvider targetDbProvider; + + + /// + /// Initializes a new instance of the class. + /// + public DelegatingDbProvider() + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// The target db provider. + public DelegatingDbProvider(IDbProvider targetDbProvider) + { + this.targetDbProvider = targetDbProvider; + } + + + /// + /// Gets or sets the target IDbProvider that this IDbProvider should delegate to + /// + /// The target db provider. + public IDbProvider TargetDbProvider + { + get { return targetDbProvider; } + set + { + AssertUtils.ArgumentNotNull(value,"TargetDbProvider"); + targetDbProvider = value; + } + } + + #region IDbProvider Members + + /// + /// Returns a new command object for executing SQL statments/Stored Procedures + /// against the database. + /// + /// An new + public virtual IDbCommand CreateCommand() + { + return TargetDbProvider.CreateCommand(); + } + + /// + /// Returns a new instance of the providers CommandBuilder class. + /// + /// In .NET 1.1 there was no common base class or interface + /// for command builders, hence the return signature is object to + /// be portable (but more loosely typed) across .NET 1.1/2.0 + /// A new Command Builder + public virtual object CreateCommandBuilder() + { + return TargetDbProvider.CreateCommandBuilder(); + } + + /// + /// Returns a new connection object to communicate with the database. + /// + /// A new + public virtual IDbConnection CreateConnection() + { + return TargetDbProvider.CreateConnection(); + } + + /// + /// Returns a new adapter objects for use with offline DataSets. + /// + /// A new + public virtual IDbDataAdapter CreateDataAdapter() + { + return TargetDbProvider.CreateDataAdapter(); + } + + /// + /// Returns a new parameter object for binding values to parameter + /// placeholders in SQL statements or Stored Procedure variables. + /// + /// A new + public virtual IDbDataParameter CreateParameter() + { + return TargetDbProvider.CreateParameter(); + } + + /// + /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. + /// + /// In most cases this adds the parameter prefix to the name passed into this method. + /// The unformatted name of the parameter. + /// The parameter name formatted foran IDbCommand.CommandText. + public virtual string CreateParameterName(string name) + { + return TargetDbProvider.CreateParameterName(name); + } + + /// + /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be + /// part of a IDataParameterCollection. + /// + /// The unformatted name of the parameter. + /// The parameter name formatted for an IDataParameter + public virtual string CreateParameterNameForCollection(string name) + { + return TargetDbProvider.CreateParameterNameForCollection(name); + } + + /// + /// Return metadata information about the database provider + /// + public virtual IDbMetadata DbMetadata + { + get { return TargetDbProvider.DbMetadata; } + } + + /// + /// Connection string used to create connections. + /// + public virtual string ConnectionString + { + get { return TargetDbProvider.ConnectionString; } + set { TargetDbProvider.ConnectionString = value; } + } + + /// + /// Extracts the provider specific error code as a string. + /// + /// The data access exception. + /// The provider specific error code + public virtual string ExtractError(Exception e) + { + return TargetDbProvider.ExtractError(e); + } + + /// + /// Determines whether the provided exception is in fact related + /// to database access. This can be provider dependent in .NET 1.1 since + /// there isn't a common base class for ADO.NET exceptions. + /// + /// The exception thrown when performing data access + /// operations. + /// + /// true if is a valid data access exception for the specified + /// exception; otherwise, false. + /// + public virtual bool IsDataAccessException(Exception e) + { + return TargetDbProvider.IsDataAccessException(e); + } + + #endregion + + #region IInitializingObject Members + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public virtual void AfterPropertiesSet() + { + if (TargetDbProvider == null) + { + throw new ArgumentNullException("Property 'TargetDbProvider' is required."); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs b/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs index 9552801a..44363ac8 100644 --- a/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs +++ b/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs @@ -1,157 +1,156 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Common.Logging; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// Holds ADO.NET error codes for a particular provider. - /// - /// - /// Used by ErrorCodeExceptionTranslator. The embedded resource - /// "dbProviders.xml" in Spring.Data.Common contains default - /// ErrorCodes instances for various providers. - /// - /// Mark Pollack (.NET) - /// $Id: ErrorCodes.cs,v 1.1 2007/08/01 18:53:06 markpollack Exp $ - public class ErrorCodes - { - #region Fields - private String[] databaseProductNames; - - private String[] badSqlGrammarCodes = new String[0]; - - private String[] invalidResultSetAccessCodes = new String[0]; - - private String[] dataAccessResourceFailureCodes = new String[0]; - - private String[] permissionDeniedCodes = new String[0]; - - private String[] dataIntegrityViolationCodes = new String[0]; - - private String[] cannotAcquireLockCodes = new String[0]; - - private String[] deadlockLoserCodes = new String[0]; - - private String[] cannotSerializeTransactionCodes = new String[0]; - - // CustomErrorCodesTranslation[] customTranslations; - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (ErrorCodes)); - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public ErrorCodes() - { - - } - - #endregion - - #region Properties - public string DatabaseProductName - { - get - { - return (databaseProductNames != null && databaseProductNames.Length > 0 ? - databaseProductNames[0] : null); - } - } - - public string[] DatabaseProductNames - { - get { return databaseProductNames; } - set { databaseProductNames = value; } - } - - public string[] BadSqlGrammarCodes - { - get { return badSqlGrammarCodes; } - set { badSqlGrammarCodes = value; } - } - - public string[] InvalidResultSetAccessCodes - { - get { return invalidResultSetAccessCodes; } - set { invalidResultSetAccessCodes = value; } - } - - public string[] DataAccessResourceFailureCodes - { - get { return dataAccessResourceFailureCodes; } - set { dataAccessResourceFailureCodes = value; } - } - - public string[] PermissionDeniedCodes - { - get { return permissionDeniedCodes; } - set { permissionDeniedCodes = value; } - } - - public string[] DataIntegrityViolationCodes - { - get { return dataIntegrityViolationCodes; } - set { dataIntegrityViolationCodes = value; } - } - - public string[] CannotAcquireLockCodes - { - get { return cannotAcquireLockCodes; } - set { cannotAcquireLockCodes = value; } - } - - public string[] DeadlockLoserCodes - { - get { return deadlockLoserCodes; } - set { deadlockLoserCodes = value; } - } - - public string[] CannotSerializeTransactionCodes - { - get { return cannotSerializeTransactionCodes; } - set { cannotSerializeTransactionCodes = value; } - } - - #endregion - - #region Methods - - #endregion - - - } +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Common.Logging; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// Holds ADO.NET error codes for a particular provider. + /// + /// + /// Used by ErrorCodeExceptionTranslator. The embedded resource + /// "dbProviders.xml" in Spring.Data.Common contains default + /// ErrorCodes instances for various providers. + /// + /// Mark Pollack (.NET) + public class ErrorCodes + { + #region Fields + private String[] databaseProductNames; + + private String[] badSqlGrammarCodes = new String[0]; + + private String[] invalidResultSetAccessCodes = new String[0]; + + private String[] dataAccessResourceFailureCodes = new String[0]; + + private String[] permissionDeniedCodes = new String[0]; + + private String[] dataIntegrityViolationCodes = new String[0]; + + private String[] cannotAcquireLockCodes = new String[0]; + + private String[] deadlockLoserCodes = new String[0]; + + private String[] cannotSerializeTransactionCodes = new String[0]; + + // CustomErrorCodesTranslation[] customTranslations; + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (ErrorCodes)); + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public ErrorCodes() + { + + } + + #endregion + + #region Properties + public string DatabaseProductName + { + get + { + return (databaseProductNames != null && databaseProductNames.Length > 0 ? + databaseProductNames[0] : null); + } + } + + public string[] DatabaseProductNames + { + get { return databaseProductNames; } + set { databaseProductNames = value; } + } + + public string[] BadSqlGrammarCodes + { + get { return badSqlGrammarCodes; } + set { badSqlGrammarCodes = value; } + } + + public string[] InvalidResultSetAccessCodes + { + get { return invalidResultSetAccessCodes; } + set { invalidResultSetAccessCodes = value; } + } + + public string[] DataAccessResourceFailureCodes + { + get { return dataAccessResourceFailureCodes; } + set { dataAccessResourceFailureCodes = value; } + } + + public string[] PermissionDeniedCodes + { + get { return permissionDeniedCodes; } + set { permissionDeniedCodes = value; } + } + + public string[] DataIntegrityViolationCodes + { + get { return dataIntegrityViolationCodes; } + set { dataIntegrityViolationCodes = value; } + } + + public string[] CannotAcquireLockCodes + { + get { return cannotAcquireLockCodes; } + set { cannotAcquireLockCodes = value; } + } + + public string[] DeadlockLoserCodes + { + get { return deadlockLoserCodes; } + set { deadlockLoserCodes = value; } + } + + public string[] CannotSerializeTransactionCodes + { + get { return cannotSerializeTransactionCodes; } + set { cannotSerializeTransactionCodes = value; } + } + + #endregion + + #region Methods + + #endregion + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/IDbMetadata.cs b/src/Spring/Spring.Data/Data/Common/IDbMetadata.cs index 958a6446..2191bb12 100644 --- a/src/Spring/Spring.Data/Data/Common/IDbMetadata.cs +++ b/src/Spring/Spring.Data/Data/Common/IDbMetadata.cs @@ -1,172 +1,171 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// Provides minimal database metadata information to support the - /// functionality in Spring.NET ADO.NET Framework. - /// - /// - /// Mark Pollack (.NET) - /// $Id: IDbMetadata.cs,v 1.8 2007/11/21 18:01:45 markpollack Exp $ - public interface IDbMetadata - { - /// - /// Gets a descriptive name of the product. - /// - /// Example: Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0 - /// The name of the product. - string ProductName { get; } - - /// - /// Gets the type of the connection. The fully qualified type name is given since some providers, - /// notably for SqlServerCe, do not use the same namespace for all data access types. - /// - /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the connection. - Type ConnectionType { get; } - - /// - /// Gets the type of the command. - /// - /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the command. - Type CommandType { get; } - - /// - /// Gets the type of the parameter. - /// - /// Example: System.Data.SqlClient.SqlParameter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the parameter. - Type ParameterType { get; } - - /// - /// Gets the type of the data adapter. - /// - /// Example: System.Data.SqlClient.SqlDataAdapter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the data adapter. - Type DataAdapterType { get; } - - /// - /// Gets the type of the command builder. - /// - /// Example: System.Data.SqlClient.SqlCommandBuilder, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the command builder. - Type CommandBuilderType { get; } - - /// - /// Gets the type of the exception. - /// - /// Example: System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the exception. - Type ExceptionType { get; } - - /// - /// Gets the error code exception expression. - /// - /// Example Errors[0].Number.ToString() for Sql Server - /// The error code exception expression. - string ErrorCodeExceptionExpression { get; } - - /// - /// Gets the command builder derive parameters method. - /// - /// If the value 'not supported' is specified then this method will throw an ArgumentException - /// Example: DeriveParameters - /// The command builder derive parameters method. - MethodInfo CommandBuilderDeriveParametersMethod { get; } - - /// - /// Provide the prefix used to indentify named parameters in SQL text. - /// - /// @ for Sql Server - string ParameterNamePrefix { get; } - - /// - /// Does the driver require the use of the parameter prefix when - /// specifying the name of the parameter in the Command's - /// Parameter collection. - /// - /// If true, then commamd.Parameters["@parameterName"] is - /// used, otherwise, command.Parameters["parameterName"]. - /// - bool UseParameterNamePrefixInParameterCollection { get; } - - - /// - /// Gets a value indicating whether the Provider requires - /// the use of a named prefix in the SQL string. - /// - /// - /// The OLE DB/ODBC .NET Provider does not support named parameters for - /// passing parameters to an SQL Statement or a stored procedure called - /// by an IDbCommand when CommandType is set to Text. - /// - /// - /// true if use parameter prefix in SQL; otherwise, false. - /// - bool UseParameterPrefixInSql { get; } - - /// - /// For providers that allow you to choose between binding parameters - /// to a command by name (true) or by position (false). - /// - bool BindByName { get; - //TODO will go away when make all of this fully configuration driven. - set; - } - - /// - /// Gets the type of the parameter db. - /// - /// Example: System.Data.SqlDbType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - /// The type of the parameter db. - Type ParameterDbType { get; } - - /// - /// Gets the parameter db type property. - /// - /// Example: SqlDbType for SqlServer - /// The parameter db type property. - PropertyInfo ParameterDbTypeProperty { get; } - - /// - /// Gets the parameter is nullable property. - /// - /// Example: IsNullable for Sql Server - /// The parameter is nullable property. - PropertyInfo ParameterIsNullableProperty { get; } - - /// - /// Gets or sets the error codes. - /// - /// The collection of error codes to map error code integer values to Spring's DAO exception hierarchy - /// The error codes. - ErrorCodes ErrorCodes { get; } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// Provides minimal database metadata information to support the + /// functionality in Spring.NET ADO.NET Framework. + /// + /// + /// Mark Pollack (.NET) + public interface IDbMetadata + { + /// + /// Gets a descriptive name of the product. + /// + /// Example: Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0 + /// The name of the product. + string ProductName { get; } + + /// + /// Gets the type of the connection. The fully qualified type name is given since some providers, + /// notably for SqlServerCe, do not use the same namespace for all data access types. + /// + /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the connection. + Type ConnectionType { get; } + + /// + /// Gets the type of the command. + /// + /// Example: System.Data.SqlClient.SqlCommand, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the command. + Type CommandType { get; } + + /// + /// Gets the type of the parameter. + /// + /// Example: System.Data.SqlClient.SqlParameter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the parameter. + Type ParameterType { get; } + + /// + /// Gets the type of the data adapter. + /// + /// Example: System.Data.SqlClient.SqlDataAdapter, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the data adapter. + Type DataAdapterType { get; } + + /// + /// Gets the type of the command builder. + /// + /// Example: System.Data.SqlClient.SqlCommandBuilder, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the command builder. + Type CommandBuilderType { get; } + + /// + /// Gets the type of the exception. + /// + /// Example: System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the exception. + Type ExceptionType { get; } + + /// + /// Gets the error code exception expression. + /// + /// Example Errors[0].Number.ToString() for Sql Server + /// The error code exception expression. + string ErrorCodeExceptionExpression { get; } + + /// + /// Gets the command builder derive parameters method. + /// + /// If the value 'not supported' is specified then this method will throw an ArgumentException + /// Example: DeriveParameters + /// The command builder derive parameters method. + MethodInfo CommandBuilderDeriveParametersMethod { get; } + + /// + /// Provide the prefix used to indentify named parameters in SQL text. + /// + /// @ for Sql Server + string ParameterNamePrefix { get; } + + /// + /// Does the driver require the use of the parameter prefix when + /// specifying the name of the parameter in the Command's + /// Parameter collection. + /// + /// If true, then commamd.Parameters["@parameterName"] is + /// used, otherwise, command.Parameters["parameterName"]. + /// + bool UseParameterNamePrefixInParameterCollection { get; } + + + /// + /// Gets a value indicating whether the Provider requires + /// the use of a named prefix in the SQL string. + /// + /// + /// The OLE DB/ODBC .NET Provider does not support named parameters for + /// passing parameters to an SQL Statement or a stored procedure called + /// by an IDbCommand when CommandType is set to Text. + /// + /// + /// true if use parameter prefix in SQL; otherwise, false. + /// + bool UseParameterPrefixInSql { get; } + + /// + /// For providers that allow you to choose between binding parameters + /// to a command by name (true) or by position (false). + /// + bool BindByName { get; + //TODO will go away when make all of this fully configuration driven. + set; + } + + /// + /// Gets the type of the parameter db. + /// + /// Example: System.Data.SqlDbType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + /// The type of the parameter db. + Type ParameterDbType { get; } + + /// + /// Gets the parameter db type property. + /// + /// Example: SqlDbType for SqlServer + /// The parameter db type property. + PropertyInfo ParameterDbTypeProperty { get; } + + /// + /// Gets the parameter is nullable property. + /// + /// Example: IsNullable for Sql Server + /// The parameter is nullable property. + PropertyInfo ParameterIsNullableProperty { get; } + + /// + /// Gets or sets the error codes. + /// + /// The collection of error codes to map error code integer values to Spring's DAO exception hierarchy + /// The error codes. + ErrorCodes ErrorCodes { get; } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/IDbParameter.cs b/src/Spring/Spring.Data/Data/Common/IDbParameter.cs index 2ead7d42..d442e30b 100644 --- a/src/Spring/Spring.Data/Data/Common/IDbParameter.cs +++ b/src/Spring/Spring.Data/Data/Common/IDbParameter.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; - -#endregion - -namespace Spring.Data.Common -{ - /// - /// A parameter interface used by - /// - /// Mark Pollack (.NET) - /// $Id: IDbParameter.cs,v 1.6 2006/12/02 07:35:23 markpollack Exp $ - public interface IDbParameter - { - - IDbParameter Type(Enum dbType); - - IDbParameter Type(Enum dbType, int size); - - Enum GetDbType(); - - IDbParameter Direction(ParameterDirection direction); - - ParameterDirection GetDirection(); - - IDbParameter IsNullable(bool isNullable); - - bool GetIsNullable(); - - IDbParameter Name(string name); - - string GetName(); - - IDbParameter SourceColumn(string sourceColumn); - - string GetSourceColumn(); - - IDbParameter SourceVersion(DataRowVersion sourceVersion); - - DataRowVersion GetSourceVersion(); - - - IDbParameter Value(object val); - - object GetValue(); - - IDbParameter Precision(byte precision); - - byte GetPrecision(); - - - IDbParameter Scale(byte scale); - - byte GetScale(); - - - IDbParameter Size(int size); - - int GetSize(); - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; + +#endregion + +namespace Spring.Data.Common +{ + /// + /// A parameter interface used by + /// + /// Mark Pollack (.NET) + public interface IDbParameter + { + + IDbParameter Type(Enum dbType); + + IDbParameter Type(Enum dbType, int size); + + Enum GetDbType(); + + IDbParameter Direction(ParameterDirection direction); + + ParameterDirection GetDirection(); + + IDbParameter IsNullable(bool isNullable); + + bool GetIsNullable(); + + IDbParameter Name(string name); + + string GetName(); + + IDbParameter SourceColumn(string sourceColumn); + + string GetSourceColumn(); + + IDbParameter SourceVersion(DataRowVersion sourceVersion); + + DataRowVersion GetSourceVersion(); + + + IDbParameter Value(object val); + + object GetValue(); + + IDbParameter Precision(byte precision); + + byte GetPrecision(); + + + IDbParameter Scale(byte scale); + + byte GetScale(); + + + IDbParameter Size(int size); + + int GetSize(); + + } +} diff --git a/src/Spring/Spring.Data/Data/Common/IDbParameters.cs b/src/Spring/Spring.Data/Data/Common/IDbParameters.cs index c9b7b636..76511dae 100644 --- a/src/Spring/Spring.Data/Data/Common/IDbParameters.cs +++ b/src/Spring/Spring.Data/Data/Common/IDbParameters.cs @@ -1,130 +1,130 @@ -using System; -using System.Data; - -namespace Spring.Data.Common -{ - public interface IDbParameters - { - //TODO implement IDataParameterCollection....? - - //TODO should add methods return IDbDataParameter? - -#if !MONO // EE: mono/win32 doesn't accept comments on indexer?!? - /// - /// Gets the underlying standard ADO.NET for the specified parameter name. - /// -#endif - IDataParameter this[string parameterName] { get; set; } - -#if !MONO // EE: mono/win32 doesn't accept comments on indexer?!? - /// - /// Gets the underlying standard ADO.NET for the specified index. - /// -#endif - IDataParameter this[int index] { get; set; } - - int Count - { - get; - } - - /// - /// Determines whether this collection contains the specified parameter name. - /// - /// Name of the parameter. - /// - /// true if contains the specified parameter name; otherwise, false. - /// - bool Contains(string parameterName); - - /// - /// Returns the underlying standard ADO.NET parameters collection. - /// - IDataParameterCollection DataParameterCollection { get; } - - /// - /// Add an instance of . - /// - /// - void AddParameter(IDataParameter dbParameter); - - /// - /// Add a parameter specifying the all the individual properties of a - /// IDbDataParameter. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The newly created parameter - IDbDataParameter AddParameter(string name, Enum parameterType, int size, ParameterDirection direction, bool isNullable, - byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object parameterValue); - - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The newly created parameter - IDbDataParameter AddParameter(string name, Enum parameterType, ParameterDirection direction, bool isNullable, byte precision, - byte scale, string sourceColumn, DataRowVersion sourceVersion, object parameterValue); - - - /// - /// Adds a value to the parameter collection - /// - /// This method can not be used with stored procedures for - /// providers that require named parameters. However, it is of - /// great convenience for other cases. - /// The value of the parameter. - /// Index of added parameter. - int Add(object parameterValue); - - /// - /// Adds a range of vlaues to the parameter collection. - /// - /// This method can not be used with stored procedures for - /// providers that require named parameters. However, it is of - /// great convenience for other cases. - /// - void AddRange(Array values); - - IDbDataParameter AddWithValue(string name, object parameterValue); - - IDbDataParameter Add(string name, Enum parameterType); - - IDbDataParameter Add(string name, Enum parameterType, int size); - - IDbDataParameter Add(string name, Enum parameterType, int size, string sourceColumn); - - IDbDataParameter AddOut(string name, Enum parameterType); - - IDbDataParameter AddOut(string name, Enum parameterType, int size); - - IDbDataParameter AddInOut(string name, Enum parameterType); - - IDbDataParameter AddInOut(string name, Enum parameterType, int size); - - IDbDataParameter AddReturn(string name, Enum parameterType); - - IDbDataParameter AddReturn(string name, Enum parameterType, int size); - - object GetValue(string name); - - void SetValue(string name, object parameterValue); - - } +using System; +using System.Data; + +namespace Spring.Data.Common +{ + public interface IDbParameters + { + //TODO implement IDataParameterCollection....? + + //TODO should add methods return IDbDataParameter? + +#if !MONO // EE: mono/win32 doesn't accept comments on indexer?!? + /// + /// Gets the underlying standard ADO.NET for the specified parameter name. + /// +#endif + IDataParameter this[string parameterName] { get; set; } + +#if !MONO // EE: mono/win32 doesn't accept comments on indexer?!? + /// + /// Gets the underlying standard ADO.NET for the specified index. + /// +#endif + IDataParameter this[int index] { get; set; } + + int Count + { + get; + } + + /// + /// Determines whether this collection contains the specified parameter name. + /// + /// Name of the parameter. + /// + /// true if contains the specified parameter name; otherwise, false. + /// + bool Contains(string parameterName); + + /// + /// Returns the underlying standard ADO.NET parameters collection. + /// + IDataParameterCollection DataParameterCollection { get; } + + /// + /// Add an instance of . + /// + /// + void AddParameter(IDataParameter dbParameter); + + /// + /// Add a parameter specifying the all the individual properties of a + /// IDbDataParameter. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The newly created parameter + IDbDataParameter AddParameter(string name, Enum parameterType, int size, ParameterDirection direction, bool isNullable, + byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object parameterValue); + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The newly created parameter + IDbDataParameter AddParameter(string name, Enum parameterType, ParameterDirection direction, bool isNullable, byte precision, + byte scale, string sourceColumn, DataRowVersion sourceVersion, object parameterValue); + + + /// + /// Adds a value to the parameter collection + /// + /// This method can not be used with stored procedures for + /// providers that require named parameters. However, it is of + /// great convenience for other cases. + /// The value of the parameter. + /// Index of added parameter. + int Add(object parameterValue); + + /// + /// Adds a range of vlaues to the parameter collection. + /// + /// This method can not be used with stored procedures for + /// providers that require named parameters. However, it is of + /// great convenience for other cases. + /// + void AddRange(Array values); + + IDbDataParameter AddWithValue(string name, object parameterValue); + + IDbDataParameter Add(string name, Enum parameterType); + + IDbDataParameter Add(string name, Enum parameterType, int size); + + IDbDataParameter Add(string name, Enum parameterType, int size, string sourceColumn); + + IDbDataParameter AddOut(string name, Enum parameterType); + + IDbDataParameter AddOut(string name, Enum parameterType, int size); + + IDbDataParameter AddInOut(string name, Enum parameterType); + + IDbDataParameter AddInOut(string name, Enum parameterType, int size); + + IDbDataParameter AddReturn(string name, Enum parameterType); + + IDbDataParameter AddReturn(string name, Enum parameterType, int size); + + object GetValue(string name); + + void SetValue(string name, object parameterValue); + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Common/IDbParametersBuilder.cs b/src/Spring/Spring.Data/Data/Common/IDbParametersBuilder.cs index 45a19f3f..0f0295d9 100644 --- a/src/Spring/Spring.Data/Data/Common/IDbParametersBuilder.cs +++ b/src/Spring/Spring.Data/Data/Common/IDbParametersBuilder.cs @@ -1,34 +1,33 @@ - -#region Imports - - - -#endregion - -namespace Spring.Data.Common -{ - /// - /// A builder to create a collection of ADO.NET parameters. - /// - /// The chaining of IDbParameter methods does the - /// building of the parameter details while the builder class - /// itself keeps track of the collection. - /// - /// Mark Pollack (.NET) - /// $Id: IDbParametersBuilder.cs,v 1.1 2006/12/02 07:38:15 markpollack Exp $ - public interface IDbParametersBuilder - { - /// - /// Creates a IDbParameter object and adds it to an internal collection for - /// later retrieval via the GetParameters method. - /// - /// - IDbParameter Create(); - - /// - /// Gets all the parameters created and configured via the Create method. - /// - /// An instance of IDbParameters - IDbParameters GetParameters(); - } -} + +#region Imports + + + +#endregion + +namespace Spring.Data.Common +{ + /// + /// A builder to create a collection of ADO.NET parameters. + /// + /// The chaining of IDbParameter methods does the + /// building of the parameter details while the builder class + /// itself keeps track of the collection. + /// + /// Mark Pollack (.NET) + public interface IDbParametersBuilder + { + /// + /// Creates a IDbParameter object and adds it to an internal collection for + /// later retrieval via the GetParameters method. + /// + /// + IDbParameter Create(); + + /// + /// Gets all the parameters created and configured via the Create method. + /// + /// An instance of IDbParameters + IDbParameters GetParameters(); + } +} diff --git a/src/Spring/Spring.Data/Data/Common/IDbProvider.cs b/src/Spring/Spring.Data/Data/Common/IDbProvider.cs index b5ad14ed..5d089877 100644 --- a/src/Spring/Spring.Data/Data/Common/IDbProvider.cs +++ b/src/Spring/Spring.Data/Data/Common/IDbProvider.cs @@ -1,126 +1,126 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; - -namespace Spring.Data.Common -{ - /// - /// Factory interface to create provider specific ADO.NET objects. - /// - public interface IDbProvider - { - - /// - /// Returns a new command object for executing SQL statments/Stored Procedures - /// against the database. - /// - /// An new - IDbCommand CreateCommand(); - - /// - /// Returns a new instance of the providers CommandBuilder class. - /// - /// In .NET 1.1 there was no common base class or interface - /// for command builders, hence the return signature is object to - /// be portable (but more loosely typed) across .NET 1.1/2.0 - /// A new Command Builder - object CreateCommandBuilder(); - - /// - /// Returns a new connection object to communicate with the database. - /// - /// A new - IDbConnection CreateConnection(); - - - /// - /// Returns a new adapter objects for use with offline DataSets. - /// - /// A new - IDbDataAdapter CreateDataAdapter(); - - /// - /// Returns a new parameter object for binding values to parameter - /// placeholders in SQL statements or Stored Procedure variables. - /// - /// A new - IDbDataParameter CreateParameter(); - - - /// - /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. - /// - /// In most cases this adds the parameter prefix to the name passed into this method. - /// The unformatted name of the parameter. - /// The parameter name formatted foran IDbCommand.CommandText. - string CreateParameterName(string name); - - /// - /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be - /// part of a IDataParameterCollection. - /// - /// The unformatted name of the parameter. - /// The parameter name formatted for an IDataParameter - string CreateParameterNameForCollection(string name); - - /// - /// Return metadata information about the database provider - /// - IDbMetadata DbMetadata - { - get; - } - - - - /// - /// Connection string used to create connections. - /// - string ConnectionString - { - set; - get; - } - - - /// - /// Extracts the provider specific error code as a string. - /// - /// The data access exception. - /// The provider specific error code - string ExtractError(Exception e); - - /// - /// Determines whether the provided exception is in fact related - /// to database access. This can be provider dependent in .NET 1.1 since - /// there isn't a common base class for ADO.NET exceptions. - /// - /// The exception thrown when performing data access - /// operations. - /// - /// true if is a valid data access exception for the specified - /// exception; otherwise, false. - /// - bool IsDataAccessException(Exception e); - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; + +namespace Spring.Data.Common +{ + /// + /// Factory interface to create provider specific ADO.NET objects. + /// + public interface IDbProvider + { + + /// + /// Returns a new command object for executing SQL statments/Stored Procedures + /// against the database. + /// + /// An new + IDbCommand CreateCommand(); + + /// + /// Returns a new instance of the providers CommandBuilder class. + /// + /// In .NET 1.1 there was no common base class or interface + /// for command builders, hence the return signature is object to + /// be portable (but more loosely typed) across .NET 1.1/2.0 + /// A new Command Builder + object CreateCommandBuilder(); + + /// + /// Returns a new connection object to communicate with the database. + /// + /// A new + IDbConnection CreateConnection(); + + + /// + /// Returns a new adapter objects for use with offline DataSets. + /// + /// A new + IDbDataAdapter CreateDataAdapter(); + + /// + /// Returns a new parameter object for binding values to parameter + /// placeholders in SQL statements or Stored Procedure variables. + /// + /// A new + IDbDataParameter CreateParameter(); + + + /// + /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. + /// + /// In most cases this adds the parameter prefix to the name passed into this method. + /// The unformatted name of the parameter. + /// The parameter name formatted foran IDbCommand.CommandText. + string CreateParameterName(string name); + + /// + /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be + /// part of a IDataParameterCollection. + /// + /// The unformatted name of the parameter. + /// The parameter name formatted for an IDataParameter + string CreateParameterNameForCollection(string name); + + /// + /// Return metadata information about the database provider + /// + IDbMetadata DbMetadata + { + get; + } + + + + /// + /// Connection string used to create connections. + /// + string ConnectionString + { + set; + get; + } + + + /// + /// Extracts the provider specific error code as a string. + /// + /// The data access exception. + /// The provider specific error code + string ExtractError(Exception e); + + /// + /// Determines whether the provided exception is in fact related + /// to database access. This can be provider dependent in .NET 1.1 since + /// there isn't a common base class for ADO.NET exceptions. + /// + /// The exception thrown when performing data access + /// operations. + /// + /// true if is a valid data access exception for the specified + /// exception; otherwise, false. + /// + bool IsDataAccessException(Exception e); + + } +} diff --git a/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs b/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs index 2d2d0a08..f5a1c5fb 100644 --- a/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs +++ b/src/Spring/Spring.Data/Data/Common/MultiDelegatingDbProvider.cs @@ -1,267 +1,266 @@ -#region Licence - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Data; -using Spring.Collections; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Objects.Factory; -using Spring.Threading; - - -namespace Spring.Data -{ - /// - /// A wrapper implementation for IDbProvider such that multiple DbProvider instances can be - /// selected at runtime, say based on web request criteria. - /// - /// - /// The name of which DbProvider to use, as provided to the IDictionary property TargetDbProviders - /// is "dbProviderName". Once the target dbprovider name is known, set the name via a call to - /// LogicalThreadContext.SetData("dbProviderName", "database1ProviderName"). The value - /// "database1ProviderName" must match a key in the provided TargetDbProviders dictionary. - /// - /// Mark Pollack - /// $Id: MultiDelegatingDbProvider.cs,v 1.5 2008/05/29 17:26:35 markpollack Exp $ - public class MultiDelegatingDbProvider : IDbProvider, IInitializingObject - { - private IDictionary targetDbProviders = new SynchronizedHashtable(); - - #region Constructors - /// - /// Initializes a new instance of the class. - /// - public MultiDelegatingDbProvider() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// The target db providers. - public MultiDelegatingDbProvider(IDictionary targetDbProviders) - { - this.targetDbProviders = targetDbProviders; - } - - #endregion - - /// - /// Sets the target db providers. - /// - /// The target db providers. - public IDictionary TargetDbProviders - { - set { targetDbProviders = value; } - } - - /// - /// Ensures that the there are values in the TargetDbProviders dictionary and that the - /// key is of the type string and value is of the type IDbProvider. - /// - /// If the above conditions are not met. - public void AfterPropertiesSet() - { - if (targetDbProviders.Count == 0) - { - throw new ArgumentException("Target DbProvider collection required."); - } - foreach (DictionaryEntry entry in targetDbProviders) - { - if (! entry.Key.GetType().Equals(typeof(string))) - { - throw new ArgumentException("Key identifying target IDbProvider in TargetDbProviders dictionary property is required to be of type string. Key = " + entry.Key); - } - IDbProvider targetProvider = entry.Value as IDbProvider; - if (targetProvider == null) - { - throw new ArgumentException("Value in TargetDbProviders dictionary is not of type IDbProvider."); - } - } - } - - #region IDbProvider methods - - - /// - /// Returns a new command object for executing SQL statments/Stored Procedures - /// against the database. - /// - /// An new - public IDbCommand CreateCommand() - { - return GetTargetProvider().CreateCommand(); - } - - /// - /// Returns a new connection object to communicate with the database. - /// - /// A new - public IDbConnection CreateConnection() - { - return GetTargetProvider().CreateConnection(); - } - - /// - /// Returns a new parameter object for binding values to parameter - /// placeholders in SQL statements or Stored Procedure variables. - /// - /// A new - public IDbDataParameter CreateParameter() - { - return GetTargetProvider().CreateParameter(); - } - - /// - /// Returns a new adapter objects for use with offline DataSets. - /// - /// A new - public IDbDataAdapter CreateDataAdapter() - { - return GetTargetProvider().CreateDataAdapter(); - } - - /// - /// Returns a new instance of the providers CommandBuilder class. - /// - /// A new Command Builder - /// In .NET 1.1 there was no common base class or interface - /// for command builders, hence the return signature is object to - /// be portable (but more loosely typed) across .NET 1.1/2.0 - public object CreateCommandBuilder() - { - return GetTargetProvider().CreateDataAdapter(); - } - - /// - /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. - /// - /// The unformatted name of the parameter. - /// - /// The parameter name formatted foran IDbCommand.CommandText. - /// - /// In most cases this adds the parameter prefix to the name passed into this method. - public string CreateParameterName(string name) - { - return GetTargetProvider().CreateParameterName(name); - } - - - /// - /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be - /// part of a IDataParameterCollection. - /// - /// The unformatted name of the parameter. - /// - /// The parameter name formatted for an IDataParameter - /// - public string CreateParameterNameForCollection(string name) - { - return GetTargetProvider().CreateParameterNameForCollection(name); - } - - /// - /// Return metadata information about the database provider - /// - /// - public IDbMetadata DbMetadata - { - get { return GetTargetProvider().DbMetadata; } - } - - /// - /// Connection string used to create connections. - /// - /// - public string ConnectionString - { - get { return GetTargetProvider().ConnectionString; } - set { GetTargetProvider().ConnectionString = value; } - } - - /// - /// Extracts the provider specific error code as a string. - /// - /// The data access exception. - /// The provider specific error code - public string ExtractError(Exception e) - { - return GetTargetProvider().ExtractError(e); - } - - /// - /// Determines whether the provided exception is in fact related - /// to database access. This can be provider dependent in .NET 1.1 since - /// there isn't a common base class for ADO.NET exceptions. - /// - /// The exception thrown when performing data access - /// operations. - /// - /// true if is a valid data access exception for the specified - /// exception; otherwise, false. - /// - public bool IsDataAccessException(Exception e) - { -#if NET_2_0 - if (e is System.Data.Common.DbException) - { - return true; - } - else - { - return false; - } -#else - return IsDataAccessExceptionBCL11(e); -#endif - } - - /// - /// Determines whether is data access exception in .NET 1.1 for the specified exception. - /// - /// The candidate exception. - /// - /// true if is data access exception in .NET 1.1 for the specified exception; otherwise, false. - /// - public bool IsDataAccessExceptionBCL11(Exception e) - { - return false; - } - #endregion - - /// - /// Gets the target provider based on the thread local name "dbProviderName" - /// - /// The corresonding IDbProvider. - protected virtual IDbProvider GetTargetProvider() - { - string dbProviderName = (string)LogicalThreadContext.GetData("dbProviderName"); - if (targetDbProviders.Contains(dbProviderName)) - { - return (IDbProvider)targetDbProviders[dbProviderName]; - } - throw new InvalidDataAccessApiUsageException("'" + dbProviderName + "'" - + "was not under the thread local key 'dbProviderName'"); - } - } -} +#region Licence + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Data; +using Spring.Collections; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Objects.Factory; +using Spring.Threading; + + +namespace Spring.Data +{ + /// + /// A wrapper implementation for IDbProvider such that multiple DbProvider instances can be + /// selected at runtime, say based on web request criteria. + /// + /// + /// The name of which DbProvider to use, as provided to the IDictionary property TargetDbProviders + /// is "dbProviderName". Once the target dbprovider name is known, set the name via a call to + /// LogicalThreadContext.SetData("dbProviderName", "database1ProviderName"). The value + /// "database1ProviderName" must match a key in the provided TargetDbProviders dictionary. + /// + /// Mark Pollack + public class MultiDelegatingDbProvider : IDbProvider, IInitializingObject + { + private IDictionary targetDbProviders = new SynchronizedHashtable(); + + #region Constructors + /// + /// Initializes a new instance of the class. + /// + public MultiDelegatingDbProvider() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The target db providers. + public MultiDelegatingDbProvider(IDictionary targetDbProviders) + { + this.targetDbProviders = targetDbProviders; + } + + #endregion + + /// + /// Sets the target db providers. + /// + /// The target db providers. + public IDictionary TargetDbProviders + { + set { targetDbProviders = value; } + } + + /// + /// Ensures that the there are values in the TargetDbProviders dictionary and that the + /// key is of the type string and value is of the type IDbProvider. + /// + /// If the above conditions are not met. + public void AfterPropertiesSet() + { + if (targetDbProviders.Count == 0) + { + throw new ArgumentException("Target DbProvider collection required."); + } + foreach (DictionaryEntry entry in targetDbProviders) + { + if (! entry.Key.GetType().Equals(typeof(string))) + { + throw new ArgumentException("Key identifying target IDbProvider in TargetDbProviders dictionary property is required to be of type string. Key = " + entry.Key); + } + IDbProvider targetProvider = entry.Value as IDbProvider; + if (targetProvider == null) + { + throw new ArgumentException("Value in TargetDbProviders dictionary is not of type IDbProvider."); + } + } + } + + #region IDbProvider methods + + + /// + /// Returns a new command object for executing SQL statments/Stored Procedures + /// against the database. + /// + /// An new + public IDbCommand CreateCommand() + { + return GetTargetProvider().CreateCommand(); + } + + /// + /// Returns a new connection object to communicate with the database. + /// + /// A new + public IDbConnection CreateConnection() + { + return GetTargetProvider().CreateConnection(); + } + + /// + /// Returns a new parameter object for binding values to parameter + /// placeholders in SQL statements or Stored Procedure variables. + /// + /// A new + public IDbDataParameter CreateParameter() + { + return GetTargetProvider().CreateParameter(); + } + + /// + /// Returns a new adapter objects for use with offline DataSets. + /// + /// A new + public IDbDataAdapter CreateDataAdapter() + { + return GetTargetProvider().CreateDataAdapter(); + } + + /// + /// Returns a new instance of the providers CommandBuilder class. + /// + /// A new Command Builder + /// In .NET 1.1 there was no common base class or interface + /// for command builders, hence the return signature is object to + /// be portable (but more loosely typed) across .NET 1.1/2.0 + public object CreateCommandBuilder() + { + return GetTargetProvider().CreateDataAdapter(); + } + + /// + /// Creates the name of the parameter in the format appropriate to use inside IDbCommand.CommandText. + /// + /// The unformatted name of the parameter. + /// + /// The parameter name formatted foran IDbCommand.CommandText. + /// + /// In most cases this adds the parameter prefix to the name passed into this method. + public string CreateParameterName(string name) + { + return GetTargetProvider().CreateParameterName(name); + } + + + /// + /// Creates the name ofthe parameter in the format appropriate for an IDataParameter, i.e. to be + /// part of a IDataParameterCollection. + /// + /// The unformatted name of the parameter. + /// + /// The parameter name formatted for an IDataParameter + /// + public string CreateParameterNameForCollection(string name) + { + return GetTargetProvider().CreateParameterNameForCollection(name); + } + + /// + /// Return metadata information about the database provider + /// + /// + public IDbMetadata DbMetadata + { + get { return GetTargetProvider().DbMetadata; } + } + + /// + /// Connection string used to create connections. + /// + /// + public string ConnectionString + { + get { return GetTargetProvider().ConnectionString; } + set { GetTargetProvider().ConnectionString = value; } + } + + /// + /// Extracts the provider specific error code as a string. + /// + /// The data access exception. + /// The provider specific error code + public string ExtractError(Exception e) + { + return GetTargetProvider().ExtractError(e); + } + + /// + /// Determines whether the provided exception is in fact related + /// to database access. This can be provider dependent in .NET 1.1 since + /// there isn't a common base class for ADO.NET exceptions. + /// + /// The exception thrown when performing data access + /// operations. + /// + /// true if is a valid data access exception for the specified + /// exception; otherwise, false. + /// + public bool IsDataAccessException(Exception e) + { +#if NET_2_0 + if (e is System.Data.Common.DbException) + { + return true; + } + else + { + return false; + } +#else + return IsDataAccessExceptionBCL11(e); +#endif + } + + /// + /// Determines whether is data access exception in .NET 1.1 for the specified exception. + /// + /// The candidate exception. + /// + /// true if is data access exception in .NET 1.1 for the specified exception; otherwise, false. + /// + public bool IsDataAccessExceptionBCL11(Exception e) + { + return false; + } + #endregion + + /// + /// Gets the target provider based on the thread local name "dbProviderName" + /// + /// The corresonding IDbProvider. + protected virtual IDbProvider GetTargetProvider() + { + string dbProviderName = (string)LogicalThreadContext.GetData("dbProviderName"); + if (targetDbProviders.Contains(dbProviderName)) + { + return (IDbProvider)targetDbProviders[dbProviderName]; + } + throw new InvalidDataAccessApiUsageException("'" + dbProviderName + "'" + + "was not under the thread local key 'dbProviderName'"); + } + } +} diff --git a/src/Spring/Spring.Data/Data/Common/UserCredentialsDbProvider.cs b/src/Spring/Spring.Data/Data/Common/UserCredentialsDbProvider.cs index 8ec7247e..6b52ea0d 100644 --- a/src/Spring/Spring.Data/Data/Common/UserCredentialsDbProvider.cs +++ b/src/Spring/Spring.Data/Data/Common/UserCredentialsDbProvider.cs @@ -1,137 +1,137 @@ -#region Licence - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; -using Spring.Threading; -using Spring.Util; - -namespace Spring.Data.Common -{ - /// - /// An adapter for a target IDbProvider, applying the specified user credentials - /// to the connection string for every GetConnection call. - /// - public class UserCredentialsDbProvider : DelegatingDbProvider - { - private string username; - - private string password; - - private string separator = ";"; - - private const string USERNAME = "UserCredentialsDbProvider.UserName"; - - private const string PASSWORD = "UserCredentialsDbProvider.Password"; - - /// - /// Sets the username string that will be appended to the connection string. - /// - /// The username. - public string Username - { - set { username = value; } - } - - /// - /// Sets the password string that will be appended to the connection string. - /// - /// The password. - public string Password - { - set { password = value; } - } - - - /// - /// Sets the separator used to separate elements of the connection string. Default is ';'. - /// - /// - /// The separator used to separate elements in the connection string. - public string Separator - { - set { separator = value; } - } - - /// - /// Sets the user credentials for current thread. The given username and password - /// strings will be added to the connection string for all subsequent GetConnection - /// requests. This will override any statically specified user credentials, that is, - /// set by the properties Username nad Password. - /// - /// The username part of the connection string. - /// The password part of the connection string. - public void SetCredentialsForCurrentThread(string user, string pass) - { - LogicalThreadContext.SetData(USERNAME, user); - LogicalThreadContext.SetData(PASSWORD, pass); - } - - /// - /// Removes the user credentials from current thread. Use statically specified - /// credentials afterwards. - /// - public void RemoveCredentialsFromCurrentThread() - { - LogicalThreadContext.FreeNamedDataSlot(USERNAME); - LogicalThreadContext.FreeNamedDataSlot(PASSWORD); - } - - - /// - /// Returns a new connection object to communicate with the database. - /// Determine if there are currently thread-bound credentials, using them if - /// available, falling back to the statically specified username and password - /// (i.e. values of the properties 'Username' and 'Password') otherwise. - /// The username and password will be concatenated on the connection string - /// using string in the Separator property - /// - /// A new - public override IDbConnection CreateConnection() - { - string user = LogicalThreadContext.GetData(USERNAME) as string; - string pass = LogicalThreadContext.GetData(PASSWORD) as string; - if (user != null && pass != null) - { - return DoCreateConnection(user, pass); - } - else - { - return DoCreateConnection(username, password); - } - } - - protected virtual IDbConnection DoCreateConnection(string user, string pass) - { - AssertUtils.ArgumentNotNull(TargetDbProvider,"TargetDbProvider"); - if (StringUtils.HasLength(user)) - { - IDbConnection conn = TargetDbProvider.CreateConnection(); - string s= ConnectionString + separator + user + separator + pass; - conn.ConnectionString = s; - return conn; - } - else - { - return TargetDbProvider.CreateConnection(); - } - } - } - +#region Licence + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; +using Spring.Threading; +using Spring.Util; + +namespace Spring.Data.Common +{ + /// + /// An adapter for a target IDbProvider, applying the specified user credentials + /// to the connection string for every GetConnection call. + /// + public class UserCredentialsDbProvider : DelegatingDbProvider + { + private string username; + + private string password; + + private string separator = ";"; + + private const string USERNAME = "UserCredentialsDbProvider.UserName"; + + private const string PASSWORD = "UserCredentialsDbProvider.Password"; + + /// + /// Sets the username string that will be appended to the connection string. + /// + /// The username. + public string Username + { + set { username = value; } + } + + /// + /// Sets the password string that will be appended to the connection string. + /// + /// The password. + public string Password + { + set { password = value; } + } + + + /// + /// Sets the separator used to separate elements of the connection string. Default is ';'. + /// + /// + /// The separator used to separate elements in the connection string. + public string Separator + { + set { separator = value; } + } + + /// + /// Sets the user credentials for current thread. The given username and password + /// strings will be added to the connection string for all subsequent GetConnection + /// requests. This will override any statically specified user credentials, that is, + /// set by the properties Username nad Password. + /// + /// The username part of the connection string. + /// The password part of the connection string. + public void SetCredentialsForCurrentThread(string user, string pass) + { + LogicalThreadContext.SetData(USERNAME, user); + LogicalThreadContext.SetData(PASSWORD, pass); + } + + /// + /// Removes the user credentials from current thread. Use statically specified + /// credentials afterwards. + /// + public void RemoveCredentialsFromCurrentThread() + { + LogicalThreadContext.FreeNamedDataSlot(USERNAME); + LogicalThreadContext.FreeNamedDataSlot(PASSWORD); + } + + + /// + /// Returns a new connection object to communicate with the database. + /// Determine if there are currently thread-bound credentials, using them if + /// available, falling back to the statically specified username and password + /// (i.e. values of the properties 'Username' and 'Password') otherwise. + /// The username and password will be concatenated on the connection string + /// using string in the Separator property + /// + /// A new + public override IDbConnection CreateConnection() + { + string user = LogicalThreadContext.GetData(USERNAME) as string; + string pass = LogicalThreadContext.GetData(PASSWORD) as string; + if (user != null && pass != null) + { + return DoCreateConnection(user, pass); + } + else + { + return DoCreateConnection(username, password); + } + } + + protected virtual IDbConnection DoCreateConnection(string user, string pass) + { + AssertUtils.ArgumentNotNull(TargetDbProvider,"TargetDbProvider"); + if (StringUtils.HasLength(user)) + { + IDbConnection conn = TargetDbProvider.CreateConnection(); + string s= ConnectionString + separator + user + separator + pass; + conn.ConnectionString = s; + return conn; + } + else + { + return TargetDbProvider.CreateConnection(); + } + } + } + } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Config/DatabaseNamespaceParser.cs b/src/Spring/Spring.Data/Data/Config/DatabaseNamespaceParser.cs index 2ee04c63..5b7fc754 100644 --- a/src/Spring/Spring.Data/Data/Config/DatabaseNamespaceParser.cs +++ b/src/Spring/Spring.Data/Data/Config/DatabaseNamespaceParser.cs @@ -1,170 +1,169 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Globalization; -using System.Xml; - -using Spring.Data.Common; -using Spring.Core.TypeResolution; -using Spring.Objects; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -#endregion - -namespace Spring.Data.Config -{ - /// - /// Implementation of the custom configuration parser for database definitions. - /// - /// Mark Pollack - /// $Id: DatabaseNamespaceParser.cs,v 1.3 2007/08/08 00:34:33 bbaia Exp $ - [ - NamespaceParser( - Namespace = "http://www.springframework.net/database", - SchemaLocationAssemblyHint = typeof(DatabaseNamespaceParser), - SchemaLocation = "/Spring.Data.Config/spring-database-1.1.xsd") - ] - public class DatabaseNamespaceParser : ObjectsNamespaceParser - { - - private const string DatabaseTypePrefix = "database: "; - - static DatabaseNamespaceParser() - { - TypeRegistry.RegisterType( - DatabaseTypePrefix + DbProviderFactoryObjectConstants.DbProviderFactoryObjectElement, - typeof (DbProviderFactoryObject)); - } - - /// - /// Initializes a new instance of the class. - /// - public DatabaseNamespaceParser() - { - } - - - - - /// - /// Parse the specified element and register any resulting - /// IObjectDefinitions with the IObjectDefinitionRegistry that is - /// embedded in the supplied ParserContext. - /// - /// The element to be parsed into one or more IObjectDefinitions - /// The object encapsulating the current state of the parsing - /// process. - /// - /// The primary IObjectDefinition (can be null as explained above) - /// - /// - /// Implementations should return the primary IObjectDefinition - /// that results from the parse phase if they wish to used nested - /// inside (for example) a <property> tag. - /// Implementations may return null if they will not - /// be used in a nested scenario. - /// - /// - public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); - IConfigurableObjectDefinition databaseConfiguration = ParseDatabaseDefinition(element, id, parserContext); - if (!StringUtils.HasText(id)) - { - id = ObjectDefinitionReaderUtils.GenerateObjectName(databaseConfiguration, parserContext.Registry); - } - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug( - string.Format( - CultureInfo.InvariantCulture, - "Registering object definition with id '{0}'.", id)); - } - - #endregion - parserContext.Registry.RegisterObjectDefinition(id, databaseConfiguration); - - return null; - } - - private IConfigurableObjectDefinition ParseDatabaseDefinition(XmlElement element, string name, ParserContext parserContext) - { - switch (element.LocalName) - { - case DbProviderFactoryObjectConstants.DbProviderFactoryObjectElement: - return ParseDatabaseConfigurer(element, name, parserContext); - } - return null; - } - - private IConfigurableObjectDefinition ParseDatabaseConfigurer(XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string providerNameAttribute = element.GetAttribute(DbProviderFactoryObjectConstants.ProviderNameAttribute); - string connectionString = element.GetAttribute(DbProviderFactoryObjectConstants.ConnectionStringAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(providerNameAttribute)) - { - properties.Add("Provider", providerNameAttribute); - } - if (StringUtils.HasText(connectionString)) - { - properties.Add("ConnectionString", connectionString); - } - - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - - return cod; - } - - /// - /// Gets the name of the object type for the specified element. This has already been aliased - /// in the static constructor. - /// - /// The element. - /// The name of the object type. - private string GetTypeName(XmlElement element) - { - string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - if (StringUtils.IsNullOrEmpty(typeName)) - { - return DatabaseTypePrefix + element.LocalName; - } - return typeName; - } - - private class DbProviderFactoryObjectConstants - { - public const string DbProviderFactoryObjectElement = "provider"; - public const string ProviderNameAttribute = "provider"; - public const string ConnectionStringAttribute = "connectionString"; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Globalization; +using System.Xml; + +using Spring.Data.Common; +using Spring.Core.TypeResolution; +using Spring.Objects; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +#endregion + +namespace Spring.Data.Config +{ + /// + /// Implementation of the custom configuration parser for database definitions. + /// + /// Mark Pollack + [ + NamespaceParser( + Namespace = "http://www.springframework.net/database", + SchemaLocationAssemblyHint = typeof(DatabaseNamespaceParser), + SchemaLocation = "/Spring.Data.Config/spring-database-1.1.xsd") + ] + public class DatabaseNamespaceParser : ObjectsNamespaceParser + { + + private const string DatabaseTypePrefix = "database: "; + + static DatabaseNamespaceParser() + { + TypeRegistry.RegisterType( + DatabaseTypePrefix + DbProviderFactoryObjectConstants.DbProviderFactoryObjectElement, + typeof (DbProviderFactoryObject)); + } + + /// + /// Initializes a new instance of the class. + /// + public DatabaseNamespaceParser() + { + } + + + + + /// + /// Parse the specified element and register any resulting + /// IObjectDefinitions with the IObjectDefinitionRegistry that is + /// embedded in the supplied ParserContext. + /// + /// The element to be parsed into one or more IObjectDefinitions + /// The object encapsulating the current state of the parsing + /// process. + /// + /// The primary IObjectDefinition (can be null as explained above) + /// + /// + /// Implementations should return the primary IObjectDefinition + /// that results from the parse phase if they wish to used nested + /// inside (for example) a <property> tag. + /// Implementations may return null if they will not + /// be used in a nested scenario. + /// + /// + public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); + IConfigurableObjectDefinition databaseConfiguration = ParseDatabaseDefinition(element, id, parserContext); + if (!StringUtils.HasText(id)) + { + id = ObjectDefinitionReaderUtils.GenerateObjectName(databaseConfiguration, parserContext.Registry); + } + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug( + string.Format( + CultureInfo.InvariantCulture, + "Registering object definition with id '{0}'.", id)); + } + + #endregion + parserContext.Registry.RegisterObjectDefinition(id, databaseConfiguration); + + return null; + } + + private IConfigurableObjectDefinition ParseDatabaseDefinition(XmlElement element, string name, ParserContext parserContext) + { + switch (element.LocalName) + { + case DbProviderFactoryObjectConstants.DbProviderFactoryObjectElement: + return ParseDatabaseConfigurer(element, name, parserContext); + } + return null; + } + + private IConfigurableObjectDefinition ParseDatabaseConfigurer(XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string providerNameAttribute = element.GetAttribute(DbProviderFactoryObjectConstants.ProviderNameAttribute); + string connectionString = element.GetAttribute(DbProviderFactoryObjectConstants.ConnectionStringAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(providerNameAttribute)) + { + properties.Add("Provider", providerNameAttribute); + } + if (StringUtils.HasText(connectionString)) + { + properties.Add("ConnectionString", connectionString); + } + + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + + return cod; + } + + /// + /// Gets the name of the object type for the specified element. This has already been aliased + /// in the static constructor. + /// + /// The element. + /// The name of the object type. + private string GetTypeName(XmlElement element) + { + string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + if (StringUtils.IsNullOrEmpty(typeName)) + { + return DatabaseTypePrefix + element.LocalName; + } + return typeName; + } + + private class DbProviderFactoryObjectConstants + { + public const string DbProviderFactoryObjectElement = "provider"; + public const string ProviderNameAttribute = "provider"; + public const string ConnectionStringAttribute = "connectionString"; + } + } +} diff --git a/src/Spring/Spring.Data/Data/Core/AdoAccessor.cs b/src/Spring/Spring.Data/Data/Core/AdoAccessor.cs index 87240431..d785f560 100644 --- a/src/Spring/Spring.Data/Data/Core/AdoAccessor.cs +++ b/src/Spring/Spring.Data/Data/Core/AdoAccessor.cs @@ -1,216 +1,216 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using Spring.Data.Common; -using Spring.Data.Support; -using Spring.Objects.Factory; - -namespace Spring.Data.Core -{ - /// - /// Base class for AdoTemplate and other ADO.NET DAO helper classes defining - /// common properties like DbProvider. - /// - /// Mark Pollack (.NET) - /// Juergen Hoeller - public abstract class AdoAccessor : IInitializingObject - { - protected int commandTimeout; - - #region Properties - - /// - /// An instance of a DbProvider implementation. - /// - public abstract IDbProvider DbProvider - { - get; - set; - } - - - - /// - /// Gets or sets a value indicating whether to lazily initialize the - /// IAdoExceptionTranslator for this accessor, on first encounter of a - /// exception from the data provider. Default is "true"; can be switched to - /// "false" for initialization on startup. - /// - /// true if to lazy initialize the IAdoExceptionTranslator; - /// otherwise, false. - public abstract bool LazyInit - { - get; - set; - } - - - /// - /// Gets or sets the exception translator. If no custom translator is provided, a default - /// is used. - /// - /// The exception translator. - public abstract IAdoExceptionTranslator ExceptionTranslator - { - get; - set; - } - - - /// - /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper - /// for the purpose of having defaults values to use in case of DBNull values read - /// from IDataReader. - /// - /// The type of the data reader wrapper. - public abstract Type DataReaderWrapperType - { - get; - set; - } - - /// - /// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes. - /// - /// Default is 0, indicating to use the database provider's default. - /// Any timeout specified here will be overridden by the remaining - /// transaction timeout when executing within a transaction that has a - /// timeout specified at the transaction level. - /// - /// The command timeout. - public virtual int CommandTimeout - { - get { return commandTimeout; } - set { commandTimeout = value; } - } - - #endregion - - /// - /// Prepare the command setting the transaction timeout. - /// - /// - protected void ApplyCommandSettings(IDbCommand command) - { - ConnectionUtils.ApplyTransactionTimeout(command, DbProvider, CommandTimeout ); - } - - protected virtual string GetCommandText(object cmdTextProvider) - { - ICommandTextProvider commandTextProvider = cmdTextProvider as ICommandTextProvider; - if (commandTextProvider != null) - { - return commandTextProvider.CommandText; - } - else - { - return null; - } - } - - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public abstract void AfterPropertiesSet(); - - /// - /// Creates the data reader wrapper for use in AdoTemplate callback methods. - /// - /// The reader to wrap. - /// The data reader used in AdoTemplate callbacks - public abstract IDataReader CreateDataReaderWrapper(IDataReader readerToWrap); - - /// - /// Creates the a db parameters collection, adding to the collection a parameter created from - /// the method parameters. - /// - /// The name of the parameter - /// The type of the parameter. - /// The size of the parameter, for use in defining lengths of string values. Use - /// 0 if not applicable. - /// The parameter value. - /// A collection of db parameters with a single parameter in the collection based - /// on the method parameters - protected IDbParameters CreateDbParameters(string name, Enum dbType, int size, object parameterValue) - { - IDbParameters parameters = new DbParameters(DbProvider); - parameters.Add(name, dbType, size).Value = parameterValue; - return parameters; - } - - - #region Parameter Creation Helper Methods - - /// - /// Creates a new instance of - /// - /// a new instance of - public virtual IDbParameters CreateDbParameters() - { - return new DbParameters(DbProvider); - } - - /// - /// Derives the parameters of a stored procedure, not including the return parameter. - /// - /// Name of the procedure. - /// The stored procedure parameters. - public virtual IDataParameter[] DeriveParameters(string procedureName) - { - return DeriveParameters(procedureName, false); - } - - /// - /// Derives the parameters of a stored procedure including the return parameter - /// - /// Name of the procedure. - /// if set to true to include return parameter. - /// The stored procedure parameters - public abstract IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter); - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using Spring.Data.Common; +using Spring.Data.Support; +using Spring.Objects.Factory; + +namespace Spring.Data.Core +{ + /// + /// Base class for AdoTemplate and other ADO.NET DAO helper classes defining + /// common properties like DbProvider. + /// + /// Mark Pollack (.NET) + /// Juergen Hoeller + public abstract class AdoAccessor : IInitializingObject + { + protected int commandTimeout; + + #region Properties + + /// + /// An instance of a DbProvider implementation. + /// + public abstract IDbProvider DbProvider + { + get; + set; + } + + + + /// + /// Gets or sets a value indicating whether to lazily initialize the + /// IAdoExceptionTranslator for this accessor, on first encounter of a + /// exception from the data provider. Default is "true"; can be switched to + /// "false" for initialization on startup. + /// + /// true if to lazy initialize the IAdoExceptionTranslator; + /// otherwise, false. + public abstract bool LazyInit + { + get; + set; + } + + + /// + /// Gets or sets the exception translator. If no custom translator is provided, a default + /// is used. + /// + /// The exception translator. + public abstract IAdoExceptionTranslator ExceptionTranslator + { + get; + set; + } + + + /// + /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper + /// for the purpose of having defaults values to use in case of DBNull values read + /// from IDataReader. + /// + /// The type of the data reader wrapper. + public abstract Type DataReaderWrapperType + { + get; + set; + } + + /// + /// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes. + /// + /// Default is 0, indicating to use the database provider's default. + /// Any timeout specified here will be overridden by the remaining + /// transaction timeout when executing within a transaction that has a + /// timeout specified at the transaction level. + /// + /// The command timeout. + public virtual int CommandTimeout + { + get { return commandTimeout; } + set { commandTimeout = value; } + } + + #endregion + + /// + /// Prepare the command setting the transaction timeout. + /// + /// + protected void ApplyCommandSettings(IDbCommand command) + { + ConnectionUtils.ApplyTransactionTimeout(command, DbProvider, CommandTimeout ); + } + + protected virtual string GetCommandText(object cmdTextProvider) + { + ICommandTextProvider commandTextProvider = cmdTextProvider as ICommandTextProvider; + if (commandTextProvider != null) + { + return commandTextProvider.CommandText; + } + else + { + return null; + } + } + + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public abstract void AfterPropertiesSet(); + + /// + /// Creates the data reader wrapper for use in AdoTemplate callback methods. + /// + /// The reader to wrap. + /// The data reader used in AdoTemplate callbacks + public abstract IDataReader CreateDataReaderWrapper(IDataReader readerToWrap); + + /// + /// Creates the a db parameters collection, adding to the collection a parameter created from + /// the method parameters. + /// + /// The name of the parameter + /// The type of the parameter. + /// The size of the parameter, for use in defining lengths of string values. Use + /// 0 if not applicable. + /// The parameter value. + /// A collection of db parameters with a single parameter in the collection based + /// on the method parameters + protected IDbParameters CreateDbParameters(string name, Enum dbType, int size, object parameterValue) + { + IDbParameters parameters = new DbParameters(DbProvider); + parameters.Add(name, dbType, size).Value = parameterValue; + return parameters; + } + + + #region Parameter Creation Helper Methods + + /// + /// Creates a new instance of + /// + /// a new instance of + public virtual IDbParameters CreateDbParameters() + { + return new DbParameters(DbProvider); + } + + /// + /// Derives the parameters of a stored procedure, not including the return parameter. + /// + /// Name of the procedure. + /// The stored procedure parameters. + public virtual IDataParameter[] DeriveParameters(string procedureName) + { + return DeriveParameters(procedureName, false); + } + + /// + /// Derives the parameters of a stored procedure including the return parameter + /// + /// Name of the procedure. + /// if set to true to include return parameter. + /// The stored procedure parameters + public abstract IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter); + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Data/Core/AdoDaoSupport.cs b/src/Spring/Spring.Data/Data/Core/AdoDaoSupport.cs index 2b8aae91..138f7287 100644 --- a/src/Spring/Spring.Data/Data/Core/AdoDaoSupport.cs +++ b/src/Spring/Spring.Data/Data/Core/AdoDaoSupport.cs @@ -1,142 +1,142 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using Spring.Dao.Support; -using Spring.Data.Common; -using Spring.Data.Support; - -namespace Spring.Data.Core -{ - /// - /// Convenient super class for ADO.NET data access objects. - /// - /// - /// Requires a IDBProvider to be set, providing a - /// AdoTemplate based on it to subclasses. - /// This base class is mainly intended for AdoTemplate usage. - /// - public class AdoDaoSupport : DaoSupport - { - private AdoTemplate adoTemplate; - - /// - /// The DbProvider instance used by this DAO - /// - public IDbProvider DbProvider - { - set - { - adoTemplate = CreateAdoTemplate(value); - } - get - { - if (adoTemplate != null) - { - return adoTemplate.DbProvider; - } - else - { - return null; - } - } - - } - - /// - /// Set the AdoTemplate for this DAO explicity, as - /// an alternative to specifying a IDbProvider - /// - public AdoTemplate AdoTemplate - { - set - { - adoTemplate = value; - } - get - { - return adoTemplate; - } - - } - - protected override void CheckDaoConfig() - { - if (adoTemplate == null) - { - throw new ArgumentException("DbProvider or AdoTemplate is required"); - } - } - - protected IDbConnection Connection - { - get - { - return ConnectionUtils.GetConnection(DbProvider); - } - } - - protected IAdoExceptionTranslator ExceptionTranslator - { - get - { - return null; //Investigate AdoExceptionTranslator on AdoAccessor - } - } - - protected void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) - { - ConnectionUtils.DisposeConnection(conn, dbProvider); - } - - - /// - /// Create a AdoTemplate for a given DbProvider - /// Only invoked if populating the DAO with a DbProvider reference. - /// - /// - /// Can be overriden in subclasses to provide AdoTemplate instances - /// with a different configuration, or a cusotm AdoTemplate subclass. - /// - /// The DbProvider to create a AdoTemplate for - protected virtual AdoTemplate CreateAdoTemplate(IDbProvider dbProvider) - { - return new AdoTemplate(dbProvider); - } - - /// - /// Convenience method to create a parameters builder. - /// - /// Virtual for sublcasses to override with custom - /// implementation. - /// A new DbParameterBuilder - protected virtual IDbParametersBuilder CreateDbParametersBuilder() - { - return new DbParametersBuilder(DbProvider); - } - - protected virtual IDbParameters CreateDbParameters() - { - return AdoTemplate.CreateDbParameters(); - } - - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using Spring.Dao.Support; +using Spring.Data.Common; +using Spring.Data.Support; + +namespace Spring.Data.Core +{ + /// + /// Convenient super class for ADO.NET data access objects. + /// + /// + /// Requires a IDBProvider to be set, providing a + /// AdoTemplate based on it to subclasses. + /// This base class is mainly intended for AdoTemplate usage. + /// + public class AdoDaoSupport : DaoSupport + { + private AdoTemplate adoTemplate; + + /// + /// The DbProvider instance used by this DAO + /// + public IDbProvider DbProvider + { + set + { + adoTemplate = CreateAdoTemplate(value); + } + get + { + if (adoTemplate != null) + { + return adoTemplate.DbProvider; + } + else + { + return null; + } + } + + } + + /// + /// Set the AdoTemplate for this DAO explicity, as + /// an alternative to specifying a IDbProvider + /// + public AdoTemplate AdoTemplate + { + set + { + adoTemplate = value; + } + get + { + return adoTemplate; + } + + } + + protected override void CheckDaoConfig() + { + if (adoTemplate == null) + { + throw new ArgumentException("DbProvider or AdoTemplate is required"); + } + } + + protected IDbConnection Connection + { + get + { + return ConnectionUtils.GetConnection(DbProvider); + } + } + + protected IAdoExceptionTranslator ExceptionTranslator + { + get + { + return null; //Investigate AdoExceptionTranslator on AdoAccessor + } + } + + protected void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) + { + ConnectionUtils.DisposeConnection(conn, dbProvider); + } + + + /// + /// Create a AdoTemplate for a given DbProvider + /// Only invoked if populating the DAO with a DbProvider reference. + /// + /// + /// Can be overriden in subclasses to provide AdoTemplate instances + /// with a different configuration, or a cusotm AdoTemplate subclass. + /// + /// The DbProvider to create a AdoTemplate for + protected virtual AdoTemplate CreateAdoTemplate(IDbProvider dbProvider) + { + return new AdoTemplate(dbProvider); + } + + /// + /// Convenience method to create a parameters builder. + /// + /// Virtual for sublcasses to override with custom + /// implementation. + /// A new DbParameterBuilder + protected virtual IDbParametersBuilder CreateDbParametersBuilder() + { + return new DbParametersBuilder(DbProvider); + } + + protected virtual IDbParameters CreateDbParameters() + { + return AdoTemplate.CreateDbParameters(); + } + + } +} diff --git a/src/Spring/Spring.Data/Data/Core/AdoPlatformTransactionManager.cs b/src/Spring/Spring.Data/Data/Core/AdoPlatformTransactionManager.cs index 612aafa9..388290e7 100644 --- a/src/Spring/Spring.Data/Data/Core/AdoPlatformTransactionManager.cs +++ b/src/Spring/Spring.Data/Data/Core/AdoPlatformTransactionManager.cs @@ -1,431 +1,430 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; -using Common.Logging; -using Spring.Data.Common; -using Spring.Data.Support; -using Spring.Objects.Factory; -using Spring.Transaction; -using Spring.Transaction.Support; - -#endregion -namespace Spring.Data.Core -{ - /// - /// ADO.NET based implementation of the - /// interface. - /// - /// Mark Pollack (.NET) - /// $Id: AdoPlatformTransactionManager.cs,v 1.7 2007/11/30 18:42:11 markpollack Exp $ - public class AdoPlatformTransactionManager : AbstractPlatformTransactionManager, IInitializingObject - { - - private IDbProvider dbProvider; - - #region Logging Definition - - private static readonly ILog LOG = LogManager.GetLogger(typeof (AdoPlatformTransactionManager)); - - #endregion - - public AdoPlatformTransactionManager() - { - NestedTransactionsAllowed = true; - } - - public AdoPlatformTransactionManager(IDbProvider dbProvider) : this() - { - DbProvider = dbProvider; - - } - - #region Propeties - - public IDbProvider DbProvider - { - get { return dbProvider; } - set { dbProvider = value; } - } - - #endregion - - /// - /// Return the current transaction object. - /// - /// The current transaction object. - /// - /// If transaction support is not available. - /// - /// - /// In the case of lookup or system errors. - /// - protected override object DoGetTransaction() - { - DbProviderTransactionObject txMgrStateObject = - new DbProviderTransactionObject(); - txMgrStateObject.SavepointAllowed = NestedTransactionsAllowed; - ConnectionHolder conHolder = - (ConnectionHolder) TransactionSynchronizationManager.GetResource(DbProvider); - txMgrStateObject.SetConnectionHolder(conHolder, false); - return txMgrStateObject; - } - - /// - /// Check if the given transaction object indicates an existing, - /// i.e. already begun, transaction. - /// - /// - /// Transaction object returned by - /// . - /// - /// True if there is an existing transaction. - /// - /// In the case of system errors. - /// - protected override bool IsExistingTransaction(object transaction) - { - DbProviderTransactionObject txMgrStateObject = - (DbProviderTransactionObject)transaction; - return (txMgrStateObject.ConnectionHolder != null - && - txMgrStateObject.ConnectionHolder.TransactionActive); - - } - - /// - /// Begin a new transaction with the given transaction definition. - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// instance, describing - /// propagation behavior, isolation level, timeout etc. - /// - /// - /// Does not have to care about applying the propagation behavior, - /// as this has already been handled by this abstract manager. - /// - /// - /// In the case of creation or system errors. - /// - protected override void DoBegin(object transaction, ITransactionDefinition definition) - { - DbProviderTransactionObject txMgrStateObject = - (DbProviderTransactionObject)transaction; - IDbConnection con = null; - - if (dbProvider == null) - { - throw new ArgumentException("DbProvider is required to be set on AdoPlatformTransactionManager"); - } - - try - { - if (txMgrStateObject.ConnectionHolder == null || txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction) - { - IDbConnection newCon = DbProvider.CreateConnection(); - if (log.IsDebugEnabled) - { - log.Debug("Acquired Connection [" + newCon + ", " + newCon.ConnectionString + "] for ADO.NET transaction"); - } - newCon.Open(); - - //TODO isolation level mgmt - will need to abstract out SQL used to specify this in DbMetaData - //MSDN docs... - //With one exception, you can switch from one isolation level to another at any time during a transaction. The exception occurs when changing from any isolation level to SNAPSHOT isolation - - - //IsolationLevel previousIsolationLevel = - - IDbTransaction newTrans = newCon.BeginTransaction(definition.TransactionIsolationLevel); - - txMgrStateObject.SetConnectionHolder(new ConnectionHolder(newCon, newTrans), true); - - } - txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction = true; - con = txMgrStateObject.ConnectionHolder.Connection; - - - txMgrStateObject.ConnectionHolder.TransactionActive = true; - - int timeout = DetermineTimeout(definition); - if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - txMgrStateObject.ConnectionHolder.TimeoutInSeconds = timeout; - } - - - //Bind transactional resources to thread - if (txMgrStateObject.NewConnectionHolder) - { - TransactionSynchronizationManager.BindResource(DbProvider, - txMgrStateObject.ConnectionHolder); - } - - } - //TODO catch specific exception - catch (Exception e) - { - ConnectionUtils.DisposeConnection(con, DbProvider); - throw new CannotCreateTransactionException("Could not create ADO.NET connection for transaction", e); - } - - } - - - /// - /// Suspend the resources of the current transaction. - /// - /// Transaction object returned by - /// . - /// - /// An object that holds suspended resources (will be kept unexamined for passing it into - /// .) - /// - /// - /// Transaction synchronization will already have been suspended. - /// - /// - /// If suspending is not supported by the transaction manager implementation. - /// - /// - /// in case of system errors. - /// - protected override object DoSuspend(object transaction) - { - DbProviderTransactionObject txMgrStateObject = (DbProviderTransactionObject)transaction; - txMgrStateObject.ConnectionHolder = null; - ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.UnbindResource(DbProvider); - return conHolder; - } - - - /// - /// Resume the resources of the current transaction. - /// - /// Transaction object returned by - /// . - /// The object that holds suspended resources as returned by - /// . - /// - /// Transaction synchronization will be resumed afterwards. - /// - /// - /// If suspending is not supported by the transaction manager implementation. - /// - /// - /// In the case of system errors. - /// - protected override void DoResume(object transaction, object suspendedResources) - { - ConnectionHolder conHolder = (ConnectionHolder)suspendedResources; - TransactionSynchronizationManager.BindResource(DbProvider, conHolder); - } - - - /// - /// Perform an actual commit on the given transaction. - /// - /// The status representation of the transaction. - /// - ///

- /// An implementation does not need to check the rollback-only flag. - ///

- ///
- /// - /// In the case of system errors. - /// - protected override void DoCommit(DefaultTransactionStatus status) - { - DbProviderTransactionObject txMgrStateObject = - (DbProviderTransactionObject)status.Transaction; - IDbTransaction trans = txMgrStateObject.ConnectionHolder.Transaction; - if (status.Debug) - { - IDbConnection conn = txMgrStateObject.ConnectionHolder.Connection; - log.Debug("Committing ADO.NET transaction on Connection [" + conn + ", " + conn.ConnectionString + "]"); - } - try - { - trans.Commit(); - } - catch (Exception e) - { - throw new TransactionSystemException("Could not commit ADO.NET transaction", e); - } - - } - - /// - /// Perform an actual rollback on the given transaction. - /// - /// The status representation of the transaction. - /// - /// An implementation does not need to check the new transaction flag. - /// - /// - /// In the case of system errors. - /// - protected override void DoRollback(DefaultTransactionStatus status) - { - DbProviderTransactionObject txMgrStateObject = - (DbProviderTransactionObject)status.Transaction; - IDbConnection conn = txMgrStateObject.ConnectionHolder.Connection; - IDbTransaction trans = txMgrStateObject.ConnectionHolder.Transaction; - if (status.Debug) - { - log.Debug("Rolling back ADO.NET transaction on Connection [" + conn + ", " + conn.ConnectionString + "]" ); - } - try - { - trans.Rollback(); - } - catch (Exception e) - { - throw new TransactionSystemException("Could not rollback ADO.NET transaction", e); - } - } - - /// - /// Set the given transaction rollback-only. Only called on rollback - /// if the current transaction takes part in an existing one. - /// - /// The status representation of the transaction. - /// - /// In the case of system errors. - /// - protected override void DoSetRollbackOnly(DefaultTransactionStatus status) - { - DbProviderTransactionObject txMgrStateObject = - (DbProviderTransactionObject)status.Transaction; - if (status.Debug) - { - IDbConnection conn = txMgrStateObject.ConnectionHolder.Connection; - log.Debug("Setting ADO.NET transaction [" + conn + ", " + conn.ConnectionString + "] rollback-only."); - } - txMgrStateObject.SetRollbackOnly(); - - } - - protected override void DoCleanupAfterCompletion(object transaction) - { - DbProviderTransactionObject txMgrStateObject = - (DbProviderTransactionObject)transaction; - if (txMgrStateObject.NewConnectionHolder) - { - TransactionSynchronizationManager.UnbindResource(DbProvider); - } - IDbConnection con = txMgrStateObject.ConnectionHolder.Connection; - - if (log.IsDebugEnabled) - { - log.Debug("Releasing ADO.NET Connection [" + con + ", " + con.ConnectionString + "] after transaction"); - } - - ConnectionUtils.DisposeConnection(con, DbProvider); - //TODO clear out IDbTransaction object? - - txMgrStateObject.ConnectionHolder.Clear(); - - - } - - - - /// - /// DbProvider transaction (state) object, representing a ConnectionHolder. - /// Used as a transaction object by AdoPlatformTransactionManager - /// - /// Derives from AdoTransactionObjectSupport to inherit the capability - /// to manage Savepoints. - /// - /// - private class DbProviderTransactionObject : AdoTransactionObjectSupport - { - private bool newConnectionHolder; - - public void SetConnectionHolder(ConnectionHolder connectionHolder, - bool newConnection) - { - ConnectionHolder = connectionHolder; - newConnectionHolder = newConnection; - } - - public bool NewConnectionHolder - { - get - { - return newConnectionHolder; - } - } - - public bool HasTransaction - { - get - { - return (ConnectionHolder != null && ConnectionHolder.TransactionActive); - } - } - - /// - /// Sets the rollback only. - /// - public void SetRollbackOnly() - { - ConnectionHolder.RollbackOnly = true; - } - - /// - /// Return whether the transaction is internally marked as rollback-only. - /// - /// - /// True of the transaction is marked as rollback-only. - public override bool RollbackOnly - { - get - { - return ConnectionHolder.RollbackOnly; - } - } - - } - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - /// If DbProvider is null. - /// - public void AfterPropertiesSet() - { - if (dbProvider == null) - { - throw new ArgumentException("DbProvider is required"); - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; +using Common.Logging; +using Spring.Data.Common; +using Spring.Data.Support; +using Spring.Objects.Factory; +using Spring.Transaction; +using Spring.Transaction.Support; + +#endregion +namespace Spring.Data.Core +{ + /// + /// ADO.NET based implementation of the + /// interface. + /// + /// Mark Pollack (.NET) + public class AdoPlatformTransactionManager : AbstractPlatformTransactionManager, IInitializingObject + { + + private IDbProvider dbProvider; + + #region Logging Definition + + private static readonly ILog LOG = LogManager.GetLogger(typeof (AdoPlatformTransactionManager)); + + #endregion + + public AdoPlatformTransactionManager() + { + NestedTransactionsAllowed = true; + } + + public AdoPlatformTransactionManager(IDbProvider dbProvider) : this() + { + DbProvider = dbProvider; + + } + + #region Propeties + + public IDbProvider DbProvider + { + get { return dbProvider; } + set { dbProvider = value; } + } + + #endregion + + /// + /// Return the current transaction object. + /// + /// The current transaction object. + /// + /// If transaction support is not available. + /// + /// + /// In the case of lookup or system errors. + /// + protected override object DoGetTransaction() + { + DbProviderTransactionObject txMgrStateObject = + new DbProviderTransactionObject(); + txMgrStateObject.SavepointAllowed = NestedTransactionsAllowed; + ConnectionHolder conHolder = + (ConnectionHolder) TransactionSynchronizationManager.GetResource(DbProvider); + txMgrStateObject.SetConnectionHolder(conHolder, false); + return txMgrStateObject; + } + + /// + /// Check if the given transaction object indicates an existing, + /// i.e. already begun, transaction. + /// + /// + /// Transaction object returned by + /// . + /// + /// True if there is an existing transaction. + /// + /// In the case of system errors. + /// + protected override bool IsExistingTransaction(object transaction) + { + DbProviderTransactionObject txMgrStateObject = + (DbProviderTransactionObject)transaction; + return (txMgrStateObject.ConnectionHolder != null + && + txMgrStateObject.ConnectionHolder.TransactionActive); + + } + + /// + /// Begin a new transaction with the given transaction definition. + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// instance, describing + /// propagation behavior, isolation level, timeout etc. + /// + /// + /// Does not have to care about applying the propagation behavior, + /// as this has already been handled by this abstract manager. + /// + /// + /// In the case of creation or system errors. + /// + protected override void DoBegin(object transaction, ITransactionDefinition definition) + { + DbProviderTransactionObject txMgrStateObject = + (DbProviderTransactionObject)transaction; + IDbConnection con = null; + + if (dbProvider == null) + { + throw new ArgumentException("DbProvider is required to be set on AdoPlatformTransactionManager"); + } + + try + { + if (txMgrStateObject.ConnectionHolder == null || txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction) + { + IDbConnection newCon = DbProvider.CreateConnection(); + if (log.IsDebugEnabled) + { + log.Debug("Acquired Connection [" + newCon + ", " + newCon.ConnectionString + "] for ADO.NET transaction"); + } + newCon.Open(); + + //TODO isolation level mgmt - will need to abstract out SQL used to specify this in DbMetaData + //MSDN docs... + //With one exception, you can switch from one isolation level to another at any time during a transaction. The exception occurs when changing from any isolation level to SNAPSHOT isolation + + + //IsolationLevel previousIsolationLevel = + + IDbTransaction newTrans = newCon.BeginTransaction(definition.TransactionIsolationLevel); + + txMgrStateObject.SetConnectionHolder(new ConnectionHolder(newCon, newTrans), true); + + } + txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction = true; + con = txMgrStateObject.ConnectionHolder.Connection; + + + txMgrStateObject.ConnectionHolder.TransactionActive = true; + + int timeout = DetermineTimeout(definition); + if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + txMgrStateObject.ConnectionHolder.TimeoutInSeconds = timeout; + } + + + //Bind transactional resources to thread + if (txMgrStateObject.NewConnectionHolder) + { + TransactionSynchronizationManager.BindResource(DbProvider, + txMgrStateObject.ConnectionHolder); + } + + } + //TODO catch specific exception + catch (Exception e) + { + ConnectionUtils.DisposeConnection(con, DbProvider); + throw new CannotCreateTransactionException("Could not create ADO.NET connection for transaction", e); + } + + } + + + /// + /// Suspend the resources of the current transaction. + /// + /// Transaction object returned by + /// . + /// + /// An object that holds suspended resources (will be kept unexamined for passing it into + /// .) + /// + /// + /// Transaction synchronization will already have been suspended. + /// + /// + /// If suspending is not supported by the transaction manager implementation. + /// + /// + /// in case of system errors. + /// + protected override object DoSuspend(object transaction) + { + DbProviderTransactionObject txMgrStateObject = (DbProviderTransactionObject)transaction; + txMgrStateObject.ConnectionHolder = null; + ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.UnbindResource(DbProvider); + return conHolder; + } + + + /// + /// Resume the resources of the current transaction. + /// + /// Transaction object returned by + /// . + /// The object that holds suspended resources as returned by + /// . + /// + /// Transaction synchronization will be resumed afterwards. + /// + /// + /// If suspending is not supported by the transaction manager implementation. + /// + /// + /// In the case of system errors. + /// + protected override void DoResume(object transaction, object suspendedResources) + { + ConnectionHolder conHolder = (ConnectionHolder)suspendedResources; + TransactionSynchronizationManager.BindResource(DbProvider, conHolder); + } + + + /// + /// Perform an actual commit on the given transaction. + /// + /// The status representation of the transaction. + /// + ///

+ /// An implementation does not need to check the rollback-only flag. + ///

+ ///
+ /// + /// In the case of system errors. + /// + protected override void DoCommit(DefaultTransactionStatus status) + { + DbProviderTransactionObject txMgrStateObject = + (DbProviderTransactionObject)status.Transaction; + IDbTransaction trans = txMgrStateObject.ConnectionHolder.Transaction; + if (status.Debug) + { + IDbConnection conn = txMgrStateObject.ConnectionHolder.Connection; + log.Debug("Committing ADO.NET transaction on Connection [" + conn + ", " + conn.ConnectionString + "]"); + } + try + { + trans.Commit(); + } + catch (Exception e) + { + throw new TransactionSystemException("Could not commit ADO.NET transaction", e); + } + + } + + /// + /// Perform an actual rollback on the given transaction. + /// + /// The status representation of the transaction. + /// + /// An implementation does not need to check the new transaction flag. + /// + /// + /// In the case of system errors. + /// + protected override void DoRollback(DefaultTransactionStatus status) + { + DbProviderTransactionObject txMgrStateObject = + (DbProviderTransactionObject)status.Transaction; + IDbConnection conn = txMgrStateObject.ConnectionHolder.Connection; + IDbTransaction trans = txMgrStateObject.ConnectionHolder.Transaction; + if (status.Debug) + { + log.Debug("Rolling back ADO.NET transaction on Connection [" + conn + ", " + conn.ConnectionString + "]" ); + } + try + { + trans.Rollback(); + } + catch (Exception e) + { + throw new TransactionSystemException("Could not rollback ADO.NET transaction", e); + } + } + + /// + /// Set the given transaction rollback-only. Only called on rollback + /// if the current transaction takes part in an existing one. + /// + /// The status representation of the transaction. + /// + /// In the case of system errors. + /// + protected override void DoSetRollbackOnly(DefaultTransactionStatus status) + { + DbProviderTransactionObject txMgrStateObject = + (DbProviderTransactionObject)status.Transaction; + if (status.Debug) + { + IDbConnection conn = txMgrStateObject.ConnectionHolder.Connection; + log.Debug("Setting ADO.NET transaction [" + conn + ", " + conn.ConnectionString + "] rollback-only."); + } + txMgrStateObject.SetRollbackOnly(); + + } + + protected override void DoCleanupAfterCompletion(object transaction) + { + DbProviderTransactionObject txMgrStateObject = + (DbProviderTransactionObject)transaction; + if (txMgrStateObject.NewConnectionHolder) + { + TransactionSynchronizationManager.UnbindResource(DbProvider); + } + IDbConnection con = txMgrStateObject.ConnectionHolder.Connection; + + if (log.IsDebugEnabled) + { + log.Debug("Releasing ADO.NET Connection [" + con + ", " + con.ConnectionString + "] after transaction"); + } + + ConnectionUtils.DisposeConnection(con, DbProvider); + //TODO clear out IDbTransaction object? + + txMgrStateObject.ConnectionHolder.Clear(); + + + } + + + + /// + /// DbProvider transaction (state) object, representing a ConnectionHolder. + /// Used as a transaction object by AdoPlatformTransactionManager + /// + /// Derives from AdoTransactionObjectSupport to inherit the capability + /// to manage Savepoints. + /// + /// + private class DbProviderTransactionObject : AdoTransactionObjectSupport + { + private bool newConnectionHolder; + + public void SetConnectionHolder(ConnectionHolder connectionHolder, + bool newConnection) + { + ConnectionHolder = connectionHolder; + newConnectionHolder = newConnection; + } + + public bool NewConnectionHolder + { + get + { + return newConnectionHolder; + } + } + + public bool HasTransaction + { + get + { + return (ConnectionHolder != null && ConnectionHolder.TransactionActive); + } + } + + /// + /// Sets the rollback only. + /// + public void SetRollbackOnly() + { + ConnectionHolder.RollbackOnly = true; + } + + /// + /// Return whether the transaction is internally marked as rollback-only. + /// + /// + /// True of the transaction is marked as rollback-only. + public override bool RollbackOnly + { + get + { + return ConnectionHolder.RollbackOnly; + } + } + + } + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + /// If DbProvider is null. + /// + public void AfterPropertiesSet() + { + if (dbProvider == null) + { + throw new ArgumentException("DbProvider is required"); + } + } + } +} diff --git a/src/Spring/Spring.Data/Data/Core/AdoTemplate.cs b/src/Spring/Spring.Data/Data/Core/AdoTemplate.cs index 8325b999..9f5984e5 100644 --- a/src/Spring/Spring.Data/Data/Core/AdoTemplate.cs +++ b/src/Spring/Spring.Data/Data/Core/AdoTemplate.cs @@ -1,3051 +1,3050 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using System.Data.Common; -using System.Globalization; -using System.Reflection; -using Common.Logging; -using Spring.Dao.Support; -using Spring.Data.Common; -using Spring.Data.Support; -using Spring.Reflection.Dynamic; -using Spring.Util; - -#endregion - -namespace Spring.Data.Core -{ - /// - /// This is the central class in the Spring.Data namespace. - /// It simplifies the use of ADO.NET and helps to avoid commons errors. - /// - /// Mark Pollack (.NET) - /// $Id: AdoTemplate.cs,v 1.9 2007/12/28 19:37:13 markpollack Exp $ - public class AdoTemplate : AdoAccessor, IAdoOperations - { - #region Logging Definition - - private static readonly ILog LOG = LogManager.GetLogger(typeof(AdoTemplate)); - - #endregion - - #region Fields - - private IDbProvider dbProvider; - - private IAdoExceptionTranslator exceptionTranslator; - - private bool lazyInit = true; - protected Type dataReaderWrapperType; - protected IDynamicConstructor newDataReaderWrapper; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - public AdoTemplate() - : base() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The database provider. - public AdoTemplate(IDbProvider provider) - { - DbProvider = provider; - AfterPropertiesSet(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The database provider. - /// if set to false - /// lazily initialize the ErrorCodeExceptionTranslator. - public AdoTemplate(IDbProvider provider, bool lazyInit) - { - DbProvider = provider; - LazyInit = lazyInit; - AfterPropertiesSet(); - } - - #endregion - - #region Properties - - /// - /// An instance of a DbProvider implementation. - /// - public override IDbProvider DbProvider - { - get { return dbProvider; } - set - { - dbProvider = value; - } - } - - /// - /// Gets or sets a value indicating whether to lazily initialize the - /// IAdoExceptionTranslator for this accessor, on first encounter of a - /// exception from the data provider. Default is "true"; can be switched to - /// "false" for initialization on startup. - /// - /// true if to lazy initialize the IAdoExceptionTranslator; - /// otherwise, false. - public override bool LazyInit - { - get { return lazyInit; } - set { lazyInit = value; } - } - - /// - /// Gets or sets the exception translator. If no custom translator is provided, a default - /// is used. - /// - /// The exception translator. - public override IAdoExceptionTranslator ExceptionTranslator - { - get - { - InitExceptionTranslator(); - return exceptionTranslator; - } - set - { - exceptionTranslator = value; - } - } - - /// - /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper - /// for the purpose of having defaults values to use in case of DBNull values read - /// from IDataReader. - /// - /// The type of the data reader wrapper. - public override Type DataReaderWrapperType - { - get { return dataReaderWrapperType; } - set - { - if (dataReaderWrapperType == null) - { - if (typeof(IDataReaderWrapper).IsAssignableFrom(value)) - { - dataReaderWrapperType = value; - ConstructorInfo constructor = ObjectUtils.GetZeroArgConstructorInfo(dataReaderWrapperType); - newDataReaderWrapper = DynamicConstructor.Create(constructor); - - } - else - { - throw new ArgumentException("DataReaderWrapper type must implement IDataReaderWrapper. Implemented interfaces on " - + value.GetType().Name + "are [" + - StringUtils.ArrayToCommaDelimitedString( - ReflectionUtils.ToInterfaceArray(value)) + "]"); - - } - } - else - { - LOG.Warn("Ignoring assignment of DataReaderWrapperType since it has already been assigned."); - } - - } - - } - - #endregion - - - public override void AfterPropertiesSet() - { - if (DbProvider == null) - { - throw new ArgumentException("DbProvider is required"); - } - if (!LazyInit) - { - InitExceptionTranslator(); - } - } - - - #region General Execute Callback Methods - /// - /// Execute a ADO.NET operation on a command object using a delegate callback. - /// - /// The delegate called with a command object. - /// - /// A result object returned by the action or null - /// - /// This allows for implementing arbitrary data access operations - /// on a single command within Spring's managed ADO.NET environment. - public Object Execute(CommandDelegate del) - { - return Execute(new ExecuteCommandCallbackUsingDelegate(del)); - } - - /// - /// Callback to execute a IDbCommand. - /// - /// the callback to execute - /// object returned from callback - public object Execute(ICommandCallback action) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - IDbCommand command = null; - try - { - command = DbProvider.CreateCommand(); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - ApplyCommandSettings(command); - Object result = action.DoInCommand(command); - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - return result; - } - catch (Exception e) - { - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); - } - else - { - throw; - } - - - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - - } - - /// - /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, - /// using the interface based callback IDbCommandCallback. - /// - /// The command creator. - /// The callback to execute based on IDbCommand - /// A result object returned by the action or null - public object Execute(IDbCommandCreator commandCreator, ICommandCallback action) - { - AssertUtils.ArgumentNotNull(commandCreator, "commandCreator", "IDbCommandCreator must not be null"); - AssertUtils.ArgumentNotNull(action, "action", "Callback object must not be null"); - - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - - IDbCommand command = null; - try - { - command = commandCreator.CreateDbCommand(DbProvider); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - ApplyCommandSettings(command); - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - Object result = action.DoInCommand(command); - - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - - return result; - } - catch (Exception e) - { - commandCreator = null; - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); - } - else - { - throw; - } - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - - } - - /// - /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. - /// - /// This allows for implementing abritrary data access operations - /// on a single DataAdapter within Spring's managed ADO.NET environment. - /// - /// The data adapter callback. - /// A result object returned by the callback or null - public object Execute(IDataAdapterCallback dataAdapterCallback) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - IDbDataAdapter dataAdapter = null; - try - { - dataAdapter = DbProvider.CreateDataAdapter(); - //TODO row updated event handling... - dataAdapter.SelectCommand = DbProvider.CreateCommand(); - dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection; - //TODO register for warnings on connection. - dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction; - ApplyCommandSettings(dataAdapter.SelectCommand); - object result = dataAdapterCallback.DoInDataAdapter(dataAdapter); - return result; - - } - catch (Exception) - { - AdoUtils.DisposeDataAdapterCommands(dataAdapter); - //TODO set dataAdapter command's = null; ? - //TODO exception translation? different hierarchy for data set operations. - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - throw; - } - finally - { - AdoUtils.DisposeDataAdapterCommands(dataAdapter); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - - - } - - #endregion - - #region ExecuteNonQuery - - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText) - { - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing NonQuery " + cmdType + "[" + cmdText + "]"); - } - #endregion - - return (int)Execute(new ExecuteNonQueryCallbackWithParameters(cmdType, cmdText, null)); - } - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText, - string parameterName, Enum dbType, int size, object parameterValue) - { - return (int)Execute(new ExecuteNonQueryCallbackWithParameters(cmdType, cmdText, - CreateDbParameters(parameterName, dbType, size, parameterValue))); - - - } - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The parameter collection to map. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText, - IDbParameters parameters) - { - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing NonQuery. " + cmdType + "[" + cmdText + "]"); - } - #endregion - - return (int)Execute(new ExecuteNonQueryCallbackWithParameters(cmdType, cmdText, parameters)); - - } - - /// - /// Executes a non query with parameters set via the - /// command setter, returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The command setter. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText, - ICommandSetter commandSetter) - { - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing NonQuery. " + cmdType + "[" + cmdText + "]"); - } - #endregion - - return (int)Execute(new ExecuteNonQueryCallbackWithCommandSetter(cmdType, cmdText, commandSetter)); - } - - - /// - /// Executes a non query with a command created via IDbCommandCreator and - /// parameters. - /// - /// Output parameters can be retrieved via the returned - /// dictionary. - /// - /// More commonly used as a lower level support method within the framework, - /// for example StoredProcedure/AdoScalar. - /// - /// - /// The callback to create a IDbCommand. - /// The number of rows affected. - public IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator) - { - - return (IDictionary)Execute(commandCreator, new AdoNonQueryWithOutputParamsCommandCallback()); - - } - - #endregion - - #region ExecuteScalar - - /// - /// Execute the query with the specified command text. - /// - /// No parameters are used. As with - /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the resultset - /// returned by the query. Extra columns or row are ignored. - /// The command type - /// The command text to execute. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText) - { - return Execute(new ExecuteScalarCallbackWithParameters(cmdType, cmdText, null)); - } - - /// - /// Execute the query with the specified command text and parameter returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText, - string parameterName, Enum dbType, int size, object parameterValue) - { - return Execute(new ExecuteScalarCallbackWithParameters(cmdType, cmdText, - CreateDbParameters(parameterName, dbType, size, parameterValue))); - - } - - - /// - /// Execute the query with the specified command text and parameters returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The parameter collection to map. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText, - IDbParameters parameters) - { - return Execute(new ExecuteScalarCallbackWithParameters(cmdType, cmdText, parameters)); - - } - - /// - /// Execute the query with the specified command text and parameters set via the - /// command setter, returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The command setter. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText, - ICommandSetter commandSetter) - { - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing ExecuteScalar. " + cmdType + "[" + cmdText + "]"); - } - #endregion - - return (int)Execute(new ExecuteScalarCallbackWithCommandSetter(cmdType, cmdText, commandSetter)); - - } - - /// - /// Execute the query with a command created via IDbCommandCreator and - /// parameters - /// - /// Output parameters can be retrieved via the returned - /// dictionary. - /// - /// More commonly used as a lower level support method within the framework, - /// for example for StoredProcedure/AdoScalar. - /// - /// The callback to create a IDbCommand. - /// A dictionary containing output parameters, if any - public IDictionary ExecuteScalar(IDbCommandCreator commandCreator) - { - return (IDictionary)Execute(commandCreator, new AdoStoredProcedureScalarCommandCallback()); - } - - #endregion - - #region Query with RowCallback - - /// - /// Execute a query given IDbCommand's type and text, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback) - { - QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback)); - } - - /// - /// Execute a query given IDbCommand's type and text by - /// passing the created IDbCommand to a ICommandSetter implementation - /// that knows how to bind values to the IDbCommand, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - /// The command setter. - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - ICommandSetter commandSetter) - { - QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback), commandSetter); - - } - - /// - /// Execute a query given IDbCommand's type and text and provided parameter - /// information, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - string parameterName, Enum dbType, int size, object parameterValue) - { - QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback), parameterName, dbType, size, parameterValue); - } - - - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, IDbParameters parameters) - { - QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback), parameters); - } - - #endregion - - // RowCallback with Delegate Questionable for 1.1 since no anonymous delegates and there isn't a collecting parameter - // in the delegate method signature. - - #region Query with RowCallback Delegate - - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate) - { - QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate)); - - } - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter) - { - QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate), commandSetter); - - } - - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, - string name, Enum dbType, int size, object parameterValue) - { - QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate), name, dbType, size, parameterValue); - - } - - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters) - { - QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate), parameters); - - } - - - - #endregion - - #region Query with RowMapper - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper)); - } - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter) - { - - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, - new RowMapperResultSetExtractor(rowMapper), commandSetter); - - } - - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, - string name, Enum dbType, int size, object parameterValue) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), name, dbType, size, parameterValue); - } - - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), parameters); - } - - - #endregion - - #region Query With RowMapper Delegate - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate)); - } - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), commandSetter); - } - - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - string parameterName, Enum dbType, int size, object parameterValue) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), parameterName, dbType, size, parameterValue); - } - - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - IDbParameters parameters) - { - return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), parameters); - } - - #endregion - - #region Query with ResultSetExtractor - - /// - /// Execute a query given static SQL/Stored Procedure name - /// and process a single result set with an instance of IResultSetExtractor - /// - /// The type of command. - /// The SQL/Stored Procedure to execute - /// Object that will extract all rows of a result set - /// An arbitrary result object, as returned by the IResultSetExtractor - public object QueryWithResultSetExtractor(CommandType cmdType, string sql, IResultSetExtractor rse) - { - AssertUtils.ArgumentNotNull(sql, "sql", "SQL must not be null"); - - //TODO check for parameter placeholders... - - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing SQL [" + sql + "]"); - } - - return Execute(new QueryCallback(this, cmdType, sql, rse, null)); - - } - - public object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, ICommandSetter commandSetter) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, - resultSetExtractor, commandSetter)); - } - - - public object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - string name, Enum dbType, int size, object parameterValue) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractor, CreateDbParameters(name, dbType, size, parameterValue))); - } - - public object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - IDbParameters parameters) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractor, parameters)); - } - - - #endregion - - - #region Query with ResultSetExtractorDelegate - - /// - /// Execute a query given static SQL/Stored Procedure name - /// and process a single result set with an instance of IResultSetExtractor - /// - /// The type of command. - /// The SQL/Stored Procedure to execute - /// Delegate that will extract all rows of a result set - /// An arbitrary result object, as returned by the IResultSetExtractor - public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate) - { - AssertUtils.ArgumentNotNull(sql, "sql", "SQL must not be null"); - - //TODO check for parameter placeholders... - - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing SQL [" + sql + "]"); - } - - return Execute(new QueryCallback(this, cmdType, sql, resultSetExtractorDelegate, null)); - - } - - public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - ICommandSetter commandSetter) - { - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, - resultSetExtractorDelegate, commandSetter)); - } - - - public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - string name, Enum dbType, int size, object parameterValue) - { - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractorDelegate, CreateDbParameters(name, dbType, size, parameterValue))); - } - - public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - IDbParameters parameters) - { - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractorDelegate, parameters)); - } - - - #endregion - - #region Query for Object - - /// - /// Execute a query with the specified command text, mapping a single result - /// row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - /// - /// Execute a query with the specified command text and parameters set via the - /// command setter, mapping a single result row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The command setter. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, commandSetter); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - /// - /// Execute a query with the specified command text and parameters, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The parameter collection to use in the query. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameters); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - /// - /// Execute a query with the specified command text and parameter, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, string parameterName, Enum dbType, int size, - object parameterValue) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameterName, dbType, size, parameterValue); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - #endregion - - #region Query for ObjectDelegate - - /// - /// Execute a query with the specified command text, mapping a single result - /// row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - - /// - /// Execute a query with the specified command text and parameters set via the - /// command setter, mapping a single result row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The command setter. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, commandSetter); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - /// - /// Execute a query with the specified command text and parameters, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The parameter collection to use in the query. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, IDbParameters parameters) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameters); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - /// - /// Execute a query with the specified command text and parameter, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, string parameterName, Enum dbType, int size, - object parameterValue) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameterName, dbType, size, parameterValue); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - #endregion - - #region Query with CommandCreator - - public object QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse) - { - return QueryWithCommandCreator(cc, rse, null); - } - - public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback) - { - QueryWithCommandCreator(cc, rowCallback, null); - } - - public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper) - { - return QueryWithCommandCreator(cc, rowMapper, null); - } - - public object QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse, IDictionary returnedParameters) - { - if (rse == null) - { - throw new ArgumentNullException("Result Set Extractor must not be null"); - } - - return Execute(cc, new AdoResultSetExtractorWithOutputParamsCommandCallback(this, rse, returnedParameters)); - } - - public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters) - { - if (rowCallback == null) - { - throw new ArgumentNullException("RowCallback must not be null"); - } - Execute(cc, new AdoRowCallbackCommandCallback(this, rowCallback, returnedParameters)); - } - - public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper, IDictionary returnedParameters) - { - if (rowMapper == null) - { - throw new ArgumentNullException("rowMapper must not be null"); - } - - return (IList)Execute(cc, new AdoRowMapperQueryCommandCallback(this, rowMapper, returnedParameters)); - } - - - - - public IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors) - { - return (IDictionary)Execute(cc, new AdoResultProcessorsQueryCommandCallback(this, namedResultSetProcessors)); - } - - #endregion - - // DataSet/DataTable related methods. - - #region DataTable Create operations without parameters - - public DataTable DataTableCreate(CommandType commandType, string sql) - { - DataTable dataTable = CreateDataTable(); - DataTableFill(dataTable, commandType, sql); - return dataTable; - } - - public DataTable DataTableCreate(CommandType commandType, string sql, - string tableMappingName) - { - DataTable dataTable = CreateDataTable(); - DataTableFill(dataTable, commandType, sql, tableMappingName); - return dataTable; - } - - public DataTable DataTableCreate(CommandType commandType, string sql, - ITableMapping tableMapping) - { - DataTable dataTable = CreateDataTable(); - DataTableFill(dataTable, commandType, sql, tableMapping); - return dataTable; - } - - public DataTable DataTableCreate(CommandType commandType, string sql, - ITableMapping tableMapping, - IDataAdapterSetter setter) - { - DataTable dataTable = CreateDataTable(); - DataTableFill(dataTable, commandType, sql, tableMapping, setter); - return dataTable; - } - - #endregion - - #region DataTable Create operations with parameters - - public DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters) - { - DataTable dataTable = CreateDataTable(); - DataTableFillWithParams(dataTable, commandType, sql, parameters); - return dataTable; - } - - public DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - string tableMappingName) - { - DataTable dataTable = CreateDataTable(); - DataTableFillWithParams(dataTable, commandType, sql, parameters, tableMappingName); - return dataTable; - } - - public DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping) - { - DataTable dataTable = CreateDataTable(); - DataTableFillWithParams(dataTable, commandType, sql, parameters, tableMapping); - return dataTable; - } - - public DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping, - IDataAdapterSetter dataAdapterSetter) - { - DataTable dataTable = CreateDataTable(); - DataTableFillWithParams(dataTable, commandType, sql, parameters, tableMapping, dataAdapterSetter); - return dataTable; - } - - - #endregion - - #region DataTable Fill operations without parameters - /// - /// Fill a based on a select command that requires no parameters. - /// - /// The to populate - /// The type of command - /// SQL query to execute - /// The number of rows successfully added to or refreshed in the - public int DataTableFill(DataTable dataTable, CommandType commandType, string sql) - { - ValidateFillArguments(dataTable, sql); - - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing DataTableFill " + commandType + "[" + sql + "]"); - } - #endregion - - ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, null, null, null)); - } - - public int DataTableFill(DataTable dataTable, CommandType commandType, string sql, - string tableMappingName) - { - ValidateFillArguments(dataTable, sql); - - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing DataTableFill " + commandType + "[" + sql + "] with table mapping name " + tableMappingName); - } - #endregion - - if (tableMappingName == null) - { - tableMappingName = "Table"; - } - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableMappingName }); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, null, null, null)); - - } - - public int DataTableFill(DataTable dataTable, CommandType commandType, string sql, - ITableMapping tableMapping) - { - ValidateFillArguments(dataTable, sql, tableMapping); - ITableMappingCollection mappingCollection = new DataTableMappingCollection(); - mappingCollection.Add((object)tableMapping); - - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, null, null, null)); - } - - public int DataTableFill(DataTable dataTable, CommandType commandType, string sql, - ITableMapping tableMapping, - IDataAdapterSetter setter) - { - ValidateFillArguments(dataTable, sql, tableMapping); - ITableMappingCollection mappingCollection = new DataTableMappingCollection(); - mappingCollection.Add((object)tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, setter, null, null)); - } - - - #endregion - - #region DataTable Fill operations with parameters - - public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters) - { - ValidateFillWithParameterArguments(dataTable, sql, parameters); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, null, null, - parameters)); - } - - public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters, - string tableMappingName) - { - ValidateFillWithParameterArguments(dataTable, sql, parameters); - if (tableMappingName == null) - { - tableMappingName = "Table"; - } - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableMappingName }); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, null, null, parameters)); - } - - public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping) - { - ValidateFillWithParameterArguments(dataTable, sql, parameters, tableMapping); - ITableMappingCollection mappingCollection = new DataTableMappingCollection(); - mappingCollection.Add((object)tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, null, null, parameters)); - } - - public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping, - IDataAdapterSetter dataAdapterSetter) - { - ValidateFillWithParameterArguments(dataTable, sql, parameters, tableMapping); - ITableMappingCollection mappingCollection = new DataTableMappingCollection(); - mappingCollection.Add((object)tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataTable, - commandType, sql, - mappingCollection, dataAdapterSetter, null, parameters)); - } - - - #endregion - - #region DataTable Update operations - //TODO conflict options... - - public int DataTableUpdateWithCommandBuilder(DataTable dataTable, - CommandType commandType, - string selectSql, - IDbParameters parameters, - string tableName) - { - ValidateUpdateWithCommandBuilderArguments(dataTable, tableName, selectSql); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataTable, - DbProvider.CreateCommandBuilder(), - mappingCollection, - commandType, - selectSql, - parameters, - null)); - } - - public int DataTableUpdateWithCommandBuilder(DataTable dataTable, - CommandType commandType, - string selectSql, - IDbParameters parameters, - string tableName, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateWithCommandBuilderArguments(dataTable, tableName, selectSql); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataTable, - DbProvider.CreateCommandBuilder(), - mappingCollection, - commandType, - selectSql, - parameters, - dataAdapterSetter)); - } - - - public int DataTableUpdateWithCommandBuilder(DataTable dataTable, - CommandType commandType, - string selectSql, - IDbParameters parameters, - ITableMapping tableMapping, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateWithCommandBuilderArguments(dataTable, tableMapping, selectSql); - ITableMappingCollection mappingCollection = new DataTableMappingCollection(); - mappingCollection.Add(tableMapping); - return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataTable, - DbProvider.CreateCommandBuilder(), - mappingCollection, - commandType, - selectSql, - parameters, - dataAdapterSetter)); - } - - - - public int DataTableUpdate(DataTable dataTable, - string tableName, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters) - { - ValidateUpdateArguments(dataTable, tableName); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - return DataTableUpdate(dataTable, mappingCollection, - insertCommandtype, insertSql, insertParameters, - updateCommandtype, updateSql, updateParameters, - deleteCommandtype, deleteSql, deleteParameters, - null); - - } - - public int DataTableUpdate(DataTable dataTable, - string tableName, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateArguments(dataTable, tableName); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - return DataTableUpdate(dataTable, mappingCollection, - insertCommandtype, insertSql, insertParameters, - updateCommandtype, updateSql, updateParameters, - deleteCommandtype, deleteSql, deleteParameters, - dataAdapterSetter); - } - - public int DataTableUpdate(DataTable dataTable, - ITableMapping tableMapping, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateArguments(dataTable, tableMapping); - ITableMappingCollection mappingCollection = new DataTableMappingCollection(); - - mappingCollection.Add((object)tableMapping); - - return DataTableUpdate(dataTable, mappingCollection, - insertCommandtype, insertSql, insertParameters, - updateCommandtype, updateSql, updateParameters, - deleteCommandtype, deleteSql, deleteParameters, - dataAdapterSetter); - - - } - - - - #endregion - - #region DataSet Create operations without parameters - - public DataSet DataSetCreate(CommandType commandType, string sql) - { - DataSet dataSet = CreateDataSet(); - DataSetFill(dataSet, commandType, sql); - return dataSet; - } - - - public DataSet DataSetCreate(CommandType commandType, string sql, - string[] tableNames) - { - DataSet dataSet = CreateDataSet(); - DataSetFill(dataSet, commandType, sql, tableNames); - return dataSet; - } - - public DataSet DataSetCreate(CommandType commandType, string sql, - ITableMappingCollection tableMapping) - { - DataSet dataSet = CreateDataSet(); - DataSetFill(dataSet, commandType, sql, tableMapping); - return dataSet; - } - - public DataSet DataSetCreate(CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter) - { - DataSet dataSet = CreateDataSet(); - DataSetFill(dataSet, commandType, sql, tableMapping, setter); - return dataSet; - } - - public DataSet DataSetCreate(CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor) - { - DataSet dataSet = CreateDataSet(); - DataSetFill(dataSet, commandType, sql, tableMapping, setter, fillLifecycleProcessor); - return dataSet; - } - #endregion - - #region DataSet Create operations with parameters - - public DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters) - { - DataSet dataSet = CreateDataSet(); - DataSetFillWithParameters(dataSet, commandType, sql, parameters); - return dataSet; - } - - public DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - string[] tableNames) - { - DataSet dataSet = CreateDataSet(); - DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableNames); - return dataSet; - } - - public DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping) - { - DataSet dataSet = CreateDataSet(); - DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableMapping); - return dataSet; - } - - public DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter) - { - DataSet dataSet = CreateDataSet(); - DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableMapping, dataAdapterSetter); - return dataSet; - } - - public DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor) - { - DataSet dataSet = CreateDataSet(); - DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableMapping, dataAdapterSetter, fillLifecycleProcessor); - return dataSet; - } - - #endregion - - #region DataSet Fill operations without parameters - - public int DataSetFill(DataSet dataSet, CommandType commandType, string sql) - { - ValidateFillArguments(dataSet, sql); - - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing DataSetFill " + commandType + "[" + sql + "]"); - } - #endregion - - - ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - mappingCollection, null, null, null)); - } - - - - public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, string[] tableNames) - { - ValidateFillArguments(dataSet, sql); - - #region Instrumentation - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing DataSetFill " + commandType + "[" + sql + "] with table names " + tableNames); - } - #endregion - - if (tableNames == null) - { - tableNames = new string[] { "Table" }; - } - ITableMappingCollection mappingCollection = DoCreateMappingCollection(tableNames); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - mappingCollection, null, null, null)); - } - - - public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - ITableMappingCollection tableMapping) - { - ValidateFillArguments(dataSet, sql, tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, null, null, null)); - - } - - public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter) - { - ValidateFillArguments(dataSet, sql, tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, setter, null, null)); - - } - - public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor) - { - ValidateFillArguments(dataSet, sql, tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, setter, fillLifecycleProcessor, null)); - - } - - #endregion - - #region DataSet Fill operations with parameters - - public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters) - { - ValidateFillWithParameterArguments(dataSet, sql, parameters); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - mappingCollection, null, null, - parameters)); - } - - public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - string[] tableNames) - { - ValidateFillWithParameterArguments(dataSet, sql, parameters); - if (tableNames == null) - { - tableNames = new string[] { "Table" }; - } - ITableMappingCollection tableMapping = DoCreateMappingCollection(tableNames); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, null, null, parameters)); - - } - - public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping) - { - ValidateFillWithParameterArguments(dataSet, sql, parameters, tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, null, null, parameters)); - } - - public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter) - { - ValidateFillWithParameterArguments(dataSet, sql, parameters, tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, dataAdapterSetter, null, parameters)); - } - - public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor) - { - ValidateFillWithParameterArguments(dataSet, sql, parameters, tableMapping); - return (int)Execute(new DataAdapterFillCallback(dataSet, - commandType, sql, - tableMapping, dataAdapterSetter, fillLifecycleProcessor, parameters)); - } - - #endregion - - #region DataSet Update operations - public int DataSetUpdateWithCommandBuilder(DataSet dataSet, - CommandType commandType, - string selectSql, - IDbParameters selectParameters, - string tableName) - { - ValidateUpdateWithCommandBuilderArguments(dataSet, tableName, selectSql); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataSet, - DbProvider.CreateCommandBuilder(), - mappingCollection, - commandType, - selectSql, - selectParameters, - null)); - } - - public int DataSetUpdateWithCommandBuilder(DataSet dataSet, - CommandType commandType, - string selectSql, - IDbParameters selectParameters, - string tableName, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateWithCommandBuilderArguments(dataSet, tableName, selectSql); - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataSet, - DbProvider.CreateCommandBuilder(), - mappingCollection, - commandType, - selectSql, - selectParameters, - dataAdapterSetter)); - } - - public int DataSetUpdateWithCommandBuilder(DataSet dataSet, - CommandType commandType, - string selectSql, - IDbParameters selectParameters, - ITableMappingCollection mappingCollection, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateWithCommandBuilderArguments(dataSet, mappingCollection, selectSql); - return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataSet, - DbProvider.CreateCommandBuilder(), - mappingCollection, - commandType, - selectSql, - selectParameters, - dataAdapterSetter)); - } - - public int DataSetUpdate(DataSet dataSet, - string tableName, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand) - { - ValidateUpdateArguments(dataSet, tableName); - - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - - return (int)Execute(new DataAdapterUpdateCallback(dataSet, - mappingCollection, - insertCommand, - updateCommand, - deleteCommand, - null)); - } - - public int DataSetUpdate(DataSet dataSet, - string tableName, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters) - { - ValidateUpdateArguments(dataSet, tableName); - IDbCommand insertCommand = null; - if (insertSql != null) - { - insertCommand = DbProvider.CreateCommand(); - insertCommand.CommandType = insertCommandtype; - insertCommand.CommandText = insertSql; - ParameterUtils.CopyParameters(insertCommand, insertParameters); - } - IDbCommand updateCommand = null; - if (updateSql != null) - { - updateCommand = DbProvider.CreateCommand(); - updateCommand.CommandType = updateCommandtype; - updateCommand.CommandText = updateSql; - ParameterUtils.CopyParameters(updateCommand, updateParameters); - } - IDbCommand deleteCommand = null; - if (deleteSql != null) - { - deleteCommand = DbProvider.CreateCommand(); - deleteCommand.CommandType = deleteCommandtype; - deleteCommand.CommandText = deleteSql; - ParameterUtils.CopyParameters(deleteCommand, deleteParameters); - } - ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); - - int returnVal = (int)Execute(new DataAdapterUpdateCallback(dataSet, mappingCollection, - insertCommand, updateCommand, deleteCommand, null)); - - if (insertSql != null) - { - ParameterUtils.CopyParameters(insertParameters, insertCommand); - } - if (updateSql != null) - { - ParameterUtils.CopyParameters(updateParameters, updateCommand); - } - if (deleteSql != null) - { - ParameterUtils.CopyParameters(deleteParameters, deleteCommand); - } - return returnVal; - } - - - - public int DataSetUpdate(DataSet dataSet, - string tableName, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateArguments(dataSet, tableName); - ITableMappingCollection tableMapping = DoCreateMappingCollection(new string[] { tableName }); - return (int)Execute(new DataAdapterUpdateCallback(dataSet, - tableMapping, - insertCommand, - updateCommand, - deleteCommand, - dataAdapterSetter)); - } - - - public int DataSetUpdate(DataSet dataSet, - ITableMappingCollection tableMapping, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand) - { - ValidateUpdateArguments(dataSet, tableMapping); - return (int)Execute(new DataAdapterUpdateCallback(dataSet, - tableMapping, - insertCommand, - updateCommand, - deleteCommand, - null)); - } - - public int DataSetUpdate(DataSet dataSet, - ITableMappingCollection tableMapping, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand, - IDataAdapterSetter dataAdapterSetter) - { - ValidateUpdateArguments(dataSet, tableMapping); - return (int)Execute(new DataAdapterUpdateCallback(dataSet, - tableMapping, - insertCommand, - updateCommand, - deleteCommand, - dataAdapterSetter)); - } - - #endregion - - #region Parameter Creation Helper Methods - - public override IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter) - { - return (IDataParameter[])Execute(new DeriveParametersCommandCallback(DbProvider, procedureName, includeReturnParameter)); - - } - - #endregion - - #region Private Helper Methods - - private IDbParameters CreateDbParameters(IDbDataParameter parameter) - { - IDbParameters parameters = new DbParameters(DbProvider); - parameters.AddParameter(parameter); - return parameters; - } - - private IDbParameters CreateDbParameters(IList parameterList) - { - IDbParameters parameters = null; - if (parameterList != null) - { - parameters = new DbParameters(DbProvider); - foreach (IDbDataParameter parameter in parameterList) - { - parameters.AddParameter(parameter); - } - } - return parameters; - } - - private IDbParameters CreateDbParameters(object[] parameterValues) - { - IDbParameters parameters = null; - if (parameterValues != null) - { - parameters = new DbParameters(DbProvider); - foreach (object parameterValue in parameterValues) - { - parameters.Add(parameterValue); - } - } - return parameters; - } - - public int DataTableUpdate(DataTable dataTable, - ITableMappingCollection mappingCollection, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, - IDataAdapterSetter dataAdapterSetter) - { - //TODO - refactor to remove cut-n-pasted code. - IDbCommand insertCommand = null; - if (insertSql != null) - { - insertCommand = DbProvider.CreateCommand(); - insertCommand.CommandType = insertCommandtype; - insertCommand.CommandText = insertSql; - ParameterUtils.CopyParameters(insertCommand, insertParameters); - } - IDbCommand updateCommand = null; - if (updateSql != null) - { - updateCommand = DbProvider.CreateCommand(); - updateCommand.CommandType = updateCommandtype; - updateCommand.CommandText = updateSql; - ParameterUtils.CopyParameters(updateCommand, updateParameters); - } - IDbCommand deleteCommand = null; - if (deleteSql != null) - { - deleteCommand = DbProvider.CreateCommand(); - deleteCommand.CommandType = deleteCommandtype; - deleteCommand.CommandText = deleteSql; - ParameterUtils.CopyParameters(deleteCommand, deleteParameters); - } - - int returnVal = (int)Execute(new DataAdapterUpdateCallback(dataTable, mappingCollection, - insertCommand, updateCommand, deleteCommand, null)); - - if (insertSql != null) - { - ParameterUtils.CopyParameters(insertParameters, insertCommand); - } - if (updateSql != null) - { - ParameterUtils.CopyParameters(updateParameters, updateCommand); - } - if (deleteSql != null) - { - ParameterUtils.CopyParameters(deleteParameters, deleteCommand); - } - return returnVal; - } - #endregion - - #region Protected Helper Methods - - protected void InitExceptionTranslator() - { - if (exceptionTranslator == null) - { - IDbProvider provider = DbProvider; - if (provider != null) - { - exceptionTranslator = new ErrorCodeExceptionTranslator(provider); - } - else - { - exceptionTranslator = new FallbackExceptionTranslator(); - } - } - } - - #endregion - - #region Protected DataAdapter Helper methods - - protected virtual DataTable CreateDataTable() - { - DataTable dataTable = new DataTable(); - dataTable.Locale = CultureInfo.InvariantCulture; - return dataTable; - } - - protected virtual DataSet CreateDataSet() - { - DataSet dataSet = new DataSet(); - dataSet.Locale = CultureInfo.InvariantCulture; - return dataSet; - } - - protected virtual void ValidateFillArguments(DataTable dataTable, string sql) - { - if (dataTable == null) - { - throw new ArgumentNullException("dataTable", "DataTable argument can not be null"); - } - if (sql == null) - { - throw new ArgumentNullException("sql", "SQL for DataSet Fill operation can not be null"); - } - } - protected virtual void ValidateFillArguments(DataSet dataSet, string sql) - { - if (dataSet == null) - { - throw new ArgumentNullException("dataSet", "DataSet argument can not be null"); - } - if (sql == null) - { - throw new ArgumentNullException("sql", "SQL for DataSet Fill operation can not be null"); - } - } - protected virtual void ValidateFillArguments(DataTable dataTable, string sql, - ITableMapping tableMapping) - { - ValidateFillArguments(dataTable, sql); - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "ITableMapping for DataTable Fill operations can not be null"); - } - } - - protected virtual void ValidateFillArguments(DataSet dataSet, string sql, - ITableMappingCollection tableMappingCollection) - { - ValidateFillArguments(dataSet, sql); - if (tableMappingCollection == null) - { - throw new ArgumentNullException("tableMappingCollection", "ITableMappingCollection for DataSet Fill operations can not be null"); - } - } - protected virtual void ValidateFillWithParameterArguments(DataTable dataTable, string sql, IDbParameters parameters) - { - ValidateFillArguments(dataTable, sql); - if (parameters == null) - { - throw new ArgumentNullException("parameters", "IDbParameters for DataTable Fill operations can not be null"); - } - } - protected virtual void ValidateFillWithParameterArguments(DataSet dataSet, string sql, IDbParameters parameters) - { - ValidateFillArguments(dataSet, sql); - if (parameters == null) - { - throw new ArgumentNullException("parameters", "IDbParameters for DataSet Fill operations can not be null"); - } - } - protected virtual void ValidateFillWithParameterArguments(DataTable dataTable, string sql, IDbParameters parameters, ITableMapping tableMapping) - { - ValidateFillWithParameterArguments(dataTable, sql, parameters); - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "ITableMappingCollection for DataTable Fill operations can not be null"); - } - } - protected virtual void ValidateFillWithParameterArguments(DataSet dataSet, string sql, IDbParameters parameters, ITableMappingCollection tableMapping) - { - ValidateFillWithParameterArguments(dataSet, sql, parameters); - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "ITableMappingCollection for DataSet Fill operations can not be null"); - } - } - - protected virtual void ValidateUpdateArguments(DataSet dataSet, ITableMappingCollection tableMapping) - { - if (dataSet == null) - { - throw new ArgumentNullException("dataSet", "DataSet argument can not be null for update operation"); - } - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "TableMappings for DataSet Update operation can not be null"); - } - } - - protected virtual void ValidateUpdateArguments(DataSet dataSet, string tableName) - { - if (dataSet == null) - { - throw new ArgumentNullException("dataSet", "DataSet argument can not be null for update operation"); - } - if (tableName == null) - { - throw new ArgumentNullException("tableName", "TableName for DataSet Update operation can not be null"); - } - } - - protected virtual void ValidateUpdateArguments(DataTable dataTable, ITableMapping tableMapping) - { - if (dataTable == null) - { - throw new ArgumentNullException("dataTable", "DataTable argument can not be null for DataTable update operation"); - } - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "TableMapping for DataTable Update operation can not be null"); - } - } - protected virtual void ValidateUpdateArguments(DataTable dataTable, string tableName) - { - if (dataTable == null) - { - throw new ArgumentNullException("dataTable", "DataTable argument can not be null for DataTable update operation"); - } - if (tableName == null) - { - throw new ArgumentNullException("tableName", "TableName for DataTable Update operation can not be null"); - } - } - protected virtual void ValidateUpdateWithCommandBuilderArguments(DataSet dataSet, ITableMappingCollection tableMapping, string selectSql) - { - if (dataSet == null) - { - throw new ArgumentNullException("dataSet", "DataSet can not be null for update operation"); - } - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "TableMapping for DataSet Update operation can not be null"); - } - if (selectSql == null) - { - throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); - } - } - - protected virtual void ValidateUpdateWithCommandBuilderArguments(DataTable dataTable, string tableName, string selectSql) - { - if (dataTable == null) - { - throw new ArgumentNullException("dataTable", "DataTable can not be null for update operation"); - } - if (tableName == null) - { - throw new ArgumentNullException("tableName", "TableName for DataSet Update operation can not be null"); - } - if (selectSql == null) - { - throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); - } - } - - protected virtual void ValidateUpdateWithCommandBuilderArguments(DataTable dataTable, ITableMapping tableMapping, string selectSql) - { - if (dataTable == null) - { - throw new ArgumentNullException("dataTable", "DataTable can not be null for update operation"); - } - if (tableMapping == null) - { - throw new ArgumentNullException("tableMapping", "TableMapping for DataSet Update operation can not be null"); - } - if (selectSql == null) - { - throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); - } - } - protected virtual void ValidateUpdateWithCommandBuilderArguments(DataSet dataSet, string tableName, string selectSql) - { - if (dataSet == null) - { - throw new ArgumentNullException("dataSet", "DataSet can not be null for update operation"); - } - if (tableName == null) - { - throw new ArgumentNullException("tableName", "TableName for DataSet Update operation can not be null"); - } - if (selectSql == null) - { - throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); - } - } - - - protected virtual ITableMappingCollection DoCreateMappingCollection(string[] dataSetTableNames) - { - DataTableMappingCollection mappingCollection; - - if (dataSetTableNames == null) - { - dataSetTableNames = new string[] { "Table" }; - } - foreach (string tableName in dataSetTableNames) - { - if (StringUtils.IsNullOrEmpty(tableName)) - { - throw new ArgumentException("TableName for DataTable mapping can not be null or empty"); - } - } - mappingCollection = new DataTableMappingCollection(); - int counter = 0; - foreach (string dataSetTableName in dataSetTableNames) - { - string sourceTableName; - if (counter == 0) - { - sourceTableName = "Table"; - } - else - { - sourceTableName = "Table" + ++counter; - } - mappingCollection.Add(sourceTableName, dataSetTableName); - } - return mappingCollection; - } - - #endregion - - #region Private DataAdapter Helper callbacks - - - - private class DataAdapterFillCallback : IDataAdapterCallback - { - private bool containsDataSet; - private DataSet dataSet; - private DataTable dataTable; - private CommandType commandType; - private string sql; - private ITableMappingCollection mappingCollection; - private IDataAdapterSetter dataAdapterSetter; - private IDataSetFillLifecycleProcessor fillLifecycleProcessor; - private IDbParameters parameters; - - public DataAdapterFillCallback(DataSet dataSet, - CommandType commandType, - string sql, - ITableMappingCollection mappingCollection, - IDataAdapterSetter dataAdapterSetter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor, - IDbParameters parameters) - { - containsDataSet = true; - this.dataSet = dataSet; - this.commandType = commandType; - this.sql = sql; - this.mappingCollection = mappingCollection; - this.dataAdapterSetter = dataAdapterSetter; - this.fillLifecycleProcessor = fillLifecycleProcessor; - this.parameters = parameters; - } - - public DataAdapterFillCallback(DataTable dataTable, - CommandType commandType, - string sql, - ITableMappingCollection mappingCollection, - IDataAdapterSetter dataAdapterSetter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor, - IDbParameters parameters) - { - containsDataSet = false; - this.dataTable = dataTable; - this.commandType = commandType; - this.sql = sql; - this.mappingCollection = mappingCollection; - this.dataAdapterSetter = dataAdapterSetter; - this.fillLifecycleProcessor = fillLifecycleProcessor; - this.parameters = parameters; - } - - - - public object DoInDataAdapter(IDbDataAdapter dataAdapter) - { - dataAdapter.SelectCommand.CommandType = commandType; - dataAdapter.SelectCommand.CommandText = sql; - //TODO investigate performance of cloning....would need to change signature to - // DataTableMapping[] otherwise... - foreach (DataTableMapping dataTableMapping in mappingCollection) - { - dataAdapter.TableMappings.Add(((ICloneable)dataTableMapping).Clone()); - } - - ParameterUtils.CopyParameters(dataAdapter.SelectCommand, parameters); - - //TODO Review these lifecycle hooks... - if (dataAdapterSetter != null) - { - dataAdapterSetter.SetValues(dataAdapter); - } - if (fillLifecycleProcessor != null) - { - fillLifecycleProcessor.BeforeFill(dataSet, dataAdapter.TableMappings); - } - - int returnVal; - if (containsDataSet) - { - returnVal = dataAdapter.Fill(dataSet); - } - else - { - //TODO should query metadata to see if supports filling dataTable directly. - if (dataAdapter is DbDataAdapter) - { - returnVal = ((DbDataAdapter)dataAdapter).Fill(dataTable); - } - else - { - //TODO could create DataSet and extract DataTable... for now just throw - throw new DataException("Provider does not support filling DataTable directly"); - } - } - - ParameterUtils.CopyParameters(parameters, dataAdapter.SelectCommand); - - if (fillLifecycleProcessor != null) - { - fillLifecycleProcessor.AfterFill(dataSet, dataAdapter.TableMappings); - } - return returnVal; - } - } - - - private class DataAdapterUpdateCallback : IDataAdapterCallback - { - private bool containsDataSet; - private DataSet dataSet; - private DataTable dataTable; - private ITableMappingCollection mappingCollection; - private IDbCommand insertCommand; - private IDbCommand updateCommand; - private IDbCommand deleteCommand; - private IDataAdapterSetter dataAdapterSetter; - - public DataAdapterUpdateCallback(DataSet dataSet, - ITableMappingCollection mappingCollection, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand, - IDataAdapterSetter dataAdapterSetter) - { - containsDataSet = true; - this.dataSet = dataSet; - this.mappingCollection = mappingCollection; - this.insertCommand = insertCommand; - this.updateCommand = updateCommand; - this.deleteCommand = deleteCommand; - this.dataAdapterSetter = dataAdapterSetter; - } - - public DataAdapterUpdateCallback(DataTable dataTable, - ITableMappingCollection mappingCollection, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand, - IDataAdapterSetter dataAdapterSetter) - { - containsDataSet = false; - this.dataTable = dataTable; - this.mappingCollection = mappingCollection; - this.insertCommand = insertCommand; - this.updateCommand = updateCommand; - this.deleteCommand = deleteCommand; - this.dataAdapterSetter = dataAdapterSetter; - } - #region IDataAdapterCallback Members - - public object DoInDataAdapter(IDbDataAdapter dataAdapter) - { - //TODO - did not make copies of parameters... - if (insertCommand == null && updateCommand == null && deleteCommand == null) - { - throw new ArgumentException("All commands for DataSet Update operation are null"); - } - - if (insertCommand != null) - { - dataAdapter.InsertCommand = insertCommand; - ApplyConnectionAndTx(dataAdapter.InsertCommand, dataAdapter.SelectCommand); - } - if (updateCommand != null) - { - dataAdapter.UpdateCommand = updateCommand; - ApplyConnectionAndTx(dataAdapter.UpdateCommand, dataAdapter.SelectCommand); - } - if (deleteCommand != null) - { - dataAdapter.DeleteCommand = deleteCommand; - ApplyConnectionAndTx(dataAdapter.DeleteCommand, dataAdapter.SelectCommand); - } - foreach (DataTableMapping dataTableMapping in mappingCollection) - { - dataAdapter.TableMappings.Add(((ICloneable)dataTableMapping).Clone()); - } - - if (dataAdapterSetter != null) - { - dataAdapterSetter.SetValues(dataAdapter); - } - - if (containsDataSet) - { - return dataAdapter.Update(dataSet); - } - else - { - //TODO should query metadata to see if supports filling dataTable directly. - if (dataAdapter is DbDataAdapter) - { - return ((DbDataAdapter)dataAdapter).Update(dataTable); - } - else - { - //TODO could create DataSet and extract DataTable... for now just throw - throw new DataException("Provider does not support filling DataTable directly"); - } - } - } - - private static void ApplyConnectionAndTx(IDbCommand dbCommand, IDbCommand sourceCommand) - { - dbCommand.Connection = sourceCommand.Connection; - dbCommand.Transaction = sourceCommand.Transaction; - } - - #endregion - - } - - private class DataAdapterUpdateWithCommandBuilderCallback : IDataAdapterCallback - { - private bool containsDataSet; - private DataSet dataSet; - private DataTable dataTable; - private object commandBuilder; - private ITableMappingCollection mappingCollection; - private CommandType selectCommandType; - private string selectSql; - private IDbParameters selectParameters; - private IDataAdapterSetter dataAdapterSetter; - - public DataAdapterUpdateWithCommandBuilderCallback(DataSet dataSet, - object commandBuilder, - ITableMappingCollection mappingCollection, - CommandType selectCommandType, - string selectSql, - IDbParameters selectParameters, - IDataAdapterSetter dataAdapterSetter) - { - containsDataSet = true; - this.dataSet = dataSet; - this.commandBuilder = commandBuilder; - this.mappingCollection = mappingCollection; - this.selectCommandType = selectCommandType; - this.selectSql = selectSql; - this.selectParameters = selectParameters; - this.dataAdapterSetter = dataAdapterSetter; - } - - public DataAdapterUpdateWithCommandBuilderCallback(DataTable dataTable, - object commandBuilder, - ITableMappingCollection mappingCollection, - CommandType selectCommandType, - string selectSql, - IDbParameters selectParameters, - IDataAdapterSetter dataAdapterSetter) - { - containsDataSet = false; - this.dataTable = dataTable; - this.commandBuilder = commandBuilder; - this.mappingCollection = mappingCollection; - this.selectCommandType = selectCommandType; - this.selectSql = selectSql; - this.selectParameters = selectParameters; - this.dataAdapterSetter = dataAdapterSetter; - } - #region IDataAdapterCallback Members - - public object DoInDataAdapter(IDbDataAdapter dataAdapter) - { - dataAdapter.SelectCommand.CommandType = selectCommandType; - dataAdapter.SelectCommand.CommandText = selectSql; - ParameterUtils.CopyParameters(dataAdapter.SelectCommand, selectParameters); - - - foreach (DataTableMapping dataTableMapping in mappingCollection) - { - dataAdapter.TableMappings.Add(((ICloneable)dataTableMapping).Clone()); - } - - if (dataAdapterSetter != null) - { - dataAdapterSetter.SetValues(dataAdapter); - } - - //TODO consider refactoring to put this inside IDbMetadata - PropertyInfo selectCommandProperty = commandBuilder.GetType().GetProperty("DataAdapter", - BindingFlags.DeclaredOnly | - BindingFlags.GetProperty | - BindingFlags.Public | - BindingFlags.Instance - ); - - selectCommandProperty.SetValue(commandBuilder, dataAdapter, null); - - ParameterUtils.CopyParameters(selectParameters, dataAdapter.SelectCommand); - if (containsDataSet) - { - return dataAdapter.Update(dataSet); - } - else - { - //TODO should query metadata to see if supports filling dataTable directly. - if (dataAdapter is DbDataAdapter) - { - return ((DbDataAdapter)dataAdapter).Update(dataTable); - } - else - { - //TODO could create DataSet and extract DataTable... for now just throw - throw new DataException("Provider does not support filling DataTable directly"); - } - } - } - - private static void ApplyConnectionAndTx(IDbCommand dbCommand, IDbCommand sourceCommand) - { - dbCommand.Connection = sourceCommand.Connection; - dbCommand.Transaction = sourceCommand.Transaction; - } - - #endregion - - } - #endregion - - #region Private Helper Classes - - private class AdoStoredProcedureScalarCommandCallback : ICommandCallback - { - - public object DoInCommand(IDbCommand command) - { - IDictionary returnedResults = new Hashtable(); - object scalar = command.ExecuteScalar(); - ParameterUtils.ExtractOutputParameters(returnedResults, command); - returnedResults.Add("scalar", scalar); - return returnedResults; - - } - } - - private class AdoNonQueryWithOutputParamsCommandCallback : ICommandCallback - { - - public object DoInCommand(IDbCommand command) - { - IDictionary returnedResults = new Hashtable(); - int rowsAffected = command.ExecuteNonQuery(); - ParameterUtils.ExtractOutputParameters(returnedResults, command); - returnedResults.Add("rowsAffected", rowsAffected); - return returnedResults; - - } - } - - - private class AdoResultProcessorsQueryCommandCallback : ICommandCallback - { - private AdoTemplate adoTemplate; - private IList namedResultSetProcessors; - //private IDbParameters declaredParameters; - - public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors) - { - //AssertUtils.ArgumentHasLength(namedResultSetProcessors, "namedResultSetProcessors"); - - this.adoTemplate = adoTemplate; - this.namedResultSetProcessors = namedResultSetProcessors; - //this.declaredParameters = declaredParameters; - } - - public object DoInCommand(IDbCommand command) - { - IDictionary returnedResults = new Hashtable(); - int resultSetIndex = 0; - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - - //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to - // see if there is a result set. now currently assuming matching - // NamedResultSetProcessor/ResultSet pairs. - - do - { - if (namedResultSetProcessors.Count == 0) - { - //We could just have output parameters and/or return value, that is, no result sets - //If we didn't register a result set processor, it is likely that a result set wasn't expected. - break; - } - NamedResultSetProcessor namedResultSetProcessor = null; - try - { - namedResultSetProcessor - = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; - //Will only have possibility of run-time type error if using QueryWithCommandCreator - if (namedResultSetProcessor == null) - { - LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + - ", is not of expected type NamedResultSetProcessor. Type = " + - namedResultSetProcessors[resultSetIndex].GetType() + - "; Skipping processing for this result set."); - continue; - } - } - catch (IndexOutOfRangeException e) - { - LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); - continue; - } - catch (ArgumentOutOfRangeException e) - { - LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); - continue; - } - - - string parameterName = namedResultSetProcessor.Name; - if (namedResultSetProcessor.ResultSetProcessor is IResultSetExtractor) - { - IResultSetExtractor rse = (IResultSetExtractor)namedResultSetProcessor.ResultSetProcessor; - object result = rse.ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (namedResultSetProcessor.ResultSetProcessor is IRowMapper) - { - IRowMapper rowMapper = (IRowMapper)namedResultSetProcessor.ResultSetProcessor; - object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (namedResultSetProcessor.ResultSetProcessor is IRowCallback) - { - IRowCallback rowCallback = (IRowCallback)namedResultSetProcessor.ResultSetProcessor; - (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); - returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); - } - resultSetIndex++; - - } while (reader.NextResult()); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedResults, command); - return returnedResults; - } - } - - - private class DeriveParametersCommandCallback : ICommandCallback, ICommandTextProvider - { - private IDbProvider provider; - private string procedureName; - private bool includeReturnParameter; - - public DeriveParametersCommandCallback(IDbProvider provider, string procedureName, bool includeReturnParameter) - { - this.provider = provider; - this.procedureName = procedureName; - this.includeReturnParameter = includeReturnParameter; - } - - public string CommandText - { - get { return procedureName; } - } - - public object DoInCommand(IDbCommand command) - { - command.CommandType = CommandType.StoredProcedure; - command.CommandText = procedureName; - - //The DeriveParameter is static in all providers...it seems.... - Type commandBuilderType = provider.DbMetadata.CommandBuilderType; - commandBuilderType.InvokeMember(provider.DbMetadata.CommandBuilderDeriveParametersMethod.Name, - BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, - new object[] { command }); - - if (command.Parameters.Count > 0) - { - IDataParameter param = (IDataParameter)command.Parameters[0]; - if (param.Direction == ParameterDirection.ReturnValue) - { - if (!includeReturnParameter) - { - command.Parameters.RemoveAt(0); - } - } - } - return ParameterUtils.CloneParameters(command); - } - } - - private class AdoRowCallbackCommandCallback : ICommandCallback - { - private AdoTemplate adoTemplate; - private IRowCallback rowCallback; - private IDictionary returnedParameters; - - public AdoRowCallbackCommandCallback(AdoTemplate adoTemplate, IRowCallback rowCallback, IDictionary returnedParameters) - { - this.adoTemplate = adoTemplate; - this.rowCallback = rowCallback; - this.returnedParameters = returnedParameters; - } - - public object DoInCommand(IDbCommand command) - { - //Extract the single returned result set - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - rowCallback.ProcessRow(reader); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedParameters, command); - return null; - } - } - private class AdoResultSetExtractorWithOutputParamsCommandCallback : ICommandCallback - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private IDictionary returnedParameters; - - public AdoResultSetExtractorWithOutputParamsCommandCallback(AdoTemplate adoTemplate, IResultSetExtractor rse, IDictionary returnedParameters) - { - this.adoTemplate = adoTemplate; - this.rse = rse; - this.returnedParameters = returnedParameters; - } - - public object DoInCommand(IDbCommand command) - { - object returnVal = null; - //Extract the single returned result set - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - returnVal = rse.ExtractData(reader); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedParameters, command); - return returnVal; - } - } - - - private class AdoRowMapperQueryCommandCallback : ICommandCallback - { - private AdoTemplate adoTemplate; - private IRowMapper rowMapper; - //private IDbParameters declaredParameters; - private IDictionary returnedParameters; - - public AdoRowMapperQueryCommandCallback(AdoTemplate adoTemplate, IRowMapper rowMapper, IDictionary returnedParameters) - { - this.adoTemplate = adoTemplate; - this.rowMapper = rowMapper; - //this.declaredParameters = declaredParameters; - this.returnedParameters = returnedParameters; - } - - public object DoInCommand(IDbCommand command) - { - IList objectList = null; - //Extract the single returned result set - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1); - objectList = (IList)rse.ExtractData(reader); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedParameters, command); - return objectList; - } - } - - - private class ExecuteNonQueryCallbackWithParameters : ICommandCallback, ICommandTextProvider - { - private CommandType commandType; - private string commandText; - private IDbParameters parameters; - - public ExecuteNonQueryCallbackWithParameters(CommandType commandType, string commandText, IDbParameters dbParameters) - { - this.commandType = commandType; - this.commandText = commandText; - parameters = dbParameters; - } - - public string CommandText - { - get { return commandText; } - } - - public Object DoInCommand(IDbCommand command) - { - command.CommandType = commandType; - command.CommandText = commandText; - ParameterUtils.CopyParameters(command, parameters); - Object returnValue = command.ExecuteNonQuery(); - ParameterUtils.CopyParameters(parameters, command); - return returnValue; - } - - } - - - private class ExecuteNonQueryCallbackWithCommandSetter : ICommandCallback, ICommandTextProvider - { - private CommandType commandType; - private string commandText; - private ICommandSetter commandSetter; - - public ExecuteNonQueryCallbackWithCommandSetter(CommandType commandType, string commandText, ICommandSetter commandSetter) - { - this.commandType = commandType; - this.commandText = commandText; - this.commandSetter = commandSetter; - } - - public string CommandText - { - get { return commandText; } - } - - public Object DoInCommand(IDbCommand command) - { - command.CommandType = commandType; - command.CommandText = commandText; - if (commandSetter != null) - { - commandSetter.SetValues(command); - } - Object rowsAffected = command.ExecuteNonQuery(); - if (LOG.IsDebugEnabled) - { - LOG.Debug("ExecuteNonQuery affected " + rowsAffected + " rows"); - } - return rowsAffected; - } - - } - - - private class ExecuteScalarCallbackWithParameters : ICommandCallback, ICommandTextProvider - { - private CommandType commandType = CommandType.Text; - private string commandText; - private IDbParameters parameters; - - public ExecuteScalarCallbackWithParameters(CommandType cmdType, string cmdText, IDbParameters dbParameters) - { - commandType = cmdType; - commandText = cmdText; - parameters = dbParameters; - } - - public string CommandText - { - get { return commandText; } - } - - public Object DoInCommand(IDbCommand command) - { - command.CommandType = commandType; - command.CommandText = commandText; - ParameterUtils.CopyParameters(command, parameters); - Object returnValue = command.ExecuteScalar(); - ParameterUtils.CopyParameters(parameters, command); - return returnValue; - } - } - - private class ExecuteScalarCallbackWithCommandSetter : ICommandCallback, ICommandTextProvider - { - private CommandType commandType; - private string commandText; - private ICommandSetter commandSetter; - - public ExecuteScalarCallbackWithCommandSetter(CommandType commandType, string commandText, ICommandSetter commandSetter) - { - this.commandType = commandType; - this.commandText = commandText; - this.commandSetter = commandSetter; - } - - public string CommandText - { - get { return commandText; } - } - - public Object DoInCommand(IDbCommand command) - { - command.CommandType = commandType; - command.CommandText = commandText; - if (commandSetter != null) - { - commandSetter.SetValues(command); - } - Object returnValue = command.ExecuteScalar(); - if (LOG.IsDebugEnabled) - { - LOG.Debug("ExecuteScalar return value = " + returnValue); - } - return returnValue; - } - - } - - - private class ExecuteCommandCallbackUsingDelegate : ICommandCallback, ICommandTextProvider - { - private CommandDelegate del; - private string commandText; - - public ExecuteCommandCallbackUsingDelegate(CommandDelegate d) - { - del = d; - } - - public string CommandText - { - get { return commandText; } - } - - public Object DoInCommand(IDbCommand command) - { - try - { - return del(command); - } - catch (Exception e) - { - e.GetType(); - commandText = command.CommandText; - throw; - } - } - } - - - - private class QueryCallbackWithCommandSetter : ICommandCallback, ICommandTextProvider - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private ResultSetExtractorDelegate resultSetExtractorDelegate; - private ICommandSetter commandSetter; - private CommandType commandType; - private string commandText; - - public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, IResultSetExtractor rse, ICommandSetter commandSetter) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.rse = rse; - this.commandSetter = commandSetter; - } - - public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, ICommandSetter commandSetter) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.resultSetExtractorDelegate = resultSetExtractorDelegate; - this.commandSetter = commandSetter; - } - - public string CommandText - { - get { return commandText; } - } - - public object DoInCommand(IDbCommand command) - { - IDataReader reader = null; - try - { - command.CommandType = commandType; - command.CommandText = commandText; - if (commandSetter != null) - { - commandSetter.SetValues(command); - } - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - if (rse != null) - { - return rse.ExtractData(reader); - } - else - { - return resultSetExtractorDelegate(reader); - } - } - finally - { - AdoUtils.CloseReader(reader); - } - } - - } - - private class QueryCallback : ICommandCallback, ICommandTextProvider - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private ResultSetExtractorDelegate resultSetExtractorDelegate; - private CommandType commandType; - private string commandText; - private IDbParameters parameters; - - public QueryCallback(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, IResultSetExtractor rse, IDbParameters dbParameters) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.rse = rse; - parameters = dbParameters; - } - - public QueryCallback(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, IDbParameters dbParameters) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.resultSetExtractorDelegate = resultSetExtractorDelegate; - parameters = dbParameters; - } - - - public string CommandText - { - get { return commandText; } - } - - public object DoInCommand(IDbCommand command) - { - IDataReader reader = null; - try - { - command.CommandType = commandType; - command.CommandText = commandText; - ParameterUtils.CopyParameters(command, parameters); - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - object returnValue; - if (rse != null) - { - returnValue = rse.ExtractData(reader); - } - else - { - returnValue = resultSetExtractorDelegate(reader); - } - return returnValue; - } - finally - { - AdoUtils.CloseReader(reader); - ParameterUtils.CopyParameters(parameters, command); - } - } - } - - #endregion - - /// - /// Creates the data reader wrapper for use in AdoTemplate callback methods. - /// - /// The reader to wrap. - /// The data reader used in AdoTemplate callbacks - public override IDataReader CreateDataReaderWrapper(IDataReader readerToWrap) - { - if (dataReaderWrapperType != null && newDataReaderWrapper != null) - { - IDataReaderWrapper wrapper = (IDataReaderWrapper) newDataReaderWrapper.Invoke(ObjectUtils.EmptyObjects); - wrapper.WrappedReader = readerToWrap; - return wrapper; - } - else - { - return readerToWrap; - } - } - } - +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using System.Data.Common; +using System.Globalization; +using System.Reflection; +using Common.Logging; +using Spring.Dao.Support; +using Spring.Data.Common; +using Spring.Data.Support; +using Spring.Reflection.Dynamic; +using Spring.Util; + +#endregion + +namespace Spring.Data.Core +{ + /// + /// This is the central class in the Spring.Data namespace. + /// It simplifies the use of ADO.NET and helps to avoid commons errors. + /// + /// Mark Pollack (.NET) + public class AdoTemplate : AdoAccessor, IAdoOperations + { + #region Logging Definition + + private static readonly ILog LOG = LogManager.GetLogger(typeof(AdoTemplate)); + + #endregion + + #region Fields + + private IDbProvider dbProvider; + + private IAdoExceptionTranslator exceptionTranslator; + + private bool lazyInit = true; + protected Type dataReaderWrapperType; + protected IDynamicConstructor newDataReaderWrapper; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public AdoTemplate() + : base() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The database provider. + public AdoTemplate(IDbProvider provider) + { + DbProvider = provider; + AfterPropertiesSet(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The database provider. + /// if set to false + /// lazily initialize the ErrorCodeExceptionTranslator. + public AdoTemplate(IDbProvider provider, bool lazyInit) + { + DbProvider = provider; + LazyInit = lazyInit; + AfterPropertiesSet(); + } + + #endregion + + #region Properties + + /// + /// An instance of a DbProvider implementation. + /// + public override IDbProvider DbProvider + { + get { return dbProvider; } + set + { + dbProvider = value; + } + } + + /// + /// Gets or sets a value indicating whether to lazily initialize the + /// IAdoExceptionTranslator for this accessor, on first encounter of a + /// exception from the data provider. Default is "true"; can be switched to + /// "false" for initialization on startup. + /// + /// true if to lazy initialize the IAdoExceptionTranslator; + /// otherwise, false. + public override bool LazyInit + { + get { return lazyInit; } + set { lazyInit = value; } + } + + /// + /// Gets or sets the exception translator. If no custom translator is provided, a default + /// is used. + /// + /// The exception translator. + public override IAdoExceptionTranslator ExceptionTranslator + { + get + { + InitExceptionTranslator(); + return exceptionTranslator; + } + set + { + exceptionTranslator = value; + } + } + + /// + /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper + /// for the purpose of having defaults values to use in case of DBNull values read + /// from IDataReader. + /// + /// The type of the data reader wrapper. + public override Type DataReaderWrapperType + { + get { return dataReaderWrapperType; } + set + { + if (dataReaderWrapperType == null) + { + if (typeof(IDataReaderWrapper).IsAssignableFrom(value)) + { + dataReaderWrapperType = value; + ConstructorInfo constructor = ObjectUtils.GetZeroArgConstructorInfo(dataReaderWrapperType); + newDataReaderWrapper = DynamicConstructor.Create(constructor); + + } + else + { + throw new ArgumentException("DataReaderWrapper type must implement IDataReaderWrapper. Implemented interfaces on " + + value.GetType().Name + "are [" + + StringUtils.ArrayToCommaDelimitedString( + ReflectionUtils.ToInterfaceArray(value)) + "]"); + + } + } + else + { + LOG.Warn("Ignoring assignment of DataReaderWrapperType since it has already been assigned."); + } + + } + + } + + #endregion + + + public override void AfterPropertiesSet() + { + if (DbProvider == null) + { + throw new ArgumentException("DbProvider is required"); + } + if (!LazyInit) + { + InitExceptionTranslator(); + } + } + + + #region General Execute Callback Methods + /// + /// Execute a ADO.NET operation on a command object using a delegate callback. + /// + /// The delegate called with a command object. + /// + /// A result object returned by the action or null + /// + /// This allows for implementing arbitrary data access operations + /// on a single command within Spring's managed ADO.NET environment. + public Object Execute(CommandDelegate del) + { + return Execute(new ExecuteCommandCallbackUsingDelegate(del)); + } + + /// + /// Callback to execute a IDbCommand. + /// + /// the callback to execute + /// object returned from callback + public object Execute(ICommandCallback action) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + IDbCommand command = null; + try + { + command = DbProvider.CreateCommand(); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + ApplyCommandSettings(command); + Object result = action.DoInCommand(command); + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + return result; + } + catch (Exception e) + { + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); + } + else + { + throw; + } + + + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + + } + + /// + /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, + /// using the interface based callback IDbCommandCallback. + /// + /// The command creator. + /// The callback to execute based on IDbCommand + /// A result object returned by the action or null + public object Execute(IDbCommandCreator commandCreator, ICommandCallback action) + { + AssertUtils.ArgumentNotNull(commandCreator, "commandCreator", "IDbCommandCreator must not be null"); + AssertUtils.ArgumentNotNull(action, "action", "Callback object must not be null"); + + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + + IDbCommand command = null; + try + { + command = commandCreator.CreateDbCommand(DbProvider); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + ApplyCommandSettings(command); + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + Object result = action.DoInCommand(command); + + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + + return result; + } + catch (Exception e) + { + commandCreator = null; + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); + } + else + { + throw; + } + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + + } + + /// + /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. + /// + /// This allows for implementing abritrary data access operations + /// on a single DataAdapter within Spring's managed ADO.NET environment. + /// + /// The data adapter callback. + /// A result object returned by the callback or null + public object Execute(IDataAdapterCallback dataAdapterCallback) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + IDbDataAdapter dataAdapter = null; + try + { + dataAdapter = DbProvider.CreateDataAdapter(); + //TODO row updated event handling... + dataAdapter.SelectCommand = DbProvider.CreateCommand(); + dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection; + //TODO register for warnings on connection. + dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction; + ApplyCommandSettings(dataAdapter.SelectCommand); + object result = dataAdapterCallback.DoInDataAdapter(dataAdapter); + return result; + + } + catch (Exception) + { + AdoUtils.DisposeDataAdapterCommands(dataAdapter); + //TODO set dataAdapter command's = null; ? + //TODO exception translation? different hierarchy for data set operations. + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + throw; + } + finally + { + AdoUtils.DisposeDataAdapterCommands(dataAdapter); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + + + } + + #endregion + + #region ExecuteNonQuery + + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText) + { + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing NonQuery " + cmdType + "[" + cmdText + "]"); + } + #endregion + + return (int)Execute(new ExecuteNonQueryCallbackWithParameters(cmdType, cmdText, null)); + } + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText, + string parameterName, Enum dbType, int size, object parameterValue) + { + return (int)Execute(new ExecuteNonQueryCallbackWithParameters(cmdType, cmdText, + CreateDbParameters(parameterName, dbType, size, parameterValue))); + + + } + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The parameter collection to map. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText, + IDbParameters parameters) + { + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing NonQuery. " + cmdType + "[" + cmdText + "]"); + } + #endregion + + return (int)Execute(new ExecuteNonQueryCallbackWithParameters(cmdType, cmdText, parameters)); + + } + + /// + /// Executes a non query with parameters set via the + /// command setter, returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The command setter. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText, + ICommandSetter commandSetter) + { + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing NonQuery. " + cmdType + "[" + cmdText + "]"); + } + #endregion + + return (int)Execute(new ExecuteNonQueryCallbackWithCommandSetter(cmdType, cmdText, commandSetter)); + } + + + /// + /// Executes a non query with a command created via IDbCommandCreator and + /// parameters. + /// + /// Output parameters can be retrieved via the returned + /// dictionary. + /// + /// More commonly used as a lower level support method within the framework, + /// for example StoredProcedure/AdoScalar. + /// + /// + /// The callback to create a IDbCommand. + /// The number of rows affected. + public IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator) + { + + return (IDictionary)Execute(commandCreator, new AdoNonQueryWithOutputParamsCommandCallback()); + + } + + #endregion + + #region ExecuteScalar + + /// + /// Execute the query with the specified command text. + /// + /// No parameters are used. As with + /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the resultset + /// returned by the query. Extra columns or row are ignored. + /// The command type + /// The command text to execute. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText) + { + return Execute(new ExecuteScalarCallbackWithParameters(cmdType, cmdText, null)); + } + + /// + /// Execute the query with the specified command text and parameter returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText, + string parameterName, Enum dbType, int size, object parameterValue) + { + return Execute(new ExecuteScalarCallbackWithParameters(cmdType, cmdText, + CreateDbParameters(parameterName, dbType, size, parameterValue))); + + } + + + /// + /// Execute the query with the specified command text and parameters returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The parameter collection to map. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText, + IDbParameters parameters) + { + return Execute(new ExecuteScalarCallbackWithParameters(cmdType, cmdText, parameters)); + + } + + /// + /// Execute the query with the specified command text and parameters set via the + /// command setter, returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The command setter. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText, + ICommandSetter commandSetter) + { + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing ExecuteScalar. " + cmdType + "[" + cmdText + "]"); + } + #endregion + + return (int)Execute(new ExecuteScalarCallbackWithCommandSetter(cmdType, cmdText, commandSetter)); + + } + + /// + /// Execute the query with a command created via IDbCommandCreator and + /// parameters + /// + /// Output parameters can be retrieved via the returned + /// dictionary. + /// + /// More commonly used as a lower level support method within the framework, + /// for example for StoredProcedure/AdoScalar. + /// + /// The callback to create a IDbCommand. + /// A dictionary containing output parameters, if any + public IDictionary ExecuteScalar(IDbCommandCreator commandCreator) + { + return (IDictionary)Execute(commandCreator, new AdoStoredProcedureScalarCommandCallback()); + } + + #endregion + + #region Query with RowCallback + + /// + /// Execute a query given IDbCommand's type and text, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback) + { + QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback)); + } + + /// + /// Execute a query given IDbCommand's type and text by + /// passing the created IDbCommand to a ICommandSetter implementation + /// that knows how to bind values to the IDbCommand, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + /// The command setter. + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + ICommandSetter commandSetter) + { + QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback), commandSetter); + + } + + /// + /// Execute a query given IDbCommand's type and text and provided parameter + /// information, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + string parameterName, Enum dbType, int size, object parameterValue) + { + QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback), parameterName, dbType, size, parameterValue); + } + + + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, IDbParameters parameters) + { + QueryWithResultSetExtractor(cmdType, cmdText, new RowCallbackResultSetExtractor(rowCallback), parameters); + } + + #endregion + + // RowCallback with Delegate Questionable for 1.1 since no anonymous delegates and there isn't a collecting parameter + // in the delegate method signature. + + #region Query with RowCallback Delegate + + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate) + { + QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate)); + + } + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter) + { + QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate), commandSetter); + + } + + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, + string name, Enum dbType, int size, object parameterValue) + { + QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate), name, dbType, size, parameterValue); + + } + + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters) + { + QueryWithResultSetExtractor(cmdType, sql, new RowCallbackResultSetExtractor(rowCallbackDelegate), parameters); + + } + + + + #endregion + + #region Query with RowMapper + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper)); + } + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter) + { + + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, + new RowMapperResultSetExtractor(rowMapper), commandSetter); + + } + + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, + string name, Enum dbType, int size, object parameterValue) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), name, dbType, size, parameterValue); + } + + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), parameters); + } + + + #endregion + + #region Query With RowMapper Delegate + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate)); + } + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), commandSetter); + } + + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + string parameterName, Enum dbType, int size, object parameterValue) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), parameterName, dbType, size, parameterValue); + } + + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + IDbParameters parameters) + { + return (IList)QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), parameters); + } + + #endregion + + #region Query with ResultSetExtractor + + /// + /// Execute a query given static SQL/Stored Procedure name + /// and process a single result set with an instance of IResultSetExtractor + /// + /// The type of command. + /// The SQL/Stored Procedure to execute + /// Object that will extract all rows of a result set + /// An arbitrary result object, as returned by the IResultSetExtractor + public object QueryWithResultSetExtractor(CommandType cmdType, string sql, IResultSetExtractor rse) + { + AssertUtils.ArgumentNotNull(sql, "sql", "SQL must not be null"); + + //TODO check for parameter placeholders... + + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing SQL [" + sql + "]"); + } + + return Execute(new QueryCallback(this, cmdType, sql, rse, null)); + + } + + public object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, ICommandSetter commandSetter) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, + resultSetExtractor, commandSetter)); + } + + + public object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + string name, Enum dbType, int size, object parameterValue) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractor, CreateDbParameters(name, dbType, size, parameterValue))); + } + + public object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + IDbParameters parameters) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractor, parameters)); + } + + + #endregion + + + #region Query with ResultSetExtractorDelegate + + /// + /// Execute a query given static SQL/Stored Procedure name + /// and process a single result set with an instance of IResultSetExtractor + /// + /// The type of command. + /// The SQL/Stored Procedure to execute + /// Delegate that will extract all rows of a result set + /// An arbitrary result object, as returned by the IResultSetExtractor + public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate) + { + AssertUtils.ArgumentNotNull(sql, "sql", "SQL must not be null"); + + //TODO check for parameter placeholders... + + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing SQL [" + sql + "]"); + } + + return Execute(new QueryCallback(this, cmdType, sql, resultSetExtractorDelegate, null)); + + } + + public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + ICommandSetter commandSetter) + { + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, + resultSetExtractorDelegate, commandSetter)); + } + + + public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + string name, Enum dbType, int size, object parameterValue) + { + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractorDelegate, CreateDbParameters(name, dbType, size, parameterValue))); + } + + public object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + IDbParameters parameters) + { + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractorDelegate, parameters)); + } + + + #endregion + + #region Query for Object + + /// + /// Execute a query with the specified command text, mapping a single result + /// row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + /// + /// Execute a query with the specified command text and parameters set via the + /// command setter, mapping a single result row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The command setter. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, commandSetter); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + /// + /// Execute a query with the specified command text and parameters, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The parameter collection to use in the query. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameters); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + /// + /// Execute a query with the specified command text and parameter, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, string parameterName, Enum dbType, int size, + object parameterValue) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameterName, dbType, size, parameterValue); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + #endregion + + #region Query for ObjectDelegate + + /// + /// Execute a query with the specified command text, mapping a single result + /// row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + + /// + /// Execute a query with the specified command text and parameters set via the + /// command setter, mapping a single result row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The command setter. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, commandSetter); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + /// + /// Execute a query with the specified command text and parameters, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The parameter collection to use in the query. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, IDbParameters parameters) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameters); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + /// + /// Execute a query with the specified command text and parameter, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + public object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, string parameterName, Enum dbType, int size, + object parameterValue) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameterName, dbType, size, parameterValue); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + #endregion + + #region Query with CommandCreator + + public object QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse) + { + return QueryWithCommandCreator(cc, rse, null); + } + + public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback) + { + QueryWithCommandCreator(cc, rowCallback, null); + } + + public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper) + { + return QueryWithCommandCreator(cc, rowMapper, null); + } + + public object QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse, IDictionary returnedParameters) + { + if (rse == null) + { + throw new ArgumentNullException("Result Set Extractor must not be null"); + } + + return Execute(cc, new AdoResultSetExtractorWithOutputParamsCommandCallback(this, rse, returnedParameters)); + } + + public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters) + { + if (rowCallback == null) + { + throw new ArgumentNullException("RowCallback must not be null"); + } + Execute(cc, new AdoRowCallbackCommandCallback(this, rowCallback, returnedParameters)); + } + + public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper, IDictionary returnedParameters) + { + if (rowMapper == null) + { + throw new ArgumentNullException("rowMapper must not be null"); + } + + return (IList)Execute(cc, new AdoRowMapperQueryCommandCallback(this, rowMapper, returnedParameters)); + } + + + + + public IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors) + { + return (IDictionary)Execute(cc, new AdoResultProcessorsQueryCommandCallback(this, namedResultSetProcessors)); + } + + #endregion + + // DataSet/DataTable related methods. + + #region DataTable Create operations without parameters + + public DataTable DataTableCreate(CommandType commandType, string sql) + { + DataTable dataTable = CreateDataTable(); + DataTableFill(dataTable, commandType, sql); + return dataTable; + } + + public DataTable DataTableCreate(CommandType commandType, string sql, + string tableMappingName) + { + DataTable dataTable = CreateDataTable(); + DataTableFill(dataTable, commandType, sql, tableMappingName); + return dataTable; + } + + public DataTable DataTableCreate(CommandType commandType, string sql, + ITableMapping tableMapping) + { + DataTable dataTable = CreateDataTable(); + DataTableFill(dataTable, commandType, sql, tableMapping); + return dataTable; + } + + public DataTable DataTableCreate(CommandType commandType, string sql, + ITableMapping tableMapping, + IDataAdapterSetter setter) + { + DataTable dataTable = CreateDataTable(); + DataTableFill(dataTable, commandType, sql, tableMapping, setter); + return dataTable; + } + + #endregion + + #region DataTable Create operations with parameters + + public DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters) + { + DataTable dataTable = CreateDataTable(); + DataTableFillWithParams(dataTable, commandType, sql, parameters); + return dataTable; + } + + public DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + string tableMappingName) + { + DataTable dataTable = CreateDataTable(); + DataTableFillWithParams(dataTable, commandType, sql, parameters, tableMappingName); + return dataTable; + } + + public DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping) + { + DataTable dataTable = CreateDataTable(); + DataTableFillWithParams(dataTable, commandType, sql, parameters, tableMapping); + return dataTable; + } + + public DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping, + IDataAdapterSetter dataAdapterSetter) + { + DataTable dataTable = CreateDataTable(); + DataTableFillWithParams(dataTable, commandType, sql, parameters, tableMapping, dataAdapterSetter); + return dataTable; + } + + + #endregion + + #region DataTable Fill operations without parameters + /// + /// Fill a based on a select command that requires no parameters. + /// + /// The to populate + /// The type of command + /// SQL query to execute + /// The number of rows successfully added to or refreshed in the + public int DataTableFill(DataTable dataTable, CommandType commandType, string sql) + { + ValidateFillArguments(dataTable, sql); + + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing DataTableFill " + commandType + "[" + sql + "]"); + } + #endregion + + ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, null, null, null)); + } + + public int DataTableFill(DataTable dataTable, CommandType commandType, string sql, + string tableMappingName) + { + ValidateFillArguments(dataTable, sql); + + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing DataTableFill " + commandType + "[" + sql + "] with table mapping name " + tableMappingName); + } + #endregion + + if (tableMappingName == null) + { + tableMappingName = "Table"; + } + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableMappingName }); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, null, null, null)); + + } + + public int DataTableFill(DataTable dataTable, CommandType commandType, string sql, + ITableMapping tableMapping) + { + ValidateFillArguments(dataTable, sql, tableMapping); + ITableMappingCollection mappingCollection = new DataTableMappingCollection(); + mappingCollection.Add((object)tableMapping); + + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, null, null, null)); + } + + public int DataTableFill(DataTable dataTable, CommandType commandType, string sql, + ITableMapping tableMapping, + IDataAdapterSetter setter) + { + ValidateFillArguments(dataTable, sql, tableMapping); + ITableMappingCollection mappingCollection = new DataTableMappingCollection(); + mappingCollection.Add((object)tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, setter, null, null)); + } + + + #endregion + + #region DataTable Fill operations with parameters + + public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters) + { + ValidateFillWithParameterArguments(dataTable, sql, parameters); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, null, null, + parameters)); + } + + public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters, + string tableMappingName) + { + ValidateFillWithParameterArguments(dataTable, sql, parameters); + if (tableMappingName == null) + { + tableMappingName = "Table"; + } + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableMappingName }); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, null, null, parameters)); + } + + public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping) + { + ValidateFillWithParameterArguments(dataTable, sql, parameters, tableMapping); + ITableMappingCollection mappingCollection = new DataTableMappingCollection(); + mappingCollection.Add((object)tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, null, null, parameters)); + } + + public int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping, + IDataAdapterSetter dataAdapterSetter) + { + ValidateFillWithParameterArguments(dataTable, sql, parameters, tableMapping); + ITableMappingCollection mappingCollection = new DataTableMappingCollection(); + mappingCollection.Add((object)tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataTable, + commandType, sql, + mappingCollection, dataAdapterSetter, null, parameters)); + } + + + #endregion + + #region DataTable Update operations + //TODO conflict options... + + public int DataTableUpdateWithCommandBuilder(DataTable dataTable, + CommandType commandType, + string selectSql, + IDbParameters parameters, + string tableName) + { + ValidateUpdateWithCommandBuilderArguments(dataTable, tableName, selectSql); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataTable, + DbProvider.CreateCommandBuilder(), + mappingCollection, + commandType, + selectSql, + parameters, + null)); + } + + public int DataTableUpdateWithCommandBuilder(DataTable dataTable, + CommandType commandType, + string selectSql, + IDbParameters parameters, + string tableName, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateWithCommandBuilderArguments(dataTable, tableName, selectSql); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataTable, + DbProvider.CreateCommandBuilder(), + mappingCollection, + commandType, + selectSql, + parameters, + dataAdapterSetter)); + } + + + public int DataTableUpdateWithCommandBuilder(DataTable dataTable, + CommandType commandType, + string selectSql, + IDbParameters parameters, + ITableMapping tableMapping, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateWithCommandBuilderArguments(dataTable, tableMapping, selectSql); + ITableMappingCollection mappingCollection = new DataTableMappingCollection(); + mappingCollection.Add(tableMapping); + return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataTable, + DbProvider.CreateCommandBuilder(), + mappingCollection, + commandType, + selectSql, + parameters, + dataAdapterSetter)); + } + + + + public int DataTableUpdate(DataTable dataTable, + string tableName, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters) + { + ValidateUpdateArguments(dataTable, tableName); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + return DataTableUpdate(dataTable, mappingCollection, + insertCommandtype, insertSql, insertParameters, + updateCommandtype, updateSql, updateParameters, + deleteCommandtype, deleteSql, deleteParameters, + null); + + } + + public int DataTableUpdate(DataTable dataTable, + string tableName, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateArguments(dataTable, tableName); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + return DataTableUpdate(dataTable, mappingCollection, + insertCommandtype, insertSql, insertParameters, + updateCommandtype, updateSql, updateParameters, + deleteCommandtype, deleteSql, deleteParameters, + dataAdapterSetter); + } + + public int DataTableUpdate(DataTable dataTable, + ITableMapping tableMapping, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateArguments(dataTable, tableMapping); + ITableMappingCollection mappingCollection = new DataTableMappingCollection(); + + mappingCollection.Add((object)tableMapping); + + return DataTableUpdate(dataTable, mappingCollection, + insertCommandtype, insertSql, insertParameters, + updateCommandtype, updateSql, updateParameters, + deleteCommandtype, deleteSql, deleteParameters, + dataAdapterSetter); + + + } + + + + #endregion + + #region DataSet Create operations without parameters + + public DataSet DataSetCreate(CommandType commandType, string sql) + { + DataSet dataSet = CreateDataSet(); + DataSetFill(dataSet, commandType, sql); + return dataSet; + } + + + public DataSet DataSetCreate(CommandType commandType, string sql, + string[] tableNames) + { + DataSet dataSet = CreateDataSet(); + DataSetFill(dataSet, commandType, sql, tableNames); + return dataSet; + } + + public DataSet DataSetCreate(CommandType commandType, string sql, + ITableMappingCollection tableMapping) + { + DataSet dataSet = CreateDataSet(); + DataSetFill(dataSet, commandType, sql, tableMapping); + return dataSet; + } + + public DataSet DataSetCreate(CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter) + { + DataSet dataSet = CreateDataSet(); + DataSetFill(dataSet, commandType, sql, tableMapping, setter); + return dataSet; + } + + public DataSet DataSetCreate(CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor) + { + DataSet dataSet = CreateDataSet(); + DataSetFill(dataSet, commandType, sql, tableMapping, setter, fillLifecycleProcessor); + return dataSet; + } + #endregion + + #region DataSet Create operations with parameters + + public DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters) + { + DataSet dataSet = CreateDataSet(); + DataSetFillWithParameters(dataSet, commandType, sql, parameters); + return dataSet; + } + + public DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + string[] tableNames) + { + DataSet dataSet = CreateDataSet(); + DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableNames); + return dataSet; + } + + public DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping) + { + DataSet dataSet = CreateDataSet(); + DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableMapping); + return dataSet; + } + + public DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter) + { + DataSet dataSet = CreateDataSet(); + DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableMapping, dataAdapterSetter); + return dataSet; + } + + public DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor) + { + DataSet dataSet = CreateDataSet(); + DataSetFillWithParameters(dataSet, commandType, sql, parameters, tableMapping, dataAdapterSetter, fillLifecycleProcessor); + return dataSet; + } + + #endregion + + #region DataSet Fill operations without parameters + + public int DataSetFill(DataSet dataSet, CommandType commandType, string sql) + { + ValidateFillArguments(dataSet, sql); + + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing DataSetFill " + commandType + "[" + sql + "]"); + } + #endregion + + + ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + mappingCollection, null, null, null)); + } + + + + public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, string[] tableNames) + { + ValidateFillArguments(dataSet, sql); + + #region Instrumentation + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing DataSetFill " + commandType + "[" + sql + "] with table names " + tableNames); + } + #endregion + + if (tableNames == null) + { + tableNames = new string[] { "Table" }; + } + ITableMappingCollection mappingCollection = DoCreateMappingCollection(tableNames); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + mappingCollection, null, null, null)); + } + + + public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + ITableMappingCollection tableMapping) + { + ValidateFillArguments(dataSet, sql, tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, null, null, null)); + + } + + public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter) + { + ValidateFillArguments(dataSet, sql, tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, setter, null, null)); + + } + + public int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor) + { + ValidateFillArguments(dataSet, sql, tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, setter, fillLifecycleProcessor, null)); + + } + + #endregion + + #region DataSet Fill operations with parameters + + public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters) + { + ValidateFillWithParameterArguments(dataSet, sql, parameters); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(null); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + mappingCollection, null, null, + parameters)); + } + + public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + string[] tableNames) + { + ValidateFillWithParameterArguments(dataSet, sql, parameters); + if (tableNames == null) + { + tableNames = new string[] { "Table" }; + } + ITableMappingCollection tableMapping = DoCreateMappingCollection(tableNames); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, null, null, parameters)); + + } + + public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping) + { + ValidateFillWithParameterArguments(dataSet, sql, parameters, tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, null, null, parameters)); + } + + public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter) + { + ValidateFillWithParameterArguments(dataSet, sql, parameters, tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, dataAdapterSetter, null, parameters)); + } + + public int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor) + { + ValidateFillWithParameterArguments(dataSet, sql, parameters, tableMapping); + return (int)Execute(new DataAdapterFillCallback(dataSet, + commandType, sql, + tableMapping, dataAdapterSetter, fillLifecycleProcessor, parameters)); + } + + #endregion + + #region DataSet Update operations + public int DataSetUpdateWithCommandBuilder(DataSet dataSet, + CommandType commandType, + string selectSql, + IDbParameters selectParameters, + string tableName) + { + ValidateUpdateWithCommandBuilderArguments(dataSet, tableName, selectSql); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataSet, + DbProvider.CreateCommandBuilder(), + mappingCollection, + commandType, + selectSql, + selectParameters, + null)); + } + + public int DataSetUpdateWithCommandBuilder(DataSet dataSet, + CommandType commandType, + string selectSql, + IDbParameters selectParameters, + string tableName, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateWithCommandBuilderArguments(dataSet, tableName, selectSql); + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataSet, + DbProvider.CreateCommandBuilder(), + mappingCollection, + commandType, + selectSql, + selectParameters, + dataAdapterSetter)); + } + + public int DataSetUpdateWithCommandBuilder(DataSet dataSet, + CommandType commandType, + string selectSql, + IDbParameters selectParameters, + ITableMappingCollection mappingCollection, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateWithCommandBuilderArguments(dataSet, mappingCollection, selectSql); + return (int)Execute(new DataAdapterUpdateWithCommandBuilderCallback(dataSet, + DbProvider.CreateCommandBuilder(), + mappingCollection, + commandType, + selectSql, + selectParameters, + dataAdapterSetter)); + } + + public int DataSetUpdate(DataSet dataSet, + string tableName, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand) + { + ValidateUpdateArguments(dataSet, tableName); + + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + + return (int)Execute(new DataAdapterUpdateCallback(dataSet, + mappingCollection, + insertCommand, + updateCommand, + deleteCommand, + null)); + } + + public int DataSetUpdate(DataSet dataSet, + string tableName, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters) + { + ValidateUpdateArguments(dataSet, tableName); + IDbCommand insertCommand = null; + if (insertSql != null) + { + insertCommand = DbProvider.CreateCommand(); + insertCommand.CommandType = insertCommandtype; + insertCommand.CommandText = insertSql; + ParameterUtils.CopyParameters(insertCommand, insertParameters); + } + IDbCommand updateCommand = null; + if (updateSql != null) + { + updateCommand = DbProvider.CreateCommand(); + updateCommand.CommandType = updateCommandtype; + updateCommand.CommandText = updateSql; + ParameterUtils.CopyParameters(updateCommand, updateParameters); + } + IDbCommand deleteCommand = null; + if (deleteSql != null) + { + deleteCommand = DbProvider.CreateCommand(); + deleteCommand.CommandType = deleteCommandtype; + deleteCommand.CommandText = deleteSql; + ParameterUtils.CopyParameters(deleteCommand, deleteParameters); + } + ITableMappingCollection mappingCollection = DoCreateMappingCollection(new string[] { tableName }); + + int returnVal = (int)Execute(new DataAdapterUpdateCallback(dataSet, mappingCollection, + insertCommand, updateCommand, deleteCommand, null)); + + if (insertSql != null) + { + ParameterUtils.CopyParameters(insertParameters, insertCommand); + } + if (updateSql != null) + { + ParameterUtils.CopyParameters(updateParameters, updateCommand); + } + if (deleteSql != null) + { + ParameterUtils.CopyParameters(deleteParameters, deleteCommand); + } + return returnVal; + } + + + + public int DataSetUpdate(DataSet dataSet, + string tableName, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateArguments(dataSet, tableName); + ITableMappingCollection tableMapping = DoCreateMappingCollection(new string[] { tableName }); + return (int)Execute(new DataAdapterUpdateCallback(dataSet, + tableMapping, + insertCommand, + updateCommand, + deleteCommand, + dataAdapterSetter)); + } + + + public int DataSetUpdate(DataSet dataSet, + ITableMappingCollection tableMapping, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand) + { + ValidateUpdateArguments(dataSet, tableMapping); + return (int)Execute(new DataAdapterUpdateCallback(dataSet, + tableMapping, + insertCommand, + updateCommand, + deleteCommand, + null)); + } + + public int DataSetUpdate(DataSet dataSet, + ITableMappingCollection tableMapping, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand, + IDataAdapterSetter dataAdapterSetter) + { + ValidateUpdateArguments(dataSet, tableMapping); + return (int)Execute(new DataAdapterUpdateCallback(dataSet, + tableMapping, + insertCommand, + updateCommand, + deleteCommand, + dataAdapterSetter)); + } + + #endregion + + #region Parameter Creation Helper Methods + + public override IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter) + { + return (IDataParameter[])Execute(new DeriveParametersCommandCallback(DbProvider, procedureName, includeReturnParameter)); + + } + + #endregion + + #region Private Helper Methods + + private IDbParameters CreateDbParameters(IDbDataParameter parameter) + { + IDbParameters parameters = new DbParameters(DbProvider); + parameters.AddParameter(parameter); + return parameters; + } + + private IDbParameters CreateDbParameters(IList parameterList) + { + IDbParameters parameters = null; + if (parameterList != null) + { + parameters = new DbParameters(DbProvider); + foreach (IDbDataParameter parameter in parameterList) + { + parameters.AddParameter(parameter); + } + } + return parameters; + } + + private IDbParameters CreateDbParameters(object[] parameterValues) + { + IDbParameters parameters = null; + if (parameterValues != null) + { + parameters = new DbParameters(DbProvider); + foreach (object parameterValue in parameterValues) + { + parameters.Add(parameterValue); + } + } + return parameters; + } + + public int DataTableUpdate(DataTable dataTable, + ITableMappingCollection mappingCollection, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, + IDataAdapterSetter dataAdapterSetter) + { + //TODO - refactor to remove cut-n-pasted code. + IDbCommand insertCommand = null; + if (insertSql != null) + { + insertCommand = DbProvider.CreateCommand(); + insertCommand.CommandType = insertCommandtype; + insertCommand.CommandText = insertSql; + ParameterUtils.CopyParameters(insertCommand, insertParameters); + } + IDbCommand updateCommand = null; + if (updateSql != null) + { + updateCommand = DbProvider.CreateCommand(); + updateCommand.CommandType = updateCommandtype; + updateCommand.CommandText = updateSql; + ParameterUtils.CopyParameters(updateCommand, updateParameters); + } + IDbCommand deleteCommand = null; + if (deleteSql != null) + { + deleteCommand = DbProvider.CreateCommand(); + deleteCommand.CommandType = deleteCommandtype; + deleteCommand.CommandText = deleteSql; + ParameterUtils.CopyParameters(deleteCommand, deleteParameters); + } + + int returnVal = (int)Execute(new DataAdapterUpdateCallback(dataTable, mappingCollection, + insertCommand, updateCommand, deleteCommand, null)); + + if (insertSql != null) + { + ParameterUtils.CopyParameters(insertParameters, insertCommand); + } + if (updateSql != null) + { + ParameterUtils.CopyParameters(updateParameters, updateCommand); + } + if (deleteSql != null) + { + ParameterUtils.CopyParameters(deleteParameters, deleteCommand); + } + return returnVal; + } + #endregion + + #region Protected Helper Methods + + protected void InitExceptionTranslator() + { + if (exceptionTranslator == null) + { + IDbProvider provider = DbProvider; + if (provider != null) + { + exceptionTranslator = new ErrorCodeExceptionTranslator(provider); + } + else + { + exceptionTranslator = new FallbackExceptionTranslator(); + } + } + } + + #endregion + + #region Protected DataAdapter Helper methods + + protected virtual DataTable CreateDataTable() + { + DataTable dataTable = new DataTable(); + dataTable.Locale = CultureInfo.InvariantCulture; + return dataTable; + } + + protected virtual DataSet CreateDataSet() + { + DataSet dataSet = new DataSet(); + dataSet.Locale = CultureInfo.InvariantCulture; + return dataSet; + } + + protected virtual void ValidateFillArguments(DataTable dataTable, string sql) + { + if (dataTable == null) + { + throw new ArgumentNullException("dataTable", "DataTable argument can not be null"); + } + if (sql == null) + { + throw new ArgumentNullException("sql", "SQL for DataSet Fill operation can not be null"); + } + } + protected virtual void ValidateFillArguments(DataSet dataSet, string sql) + { + if (dataSet == null) + { + throw new ArgumentNullException("dataSet", "DataSet argument can not be null"); + } + if (sql == null) + { + throw new ArgumentNullException("sql", "SQL for DataSet Fill operation can not be null"); + } + } + protected virtual void ValidateFillArguments(DataTable dataTable, string sql, + ITableMapping tableMapping) + { + ValidateFillArguments(dataTable, sql); + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "ITableMapping for DataTable Fill operations can not be null"); + } + } + + protected virtual void ValidateFillArguments(DataSet dataSet, string sql, + ITableMappingCollection tableMappingCollection) + { + ValidateFillArguments(dataSet, sql); + if (tableMappingCollection == null) + { + throw new ArgumentNullException("tableMappingCollection", "ITableMappingCollection for DataSet Fill operations can not be null"); + } + } + protected virtual void ValidateFillWithParameterArguments(DataTable dataTable, string sql, IDbParameters parameters) + { + ValidateFillArguments(dataTable, sql); + if (parameters == null) + { + throw new ArgumentNullException("parameters", "IDbParameters for DataTable Fill operations can not be null"); + } + } + protected virtual void ValidateFillWithParameterArguments(DataSet dataSet, string sql, IDbParameters parameters) + { + ValidateFillArguments(dataSet, sql); + if (parameters == null) + { + throw new ArgumentNullException("parameters", "IDbParameters for DataSet Fill operations can not be null"); + } + } + protected virtual void ValidateFillWithParameterArguments(DataTable dataTable, string sql, IDbParameters parameters, ITableMapping tableMapping) + { + ValidateFillWithParameterArguments(dataTable, sql, parameters); + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "ITableMappingCollection for DataTable Fill operations can not be null"); + } + } + protected virtual void ValidateFillWithParameterArguments(DataSet dataSet, string sql, IDbParameters parameters, ITableMappingCollection tableMapping) + { + ValidateFillWithParameterArguments(dataSet, sql, parameters); + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "ITableMappingCollection for DataSet Fill operations can not be null"); + } + } + + protected virtual void ValidateUpdateArguments(DataSet dataSet, ITableMappingCollection tableMapping) + { + if (dataSet == null) + { + throw new ArgumentNullException("dataSet", "DataSet argument can not be null for update operation"); + } + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "TableMappings for DataSet Update operation can not be null"); + } + } + + protected virtual void ValidateUpdateArguments(DataSet dataSet, string tableName) + { + if (dataSet == null) + { + throw new ArgumentNullException("dataSet", "DataSet argument can not be null for update operation"); + } + if (tableName == null) + { + throw new ArgumentNullException("tableName", "TableName for DataSet Update operation can not be null"); + } + } + + protected virtual void ValidateUpdateArguments(DataTable dataTable, ITableMapping tableMapping) + { + if (dataTable == null) + { + throw new ArgumentNullException("dataTable", "DataTable argument can not be null for DataTable update operation"); + } + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "TableMapping for DataTable Update operation can not be null"); + } + } + protected virtual void ValidateUpdateArguments(DataTable dataTable, string tableName) + { + if (dataTable == null) + { + throw new ArgumentNullException("dataTable", "DataTable argument can not be null for DataTable update operation"); + } + if (tableName == null) + { + throw new ArgumentNullException("tableName", "TableName for DataTable Update operation can not be null"); + } + } + protected virtual void ValidateUpdateWithCommandBuilderArguments(DataSet dataSet, ITableMappingCollection tableMapping, string selectSql) + { + if (dataSet == null) + { + throw new ArgumentNullException("dataSet", "DataSet can not be null for update operation"); + } + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "TableMapping for DataSet Update operation can not be null"); + } + if (selectSql == null) + { + throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); + } + } + + protected virtual void ValidateUpdateWithCommandBuilderArguments(DataTable dataTable, string tableName, string selectSql) + { + if (dataTable == null) + { + throw new ArgumentNullException("dataTable", "DataTable can not be null for update operation"); + } + if (tableName == null) + { + throw new ArgumentNullException("tableName", "TableName for DataSet Update operation can not be null"); + } + if (selectSql == null) + { + throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); + } + } + + protected virtual void ValidateUpdateWithCommandBuilderArguments(DataTable dataTable, ITableMapping tableMapping, string selectSql) + { + if (dataTable == null) + { + throw new ArgumentNullException("dataTable", "DataTable can not be null for update operation"); + } + if (tableMapping == null) + { + throw new ArgumentNullException("tableMapping", "TableMapping for DataSet Update operation can not be null"); + } + if (selectSql == null) + { + throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); + } + } + protected virtual void ValidateUpdateWithCommandBuilderArguments(DataSet dataSet, string tableName, string selectSql) + { + if (dataSet == null) + { + throw new ArgumentNullException("dataSet", "DataSet can not be null for update operation"); + } + if (tableName == null) + { + throw new ArgumentNullException("tableName", "TableName for DataSet Update operation can not be null"); + } + if (selectSql == null) + { + throw new ArgumentNullException("selectSql", "SelectSql for DataSet Update operations can not be null"); + } + } + + + protected virtual ITableMappingCollection DoCreateMappingCollection(string[] dataSetTableNames) + { + DataTableMappingCollection mappingCollection; + + if (dataSetTableNames == null) + { + dataSetTableNames = new string[] { "Table" }; + } + foreach (string tableName in dataSetTableNames) + { + if (StringUtils.IsNullOrEmpty(tableName)) + { + throw new ArgumentException("TableName for DataTable mapping can not be null or empty"); + } + } + mappingCollection = new DataTableMappingCollection(); + int counter = 0; + foreach (string dataSetTableName in dataSetTableNames) + { + string sourceTableName; + if (counter == 0) + { + sourceTableName = "Table"; + } + else + { + sourceTableName = "Table" + ++counter; + } + mappingCollection.Add(sourceTableName, dataSetTableName); + } + return mappingCollection; + } + + #endregion + + #region Private DataAdapter Helper callbacks + + + + private class DataAdapterFillCallback : IDataAdapterCallback + { + private bool containsDataSet; + private DataSet dataSet; + private DataTable dataTable; + private CommandType commandType; + private string sql; + private ITableMappingCollection mappingCollection; + private IDataAdapterSetter dataAdapterSetter; + private IDataSetFillLifecycleProcessor fillLifecycleProcessor; + private IDbParameters parameters; + + public DataAdapterFillCallback(DataSet dataSet, + CommandType commandType, + string sql, + ITableMappingCollection mappingCollection, + IDataAdapterSetter dataAdapterSetter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor, + IDbParameters parameters) + { + containsDataSet = true; + this.dataSet = dataSet; + this.commandType = commandType; + this.sql = sql; + this.mappingCollection = mappingCollection; + this.dataAdapterSetter = dataAdapterSetter; + this.fillLifecycleProcessor = fillLifecycleProcessor; + this.parameters = parameters; + } + + public DataAdapterFillCallback(DataTable dataTable, + CommandType commandType, + string sql, + ITableMappingCollection mappingCollection, + IDataAdapterSetter dataAdapterSetter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor, + IDbParameters parameters) + { + containsDataSet = false; + this.dataTable = dataTable; + this.commandType = commandType; + this.sql = sql; + this.mappingCollection = mappingCollection; + this.dataAdapterSetter = dataAdapterSetter; + this.fillLifecycleProcessor = fillLifecycleProcessor; + this.parameters = parameters; + } + + + + public object DoInDataAdapter(IDbDataAdapter dataAdapter) + { + dataAdapter.SelectCommand.CommandType = commandType; + dataAdapter.SelectCommand.CommandText = sql; + //TODO investigate performance of cloning....would need to change signature to + // DataTableMapping[] otherwise... + foreach (DataTableMapping dataTableMapping in mappingCollection) + { + dataAdapter.TableMappings.Add(((ICloneable)dataTableMapping).Clone()); + } + + ParameterUtils.CopyParameters(dataAdapter.SelectCommand, parameters); + + //TODO Review these lifecycle hooks... + if (dataAdapterSetter != null) + { + dataAdapterSetter.SetValues(dataAdapter); + } + if (fillLifecycleProcessor != null) + { + fillLifecycleProcessor.BeforeFill(dataSet, dataAdapter.TableMappings); + } + + int returnVal; + if (containsDataSet) + { + returnVal = dataAdapter.Fill(dataSet); + } + else + { + //TODO should query metadata to see if supports filling dataTable directly. + if (dataAdapter is DbDataAdapter) + { + returnVal = ((DbDataAdapter)dataAdapter).Fill(dataTable); + } + else + { + //TODO could create DataSet and extract DataTable... for now just throw + throw new DataException("Provider does not support filling DataTable directly"); + } + } + + ParameterUtils.CopyParameters(parameters, dataAdapter.SelectCommand); + + if (fillLifecycleProcessor != null) + { + fillLifecycleProcessor.AfterFill(dataSet, dataAdapter.TableMappings); + } + return returnVal; + } + } + + + private class DataAdapterUpdateCallback : IDataAdapterCallback + { + private bool containsDataSet; + private DataSet dataSet; + private DataTable dataTable; + private ITableMappingCollection mappingCollection; + private IDbCommand insertCommand; + private IDbCommand updateCommand; + private IDbCommand deleteCommand; + private IDataAdapterSetter dataAdapterSetter; + + public DataAdapterUpdateCallback(DataSet dataSet, + ITableMappingCollection mappingCollection, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand, + IDataAdapterSetter dataAdapterSetter) + { + containsDataSet = true; + this.dataSet = dataSet; + this.mappingCollection = mappingCollection; + this.insertCommand = insertCommand; + this.updateCommand = updateCommand; + this.deleteCommand = deleteCommand; + this.dataAdapterSetter = dataAdapterSetter; + } + + public DataAdapterUpdateCallback(DataTable dataTable, + ITableMappingCollection mappingCollection, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand, + IDataAdapterSetter dataAdapterSetter) + { + containsDataSet = false; + this.dataTable = dataTable; + this.mappingCollection = mappingCollection; + this.insertCommand = insertCommand; + this.updateCommand = updateCommand; + this.deleteCommand = deleteCommand; + this.dataAdapterSetter = dataAdapterSetter; + } + #region IDataAdapterCallback Members + + public object DoInDataAdapter(IDbDataAdapter dataAdapter) + { + //TODO - did not make copies of parameters... + if (insertCommand == null && updateCommand == null && deleteCommand == null) + { + throw new ArgumentException("All commands for DataSet Update operation are null"); + } + + if (insertCommand != null) + { + dataAdapter.InsertCommand = insertCommand; + ApplyConnectionAndTx(dataAdapter.InsertCommand, dataAdapter.SelectCommand); + } + if (updateCommand != null) + { + dataAdapter.UpdateCommand = updateCommand; + ApplyConnectionAndTx(dataAdapter.UpdateCommand, dataAdapter.SelectCommand); + } + if (deleteCommand != null) + { + dataAdapter.DeleteCommand = deleteCommand; + ApplyConnectionAndTx(dataAdapter.DeleteCommand, dataAdapter.SelectCommand); + } + foreach (DataTableMapping dataTableMapping in mappingCollection) + { + dataAdapter.TableMappings.Add(((ICloneable)dataTableMapping).Clone()); + } + + if (dataAdapterSetter != null) + { + dataAdapterSetter.SetValues(dataAdapter); + } + + if (containsDataSet) + { + return dataAdapter.Update(dataSet); + } + else + { + //TODO should query metadata to see if supports filling dataTable directly. + if (dataAdapter is DbDataAdapter) + { + return ((DbDataAdapter)dataAdapter).Update(dataTable); + } + else + { + //TODO could create DataSet and extract DataTable... for now just throw + throw new DataException("Provider does not support filling DataTable directly"); + } + } + } + + private static void ApplyConnectionAndTx(IDbCommand dbCommand, IDbCommand sourceCommand) + { + dbCommand.Connection = sourceCommand.Connection; + dbCommand.Transaction = sourceCommand.Transaction; + } + + #endregion + + } + + private class DataAdapterUpdateWithCommandBuilderCallback : IDataAdapterCallback + { + private bool containsDataSet; + private DataSet dataSet; + private DataTable dataTable; + private object commandBuilder; + private ITableMappingCollection mappingCollection; + private CommandType selectCommandType; + private string selectSql; + private IDbParameters selectParameters; + private IDataAdapterSetter dataAdapterSetter; + + public DataAdapterUpdateWithCommandBuilderCallback(DataSet dataSet, + object commandBuilder, + ITableMappingCollection mappingCollection, + CommandType selectCommandType, + string selectSql, + IDbParameters selectParameters, + IDataAdapterSetter dataAdapterSetter) + { + containsDataSet = true; + this.dataSet = dataSet; + this.commandBuilder = commandBuilder; + this.mappingCollection = mappingCollection; + this.selectCommandType = selectCommandType; + this.selectSql = selectSql; + this.selectParameters = selectParameters; + this.dataAdapterSetter = dataAdapterSetter; + } + + public DataAdapterUpdateWithCommandBuilderCallback(DataTable dataTable, + object commandBuilder, + ITableMappingCollection mappingCollection, + CommandType selectCommandType, + string selectSql, + IDbParameters selectParameters, + IDataAdapterSetter dataAdapterSetter) + { + containsDataSet = false; + this.dataTable = dataTable; + this.commandBuilder = commandBuilder; + this.mappingCollection = mappingCollection; + this.selectCommandType = selectCommandType; + this.selectSql = selectSql; + this.selectParameters = selectParameters; + this.dataAdapterSetter = dataAdapterSetter; + } + #region IDataAdapterCallback Members + + public object DoInDataAdapter(IDbDataAdapter dataAdapter) + { + dataAdapter.SelectCommand.CommandType = selectCommandType; + dataAdapter.SelectCommand.CommandText = selectSql; + ParameterUtils.CopyParameters(dataAdapter.SelectCommand, selectParameters); + + + foreach (DataTableMapping dataTableMapping in mappingCollection) + { + dataAdapter.TableMappings.Add(((ICloneable)dataTableMapping).Clone()); + } + + if (dataAdapterSetter != null) + { + dataAdapterSetter.SetValues(dataAdapter); + } + + //TODO consider refactoring to put this inside IDbMetadata + PropertyInfo selectCommandProperty = commandBuilder.GetType().GetProperty("DataAdapter", + BindingFlags.DeclaredOnly | + BindingFlags.GetProperty | + BindingFlags.Public | + BindingFlags.Instance + ); + + selectCommandProperty.SetValue(commandBuilder, dataAdapter, null); + + ParameterUtils.CopyParameters(selectParameters, dataAdapter.SelectCommand); + if (containsDataSet) + { + return dataAdapter.Update(dataSet); + } + else + { + //TODO should query metadata to see if supports filling dataTable directly. + if (dataAdapter is DbDataAdapter) + { + return ((DbDataAdapter)dataAdapter).Update(dataTable); + } + else + { + //TODO could create DataSet and extract DataTable... for now just throw + throw new DataException("Provider does not support filling DataTable directly"); + } + } + } + + private static void ApplyConnectionAndTx(IDbCommand dbCommand, IDbCommand sourceCommand) + { + dbCommand.Connection = sourceCommand.Connection; + dbCommand.Transaction = sourceCommand.Transaction; + } + + #endregion + + } + #endregion + + #region Private Helper Classes + + private class AdoStoredProcedureScalarCommandCallback : ICommandCallback + { + + public object DoInCommand(IDbCommand command) + { + IDictionary returnedResults = new Hashtable(); + object scalar = command.ExecuteScalar(); + ParameterUtils.ExtractOutputParameters(returnedResults, command); + returnedResults.Add("scalar", scalar); + return returnedResults; + + } + } + + private class AdoNonQueryWithOutputParamsCommandCallback : ICommandCallback + { + + public object DoInCommand(IDbCommand command) + { + IDictionary returnedResults = new Hashtable(); + int rowsAffected = command.ExecuteNonQuery(); + ParameterUtils.ExtractOutputParameters(returnedResults, command); + returnedResults.Add("rowsAffected", rowsAffected); + return returnedResults; + + } + } + + + private class AdoResultProcessorsQueryCommandCallback : ICommandCallback + { + private AdoTemplate adoTemplate; + private IList namedResultSetProcessors; + //private IDbParameters declaredParameters; + + public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors) + { + //AssertUtils.ArgumentHasLength(namedResultSetProcessors, "namedResultSetProcessors"); + + this.adoTemplate = adoTemplate; + this.namedResultSetProcessors = namedResultSetProcessors; + //this.declaredParameters = declaredParameters; + } + + public object DoInCommand(IDbCommand command) + { + IDictionary returnedResults = new Hashtable(); + int resultSetIndex = 0; + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + + //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to + // see if there is a result set. now currently assuming matching + // NamedResultSetProcessor/ResultSet pairs. + + do + { + if (namedResultSetProcessors.Count == 0) + { + //We could just have output parameters and/or return value, that is, no result sets + //If we didn't register a result set processor, it is likely that a result set wasn't expected. + break; + } + NamedResultSetProcessor namedResultSetProcessor = null; + try + { + namedResultSetProcessor + = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; + //Will only have possibility of run-time type error if using QueryWithCommandCreator + if (namedResultSetProcessor == null) + { + LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + + ", is not of expected type NamedResultSetProcessor. Type = " + + namedResultSetProcessors[resultSetIndex].GetType() + + "; Skipping processing for this result set."); + continue; + } + } + catch (IndexOutOfRangeException e) + { + LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); + continue; + } + catch (ArgumentOutOfRangeException e) + { + LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); + continue; + } + + + string parameterName = namedResultSetProcessor.Name; + if (namedResultSetProcessor.ResultSetProcessor is IResultSetExtractor) + { + IResultSetExtractor rse = (IResultSetExtractor)namedResultSetProcessor.ResultSetProcessor; + object result = rse.ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (namedResultSetProcessor.ResultSetProcessor is IRowMapper) + { + IRowMapper rowMapper = (IRowMapper)namedResultSetProcessor.ResultSetProcessor; + object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (namedResultSetProcessor.ResultSetProcessor is IRowCallback) + { + IRowCallback rowCallback = (IRowCallback)namedResultSetProcessor.ResultSetProcessor; + (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); + returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); + } + resultSetIndex++; + + } while (reader.NextResult()); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedResults, command); + return returnedResults; + } + } + + + private class DeriveParametersCommandCallback : ICommandCallback, ICommandTextProvider + { + private IDbProvider provider; + private string procedureName; + private bool includeReturnParameter; + + public DeriveParametersCommandCallback(IDbProvider provider, string procedureName, bool includeReturnParameter) + { + this.provider = provider; + this.procedureName = procedureName; + this.includeReturnParameter = includeReturnParameter; + } + + public string CommandText + { + get { return procedureName; } + } + + public object DoInCommand(IDbCommand command) + { + command.CommandType = CommandType.StoredProcedure; + command.CommandText = procedureName; + + //The DeriveParameter is static in all providers...it seems.... + Type commandBuilderType = provider.DbMetadata.CommandBuilderType; + commandBuilderType.InvokeMember(provider.DbMetadata.CommandBuilderDeriveParametersMethod.Name, + BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, + new object[] { command }); + + if (command.Parameters.Count > 0) + { + IDataParameter param = (IDataParameter)command.Parameters[0]; + if (param.Direction == ParameterDirection.ReturnValue) + { + if (!includeReturnParameter) + { + command.Parameters.RemoveAt(0); + } + } + } + return ParameterUtils.CloneParameters(command); + } + } + + private class AdoRowCallbackCommandCallback : ICommandCallback + { + private AdoTemplate adoTemplate; + private IRowCallback rowCallback; + private IDictionary returnedParameters; + + public AdoRowCallbackCommandCallback(AdoTemplate adoTemplate, IRowCallback rowCallback, IDictionary returnedParameters) + { + this.adoTemplate = adoTemplate; + this.rowCallback = rowCallback; + this.returnedParameters = returnedParameters; + } + + public object DoInCommand(IDbCommand command) + { + //Extract the single returned result set + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + rowCallback.ProcessRow(reader); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedParameters, command); + return null; + } + } + private class AdoResultSetExtractorWithOutputParamsCommandCallback : ICommandCallback + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private IDictionary returnedParameters; + + public AdoResultSetExtractorWithOutputParamsCommandCallback(AdoTemplate adoTemplate, IResultSetExtractor rse, IDictionary returnedParameters) + { + this.adoTemplate = adoTemplate; + this.rse = rse; + this.returnedParameters = returnedParameters; + } + + public object DoInCommand(IDbCommand command) + { + object returnVal = null; + //Extract the single returned result set + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + returnVal = rse.ExtractData(reader); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedParameters, command); + return returnVal; + } + } + + + private class AdoRowMapperQueryCommandCallback : ICommandCallback + { + private AdoTemplate adoTemplate; + private IRowMapper rowMapper; + //private IDbParameters declaredParameters; + private IDictionary returnedParameters; + + public AdoRowMapperQueryCommandCallback(AdoTemplate adoTemplate, IRowMapper rowMapper, IDictionary returnedParameters) + { + this.adoTemplate = adoTemplate; + this.rowMapper = rowMapper; + //this.declaredParameters = declaredParameters; + this.returnedParameters = returnedParameters; + } + + public object DoInCommand(IDbCommand command) + { + IList objectList = null; + //Extract the single returned result set + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1); + objectList = (IList)rse.ExtractData(reader); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedParameters, command); + return objectList; + } + } + + + private class ExecuteNonQueryCallbackWithParameters : ICommandCallback, ICommandTextProvider + { + private CommandType commandType; + private string commandText; + private IDbParameters parameters; + + public ExecuteNonQueryCallbackWithParameters(CommandType commandType, string commandText, IDbParameters dbParameters) + { + this.commandType = commandType; + this.commandText = commandText; + parameters = dbParameters; + } + + public string CommandText + { + get { return commandText; } + } + + public Object DoInCommand(IDbCommand command) + { + command.CommandType = commandType; + command.CommandText = commandText; + ParameterUtils.CopyParameters(command, parameters); + Object returnValue = command.ExecuteNonQuery(); + ParameterUtils.CopyParameters(parameters, command); + return returnValue; + } + + } + + + private class ExecuteNonQueryCallbackWithCommandSetter : ICommandCallback, ICommandTextProvider + { + private CommandType commandType; + private string commandText; + private ICommandSetter commandSetter; + + public ExecuteNonQueryCallbackWithCommandSetter(CommandType commandType, string commandText, ICommandSetter commandSetter) + { + this.commandType = commandType; + this.commandText = commandText; + this.commandSetter = commandSetter; + } + + public string CommandText + { + get { return commandText; } + } + + public Object DoInCommand(IDbCommand command) + { + command.CommandType = commandType; + command.CommandText = commandText; + if (commandSetter != null) + { + commandSetter.SetValues(command); + } + Object rowsAffected = command.ExecuteNonQuery(); + if (LOG.IsDebugEnabled) + { + LOG.Debug("ExecuteNonQuery affected " + rowsAffected + " rows"); + } + return rowsAffected; + } + + } + + + private class ExecuteScalarCallbackWithParameters : ICommandCallback, ICommandTextProvider + { + private CommandType commandType = CommandType.Text; + private string commandText; + private IDbParameters parameters; + + public ExecuteScalarCallbackWithParameters(CommandType cmdType, string cmdText, IDbParameters dbParameters) + { + commandType = cmdType; + commandText = cmdText; + parameters = dbParameters; + } + + public string CommandText + { + get { return commandText; } + } + + public Object DoInCommand(IDbCommand command) + { + command.CommandType = commandType; + command.CommandText = commandText; + ParameterUtils.CopyParameters(command, parameters); + Object returnValue = command.ExecuteScalar(); + ParameterUtils.CopyParameters(parameters, command); + return returnValue; + } + } + + private class ExecuteScalarCallbackWithCommandSetter : ICommandCallback, ICommandTextProvider + { + private CommandType commandType; + private string commandText; + private ICommandSetter commandSetter; + + public ExecuteScalarCallbackWithCommandSetter(CommandType commandType, string commandText, ICommandSetter commandSetter) + { + this.commandType = commandType; + this.commandText = commandText; + this.commandSetter = commandSetter; + } + + public string CommandText + { + get { return commandText; } + } + + public Object DoInCommand(IDbCommand command) + { + command.CommandType = commandType; + command.CommandText = commandText; + if (commandSetter != null) + { + commandSetter.SetValues(command); + } + Object returnValue = command.ExecuteScalar(); + if (LOG.IsDebugEnabled) + { + LOG.Debug("ExecuteScalar return value = " + returnValue); + } + return returnValue; + } + + } + + + private class ExecuteCommandCallbackUsingDelegate : ICommandCallback, ICommandTextProvider + { + private CommandDelegate del; + private string commandText; + + public ExecuteCommandCallbackUsingDelegate(CommandDelegate d) + { + del = d; + } + + public string CommandText + { + get { return commandText; } + } + + public Object DoInCommand(IDbCommand command) + { + try + { + return del(command); + } + catch (Exception e) + { + e.GetType(); + commandText = command.CommandText; + throw; + } + } + } + + + + private class QueryCallbackWithCommandSetter : ICommandCallback, ICommandTextProvider + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private ResultSetExtractorDelegate resultSetExtractorDelegate; + private ICommandSetter commandSetter; + private CommandType commandType; + private string commandText; + + public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, IResultSetExtractor rse, ICommandSetter commandSetter) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.rse = rse; + this.commandSetter = commandSetter; + } + + public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, ICommandSetter commandSetter) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.resultSetExtractorDelegate = resultSetExtractorDelegate; + this.commandSetter = commandSetter; + } + + public string CommandText + { + get { return commandText; } + } + + public object DoInCommand(IDbCommand command) + { + IDataReader reader = null; + try + { + command.CommandType = commandType; + command.CommandText = commandText; + if (commandSetter != null) + { + commandSetter.SetValues(command); + } + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + if (rse != null) + { + return rse.ExtractData(reader); + } + else + { + return resultSetExtractorDelegate(reader); + } + } + finally + { + AdoUtils.CloseReader(reader); + } + } + + } + + private class QueryCallback : ICommandCallback, ICommandTextProvider + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private ResultSetExtractorDelegate resultSetExtractorDelegate; + private CommandType commandType; + private string commandText; + private IDbParameters parameters; + + public QueryCallback(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, IResultSetExtractor rse, IDbParameters dbParameters) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.rse = rse; + parameters = dbParameters; + } + + public QueryCallback(AdoTemplate adoTemplate, CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, IDbParameters dbParameters) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.resultSetExtractorDelegate = resultSetExtractorDelegate; + parameters = dbParameters; + } + + + public string CommandText + { + get { return commandText; } + } + + public object DoInCommand(IDbCommand command) + { + IDataReader reader = null; + try + { + command.CommandType = commandType; + command.CommandText = commandText; + ParameterUtils.CopyParameters(command, parameters); + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + object returnValue; + if (rse != null) + { + returnValue = rse.ExtractData(reader); + } + else + { + returnValue = resultSetExtractorDelegate(reader); + } + return returnValue; + } + finally + { + AdoUtils.CloseReader(reader); + ParameterUtils.CopyParameters(parameters, command); + } + } + } + + #endregion + + /// + /// Creates the data reader wrapper for use in AdoTemplate callback methods. + /// + /// The reader to wrap. + /// The data reader used in AdoTemplate callbacks + public override IDataReader CreateDataReaderWrapper(IDataReader readerToWrap) + { + if (dataReaderWrapperType != null && newDataReaderWrapper != null) + { + IDataReaderWrapper wrapper = (IDataReaderWrapper) newDataReaderWrapper.Invoke(ObjectUtils.EmptyObjects); + wrapper.WrappedReader = readerToWrap; + return wrapper; + } + else + { + return readerToWrap; + } + } + } + } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Core/RowMapperResultSetExtractor.cs b/src/Spring/Spring.Data/Data/Core/RowMapperResultSetExtractor.cs index 67195813..a4dcb96d 100644 --- a/src/Spring/Spring.Data/Data/Core/RowMapperResultSetExtractor.cs +++ b/src/Spring/Spring.Data/Data/Core/RowMapperResultSetExtractor.cs @@ -1,137 +1,136 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using Spring.Collections; -using Spring.Data.Support; - -#endregion - -namespace Spring.Data.Core -{ - /// - /// Adapter implementation of the ResultSetExtractor interface that delegates - /// to a RowMapper which is supposed to create an object for each row. - /// Each object is added to the results List of this ResultSetExtractor. - /// - /// - /// Useful for the typical case of one object per row in the database table. - /// The number of entries in the results list will match the number of rows. - ///

- /// Note that a RowMapper object is typically stateless and thus reusable; - /// just the RowMapperResultSetExtractor adapter is stateful. - ///

- ///

- /// As an alternative consider subclassing MappingAdoQuery from the - /// Spring.Data.Objects namespace: Instead of working with separate - /// AdoTemplate and IRowMapper objects you can have executable - /// query objects (containing row-mapping logic) there. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: RowMapperResultSetExtractor.cs,v 1.1 2007/08/03 19:51:11 markpollack Exp $ - public class RowMapperResultSetExtractor : IResultSetExtractor - { - #region Fields - - private IRowMapper rowMapper; - - private RowMapperDelegate rowMapperDelegate; - - private int rowsExpected; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public RowMapperResultSetExtractor(IRowMapper rowMapper) : this(rowMapper,0, null) - { - } - - public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected) : this(rowMapper, rowsExpected, null) - { - } - public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected, IDataReaderWrapper dataReaderWrapper) - { - //TODO use datareaderwrapper - if (rowMapper == null) - { - throw new ArgumentNullException("rowMapper"); - } - this.rowMapper = rowMapper; - this.rowsExpected = rowsExpected; - } - - public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate) - : this(rowMapperDelegate, 0, null) - { - } - - public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected) - : this(rowMapperDelegate, rowsExpected, null) - { - } - public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected, IDataReaderWrapper dataReaderWrapper) - { - //TODO use datareaderwrapper - if (rowMapperDelegate == null) - { - throw new ArgumentNullException("rowMapperDelegate"); - } - this.rowMapperDelegate = rowMapperDelegate; - this.rowsExpected = rowsExpected; - } - - #endregion - - #region IResultSetExtractor Members - - public object ExtractData(System.Data.IDataReader reader) - { - // Use the more efficient collection if we know how many rows to expect: - // ArrayList in case of a known row count, LinkedList if unknown - IList results = (rowsExpected > 0) ? (IList) new ArrayList(rowsExpected) : new LinkedList(); - int rowNum = 0; - if (rowMapper != null) - { - while (reader.Read()) - { - results.Add(rowMapper.MapRow(reader, rowNum++)); - } - } - else - { - while (reader.Read()) - { - results.Add(rowMapperDelegate(reader, rowNum++)); - } - } - - return results; - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using Spring.Collections; +using Spring.Data.Support; + +#endregion + +namespace Spring.Data.Core +{ + /// + /// Adapter implementation of the ResultSetExtractor interface that delegates + /// to a RowMapper which is supposed to create an object for each row. + /// Each object is added to the results List of this ResultSetExtractor. + /// + /// + /// Useful for the typical case of one object per row in the database table. + /// The number of entries in the results list will match the number of rows. + ///

+ /// Note that a RowMapper object is typically stateless and thus reusable; + /// just the RowMapperResultSetExtractor adapter is stateful. + ///

+ ///

+ /// As an alternative consider subclassing MappingAdoQuery from the + /// Spring.Data.Objects namespace: Instead of working with separate + /// AdoTemplate and IRowMapper objects you can have executable + /// query objects (containing row-mapping logic) there. + ///

+ ///
+ /// Mark Pollack (.NET) + public class RowMapperResultSetExtractor : IResultSetExtractor + { + #region Fields + + private IRowMapper rowMapper; + + private RowMapperDelegate rowMapperDelegate; + + private int rowsExpected; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public RowMapperResultSetExtractor(IRowMapper rowMapper) : this(rowMapper,0, null) + { + } + + public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected) : this(rowMapper, rowsExpected, null) + { + } + public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected, IDataReaderWrapper dataReaderWrapper) + { + //TODO use datareaderwrapper + if (rowMapper == null) + { + throw new ArgumentNullException("rowMapper"); + } + this.rowMapper = rowMapper; + this.rowsExpected = rowsExpected; + } + + public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate) + : this(rowMapperDelegate, 0, null) + { + } + + public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected) + : this(rowMapperDelegate, rowsExpected, null) + { + } + public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected, IDataReaderWrapper dataReaderWrapper) + { + //TODO use datareaderwrapper + if (rowMapperDelegate == null) + { + throw new ArgumentNullException("rowMapperDelegate"); + } + this.rowMapperDelegate = rowMapperDelegate; + this.rowsExpected = rowsExpected; + } + + #endregion + + #region IResultSetExtractor Members + + public object ExtractData(System.Data.IDataReader reader) + { + // Use the more efficient collection if we know how many rows to expect: + // ArrayList in case of a known row count, LinkedList if unknown + IList results = (rowsExpected > 0) ? (IList) new ArrayList(rowsExpected) : new LinkedList(); + int rowNum = 0; + if (rowMapper != null) + { + while (reader.Read()) + { + results.Add(rowMapper.MapRow(reader, rowNum++)); + } + } + else + { + while (reader.Read()) + { + results.Add(rowMapperDelegate(reader, rowNum++)); + } + } + + return results; + } + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Data/Core/ServiceDomainPlatformTransactionManager.cs b/src/Spring/Spring.Data/Data/Core/ServiceDomainPlatformTransactionManager.cs index 532afacb..c3f9109a 100644 --- a/src/Spring/Spring.Data/Data/Core/ServiceDomainPlatformTransactionManager.cs +++ b/src/Spring/Spring.Data/Data/Core/ServiceDomainPlatformTransactionManager.cs @@ -1,402 +1,401 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -#region Imports - -using System; -using System.EnterpriseServices; -using System.Threading; -using Spring.Data.Support; -using Spring.Objects.Factory; -using Spring.Transaction; -using Spring.Transaction.Support; - -#endregion - -namespace Spring.Data.Core -{ - /// - /// Transaction Manager that uses EnterpriseServices to access the - /// MS-DTC. It requires the support of 'Services without Components' - /// functionality which is available on Win 2003 and Win XP SP2. - /// - /// Mark Pollack (.NET) - /// $Id: ServiceDomainPlatformTransactionManager.cs,v 1.6 2007/12/04 19:43:16 markpollack Exp $ - public class ServiceDomainPlatformTransactionManager : AbstractPlatformTransactionManager, IInitializingObject - { - private IServiceDomainAdapter txAdapter; - - private bool trackingEnabled = true; - private string trackingAppName = "Spring.NET"; - private string trackingComponentName = "ServiceDomainPlatformTransactionManager"; - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public ServiceDomainPlatformTransactionManager() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// This is indented only for unit testing purposes and should not be - /// called by production application code. - /// The tx adapter. - public ServiceDomainPlatformTransactionManager(IServiceDomainAdapter txAdapter) - { - this.txAdapter = txAdapter; - } - - #endregion - - - /// - /// Gets or sets a value indicating whether tracking is enabled. - /// - /// true if tracking is enabled; otherwise, false. - public bool TrackingEnabled - { - get { return trackingEnabled; } - set { trackingEnabled = value; } - } - - /// - /// Gets or sets a text string that corresponds to the application ID under which tracker information is reported. - /// The default value is 'Spring.NET' - /// - /// The name of the tracking app. - public string TrackingAppName - { - get { return trackingAppName; } - set { trackingAppName = value; } - } - - /// - /// Gets or sets a text string that corresponds to the context name under which tracker information is reported. - /// - /// The name of the tracking component. - public string TrackingComponentName - { - get { return trackingComponentName; } - set { trackingComponentName = value; } - } - - public void AfterPropertiesSet() - { - //TODO decide what should be validated for advanced configurations. - } - - protected override object DoGetTransaction() - { - ServiceDomainTransactionObject txObject = new ServiceDomainTransactionObject(); - if (txAdapter != null) - { - txObject.ServiceDomainAdapter = txAdapter; - } - return txObject; - } - - - - protected override bool IsExistingTransaction(object transaction) - { - ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)transaction; - if (txObject.ServiceDomainAdapter.IsInTransaction) - { - return true; - } - else - { - return false; - } - } - - protected override void DoBegin(object transaction, ITransactionDefinition definition) - { - try - { - ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)transaction; - - DoServiceDomainBegin(txObject, definition); - } - catch (PlatformNotSupportedException ex) - { - throw new TransactionSystemException("ServiceDomain failure on begin of transaction. Platform does not support EnterpriseServices 'Services without Components'", ex); - } - catch (Exception e) - { - throw new CannotCreateTransactionException("ServiceDomain failure on begin of transaction", e); - } - } - - private void DoServiceDomainBegin(ServiceDomainTransactionObject serviceDomainTxObject, ITransactionDefinition definition) - { - SimpleServiceConfig serviceConfig = CreateServiceConfig(definition); - //The context is created when we call Enter. - serviceDomainTxObject.ServiceDomainAdapter.Enter(serviceConfig); - if (log.IsDebugEnabled) - { - log.Debug("Context created. TransactionId = " + ContextUtil.TransactionId - + ", ActivityId = " + ContextUtil.ActivityId); - } - } - - protected override object DoSuspend(object transaction) - { - // Passing the current transaction object, literally an 'object' as the 'suspended resource', - // even though it is not used just to avoid passing null - // ServiceDomainPlatformTransactionManager is not binding any resources to the local thread, instead delegating to - // System.EnterpriseServices to handle thread local resources. - return transaction; - } - - protected override void DoResume(object transaction, object suspendedResources) - { - } - - private SimpleServiceConfig CreateServiceConfig(ITransactionDefinition definition) - { - SimpleServiceConfig serviceConfig = new SimpleServiceConfig(); - - //TODO investigate BringYourOwnTransaction and TipUrl properties of ServiceConfig - serviceConfig.TransactionDescription = definition.Name; - - serviceConfig.TrackingEnabled = TrackingEnabled; - serviceConfig.TrackingAppName = TrackingAppName; - serviceConfig.TrackingComponentName = TrackingComponentName; - - ApplyPropagationBehavior(serviceConfig, definition); - - ApplyIsolationLevel(serviceConfig, definition); - - // infinite==-1 would cause transactions to be aborted immediately! - if(definition.TransactionTimeout != Timeout.Infinite) - { - serviceConfig.TransactionTimeout = definition.TransactionTimeout; - } - return serviceConfig; - } - - protected void ApplyIsolationLevel(SimpleServiceConfig serviceConfig, ITransactionDefinition definition) - { - switch (definition.TransactionIsolationLevel) - { - - case System.Data.IsolationLevel.Chaos: - if (log.IsInfoEnabled) - { - log.Info("IsolationLevel Chaos does not have a direct counterpart in EnterpriseServices, using Any"); - } - serviceConfig.IsolationLevel = TransactionIsolationLevel.Any; - break; - case System.Data.IsolationLevel.ReadCommitted: - serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted; - break; - case System.Data.IsolationLevel.ReadUncommitted: - serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadUncommitted; - break; - case System.Data.IsolationLevel.RepeatableRead: - serviceConfig.IsolationLevel = TransactionIsolationLevel.RepeatableRead; - break; - case System.Data.IsolationLevel.Serializable: - serviceConfig.IsolationLevel = TransactionIsolationLevel.Serializable; - break; -#if NET_2_0 - case System.Data.IsolationLevel.Snapshot: - if (log.IsInfoEnabled) - { - log.Info("IsolationLevel Snapshot does not have a direct counterpart in EnterpriseServices, using ReadCommitted. Introduced in SqlServer 2005. Consider using System.Transactions for transaction management instead."); - } - serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted; //err on the side of consistency - break; -#endif - case System.Data.IsolationLevel.Unspecified: - serviceConfig.IsolationLevel = TransactionIsolationLevel.Any; - break; - } - - } - - protected void ApplyPropagationBehavior(SimpleServiceConfig serviceConfig, ITransactionDefinition definition) - { - if (definition.PropagationBehavior == TransactionPropagation.Required) - { - serviceConfig.TransactionOption = TransactionOption.Required; - } - else if (definition.PropagationBehavior == TransactionPropagation.RequiresNew) - { - serviceConfig.TransactionOption = TransactionOption.RequiresNew; - } - else if (definition.PropagationBehavior == TransactionPropagation.Supports) - { - serviceConfig.TransactionOption = TransactionOption.Supported; - } - else if (definition.PropagationBehavior == TransactionPropagation.NotSupported) - { - serviceConfig.TransactionOption = TransactionOption.NotSupported; - } - else if (definition.PropagationBehavior == TransactionPropagation.Never) - { - //TODO check the validity of this mapping - serviceConfig.TransactionOption = TransactionOption.Disabled; - } else - { - //TODO Should we throw an exception instead? - log.Warn("The requested transaction propagation option " + - definition.PropagationBehavior + " is not supported. " + - "Defaulting to Never(Disabled) "); - } - } - - - - - protected override void DoCommit(DefaultTransactionStatus status) - { - ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject) status.Transaction; - bool globalRollbackOnly = status.GlobalRollbackOnly; - try - { - if (txObject.ServiceDomainAdapter.IsInTransaction) - { - - if (txObject.ServiceDomainAdapter.MyTransactionVote == TransactionVote.Commit) - { - txObject.ServiceDomainAdapter.SetComplete(); - } - else - { - txObject.ServiceDomainAdapter.SetAbort(); - } - } - TransactionStatus serviceDomainTxstatus = txObject.ServiceDomainAdapter.Leave(); - if (log.IsDebugEnabled) - { - log.Debug("ServiceDomain Transaction Status upon leaving ServiceDomain = " + serviceDomainTxstatus); - } - txObject.TransactionStatus = serviceDomainTxstatus; - if (!globalRollbackOnly && serviceDomainTxstatus == TransactionStatus.Aborted) - { - throw new UnexpectedRollbackException("Transaction unexpectedly rolled-back (maybe due to a timeout)"); - } - } - catch (PlatformNotSupportedException ex) - { - throw new TransactionSystemException("Failure on Commit. Platform does not support EnterpriseServices 'Services without Components'", ex); - } - catch (Exception e) - { - throw new TransactionSystemException("Failure upon Leaving ServiceDomain (for Commit)", e); - } - - } - - protected override void DoRollback(DefaultTransactionStatus status) - { - ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)status.Transaction; - if (txObject.ServiceDomainAdapter.IsInTransaction) - { - try - { - txObject.ServiceDomainAdapter.SetAbort(); - txObject.ServiceDomainAdapter.Leave(); - } - catch (PlatformNotSupportedException ex) - { - throw new TransactionSystemException("Failure on Rollback. Platform does not support EnterpriseServices 'Services without Components'", ex); - } - catch (Exception e) - { - throw new Spring.Transaction.TransactionSystemException("Failure upon Leaving ServiceDomain (for Rollback)", e); - } - } - } - - protected override void DoSetRollbackOnly(DefaultTransactionStatus status) - { - ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)status.Transaction; - if (status.Debug) - { - log.Debug("Setting transaction rollback-only"); - } - try - { - txObject.ServiceDomainAdapter.MyTransactionVote = TransactionVote.Abort; - } - catch (Exception ex) - { - throw new TransactionSystemException("Failure on System.Transactions.Transaction.Current.Rollback", ex); - } - - } - - protected override bool ShouldCommitOnGlobalRollbackOnly - { - get { return true; } - } - - - public class ServiceDomainTransactionObject : ISmartTransactionObject - { - private TransactionStatus transactionStatus; - private IServiceDomainAdapter serviceDomainAdapter; - - - public ServiceDomainTransactionObject() - { - serviceDomainAdapter = new DefaultServiceDomainAdapter(); - } - - public IServiceDomainAdapter ServiceDomainAdapter - { - get { return serviceDomainAdapter; } - set { serviceDomainAdapter = value; } - } - - public TransactionStatus TransactionStatus - { - get { return transactionStatus; } - set { transactionStatus = value; } - } - - public bool RollbackOnly - { - get - { - if ( serviceDomainAdapter.MyTransactionVote == TransactionVote.Abort) - { - return true; - } - else - { - return false; - } - } - } - } - } -} - -#endif // (!NET_1_0) +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +#region Imports + +using System; +using System.EnterpriseServices; +using System.Threading; +using Spring.Data.Support; +using Spring.Objects.Factory; +using Spring.Transaction; +using Spring.Transaction.Support; + +#endregion + +namespace Spring.Data.Core +{ + /// + /// Transaction Manager that uses EnterpriseServices to access the + /// MS-DTC. It requires the support of 'Services without Components' + /// functionality which is available on Win 2003 and Win XP SP2. + /// + /// Mark Pollack (.NET) + public class ServiceDomainPlatformTransactionManager : AbstractPlatformTransactionManager, IInitializingObject + { + private IServiceDomainAdapter txAdapter; + + private bool trackingEnabled = true; + private string trackingAppName = "Spring.NET"; + private string trackingComponentName = "ServiceDomainPlatformTransactionManager"; + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public ServiceDomainPlatformTransactionManager() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// This is indented only for unit testing purposes and should not be + /// called by production application code. + /// The tx adapter. + public ServiceDomainPlatformTransactionManager(IServiceDomainAdapter txAdapter) + { + this.txAdapter = txAdapter; + } + + #endregion + + + /// + /// Gets or sets a value indicating whether tracking is enabled. + /// + /// true if tracking is enabled; otherwise, false. + public bool TrackingEnabled + { + get { return trackingEnabled; } + set { trackingEnabled = value; } + } + + /// + /// Gets or sets a text string that corresponds to the application ID under which tracker information is reported. + /// The default value is 'Spring.NET' + /// + /// The name of the tracking app. + public string TrackingAppName + { + get { return trackingAppName; } + set { trackingAppName = value; } + } + + /// + /// Gets or sets a text string that corresponds to the context name under which tracker information is reported. + /// + /// The name of the tracking component. + public string TrackingComponentName + { + get { return trackingComponentName; } + set { trackingComponentName = value; } + } + + public void AfterPropertiesSet() + { + //TODO decide what should be validated for advanced configurations. + } + + protected override object DoGetTransaction() + { + ServiceDomainTransactionObject txObject = new ServiceDomainTransactionObject(); + if (txAdapter != null) + { + txObject.ServiceDomainAdapter = txAdapter; + } + return txObject; + } + + + + protected override bool IsExistingTransaction(object transaction) + { + ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)transaction; + if (txObject.ServiceDomainAdapter.IsInTransaction) + { + return true; + } + else + { + return false; + } + } + + protected override void DoBegin(object transaction, ITransactionDefinition definition) + { + try + { + ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)transaction; + + DoServiceDomainBegin(txObject, definition); + } + catch (PlatformNotSupportedException ex) + { + throw new TransactionSystemException("ServiceDomain failure on begin of transaction. Platform does not support EnterpriseServices 'Services without Components'", ex); + } + catch (Exception e) + { + throw new CannotCreateTransactionException("ServiceDomain failure on begin of transaction", e); + } + } + + private void DoServiceDomainBegin(ServiceDomainTransactionObject serviceDomainTxObject, ITransactionDefinition definition) + { + SimpleServiceConfig serviceConfig = CreateServiceConfig(definition); + //The context is created when we call Enter. + serviceDomainTxObject.ServiceDomainAdapter.Enter(serviceConfig); + if (log.IsDebugEnabled) + { + log.Debug("Context created. TransactionId = " + ContextUtil.TransactionId + + ", ActivityId = " + ContextUtil.ActivityId); + } + } + + protected override object DoSuspend(object transaction) + { + // Passing the current transaction object, literally an 'object' as the 'suspended resource', + // even though it is not used just to avoid passing null + // ServiceDomainPlatformTransactionManager is not binding any resources to the local thread, instead delegating to + // System.EnterpriseServices to handle thread local resources. + return transaction; + } + + protected override void DoResume(object transaction, object suspendedResources) + { + } + + private SimpleServiceConfig CreateServiceConfig(ITransactionDefinition definition) + { + SimpleServiceConfig serviceConfig = new SimpleServiceConfig(); + + //TODO investigate BringYourOwnTransaction and TipUrl properties of ServiceConfig + serviceConfig.TransactionDescription = definition.Name; + + serviceConfig.TrackingEnabled = TrackingEnabled; + serviceConfig.TrackingAppName = TrackingAppName; + serviceConfig.TrackingComponentName = TrackingComponentName; + + ApplyPropagationBehavior(serviceConfig, definition); + + ApplyIsolationLevel(serviceConfig, definition); + + // infinite==-1 would cause transactions to be aborted immediately! + if(definition.TransactionTimeout != Timeout.Infinite) + { + serviceConfig.TransactionTimeout = definition.TransactionTimeout; + } + return serviceConfig; + } + + protected void ApplyIsolationLevel(SimpleServiceConfig serviceConfig, ITransactionDefinition definition) + { + switch (definition.TransactionIsolationLevel) + { + + case System.Data.IsolationLevel.Chaos: + if (log.IsInfoEnabled) + { + log.Info("IsolationLevel Chaos does not have a direct counterpart in EnterpriseServices, using Any"); + } + serviceConfig.IsolationLevel = TransactionIsolationLevel.Any; + break; + case System.Data.IsolationLevel.ReadCommitted: + serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted; + break; + case System.Data.IsolationLevel.ReadUncommitted: + serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadUncommitted; + break; + case System.Data.IsolationLevel.RepeatableRead: + serviceConfig.IsolationLevel = TransactionIsolationLevel.RepeatableRead; + break; + case System.Data.IsolationLevel.Serializable: + serviceConfig.IsolationLevel = TransactionIsolationLevel.Serializable; + break; +#if NET_2_0 + case System.Data.IsolationLevel.Snapshot: + if (log.IsInfoEnabled) + { + log.Info("IsolationLevel Snapshot does not have a direct counterpart in EnterpriseServices, using ReadCommitted. Introduced in SqlServer 2005. Consider using System.Transactions for transaction management instead."); + } + serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted; //err on the side of consistency + break; +#endif + case System.Data.IsolationLevel.Unspecified: + serviceConfig.IsolationLevel = TransactionIsolationLevel.Any; + break; + } + + } + + protected void ApplyPropagationBehavior(SimpleServiceConfig serviceConfig, ITransactionDefinition definition) + { + if (definition.PropagationBehavior == TransactionPropagation.Required) + { + serviceConfig.TransactionOption = TransactionOption.Required; + } + else if (definition.PropagationBehavior == TransactionPropagation.RequiresNew) + { + serviceConfig.TransactionOption = TransactionOption.RequiresNew; + } + else if (definition.PropagationBehavior == TransactionPropagation.Supports) + { + serviceConfig.TransactionOption = TransactionOption.Supported; + } + else if (definition.PropagationBehavior == TransactionPropagation.NotSupported) + { + serviceConfig.TransactionOption = TransactionOption.NotSupported; + } + else if (definition.PropagationBehavior == TransactionPropagation.Never) + { + //TODO check the validity of this mapping + serviceConfig.TransactionOption = TransactionOption.Disabled; + } else + { + //TODO Should we throw an exception instead? + log.Warn("The requested transaction propagation option " + + definition.PropagationBehavior + " is not supported. " + + "Defaulting to Never(Disabled) "); + } + } + + + + + protected override void DoCommit(DefaultTransactionStatus status) + { + ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject) status.Transaction; + bool globalRollbackOnly = status.GlobalRollbackOnly; + try + { + if (txObject.ServiceDomainAdapter.IsInTransaction) + { + + if (txObject.ServiceDomainAdapter.MyTransactionVote == TransactionVote.Commit) + { + txObject.ServiceDomainAdapter.SetComplete(); + } + else + { + txObject.ServiceDomainAdapter.SetAbort(); + } + } + TransactionStatus serviceDomainTxstatus = txObject.ServiceDomainAdapter.Leave(); + if (log.IsDebugEnabled) + { + log.Debug("ServiceDomain Transaction Status upon leaving ServiceDomain = " + serviceDomainTxstatus); + } + txObject.TransactionStatus = serviceDomainTxstatus; + if (!globalRollbackOnly && serviceDomainTxstatus == TransactionStatus.Aborted) + { + throw new UnexpectedRollbackException("Transaction unexpectedly rolled-back (maybe due to a timeout)"); + } + } + catch (PlatformNotSupportedException ex) + { + throw new TransactionSystemException("Failure on Commit. Platform does not support EnterpriseServices 'Services without Components'", ex); + } + catch (Exception e) + { + throw new TransactionSystemException("Failure upon Leaving ServiceDomain (for Commit)", e); + } + + } + + protected override void DoRollback(DefaultTransactionStatus status) + { + ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)status.Transaction; + if (txObject.ServiceDomainAdapter.IsInTransaction) + { + try + { + txObject.ServiceDomainAdapter.SetAbort(); + txObject.ServiceDomainAdapter.Leave(); + } + catch (PlatformNotSupportedException ex) + { + throw new TransactionSystemException("Failure on Rollback. Platform does not support EnterpriseServices 'Services without Components'", ex); + } + catch (Exception e) + { + throw new Spring.Transaction.TransactionSystemException("Failure upon Leaving ServiceDomain (for Rollback)", e); + } + } + } + + protected override void DoSetRollbackOnly(DefaultTransactionStatus status) + { + ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)status.Transaction; + if (status.Debug) + { + log.Debug("Setting transaction rollback-only"); + } + try + { + txObject.ServiceDomainAdapter.MyTransactionVote = TransactionVote.Abort; + } + catch (Exception ex) + { + throw new TransactionSystemException("Failure on System.Transactions.Transaction.Current.Rollback", ex); + } + + } + + protected override bool ShouldCommitOnGlobalRollbackOnly + { + get { return true; } + } + + + public class ServiceDomainTransactionObject : ISmartTransactionObject + { + private TransactionStatus transactionStatus; + private IServiceDomainAdapter serviceDomainAdapter; + + + public ServiceDomainTransactionObject() + { + serviceDomainAdapter = new DefaultServiceDomainAdapter(); + } + + public IServiceDomainAdapter ServiceDomainAdapter + { + get { return serviceDomainAdapter; } + set { serviceDomainAdapter = value; } + } + + public TransactionStatus TransactionStatus + { + get { return transactionStatus; } + set { transactionStatus = value; } + } + + public bool RollbackOnly + { + get + { + if ( serviceDomainAdapter.MyTransactionVote == TransactionVote.Abort) + { + return true; + } + else + { + return false; + } + } + } + } + } +} + +#endif // (!NET_1_0) diff --git a/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs b/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs index 342cb01f..ec7c2003 100644 --- a/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs +++ b/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs @@ -1,284 +1,283 @@ -#if NET_2_0 - -#region License - -/* - * Copyright 2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Transactions; -using Spring.Data.Support; -using Spring.Objects.Factory; -using Spring.Transaction; -using Spring.Transaction.Support; - -namespace Spring.Data.Core -{ - /// - /// TransactionManager that uses TransactionScope provided by System.Transactions. - /// - /// Mark Pollack (.NET) - /// $Id: TxScopeTransactionManager.cs,v 1.5 2007/12/04 19:43:16 markpollack Exp $ - public class TxScopeTransactionManager : AbstractPlatformTransactionManager, IInitializingObject - { - private ITransactionScopeAdapter txAdapter; - - /// - /// Initializes a new instance of the class. - /// - public TxScopeTransactionManager() - { - - } - /// - /// Initializes a new instance of the class. - /// - /// This is indented only for unit testing purposes and should not be - /// called by production application code. - /// The tx adapter. - public TxScopeTransactionManager(ITransactionScopeAdapter txAdapter) - { - this.txAdapter = txAdapter; - } - - #region IInitializingObject Members - - /// - /// No-op initialization - /// - public void AfterPropertiesSet() - { - // placeholder for more advanced configurations. - } - - #endregion - - protected override object DoGetTransaction() - { - PromotableTxScopeTransactionObject txObject = new PromotableTxScopeTransactionObject(); - - if (txAdapter != null) - { - txObject.TxScopeAdapter = txAdapter; - } - return txObject; - } - - protected override bool IsExistingTransaction(object transaction) - { - PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)transaction; - return txObject.TxScopeAdapter.IsExistingTransaction; - } - - protected override void DoBegin(object transaction, Spring.Transaction.ITransactionDefinition definition) - { - PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)transaction; - try - { - DoTxScopeBegin(txObject, definition); - } - catch (Exception e) - { - throw new CannotCreateTransactionException("Transaction Scope failure on begin", e); - } - } - - protected override object DoSuspend(object transaction) - { - // Passing the current TxScopeAdapter as the 'suspended resource', even though it is not used just to avoid passing null - // TxScopeTransactionManager is not binding any resources to the local thread, instead delegating to - // System.Transactions to handle thread local resources. - PromotableTxScopeTransactionObject txMgrStateObject = (PromotableTxScopeTransactionObject) transaction; - return txMgrStateObject.TxScopeAdapter; - } - - protected override void DoResume(object transaction, object suspendedResources) - { - } - - protected override void DoCommit(DefaultTransactionStatus status) - { - PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)status.Transaction; - try - { - txObject.TxScopeAdapter.Complete(); - txObject.TxScopeAdapter.Dispose(); - } - catch (TransactionAbortedException ex) - { - throw new UnexpectedRollbackException("Transaction unexpectedly rolled back (maybe due to a timeout)", ex); - } - catch (TransactionInDoubtException ex) - { - throw new HeuristicCompletionException(TransactionOutcomeState.Unknown, ex); - } - catch (Exception ex) - { - throw new TransactionSystemException("Failure on Transaction Scope Commit", ex); - } - } - - protected override void DoRollback(DefaultTransactionStatus status) - { - PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)status.Transaction; - - try - { - - txObject.TxScopeAdapter.Dispose(); - } - catch (Exception e) - { - throw new Spring.Transaction.TransactionSystemException("Failure on Transaction Scope rollback.", e); - } - } - - - protected override void DoSetRollbackOnly(DefaultTransactionStatus status) - { - if (status.Debug) - { - log.Debug("Setting transaction rollback-only"); - } - try - { - System.Transactions.Transaction.Current.Rollback(); - } catch (Exception ex) - { - throw new TransactionSystemException("Failure on System.Transactions.Transaction.Current.Rollback", ex); - } - } - - protected override bool ShouldCommitOnGlobalRollbackOnly - { - get { return true; } - } - - private void DoTxScopeBegin(PromotableTxScopeTransactionObject txObject, - Spring.Transaction.ITransactionDefinition definition) - { - - TransactionScopeOption txScopeOption = CreateTransactionScopeOptions(definition); - TransactionOptions txOptions = CreateTransactionOptions(definition); - txObject.TxScopeAdapter.CreateTransactionScope(txScopeOption, txOptions, definition.EnterpriseServicesInteropOption); - - } - - private static TransactionOptions CreateTransactionOptions(ITransactionDefinition definition) - { - TransactionOptions txOptions = new TransactionOptions(); - switch (definition.TransactionIsolationLevel ) - { - case System.Data.IsolationLevel.Chaos: - txOptions.IsolationLevel = IsolationLevel.Chaos; - break; - case System.Data.IsolationLevel.ReadCommitted: - txOptions.IsolationLevel = IsolationLevel.ReadCommitted; - break; - case System.Data.IsolationLevel.ReadUncommitted: - txOptions.IsolationLevel = IsolationLevel.ReadUncommitted; - break; - case System.Data.IsolationLevel.RepeatableRead: - txOptions.IsolationLevel = IsolationLevel.RepeatableRead; - break; - case System.Data.IsolationLevel.Serializable: - txOptions.IsolationLevel = IsolationLevel.Serializable; - break; - case System.Data.IsolationLevel.Snapshot: - txOptions.IsolationLevel = IsolationLevel.Snapshot; - break; - case System.Data.IsolationLevel.Unspecified: - txOptions.IsolationLevel = IsolationLevel.Unspecified; - break; - } - - if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - txOptions.Timeout = new TimeSpan(0, 0, definition.TransactionTimeout); - } - return txOptions; - } - - private static TransactionScopeOption CreateTransactionScopeOptions(ITransactionDefinition definition) - { - TransactionScopeOption txScopeOption; - if (definition.PropagationBehavior == TransactionPropagation.Required) - { - txScopeOption = TransactionScopeOption.Required; - } - else if (definition.PropagationBehavior == TransactionPropagation.RequiresNew) - { - txScopeOption = TransactionScopeOption.RequiresNew; - } - else - { - throw new Spring.Transaction.TransactionSystemException("Transaction Propagation Behavior" + - definition.PropagationBehavior + - " not supported by TransactionScope. Use Required or RequiredNew"); - } - return txScopeOption; - } - - /// - /// The transaction resource object that encapsulates the state and functionality - /// contained in TransactionScope and Transaction.Current via the ITransactionScopeAdapter - /// property. - /// - public class PromotableTxScopeTransactionObject : ISmartTransactionObject - { - private ITransactionScopeAdapter txScopeAdapter; - - /// - /// Initializes a new instance of the class. - /// Will create an instance of . - /// - public PromotableTxScopeTransactionObject() - { - txScopeAdapter = new DefaultTransactionScopeAdapter(); - } - - /// - /// Gets or sets the transaction scope adapter. - /// - /// The transaction scope adapter. - public ITransactionScopeAdapter TxScopeAdapter - { - get { return txScopeAdapter; } - set { txScopeAdapter = value; } - } - - - /// - /// Return whether the transaction is internally marked as rollback-only. - /// - /// - /// True of the transaction is marked as rollback-only. - public bool RollbackOnly - { - get { - return txScopeAdapter.RollbackOnly; - } - } - } - } -} +#if NET_2_0 + +#region License + +/* + * Copyright 2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Transactions; +using Spring.Data.Support; +using Spring.Objects.Factory; +using Spring.Transaction; +using Spring.Transaction.Support; + +namespace Spring.Data.Core +{ + /// + /// TransactionManager that uses TransactionScope provided by System.Transactions. + /// + /// Mark Pollack (.NET) + public class TxScopeTransactionManager : AbstractPlatformTransactionManager, IInitializingObject + { + private ITransactionScopeAdapter txAdapter; + + /// + /// Initializes a new instance of the class. + /// + public TxScopeTransactionManager() + { + + } + /// + /// Initializes a new instance of the class. + /// + /// This is indented only for unit testing purposes and should not be + /// called by production application code. + /// The tx adapter. + public TxScopeTransactionManager(ITransactionScopeAdapter txAdapter) + { + this.txAdapter = txAdapter; + } + + #region IInitializingObject Members + + /// + /// No-op initialization + /// + public void AfterPropertiesSet() + { + // placeholder for more advanced configurations. + } + + #endregion + + protected override object DoGetTransaction() + { + PromotableTxScopeTransactionObject txObject = new PromotableTxScopeTransactionObject(); + + if (txAdapter != null) + { + txObject.TxScopeAdapter = txAdapter; + } + return txObject; + } + + protected override bool IsExistingTransaction(object transaction) + { + PromotableTxScopeTransactionObject txObject = + (PromotableTxScopeTransactionObject)transaction; + return txObject.TxScopeAdapter.IsExistingTransaction; + } + + protected override void DoBegin(object transaction, Spring.Transaction.ITransactionDefinition definition) + { + PromotableTxScopeTransactionObject txObject = + (PromotableTxScopeTransactionObject)transaction; + try + { + DoTxScopeBegin(txObject, definition); + } + catch (Exception e) + { + throw new CannotCreateTransactionException("Transaction Scope failure on begin", e); + } + } + + protected override object DoSuspend(object transaction) + { + // Passing the current TxScopeAdapter as the 'suspended resource', even though it is not used just to avoid passing null + // TxScopeTransactionManager is not binding any resources to the local thread, instead delegating to + // System.Transactions to handle thread local resources. + PromotableTxScopeTransactionObject txMgrStateObject = (PromotableTxScopeTransactionObject) transaction; + return txMgrStateObject.TxScopeAdapter; + } + + protected override void DoResume(object transaction, object suspendedResources) + { + } + + protected override void DoCommit(DefaultTransactionStatus status) + { + PromotableTxScopeTransactionObject txObject = + (PromotableTxScopeTransactionObject)status.Transaction; + try + { + txObject.TxScopeAdapter.Complete(); + txObject.TxScopeAdapter.Dispose(); + } + catch (TransactionAbortedException ex) + { + throw new UnexpectedRollbackException("Transaction unexpectedly rolled back (maybe due to a timeout)", ex); + } + catch (TransactionInDoubtException ex) + { + throw new HeuristicCompletionException(TransactionOutcomeState.Unknown, ex); + } + catch (Exception ex) + { + throw new TransactionSystemException("Failure on Transaction Scope Commit", ex); + } + } + + protected override void DoRollback(DefaultTransactionStatus status) + { + PromotableTxScopeTransactionObject txObject = + (PromotableTxScopeTransactionObject)status.Transaction; + + try + { + + txObject.TxScopeAdapter.Dispose(); + } + catch (Exception e) + { + throw new Spring.Transaction.TransactionSystemException("Failure on Transaction Scope rollback.", e); + } + } + + + protected override void DoSetRollbackOnly(DefaultTransactionStatus status) + { + if (status.Debug) + { + log.Debug("Setting transaction rollback-only"); + } + try + { + System.Transactions.Transaction.Current.Rollback(); + } catch (Exception ex) + { + throw new TransactionSystemException("Failure on System.Transactions.Transaction.Current.Rollback", ex); + } + } + + protected override bool ShouldCommitOnGlobalRollbackOnly + { + get { return true; } + } + + private void DoTxScopeBegin(PromotableTxScopeTransactionObject txObject, + Spring.Transaction.ITransactionDefinition definition) + { + + TransactionScopeOption txScopeOption = CreateTransactionScopeOptions(definition); + TransactionOptions txOptions = CreateTransactionOptions(definition); + txObject.TxScopeAdapter.CreateTransactionScope(txScopeOption, txOptions, definition.EnterpriseServicesInteropOption); + + } + + private static TransactionOptions CreateTransactionOptions(ITransactionDefinition definition) + { + TransactionOptions txOptions = new TransactionOptions(); + switch (definition.TransactionIsolationLevel ) + { + case System.Data.IsolationLevel.Chaos: + txOptions.IsolationLevel = IsolationLevel.Chaos; + break; + case System.Data.IsolationLevel.ReadCommitted: + txOptions.IsolationLevel = IsolationLevel.ReadCommitted; + break; + case System.Data.IsolationLevel.ReadUncommitted: + txOptions.IsolationLevel = IsolationLevel.ReadUncommitted; + break; + case System.Data.IsolationLevel.RepeatableRead: + txOptions.IsolationLevel = IsolationLevel.RepeatableRead; + break; + case System.Data.IsolationLevel.Serializable: + txOptions.IsolationLevel = IsolationLevel.Serializable; + break; + case System.Data.IsolationLevel.Snapshot: + txOptions.IsolationLevel = IsolationLevel.Snapshot; + break; + case System.Data.IsolationLevel.Unspecified: + txOptions.IsolationLevel = IsolationLevel.Unspecified; + break; + } + + if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + txOptions.Timeout = new TimeSpan(0, 0, definition.TransactionTimeout); + } + return txOptions; + } + + private static TransactionScopeOption CreateTransactionScopeOptions(ITransactionDefinition definition) + { + TransactionScopeOption txScopeOption; + if (definition.PropagationBehavior == TransactionPropagation.Required) + { + txScopeOption = TransactionScopeOption.Required; + } + else if (definition.PropagationBehavior == TransactionPropagation.RequiresNew) + { + txScopeOption = TransactionScopeOption.RequiresNew; + } + else + { + throw new Spring.Transaction.TransactionSystemException("Transaction Propagation Behavior" + + definition.PropagationBehavior + + " not supported by TransactionScope. Use Required or RequiredNew"); + } + return txScopeOption; + } + + /// + /// The transaction resource object that encapsulates the state and functionality + /// contained in TransactionScope and Transaction.Current via the ITransactionScopeAdapter + /// property. + /// + public class PromotableTxScopeTransactionObject : ISmartTransactionObject + { + private ITransactionScopeAdapter txScopeAdapter; + + /// + /// Initializes a new instance of the class. + /// Will create an instance of . + /// + public PromotableTxScopeTransactionObject() + { + txScopeAdapter = new DefaultTransactionScopeAdapter(); + } + + /// + /// Gets or sets the transaction scope adapter. + /// + /// The transaction scope adapter. + public ITransactionScopeAdapter TxScopeAdapter + { + get { return txScopeAdapter; } + set { txScopeAdapter = value; } + } + + + /// + /// Return whether the transaction is internally marked as rollback-only. + /// + /// + /// True of the transaction is marked as rollback-only. + public bool RollbackOnly + { + get { + return txScopeAdapter.RollbackOnly; + } + } + } + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/AdoDaoSupport.cs b/src/Spring/Spring.Data/Data/Generic/AdoDaoSupport.cs index 99264e21..bdc257cc 100644 --- a/src/Spring/Spring.Data/Data/Generic/AdoDaoSupport.cs +++ b/src/Spring/Spring.Data/Data/Generic/AdoDaoSupport.cs @@ -1,153 +1,153 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System; -using System.Data; -using Spring.Dao.Support; -using Spring.Data.Common; -using Spring.Data.Support; - -#endregion - -namespace Spring.Data.Generic -{ - /// - /// Convenient super class for ADO.NET data access objects using generics. - /// - /// - /// Requires a IDBProvider to be set, providing a - /// AdoTemplate based on it to subclasses. - /// This base class is mainly intended for AdoTemplate usage. - /// - public class AdoDaoSupport : DaoSupport - { - private AdoTemplate adoTemplate; - - /// - /// The DbProvider instance used by this DAO - /// - public IDbProvider DbProvider - { - set - { - adoTemplate = CreateAdoTemplate(value); - } - get - { - if (adoTemplate != null) - { - return adoTemplate.DbProvider; - } - else - { - return null; - } - } - - } - - /// - /// Set the AdoTemplate for this DAO explicity, as - /// an alternative to specifying a IDbProvider - /// - public AdoTemplate AdoTemplate - { - set - { - adoTemplate = value; - } - get - { - return adoTemplate; - } - - } - - protected override void CheckDaoConfig() - { - if (adoTemplate == null) - { - throw new ArgumentException("DbProvider or AdoTemplate is required"); - } - } - - protected IDbConnection Connection - { - get - { - return ConnectionUtils.GetConnection(DbProvider); - } - } - - protected IAdoExceptionTranslator ExceptionTranslator - { - get - { - return null; //Investigate AdoExceptionTranslator on AdoAccessor - } - } - - protected void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) - { - ConnectionUtils.DisposeConnection(conn, dbProvider); - } - - - /// - /// Create a AdoTemplate for a given DbProvider - /// Only invoked if populating the DAO with a DbProvider reference. - /// - /// - /// Can be overriden in subclasses to provide AdoTemplate instances - /// with a different configuration, or a cusotm AdoTemplate subclass. - /// - /// The DbProvider to create a AdoTemplate for - protected virtual AdoTemplate CreateAdoTemplate(IDbProvider dbProvider) - { - return new AdoTemplate(dbProvider); - } - - /// - /// Convenience method to create a parameters builder. - /// - /// Virtual for sublcasses to override with custom - /// implementation. - /// A new DbParameterBuilder - protected virtual IDbParametersBuilder CreateDbParametersBuilder() - { - return new DbParametersBuilder(DbProvider); - } - - protected virtual IDbParameters CreateDbParameters() - { - return AdoTemplate.CreateDbParameters(); - } - - - - - } -} - +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System; +using System.Data; +using Spring.Dao.Support; +using Spring.Data.Common; +using Spring.Data.Support; + +#endregion + +namespace Spring.Data.Generic +{ + /// + /// Convenient super class for ADO.NET data access objects using generics. + /// + /// + /// Requires a IDBProvider to be set, providing a + /// AdoTemplate based on it to subclasses. + /// This base class is mainly intended for AdoTemplate usage. + /// + public class AdoDaoSupport : DaoSupport + { + private AdoTemplate adoTemplate; + + /// + /// The DbProvider instance used by this DAO + /// + public IDbProvider DbProvider + { + set + { + adoTemplate = CreateAdoTemplate(value); + } + get + { + if (adoTemplate != null) + { + return adoTemplate.DbProvider; + } + else + { + return null; + } + } + + } + + /// + /// Set the AdoTemplate for this DAO explicity, as + /// an alternative to specifying a IDbProvider + /// + public AdoTemplate AdoTemplate + { + set + { + adoTemplate = value; + } + get + { + return adoTemplate; + } + + } + + protected override void CheckDaoConfig() + { + if (adoTemplate == null) + { + throw new ArgumentException("DbProvider or AdoTemplate is required"); + } + } + + protected IDbConnection Connection + { + get + { + return ConnectionUtils.GetConnection(DbProvider); + } + } + + protected IAdoExceptionTranslator ExceptionTranslator + { + get + { + return null; //Investigate AdoExceptionTranslator on AdoAccessor + } + } + + protected void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) + { + ConnectionUtils.DisposeConnection(conn, dbProvider); + } + + + /// + /// Create a AdoTemplate for a given DbProvider + /// Only invoked if populating the DAO with a DbProvider reference. + /// + /// + /// Can be overriden in subclasses to provide AdoTemplate instances + /// with a different configuration, or a cusotm AdoTemplate subclass. + /// + /// The DbProvider to create a AdoTemplate for + protected virtual AdoTemplate CreateAdoTemplate(IDbProvider dbProvider) + { + return new AdoTemplate(dbProvider); + } + + /// + /// Convenience method to create a parameters builder. + /// + /// Virtual for sublcasses to override with custom + /// implementation. + /// A new DbParameterBuilder + protected virtual IDbParametersBuilder CreateDbParametersBuilder() + { + return new DbParametersBuilder(DbProvider); + } + + protected virtual IDbParameters CreateDbParameters() + { + return AdoTemplate.CreateDbParameters(); + } + + + + + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/AdoTemplate.cs b/src/Spring/Spring.Data/Data/Generic/AdoTemplate.cs index 65eeb28c..d6307172 100644 --- a/src/Spring/Spring.Data/Data/Generic/AdoTemplate.cs +++ b/src/Spring/Spring.Data/Data/Generic/AdoTemplate.cs @@ -1,1707 +1,1706 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using Common.Logging; -using Spring.Dao; -using Spring.Dao.Support.Generic; -using Spring.Data.Common; -using Spring.Data.Core; -using Spring.Data.Support; -using Spring.Util; - -namespace Spring.Data.Generic -{ - /// - /// This is the central class in the Spring.Data.Generic namespace. - /// It simplifies the use of ADO.NET and helps to avoid commons errors. - /// - /// Mark Pollack (.NET) - /// $Id: AdoTemplate.cs,v 1.19 2007/12/07 22:56:22 markpollack Exp $ - public class AdoTemplate : AdoAccessor, IAdoOperations - { - - #region Logging Definition - - private static readonly ILog LOG = LogManager.GetLogger(typeof(AdoTemplate)); - - #endregion - - #region Fields - - private Core.AdoTemplate classicAdoTemplate; - protected Type dataReaderWrapperType; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - public AdoTemplate() - : base() - { - classicAdoTemplate = new Core.AdoTemplate(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The provider. - public AdoTemplate(IDbProvider provider) - { - classicAdoTemplate = new Core.AdoTemplate(provider); - AfterPropertiesSet(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The database provider. - /// if set to false - /// lazily initialize the ErrorCodeExceptionTranslator. - public AdoTemplate(IDbProvider provider, bool lazyInit) - { - classicAdoTemplate = new Core.AdoTemplate(provider, lazyInit); - AfterPropertiesSet(); - } - - /// - /// Initializes a new instance of the class. - /// - /// Useful if you have a subclass of Spring.Data.Core.AdoTemplate. - /// The classic ADO template. - public AdoTemplate(Core.AdoTemplate classicAdoTemplate) - { - this.classicAdoTemplate = classicAdoTemplate; - AfterPropertiesSet(); - } - #endregion - - #region Properties - - /// - /// An instance of a DbProvider implementation. - /// - public override IDbProvider DbProvider - { - get { return classicAdoTemplate.DbProvider; } - set { classicAdoTemplate.DbProvider = value; } - } - - /// - /// Gets or sets a value indicating whether to lazily initialize the - /// IAdoExceptionTranslator for this accessor, on first encounter of a - /// exception from the data provider. Default is "true"; can be switched to - /// "false" for initialization on startup. - /// - /// true if to lazy initialize the IAdoExceptionTranslator; - /// otherwise, false. - public override bool LazyInit - { - get { return classicAdoTemplate.LazyInit; } - set { classicAdoTemplate.LazyInit = value; } - } - - /// - /// Gets or sets the exception translator. If no custom translator is provided, a default - /// is used. - /// - /// The exception translator. - public override IAdoExceptionTranslator ExceptionTranslator - { - get { return classicAdoTemplate.ExceptionTranslator; } - set { classicAdoTemplate.ExceptionTranslator = value; } - } - - - /// - /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper - /// for the purpose of having defaults values to use in case of DBNull values read - /// from IDataReader. - /// - /// The type of the data reader wrapper. - public override Type DataReaderWrapperType - { - get { return classicAdoTemplate.DataReaderWrapperType; } - set { classicAdoTemplate.DataReaderWrapperType = value; } - } - - /// - /// Gets the 'Classic' AdoTemplate in Spring.Data - /// - /// - /// Useful to access methods that return non-generic collections. - /// - /// The 'Classic; AdoTemplate in Spring.Data. - public Core.AdoTemplate ClassicAdoTemplate - { - get { return classicAdoTemplate; } - } - - /// - /// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes. It also - /// sets the value of the contained 'ClassicAdoTemplate'. - /// - /// The command timeout. - /// Default is 0, indicating to use the database provider's default. - /// Any timeout specified here will be overridden by the remaining - /// transaction timeout when executing within a transaction that has a - /// timeout specified at the transaction level. - /// - public override int CommandTimeout - { - get { return commandTimeout; } - set - { - commandTimeout = value; - classicAdoTemplate.CommandTimeout = value; - } - } - - #endregion - - #region General Execute Callback methods - - /// - /// Execute a ADO.NET operation on a command object using a interface based callback. - /// - /// the callback to execute - /// object returned from callback - public T Execute(ICommandCallback action) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - IDbCommand command = null; - try - { - command = DbProvider.CreateCommand(); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - ApplyCommandSettings(command); - //TODO explicit check to cast to base class. - DbCommand commandToUse = command as DbCommand; - if (commandToUse != null) - { - T result = action.DoInCommand((DbCommand)command); - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - return result; - } - else - { - throw new InvalidDataAccessApiUsageException( - "Providers implementation of IDbCommand does not inherit from System.Data.Common.DbCommand. Use the alternative overloaded Execute method that specifies IDbCommandCallback as a parameter."); - } - - } - catch (Exception e) - { - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); - } - else - { - throw; - } - - - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - } - - /// - /// Execute a ADO.NET operation on a command object using a delegate callback. - /// - /// This allows for implementing arbitrary data access operations - /// on a single command within Spring's managed ADO.NET environment. - /// The delegate called with a command object. - /// A result object returned by the action or null - public T Execute(CommandDelegate del) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - IDbCommand command = null; - try - { - command = DbProvider.CreateCommand(); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - ApplyCommandSettings(command); - DbCommand commandToUse = command as DbCommand; - if (commandToUse != null) - { - T result = del((DbCommand) command); - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - return result; - } - else - { - throw new InvalidDataAccessApiUsageException( - "Providers implementation of IDbCommand does not inherit from System.Data.Common.DbCommand. Use the alternative overloaded Execute method that specifies IDbCommandDelegate as a parameter."); - } - } - catch (Exception e) - { - string commandText = command.CommandText; - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", commandText, e); - } - else - { - throw; - } - - - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - } - - - /// - /// Execute a ADO.NET operation on a command object using a interface based callback. - /// - /// the callback to execute - /// object returned from callback - public T Execute(IDbCommandCallback action) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - IDbCommand command = null; - try - { - command = DbProvider.CreateCommand(); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - ApplyCommandSettings(command); - T result = action.DoInCommand(command); - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - return result; - } - catch (Exception e) - { - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); - } - else - { - throw; - } - - - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - } - - /// - /// Execute a ADO.NET operation on a command object using a delegate callback. - /// - /// This allows for implementing arbitrary data access operations - /// on a single command within Spring's managed ADO.NET environment. - /// The delegate called with a command object. - /// A result object returned by the action or null - public T Execute(IDbCommandDelegate del) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - IDbCommand command = null; - try - { - command = DbProvider.CreateCommand(); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - ApplyCommandSettings(command); - T result = del(command); - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - return result; - } - catch (Exception e) - { - string commandText = command.CommandText; - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", commandText, e); - } - else - { - throw; - } - - - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - } - - - /// - /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, - /// using the interface based callback IDbCommandCallback. - /// - /// The type of object returned from the callback. - /// The command creator. - /// The callback to execute based on IDbCommand - /// - /// A result object returned by the action or null - /// - public T Execute(IDbCommandCreator commandCreator, IDbCommandCallback action) - { - AssertUtils.ArgumentNotNull(commandCreator, "commandCreator", "IDbCommandCreator must not be null"); - AssertUtils.ArgumentNotNull(action, "action", "Callback object must not be null"); - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - - IDbCommand command = null; - try - { - command = commandCreator.CreateDbCommand(DbProvider); - command.Connection = connectionTxPairToUse.Connection; - command.Transaction = connectionTxPairToUse.Transaction; - //TODO collect warnings... - //RegisterEventHandlers(command.Connection); - ApplyCommandSettings(command); - T result = action.DoInCommand(command); - //SqlWarnings sqlWarnings = GetSqlWarnings() - //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); - return result; - } - catch (Exception e) - { - AdoUtils.DisposeCommand(command); - command = null; - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - if (DbProvider.IsDataAccessException(e)) - { - throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); - } - else - { - throw; - } - - - } - finally - { - AdoUtils.DisposeCommand(command); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - - } - - /// - /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. - /// - /// The type of object returned from the callback. - /// The data adapter callback. - /// - /// A result object returned by the callback or null - /// - /// This allows for implementing abritrary data access operations - /// on a single DataAdapter within Spring's managed ADO.NET environment. - /// - public T Execute(IDataAdapterCallback dataAdapterCallback) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - IDbDataAdapter dataAdapter = null; - try - { - dataAdapter = DbProvider.CreateDataAdapter(); - //TODO row updated event handling... - dataAdapter.SelectCommand = DbProvider.CreateCommand(); - dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection; - //TODO register for warnings on connection. - dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction; - ApplyCommandSettings(dataAdapter.SelectCommand); - T result = dataAdapterCallback.DoInDataAdapter(dataAdapter); - return result; - } - catch (Exception) - { - AdoUtils.DisposeDataAdapterCommands(dataAdapter); - //TODO set dataAdapter command's = null; ? - //TODO exception translation? different hierarchy for data set operations. - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - throw; - } - finally - { - AdoUtils.DisposeDataAdapterCommands(dataAdapter); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - - - } - - /// - /// Execute ADO.NET operations on a IDbDataAdapter object using an delgate based callback. - /// - /// This allows for implementing abritrary data access operations - /// on a single DataAdapter within Spring's managed ADO.NET environment. - /// - /// The type of object returned from the callback. - /// The delegate called with a IDbDataAdapter object. - /// A result object returned by the callback or null - public T Execute(DataAdapterDelegate dataAdapterCallback) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); - IDbDataAdapter dataAdapter = null; - try - { - dataAdapter = DbProvider.CreateDataAdapter(); - //TODO row updated event handling... - dataAdapter.SelectCommand = DbProvider.CreateCommand(); - dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection; - //TODO register for warnings on connection. - dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction; - ApplyCommandSettings(dataAdapter.SelectCommand); - T result = dataAdapterCallback(dataAdapter); - return result; - - } - catch (Exception) - { - AdoUtils.DisposeDataAdapterCommands(dataAdapter); - //TODO set dataAdapter command's = null; ? - //TODO exception translation? different hierarchy for data set operations. - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - connectionTxPairToUse.Connection = null; - throw; - } - finally - { - AdoUtils.DisposeDataAdapterCommands(dataAdapter); - ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); - } - } - - #endregion - - #region ExecuteNonQuery - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText) - { - return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText); - } - - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText, - string parameterName, Enum dbType, int size, object parameterValue) - { - return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, parameterName, dbType, size, parameterValue); - - - } - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The parameter collection to map. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText, - IDbParameters parameters) - { - return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, parameters); - - } - - /// - /// Executes a non query with parameters set via the - /// command setter, returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The command setter. - /// The number of rows affected. - public int ExecuteNonQuery(CommandType cmdType, string cmdText, - ICommandSetter commandSetter) - { - return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, commandSetter); - } - - /// - /// Executes a non query with a command created via IDbCommandCreator and - /// parameters. - /// - /// Output parameters can be retrieved via the returned - /// dictionary. - /// - /// More commonly used as a lower level support method within the framework, - /// for example StoredProcedure/AdoScalar. - /// - /// - /// The callback to create a IDbCommand. - /// The number of rows affected. - public IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator) - { - return classicAdoTemplate.ExecuteNonQuery(commandCreator); - } - - #endregion - - #region ExecuteScalar - - /// - /// Execute the query with the specified command text. - /// - /// No parameters are used. As with - /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the result set - /// returned by the query. Extra columns or row are ignored. - /// The command type - /// The command text to execute. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText) - { - return classicAdoTemplate.ExecuteScalar(cmdType, cmdText); - } - - /// - /// Execute the query with the specified command text and parameter returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText, - string parameterName, Enum dbType, int size, object parameterValue) - { - return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, parameterName, dbType, size, parameterValue); - - } - - - /// - /// Execute the query with the specified command text and parameters returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The parameter collection to map. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText, - IDbParameters parameters) - { - return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, parameters); - } - - /// - /// Execute the query with the specified command text and parameters set via the - /// command setter, returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The command setter. - /// The first column of the first row in the result set - public object ExecuteScalar(CommandType cmdType, string cmdText, - ICommandSetter commandSetter) - { - return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, commandSetter); - } - - /// - /// Execute the query with a command created via IDbCommandCreator and - /// parameters - /// - /// Output parameters can be retrieved via the returned - /// dictionary. - /// - /// More commonly used as a lower level support method within the framework, - /// for example for StoredProcedure/AdoScalar. - /// - /// The callback to create a IDbCommand. - /// A dictionary containing output parameters, if any - public IDictionary ExecuteScalar(IDbCommandCreator commandCreator) - { - return classicAdoTemplate.ExecuteScalar(commandCreator); - } - - #endregion - - #region Queries with RowCallback - - /// - /// Execute a query given IDbCommand's type and text by - /// passing the created IDbCommand to a ICommandSetter implementation - /// that knows how to bind values to the IDbCommand, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - /// The command setter. - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - ICommandSetter commandSetter) - { - classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, commandSetter); - } - /// - /// Execute a query given IDbCommand's type and text, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback) - { - classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback); - } - - /// - /// Execute a query given IDbCommand's type and text and provided parameter - /// information, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - string parameterName, Enum dbType, int size, object parameterValue) - { - classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, - parameterName, dbType, size, parameterValue); - } - - /// - /// Execute a query given IDbCommand's type and text and provided IDbParameters, - /// reading a single result set on a per-row basis with a . - /// - /// Type of the command. - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// The parameter collection to map. - public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - IDbParameters parameter) - { - classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, - parameter); - } - - #endregion - - #region Queries with RowCallback Delegate - - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate) - { - classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate); - - } - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter) - { - throw new NotImplementedException(); - } - - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, - string parameterName, Enum dbType, int size, object parameterValue) - { - classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate, - parameterName, dbType, size, parameterValue); - - } - - public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters) - { - classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate, parameters); - - } - - #endregion - - #region Queries with RowMapper - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper)); - - } - - - public IList QueryWithRowMapper(CommandType cmdType, String cmdText, IRowMapper rowMapper, - ICommandSetter commandSetter) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), commandSetter); - - } - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, - string parameterName, Enum dbType, int size, object parameterValue) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), parameterName, dbType, size, parameterValue); - - } - - public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), parameters); - - } - - - - #endregion - - #region Queries with RowMapperDelegate - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate)); - - } - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - ICommandSetter commandSetter) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), - commandSetter); - } - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - string parameterName, Enum dbType, int size, object parameterValue) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), - parameterName, dbType, size, parameterValue); - } - - public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - IDbParameters parameters) - { - return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), - parameters); - } - #endregion - - #region Queries with ResultSetExtractor - - public T QueryWithResultSetExtractor(CommandType cmdType, - string cmdText, - IResultSetExtractor resultSetExtractor) - { - AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing CommandText [" + cmdText + "]"); - } - return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractor, null)); - } - - public T QueryWithResultSetExtractor(CommandType commandType, string cmdText, IResultSetExtractor resultSetExtractor, - string name, Enum dbType, int size, object parameterValue) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractor, - CreateDbParameters(name, dbType, size, parameterValue))); - } - - public T QueryWithResultSetExtractor(CommandType commandType, string cmdText, - IResultSetExtractor resultSetExtractor, - IDbParameters parameters) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractor, parameters)); - } - - public T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, - IResultSetExtractor resultSetExtractor, - ICommandSetter commandSetter) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, - resultSetExtractor, - commandSetter)); - } - - public T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, - IResultSetExtractor resultSetExtractor, - CommandSetterDelegate commandSetterDelegate) - { - AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); - return Execute(new QueryCallbackWithCommandSetterDelegate(this, cmdType, cmdText, - resultSetExtractor, - commandSetterDelegate)); - } - - #endregion - - - #region Queries with ResultSetExtractorDelegate - - public T QueryWithResultSetExtractorDelegate(CommandType cmdType, - string cmdText, - ResultSetExtractorDelegate resultSetExtractorDelegate) - { - AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - if (LOG.IsDebugEnabled) - { - LOG.Debug("Executing CommandText [" + cmdText + "]"); - } - - return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractorDelegate, null)); - } - - public T QueryWithResultSetExtractorDelegate(CommandType commandType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - string paramenterName, Enum dbType, int size, object parameterValue) - { - AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractorDelegate, - CreateDbParameters(paramenterName, dbType, size, parameterValue))); - } - - public T QueryWithResultSetExtractorDelegate(CommandType commandType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - IDbParameters parameters) - { - AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractorDelegate, parameters)); - } - - public T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - ICommandSetter commandSetter) - { - AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, - resultSetExtractorDelegate, - commandSetter)); - } - - public T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, - CommandSetterDelegate commandSetterDelegate) - { - AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); - return Execute(new QueryCallbackWithCommandSetterDelegate(this, cmdType, cmdText, - resultSetExtractorDelegate, - commandSetterDelegate)); - } - - #endregion - - #region Query for Object - - public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, commandSetter); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameters); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - - public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, - string parameterName, Enum dbType, int size, object parameterValue) - { - IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameterName, dbType, size, parameterValue); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - #endregion - - #region Query for ObjectDelegate - - public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, commandSetter); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, IDbParameters parameters) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameters); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - - public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - string parameterName, Enum dbType, int size, object parameterValue) - { - IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameterName, dbType, size, parameterValue); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - #endregion - - - #region Query with CommandCreator - - public T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse) - { - return QueryWithCommandCreator(cc, rse, null); - } - - public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback) - { - classicAdoTemplate.QueryWithCommandCreator(cc, rowCallback, null); - } - - public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper) - { - return QueryWithCommandCreator(cc, rowMapper, null); - } - - public T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse, IDictionary returnedParameters) - { - if (rse == null) - { - throw new ArgumentNullException("Result Set Extractor must not be null"); - } - - return Execute(cc, new AdoResultSetExtractorWithOutputParamsCommandCallback(this, rse, returnedParameters)); - } - - - public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters) - { - classicAdoTemplate.QueryWithCommandCreator(cc, rowCallback, returnedParameters); - } - - - public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper, IDictionary returnedParameters) - { - if (rowMapper == null) - { - throw new ArgumentNullException("rowMapper must not be null"); - } - - return Execute(cc, new AdoRowMapperQueryCommandCallback(this, rowMapper, returnedParameters)); - } - - - public IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors) - { - return classicAdoTemplate.Execute(cc, new AdoResultProcessorsQueryCommandCallback(this, namedResultSetProcessors)) as IDictionary; - } - - - public IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors) - { - return classicAdoTemplate.Execute(cc, new AdoResultProcessorsQueryCommandCallback(this, namedResultSetProcessors)) as IDictionary; - } - - - #endregion - - #region General Helper Methods - - /// - /// Checks if DbProvider is not null and creates ExceptionTranslator if not LazyInit. - /// - public override void AfterPropertiesSet() - { - classicAdoTemplate.AfterPropertiesSet(); - classicAdoTemplate.CommandTimeout = CommandTimeout; - } - - /// - /// Creates the data reader wrapper for use in AdoTemplate callback methods. - /// - /// The reader to wrap. - /// The data reader used in AdoTemplate callbacks - public override IDataReader CreateDataReaderWrapper(IDataReader readerToWrap) - { - return classicAdoTemplate.CreateDataReaderWrapper(readerToWrap); - } - - #endregion - - #region Parameter Creation Helper Methods - - /// - /// Derives the parameters of a stored procedure including the return parameter - /// - /// Name of the procedure. - /// if set to true to include return parameter. - /// The stored procedure parameters - public override IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter) - { - return classicAdoTemplate.DeriveParameters(procedureName, includeReturnParameter); - } - - #endregion - - - - - - #region Internal Helper classes - - internal class QueryCallback : IDbCommandCallback, ICommandTextProvider - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private ResultSetExtractorDelegate resultSetExtractorDelegate; - private CommandType commandType; - private string commandText; - private IDbParameters parameters; - - public QueryCallback(AdoTemplate adoTemplate, - CommandType cmdType, - string cmdText, - IResultSetExtractor rse, - IDbParameters dbParameters) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.rse = rse; - parameters = dbParameters; - } - - public QueryCallback(AdoTemplate adoTemplate, - CommandType cmdType, - string cmdText, - ResultSetExtractorDelegate resultSetExtractorDelegate, - IDbParameters dbParameters) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.resultSetExtractorDelegate = resultSetExtractorDelegate; - parameters = dbParameters; - } - - public string CommandText - { - get { return commandText; } - } - - public T DoInCommand(IDbCommand command) - { - IDataReader reader = null; - try - { - command.CommandType = commandType; - command.CommandText = commandText; - ParameterUtils.CopyParameters(command, parameters); - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - T returnValue = default(T); - if (rse != null) - { - returnValue = rse.ExtractData(reader); - } - else - { - returnValue = resultSetExtractorDelegate(reader); - } - return returnValue; - } - finally - { - AdoUtils.CloseReader(reader); - ParameterUtils.CopyParameters(parameters, command); - } - } - - - } - - internal class QueryCallbackWithCommandSetter : IDbCommandCallback, ICommandTextProvider - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private ResultSetExtractorDelegate resultSetExtractorDelegate; - private CommandType commandType; - private string commandText; - private ICommandSetter commandSetter; - - public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, - CommandType cmdType, - string cmdText, - IResultSetExtractor rse, - ICommandSetter commandSetter) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.rse = rse; - this.commandSetter = commandSetter; - } - - public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, - CommandType cmdType, - string cmdText, - ResultSetExtractorDelegate resultSetExtractorDelegate, - ICommandSetter commandSetter) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.resultSetExtractorDelegate = resultSetExtractorDelegate; - this.commandSetter = commandSetter; - } - - public string CommandText - { - get { return commandText; } - } - - public T DoInCommand(IDbCommand command) - { - IDataReader reader = null; - try - { - command.CommandType = commandType; - command.CommandText = commandText; - if (commandSetter != null) - { - commandSetter.SetValues(command); - } - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - if (rse != null) - { - return rse.ExtractData(reader); - } - else - { - return resultSetExtractorDelegate(reader); - } - - } - finally - { - AdoUtils.CloseReader(reader); - } - } - - - } - - internal class QueryCallbackWithCommandSetterDelegate : IDbCommandCallback, ICommandTextProvider - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private ResultSetExtractorDelegate resultSetExtractorDelegate; - private CommandType commandType; - private string commandText; - private CommandSetterDelegate commandSetterDelegate; - - public QueryCallbackWithCommandSetterDelegate(AdoTemplate adoTemplate, - CommandType cmdType, - string cmdText, - IResultSetExtractor rse, - CommandSetterDelegate commandSetterDelegate) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.rse = rse; - this.commandSetterDelegate = commandSetterDelegate; - } - - public QueryCallbackWithCommandSetterDelegate(AdoTemplate adoTemplate, - CommandType cmdType, - string cmdText, - ResultSetExtractorDelegate resultSetExtractorDelegate, - CommandSetterDelegate commandSetterDelegate) - { - this.adoTemplate = adoTemplate; - commandType = cmdType; - commandText = cmdText; - this.resultSetExtractorDelegate = resultSetExtractorDelegate; - this.commandSetterDelegate = commandSetterDelegate; - } - - public string CommandText - { - get { return commandText; } - } - - public T DoInCommand(IDbCommand command) - { - IDataReader reader = null; - try - { - command.CommandType = commandType; - command.CommandText = commandText; - if (commandSetterDelegate != null) - { - commandSetterDelegate(command); - } - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - if (rse != null) - { - return rse.ExtractData(reader); - } - else - { - return resultSetExtractorDelegate(reader); - } - } - finally - { - AdoUtils.CloseReader(reader); - } - } - - - } - - internal class AdoRowMapperQueryCommandCallback : IDbCommandCallback> - { - private AdoTemplate adoTemplate; - private IRowMapper rowMapper; - private IDictionary returnedParameters; - - public AdoRowMapperQueryCommandCallback(AdoTemplate adoTemplate, IRowMapper rowMapper, IDictionary returnedParameters) - { - this.adoTemplate = adoTemplate; - this.rowMapper = rowMapper; - this.returnedParameters = returnedParameters; - } - - public IList DoInCommand(IDbCommand command) - { - IList objectList; - //Extract the single returned result set - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1); - objectList = rse.ExtractData(reader); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedParameters, command); - return objectList; - } - } - - internal class AdoResultSetExtractorWithOutputParamsCommandCallback : IDbCommandCallback - { - private AdoTemplate adoTemplate; - private IResultSetExtractor rse; - private IDictionary returnedParameters; - - public AdoResultSetExtractorWithOutputParamsCommandCallback(AdoTemplate adoTemplate, IResultSetExtractor rse, IDictionary returnedParameters) - { - this.adoTemplate = adoTemplate; - this.rse = rse; - this.returnedParameters = returnedParameters; - } - - public T DoInCommand(IDbCommand command) - { - T returnVal; - //Extract the single returned result set - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - returnVal = rse.ExtractData(reader); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedParameters, command); - return returnVal; - } - } - - internal class BaseAdoResultProcessorsQueryCommandCallback - { - public static void ProcessNonGenericResultSetProcessor(NamedResultSetProcessor otherResultSetProcessor, IDataReader reader, IDictionary returnedResults) - { - string parameterName = otherResultSetProcessor.Name; - if (otherResultSetProcessor.ResultSetProcessor is IResultSetExtractor) - { - IResultSetExtractor rse = (IResultSetExtractor)otherResultSetProcessor.ResultSetProcessor; - object result = rse.ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (otherResultSetProcessor.ResultSetProcessor is IRowMapper) - { - IRowMapper rowMapper = (IRowMapper)otherResultSetProcessor.ResultSetProcessor; - object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (otherResultSetProcessor.ResultSetProcessor is IRowCallback) - { - IRowCallback rowCallback = (IRowCallback)otherResultSetProcessor.ResultSetProcessor; - (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); - returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); - } - } - - public static void ProcessFirstGenericResultSetProcessor(NamedResultSetProcessor firstResultSetProcessor, IDataReader reader, IDictionary returnedResults) - { - string parameterName = firstResultSetProcessor.Name; - if (firstResultSetProcessor.ResultSetExtractor != null) - { - IResultSetExtractor rse = firstResultSetProcessor.ResultSetExtractor; - T result = rse.ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (firstResultSetProcessor.RowMapper != null) - { - IRowMapper rowMapper = firstResultSetProcessor.RowMapper; - object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (firstResultSetProcessor.RowCallback != null) - { - IRowCallback rowCallback = firstResultSetProcessor.RowCallback; - (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); - returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); - } - } - } - - internal class AdoResultProcessorsQueryCommandCallback : BaseAdoResultProcessorsQueryCommandCallback, ICommandCallback - { - private AdoTemplate adoTemplate; - private IList namedResultSetProcessors; - - public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors) - { - this.adoTemplate = adoTemplate; - this.namedResultSetProcessors = namedResultSetProcessors; - } - - public object DoInCommand(IDbCommand command) - { - IDictionary returnedResults = new Hashtable(); - int resultSetIndex = 0; - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - - //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to - // see if there is a result set. now currently assuming matching - // NamedResultSetProcessor/ResultSet pairs. - - do - { - if (namedResultSetProcessors.Count == 0) - { - //We could just have output parameters and/or return value, that is, no result sets - //If we didn't register a result set processor, it is likely that a result set wasn't expected. - break; - } - NamedResultSetProcessor firstResultSetProcessor = null; - NamedResultSetProcessor otherResultSetProcessor = null; - try - { - if (resultSetIndex == 0) - { - firstResultSetProcessor - = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; - //Will have possibility of run-time type error if using QueryWithCommandCreator - if (firstResultSetProcessor == null) - { - LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + - ", is not of expected type NamedResultSetProcessor. Type = " + - namedResultSetProcessors[resultSetIndex].GetType() + - "; Skipping processing for this result set."); - continue; - } - } - else - { - otherResultSetProcessor = - namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; - if (otherResultSetProcessor == null) - { - - LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + - ", is not of expected type NamedResultSetProcessor Type = " + - namedResultSetProcessors[resultSetIndex].GetType() + - "; Skipping processing for this result set."); - continue; - } - } - } - catch (IndexOutOfRangeException e) - { - LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); - continue; - } - catch (ArgumentOutOfRangeException e) - { - LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); - continue; - } - - - if (resultSetIndex == 0) - { - ProcessFirstGenericResultSetProcessor(firstResultSetProcessor, reader, returnedResults); - } - else - { - ProcessNonGenericResultSetProcessor(otherResultSetProcessor, reader, returnedResults); - } - resultSetIndex++; - - } while (reader.NextResult()); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedResults, command); - return returnedResults; - } - } - - - internal class AdoResultProcessorsQueryCommandCallback : BaseAdoResultProcessorsQueryCommandCallback, ICommandCallback - { - private AdoTemplate adoTemplate; - private IList namedResultSetProcessors; - - public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors) - { - this.adoTemplate = adoTemplate; - this.namedResultSetProcessors = namedResultSetProcessors; - } - - public object DoInCommand(IDbCommand command) - { - IDictionary returnedResults = new Hashtable(); - int resultSetIndex = 0; - IDataReader reader = null; - try - { - reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); - - //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to - // see if there is a result set. now currently assuming matching - // NamedResultSetProcessor/ResultSet pairs. - - do - { - if (namedResultSetProcessors.Count == 0) - { - //We could just have output parameters and/or return value, that is, no result sets - //If we didn't register a result set processor, it is likely that a result set wasn't expected. - break; - } - NamedResultSetProcessor firstResultSetProcessor = null; - NamedResultSetProcessor secondResultSetProcessor = null; - NamedResultSetProcessor otherResultSetProcessor = null; - try - { - if (resultSetIndex == 0) - { - firstResultSetProcessor = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; - //Will only have possibility of run-time type error if using QueryWithCommandCreator - if (firstResultSetProcessor == null) - { - - LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + - ", is not of expected type NamedResultSetProcessor Type = " + - namedResultSetProcessors[resultSetIndex].GetType() + - "; Skipping processing for this result set."); - continue; - } - } else if (resultSetIndex == 1) - { - secondResultSetProcessor - = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; - if (secondResultSetProcessor == null) - { - - LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + - ", is not of expected type NamedResultSetProcessor Type = " + - namedResultSetProcessors[resultSetIndex].GetType() + - "; Skipping processing for this result set."); - continue; - } - } else - { - otherResultSetProcessor = - namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; - if (otherResultSetProcessor == null) - { - - LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + - ", is not of expected type NamedResultSetProcessor Type = " + - namedResultSetProcessors[resultSetIndex].GetType() + - "; Skipping processing for this result set."); - continue; - } - } - - } - catch (IndexOutOfRangeException e) - { - LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); - continue; - } - catch (ArgumentOutOfRangeException e) - { - LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); - continue; - } - - if (resultSetIndex == 0) - { - ProcessFirstGenericResultSetProcessor(firstResultSetProcessor, reader, returnedResults); - } - else if (resultSetIndex == 1) - { - string parameterName = secondResultSetProcessor.Name; - if (secondResultSetProcessor.ResultSetExtractor != null) - { - IResultSetExtractor rse = secondResultSetProcessor.ResultSetExtractor; - U result = rse.ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (secondResultSetProcessor.RowMapper != null) - { - IRowMapper rowMapper = secondResultSetProcessor.RowMapper; - object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); - returnedResults.Add(parameterName, result); - } - else if (secondResultSetProcessor.RowCallback != null) - { - //In this case a dummy type parameter would need to be specified a better alternative would - //be to to use the single type parameterization of this callback. - IRowCallback rowCallback = secondResultSetProcessor.RowCallback; - (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); - returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); - } - } - else - { - ProcessNonGenericResultSetProcessor(otherResultSetProcessor, reader, returnedResults); - } - resultSetIndex++; - - } while (reader.NextResult()); - } - finally - { - AdoUtils.CloseReader(reader); - } - ParameterUtils.ExtractOutputParameters(returnedResults, command); - return returnedResults; - } - - - } - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using Common.Logging; +using Spring.Dao; +using Spring.Dao.Support.Generic; +using Spring.Data.Common; +using Spring.Data.Core; +using Spring.Data.Support; +using Spring.Util; + +namespace Spring.Data.Generic +{ + /// + /// This is the central class in the Spring.Data.Generic namespace. + /// It simplifies the use of ADO.NET and helps to avoid commons errors. + /// + /// Mark Pollack (.NET) + public class AdoTemplate : AdoAccessor, IAdoOperations + { + + #region Logging Definition + + private static readonly ILog LOG = LogManager.GetLogger(typeof(AdoTemplate)); + + #endregion + + #region Fields + + private Core.AdoTemplate classicAdoTemplate; + protected Type dataReaderWrapperType; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public AdoTemplate() + : base() + { + classicAdoTemplate = new Core.AdoTemplate(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The provider. + public AdoTemplate(IDbProvider provider) + { + classicAdoTemplate = new Core.AdoTemplate(provider); + AfterPropertiesSet(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The database provider. + /// if set to false + /// lazily initialize the ErrorCodeExceptionTranslator. + public AdoTemplate(IDbProvider provider, bool lazyInit) + { + classicAdoTemplate = new Core.AdoTemplate(provider, lazyInit); + AfterPropertiesSet(); + } + + /// + /// Initializes a new instance of the class. + /// + /// Useful if you have a subclass of Spring.Data.Core.AdoTemplate. + /// The classic ADO template. + public AdoTemplate(Core.AdoTemplate classicAdoTemplate) + { + this.classicAdoTemplate = classicAdoTemplate; + AfterPropertiesSet(); + } + #endregion + + #region Properties + + /// + /// An instance of a DbProvider implementation. + /// + public override IDbProvider DbProvider + { + get { return classicAdoTemplate.DbProvider; } + set { classicAdoTemplate.DbProvider = value; } + } + + /// + /// Gets or sets a value indicating whether to lazily initialize the + /// IAdoExceptionTranslator for this accessor, on first encounter of a + /// exception from the data provider. Default is "true"; can be switched to + /// "false" for initialization on startup. + /// + /// true if to lazy initialize the IAdoExceptionTranslator; + /// otherwise, false. + public override bool LazyInit + { + get { return classicAdoTemplate.LazyInit; } + set { classicAdoTemplate.LazyInit = value; } + } + + /// + /// Gets or sets the exception translator. If no custom translator is provided, a default + /// is used. + /// + /// The exception translator. + public override IAdoExceptionTranslator ExceptionTranslator + { + get { return classicAdoTemplate.ExceptionTranslator; } + set { classicAdoTemplate.ExceptionTranslator = value; } + } + + + /// + /// Gets or set the System.Type to use to create an instance of IDataReaderWrapper + /// for the purpose of having defaults values to use in case of DBNull values read + /// from IDataReader. + /// + /// The type of the data reader wrapper. + public override Type DataReaderWrapperType + { + get { return classicAdoTemplate.DataReaderWrapperType; } + set { classicAdoTemplate.DataReaderWrapperType = value; } + } + + /// + /// Gets the 'Classic' AdoTemplate in Spring.Data + /// + /// + /// Useful to access methods that return non-generic collections. + /// + /// The 'Classic; AdoTemplate in Spring.Data. + public Core.AdoTemplate ClassicAdoTemplate + { + get { return classicAdoTemplate; } + } + + /// + /// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes. It also + /// sets the value of the contained 'ClassicAdoTemplate'. + /// + /// The command timeout. + /// Default is 0, indicating to use the database provider's default. + /// Any timeout specified here will be overridden by the remaining + /// transaction timeout when executing within a transaction that has a + /// timeout specified at the transaction level. + /// + public override int CommandTimeout + { + get { return commandTimeout; } + set + { + commandTimeout = value; + classicAdoTemplate.CommandTimeout = value; + } + } + + #endregion + + #region General Execute Callback methods + + /// + /// Execute a ADO.NET operation on a command object using a interface based callback. + /// + /// the callback to execute + /// object returned from callback + public T Execute(ICommandCallback action) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + IDbCommand command = null; + try + { + command = DbProvider.CreateCommand(); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + ApplyCommandSettings(command); + //TODO explicit check to cast to base class. + DbCommand commandToUse = command as DbCommand; + if (commandToUse != null) + { + T result = action.DoInCommand((DbCommand)command); + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + return result; + } + else + { + throw new InvalidDataAccessApiUsageException( + "Providers implementation of IDbCommand does not inherit from System.Data.Common.DbCommand. Use the alternative overloaded Execute method that specifies IDbCommandCallback as a parameter."); + } + + } + catch (Exception e) + { + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); + } + else + { + throw; + } + + + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + } + + /// + /// Execute a ADO.NET operation on a command object using a delegate callback. + /// + /// This allows for implementing arbitrary data access operations + /// on a single command within Spring's managed ADO.NET environment. + /// The delegate called with a command object. + /// A result object returned by the action or null + public T Execute(CommandDelegate del) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + IDbCommand command = null; + try + { + command = DbProvider.CreateCommand(); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + ApplyCommandSettings(command); + DbCommand commandToUse = command as DbCommand; + if (commandToUse != null) + { + T result = del((DbCommand) command); + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + return result; + } + else + { + throw new InvalidDataAccessApiUsageException( + "Providers implementation of IDbCommand does not inherit from System.Data.Common.DbCommand. Use the alternative overloaded Execute method that specifies IDbCommandDelegate as a parameter."); + } + } + catch (Exception e) + { + string commandText = command.CommandText; + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", commandText, e); + } + else + { + throw; + } + + + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + } + + + /// + /// Execute a ADO.NET operation on a command object using a interface based callback. + /// + /// the callback to execute + /// object returned from callback + public T Execute(IDbCommandCallback action) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + IDbCommand command = null; + try + { + command = DbProvider.CreateCommand(); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + ApplyCommandSettings(command); + T result = action.DoInCommand(command); + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + return result; + } + catch (Exception e) + { + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); + } + else + { + throw; + } + + + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + } + + /// + /// Execute a ADO.NET operation on a command object using a delegate callback. + /// + /// This allows for implementing arbitrary data access operations + /// on a single command within Spring's managed ADO.NET environment. + /// The delegate called with a command object. + /// A result object returned by the action or null + public T Execute(IDbCommandDelegate del) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + IDbCommand command = null; + try + { + command = DbProvider.CreateCommand(); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + ApplyCommandSettings(command); + T result = del(command); + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + return result; + } + catch (Exception e) + { + string commandText = command.CommandText; + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", commandText, e); + } + else + { + throw; + } + + + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + } + + + /// + /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, + /// using the interface based callback IDbCommandCallback. + /// + /// The type of object returned from the callback. + /// The command creator. + /// The callback to execute based on IDbCommand + /// + /// A result object returned by the action or null + /// + public T Execute(IDbCommandCreator commandCreator, IDbCommandCallback action) + { + AssertUtils.ArgumentNotNull(commandCreator, "commandCreator", "IDbCommandCreator must not be null"); + AssertUtils.ArgumentNotNull(action, "action", "Callback object must not be null"); + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + + IDbCommand command = null; + try + { + command = commandCreator.CreateDbCommand(DbProvider); + command.Connection = connectionTxPairToUse.Connection; + command.Transaction = connectionTxPairToUse.Transaction; + //TODO collect warnings... + //RegisterEventHandlers(command.Connection); + ApplyCommandSettings(command); + T result = action.DoInCommand(command); + //SqlWarnings sqlWarnings = GetSqlWarnings() + //ThrowExceptionOnWarningIfNotIgnoringWarnings(sqlWarnings); + return result; + } + catch (Exception e) + { + AdoUtils.DisposeCommand(command); + command = null; + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + if (DbProvider.IsDataAccessException(e)) + { + throw ExceptionTranslator.Translate("CommandCallback", GetCommandText(action), e); + } + else + { + throw; + } + + + } + finally + { + AdoUtils.DisposeCommand(command); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + + } + + /// + /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. + /// + /// The type of object returned from the callback. + /// The data adapter callback. + /// + /// A result object returned by the callback or null + /// + /// This allows for implementing abritrary data access operations + /// on a single DataAdapter within Spring's managed ADO.NET environment. + /// + public T Execute(IDataAdapterCallback dataAdapterCallback) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + IDbDataAdapter dataAdapter = null; + try + { + dataAdapter = DbProvider.CreateDataAdapter(); + //TODO row updated event handling... + dataAdapter.SelectCommand = DbProvider.CreateCommand(); + dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection; + //TODO register for warnings on connection. + dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction; + ApplyCommandSettings(dataAdapter.SelectCommand); + T result = dataAdapterCallback.DoInDataAdapter(dataAdapter); + return result; + } + catch (Exception) + { + AdoUtils.DisposeDataAdapterCommands(dataAdapter); + //TODO set dataAdapter command's = null; ? + //TODO exception translation? different hierarchy for data set operations. + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + throw; + } + finally + { + AdoUtils.DisposeDataAdapterCommands(dataAdapter); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + + + } + + /// + /// Execute ADO.NET operations on a IDbDataAdapter object using an delgate based callback. + /// + /// This allows for implementing abritrary data access operations + /// on a single DataAdapter within Spring's managed ADO.NET environment. + /// + /// The type of object returned from the callback. + /// The delegate called with a IDbDataAdapter object. + /// A result object returned by the callback or null + public T Execute(DataAdapterDelegate dataAdapterCallback) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(DbProvider); + IDbDataAdapter dataAdapter = null; + try + { + dataAdapter = DbProvider.CreateDataAdapter(); + //TODO row updated event handling... + dataAdapter.SelectCommand = DbProvider.CreateCommand(); + dataAdapter.SelectCommand.Connection = connectionTxPairToUse.Connection; + //TODO register for warnings on connection. + dataAdapter.SelectCommand.Transaction = connectionTxPairToUse.Transaction; + ApplyCommandSettings(dataAdapter.SelectCommand); + T result = dataAdapterCallback(dataAdapter); + return result; + + } + catch (Exception) + { + AdoUtils.DisposeDataAdapterCommands(dataAdapter); + //TODO set dataAdapter command's = null; ? + //TODO exception translation? different hierarchy for data set operations. + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + connectionTxPairToUse.Connection = null; + throw; + } + finally + { + AdoUtils.DisposeDataAdapterCommands(dataAdapter); + ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, DbProvider); + } + } + + #endregion + + #region ExecuteNonQuery + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText) + { + return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText); + } + + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText, + string parameterName, Enum dbType, int size, object parameterValue) + { + return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, parameterName, dbType, size, parameterValue); + + + } + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The parameter collection to map. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText, + IDbParameters parameters) + { + return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, parameters); + + } + + /// + /// Executes a non query with parameters set via the + /// command setter, returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The command setter. + /// The number of rows affected. + public int ExecuteNonQuery(CommandType cmdType, string cmdText, + ICommandSetter commandSetter) + { + return classicAdoTemplate.ExecuteNonQuery(cmdType, cmdText, commandSetter); + } + + /// + /// Executes a non query with a command created via IDbCommandCreator and + /// parameters. + /// + /// Output parameters can be retrieved via the returned + /// dictionary. + /// + /// More commonly used as a lower level support method within the framework, + /// for example StoredProcedure/AdoScalar. + /// + /// + /// The callback to create a IDbCommand. + /// The number of rows affected. + public IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator) + { + return classicAdoTemplate.ExecuteNonQuery(commandCreator); + } + + #endregion + + #region ExecuteScalar + + /// + /// Execute the query with the specified command text. + /// + /// No parameters are used. As with + /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the result set + /// returned by the query. Extra columns or row are ignored. + /// The command type + /// The command text to execute. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText) + { + return classicAdoTemplate.ExecuteScalar(cmdType, cmdText); + } + + /// + /// Execute the query with the specified command text and parameter returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText, + string parameterName, Enum dbType, int size, object parameterValue) + { + return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, parameterName, dbType, size, parameterValue); + + } + + + /// + /// Execute the query with the specified command text and parameters returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The parameter collection to map. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText, + IDbParameters parameters) + { + return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, parameters); + } + + /// + /// Execute the query with the specified command text and parameters set via the + /// command setter, returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The command setter. + /// The first column of the first row in the result set + public object ExecuteScalar(CommandType cmdType, string cmdText, + ICommandSetter commandSetter) + { + return classicAdoTemplate.ExecuteScalar(cmdType, cmdText, commandSetter); + } + + /// + /// Execute the query with a command created via IDbCommandCreator and + /// parameters + /// + /// Output parameters can be retrieved via the returned + /// dictionary. + /// + /// More commonly used as a lower level support method within the framework, + /// for example for StoredProcedure/AdoScalar. + /// + /// The callback to create a IDbCommand. + /// A dictionary containing output parameters, if any + public IDictionary ExecuteScalar(IDbCommandCreator commandCreator) + { + return classicAdoTemplate.ExecuteScalar(commandCreator); + } + + #endregion + + #region Queries with RowCallback + + /// + /// Execute a query given IDbCommand's type and text by + /// passing the created IDbCommand to a ICommandSetter implementation + /// that knows how to bind values to the IDbCommand, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + /// The command setter. + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + ICommandSetter commandSetter) + { + classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, commandSetter); + } + /// + /// Execute a query given IDbCommand's type and text, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback) + { + classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback); + } + + /// + /// Execute a query given IDbCommand's type and text and provided parameter + /// information, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + string parameterName, Enum dbType, int size, object parameterValue) + { + classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, + parameterName, dbType, size, parameterValue); + } + + /// + /// Execute a query given IDbCommand's type and text and provided IDbParameters, + /// reading a single result set on a per-row basis with a . + /// + /// Type of the command. + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// The parameter collection to map. + public void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + IDbParameters parameter) + { + classicAdoTemplate.QueryWithRowCallback(cmdType, cmdText, rowCallback, + parameter); + } + + #endregion + + #region Queries with RowCallback Delegate + + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate) + { + classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate); + + } + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter) + { + throw new NotImplementedException(); + } + + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, + string parameterName, Enum dbType, int size, object parameterValue) + { + classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate, + parameterName, dbType, size, parameterValue); + + } + + public void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters) + { + classicAdoTemplate.QueryWithRowCallbackDelegate(cmdType, sql, rowCallbackDelegate, parameters); + + } + + #endregion + + #region Queries with RowMapper + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper)); + + } + + + public IList QueryWithRowMapper(CommandType cmdType, String cmdText, IRowMapper rowMapper, + ICommandSetter commandSetter) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), commandSetter); + + } + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, + string parameterName, Enum dbType, int size, object parameterValue) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), parameterName, dbType, size, parameterValue); + + } + + public IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapper), parameters); + + } + + + + #endregion + + #region Queries with RowMapperDelegate + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate)); + + } + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + ICommandSetter commandSetter) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), + commandSetter); + } + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + string parameterName, Enum dbType, int size, object parameterValue) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), + parameterName, dbType, size, parameterValue); + } + + public IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + IDbParameters parameters) + { + return QueryWithResultSetExtractor(cmdType, cmdText, new RowMapperResultSetExtractor(rowMapperDelegate), + parameters); + } + #endregion + + #region Queries with ResultSetExtractor + + public T QueryWithResultSetExtractor(CommandType cmdType, + string cmdText, + IResultSetExtractor resultSetExtractor) + { + AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing CommandText [" + cmdText + "]"); + } + return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractor, null)); + } + + public T QueryWithResultSetExtractor(CommandType commandType, string cmdText, IResultSetExtractor resultSetExtractor, + string name, Enum dbType, int size, object parameterValue) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractor, + CreateDbParameters(name, dbType, size, parameterValue))); + } + + public T QueryWithResultSetExtractor(CommandType commandType, string cmdText, + IResultSetExtractor resultSetExtractor, + IDbParameters parameters) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractor, parameters)); + } + + public T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, + IResultSetExtractor resultSetExtractor, + ICommandSetter commandSetter) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, + resultSetExtractor, + commandSetter)); + } + + public T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, + IResultSetExtractor resultSetExtractor, + CommandSetterDelegate commandSetterDelegate) + { + AssertUtils.ArgumentNotNull(resultSetExtractor, "resultSetExtractor", "Result Set Extractor must not be null"); + return Execute(new QueryCallbackWithCommandSetterDelegate(this, cmdType, cmdText, + resultSetExtractor, + commandSetterDelegate)); + } + + #endregion + + + #region Queries with ResultSetExtractorDelegate + + public T QueryWithResultSetExtractorDelegate(CommandType cmdType, + string cmdText, + ResultSetExtractorDelegate resultSetExtractorDelegate) + { + AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + if (LOG.IsDebugEnabled) + { + LOG.Debug("Executing CommandText [" + cmdText + "]"); + } + + return Execute(new QueryCallback(this, cmdType, cmdText, resultSetExtractorDelegate, null)); + } + + public T QueryWithResultSetExtractorDelegate(CommandType commandType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + string paramenterName, Enum dbType, int size, object parameterValue) + { + AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractorDelegate, + CreateDbParameters(paramenterName, dbType, size, parameterValue))); + } + + public T QueryWithResultSetExtractorDelegate(CommandType commandType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + IDbParameters parameters) + { + AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallback(this, commandType, cmdText, resultSetExtractorDelegate, parameters)); + } + + public T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + ICommandSetter commandSetter) + { + AssertUtils.ArgumentNotNull(cmdText, "cmdText", "CommandText must not be null"); + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallbackWithCommandSetter(this, cmdType, cmdText, + resultSetExtractorDelegate, + commandSetter)); + } + + public T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate, + CommandSetterDelegate commandSetterDelegate) + { + AssertUtils.ArgumentNotNull(resultSetExtractorDelegate, "resultSetExtractorDelegate", "Result set extractor delegate must not be null"); + return Execute(new QueryCallbackWithCommandSetterDelegate(this, cmdType, cmdText, + resultSetExtractorDelegate, + commandSetterDelegate)); + } + + #endregion + + #region Query for Object + + public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, commandSetter); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameters); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + + public T QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, + string parameterName, Enum dbType, int size, object parameterValue) + { + IList results = QueryWithRowMapper(cmdType, cmdText, rowMapper, parameterName, dbType, size, parameterValue); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + #endregion + + #region Query for ObjectDelegate + + public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, commandSetter); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, IDbParameters parameters) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameters); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + + public T QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + string parameterName, Enum dbType, int size, object parameterValue) + { + IList results = QueryWithRowMapperDelegate(cmdType, cmdText, rowMapperDelegate, parameterName, dbType, size, parameterValue); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + #endregion + + + #region Query with CommandCreator + + public T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse) + { + return QueryWithCommandCreator(cc, rse, null); + } + + public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback) + { + classicAdoTemplate.QueryWithCommandCreator(cc, rowCallback, null); + } + + public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper) + { + return QueryWithCommandCreator(cc, rowMapper, null); + } + + public T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse, IDictionary returnedParameters) + { + if (rse == null) + { + throw new ArgumentNullException("Result Set Extractor must not be null"); + } + + return Execute(cc, new AdoResultSetExtractorWithOutputParamsCommandCallback(this, rse, returnedParameters)); + } + + + public void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters) + { + classicAdoTemplate.QueryWithCommandCreator(cc, rowCallback, returnedParameters); + } + + + public IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper, IDictionary returnedParameters) + { + if (rowMapper == null) + { + throw new ArgumentNullException("rowMapper must not be null"); + } + + return Execute(cc, new AdoRowMapperQueryCommandCallback(this, rowMapper, returnedParameters)); + } + + + public IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors) + { + return classicAdoTemplate.Execute(cc, new AdoResultProcessorsQueryCommandCallback(this, namedResultSetProcessors)) as IDictionary; + } + + + public IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors) + { + return classicAdoTemplate.Execute(cc, new AdoResultProcessorsQueryCommandCallback(this, namedResultSetProcessors)) as IDictionary; + } + + + #endregion + + #region General Helper Methods + + /// + /// Checks if DbProvider is not null and creates ExceptionTranslator if not LazyInit. + /// + public override void AfterPropertiesSet() + { + classicAdoTemplate.AfterPropertiesSet(); + classicAdoTemplate.CommandTimeout = CommandTimeout; + } + + /// + /// Creates the data reader wrapper for use in AdoTemplate callback methods. + /// + /// The reader to wrap. + /// The data reader used in AdoTemplate callbacks + public override IDataReader CreateDataReaderWrapper(IDataReader readerToWrap) + { + return classicAdoTemplate.CreateDataReaderWrapper(readerToWrap); + } + + #endregion + + #region Parameter Creation Helper Methods + + /// + /// Derives the parameters of a stored procedure including the return parameter + /// + /// Name of the procedure. + /// if set to true to include return parameter. + /// The stored procedure parameters + public override IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter) + { + return classicAdoTemplate.DeriveParameters(procedureName, includeReturnParameter); + } + + #endregion + + + + + + #region Internal Helper classes + + internal class QueryCallback : IDbCommandCallback, ICommandTextProvider + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private ResultSetExtractorDelegate resultSetExtractorDelegate; + private CommandType commandType; + private string commandText; + private IDbParameters parameters; + + public QueryCallback(AdoTemplate adoTemplate, + CommandType cmdType, + string cmdText, + IResultSetExtractor rse, + IDbParameters dbParameters) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.rse = rse; + parameters = dbParameters; + } + + public QueryCallback(AdoTemplate adoTemplate, + CommandType cmdType, + string cmdText, + ResultSetExtractorDelegate resultSetExtractorDelegate, + IDbParameters dbParameters) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.resultSetExtractorDelegate = resultSetExtractorDelegate; + parameters = dbParameters; + } + + public string CommandText + { + get { return commandText; } + } + + public T DoInCommand(IDbCommand command) + { + IDataReader reader = null; + try + { + command.CommandType = commandType; + command.CommandText = commandText; + ParameterUtils.CopyParameters(command, parameters); + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + T returnValue = default(T); + if (rse != null) + { + returnValue = rse.ExtractData(reader); + } + else + { + returnValue = resultSetExtractorDelegate(reader); + } + return returnValue; + } + finally + { + AdoUtils.CloseReader(reader); + ParameterUtils.CopyParameters(parameters, command); + } + } + + + } + + internal class QueryCallbackWithCommandSetter : IDbCommandCallback, ICommandTextProvider + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private ResultSetExtractorDelegate resultSetExtractorDelegate; + private CommandType commandType; + private string commandText; + private ICommandSetter commandSetter; + + public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, + CommandType cmdType, + string cmdText, + IResultSetExtractor rse, + ICommandSetter commandSetter) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.rse = rse; + this.commandSetter = commandSetter; + } + + public QueryCallbackWithCommandSetter(AdoTemplate adoTemplate, + CommandType cmdType, + string cmdText, + ResultSetExtractorDelegate resultSetExtractorDelegate, + ICommandSetter commandSetter) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.resultSetExtractorDelegate = resultSetExtractorDelegate; + this.commandSetter = commandSetter; + } + + public string CommandText + { + get { return commandText; } + } + + public T DoInCommand(IDbCommand command) + { + IDataReader reader = null; + try + { + command.CommandType = commandType; + command.CommandText = commandText; + if (commandSetter != null) + { + commandSetter.SetValues(command); + } + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + if (rse != null) + { + return rse.ExtractData(reader); + } + else + { + return resultSetExtractorDelegate(reader); + } + + } + finally + { + AdoUtils.CloseReader(reader); + } + } + + + } + + internal class QueryCallbackWithCommandSetterDelegate : IDbCommandCallback, ICommandTextProvider + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private ResultSetExtractorDelegate resultSetExtractorDelegate; + private CommandType commandType; + private string commandText; + private CommandSetterDelegate commandSetterDelegate; + + public QueryCallbackWithCommandSetterDelegate(AdoTemplate adoTemplate, + CommandType cmdType, + string cmdText, + IResultSetExtractor rse, + CommandSetterDelegate commandSetterDelegate) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.rse = rse; + this.commandSetterDelegate = commandSetterDelegate; + } + + public QueryCallbackWithCommandSetterDelegate(AdoTemplate adoTemplate, + CommandType cmdType, + string cmdText, + ResultSetExtractorDelegate resultSetExtractorDelegate, + CommandSetterDelegate commandSetterDelegate) + { + this.adoTemplate = adoTemplate; + commandType = cmdType; + commandText = cmdText; + this.resultSetExtractorDelegate = resultSetExtractorDelegate; + this.commandSetterDelegate = commandSetterDelegate; + } + + public string CommandText + { + get { return commandText; } + } + + public T DoInCommand(IDbCommand command) + { + IDataReader reader = null; + try + { + command.CommandType = commandType; + command.CommandText = commandText; + if (commandSetterDelegate != null) + { + commandSetterDelegate(command); + } + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + if (rse != null) + { + return rse.ExtractData(reader); + } + else + { + return resultSetExtractorDelegate(reader); + } + } + finally + { + AdoUtils.CloseReader(reader); + } + } + + + } + + internal class AdoRowMapperQueryCommandCallback : IDbCommandCallback> + { + private AdoTemplate adoTemplate; + private IRowMapper rowMapper; + private IDictionary returnedParameters; + + public AdoRowMapperQueryCommandCallback(AdoTemplate adoTemplate, IRowMapper rowMapper, IDictionary returnedParameters) + { + this.adoTemplate = adoTemplate; + this.rowMapper = rowMapper; + this.returnedParameters = returnedParameters; + } + + public IList DoInCommand(IDbCommand command) + { + IList objectList; + //Extract the single returned result set + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1); + objectList = rse.ExtractData(reader); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedParameters, command); + return objectList; + } + } + + internal class AdoResultSetExtractorWithOutputParamsCommandCallback : IDbCommandCallback + { + private AdoTemplate adoTemplate; + private IResultSetExtractor rse; + private IDictionary returnedParameters; + + public AdoResultSetExtractorWithOutputParamsCommandCallback(AdoTemplate adoTemplate, IResultSetExtractor rse, IDictionary returnedParameters) + { + this.adoTemplate = adoTemplate; + this.rse = rse; + this.returnedParameters = returnedParameters; + } + + public T DoInCommand(IDbCommand command) + { + T returnVal; + //Extract the single returned result set + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + returnVal = rse.ExtractData(reader); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedParameters, command); + return returnVal; + } + } + + internal class BaseAdoResultProcessorsQueryCommandCallback + { + public static void ProcessNonGenericResultSetProcessor(NamedResultSetProcessor otherResultSetProcessor, IDataReader reader, IDictionary returnedResults) + { + string parameterName = otherResultSetProcessor.Name; + if (otherResultSetProcessor.ResultSetProcessor is IResultSetExtractor) + { + IResultSetExtractor rse = (IResultSetExtractor)otherResultSetProcessor.ResultSetProcessor; + object result = rse.ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (otherResultSetProcessor.ResultSetProcessor is IRowMapper) + { + IRowMapper rowMapper = (IRowMapper)otherResultSetProcessor.ResultSetProcessor; + object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (otherResultSetProcessor.ResultSetProcessor is IRowCallback) + { + IRowCallback rowCallback = (IRowCallback)otherResultSetProcessor.ResultSetProcessor; + (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); + returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); + } + } + + public static void ProcessFirstGenericResultSetProcessor(NamedResultSetProcessor firstResultSetProcessor, IDataReader reader, IDictionary returnedResults) + { + string parameterName = firstResultSetProcessor.Name; + if (firstResultSetProcessor.ResultSetExtractor != null) + { + IResultSetExtractor rse = firstResultSetProcessor.ResultSetExtractor; + T result = rse.ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (firstResultSetProcessor.RowMapper != null) + { + IRowMapper rowMapper = firstResultSetProcessor.RowMapper; + object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (firstResultSetProcessor.RowCallback != null) + { + IRowCallback rowCallback = firstResultSetProcessor.RowCallback; + (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); + returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); + } + } + } + + internal class AdoResultProcessorsQueryCommandCallback : BaseAdoResultProcessorsQueryCommandCallback, ICommandCallback + { + private AdoTemplate adoTemplate; + private IList namedResultSetProcessors; + + public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors) + { + this.adoTemplate = adoTemplate; + this.namedResultSetProcessors = namedResultSetProcessors; + } + + public object DoInCommand(IDbCommand command) + { + IDictionary returnedResults = new Hashtable(); + int resultSetIndex = 0; + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + + //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to + // see if there is a result set. now currently assuming matching + // NamedResultSetProcessor/ResultSet pairs. + + do + { + if (namedResultSetProcessors.Count == 0) + { + //We could just have output parameters and/or return value, that is, no result sets + //If we didn't register a result set processor, it is likely that a result set wasn't expected. + break; + } + NamedResultSetProcessor firstResultSetProcessor = null; + NamedResultSetProcessor otherResultSetProcessor = null; + try + { + if (resultSetIndex == 0) + { + firstResultSetProcessor + = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; + //Will have possibility of run-time type error if using QueryWithCommandCreator + if (firstResultSetProcessor == null) + { + LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + + ", is not of expected type NamedResultSetProcessor. Type = " + + namedResultSetProcessors[resultSetIndex].GetType() + + "; Skipping processing for this result set."); + continue; + } + } + else + { + otherResultSetProcessor = + namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; + if (otherResultSetProcessor == null) + { + + LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + + ", is not of expected type NamedResultSetProcessor Type = " + + namedResultSetProcessors[resultSetIndex].GetType() + + "; Skipping processing for this result set."); + continue; + } + } + } + catch (IndexOutOfRangeException e) + { + LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); + continue; + } + catch (ArgumentOutOfRangeException e) + { + LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); + continue; + } + + + if (resultSetIndex == 0) + { + ProcessFirstGenericResultSetProcessor(firstResultSetProcessor, reader, returnedResults); + } + else + { + ProcessNonGenericResultSetProcessor(otherResultSetProcessor, reader, returnedResults); + } + resultSetIndex++; + + } while (reader.NextResult()); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedResults, command); + return returnedResults; + } + } + + + internal class AdoResultProcessorsQueryCommandCallback : BaseAdoResultProcessorsQueryCommandCallback, ICommandCallback + { + private AdoTemplate adoTemplate; + private IList namedResultSetProcessors; + + public AdoResultProcessorsQueryCommandCallback(AdoTemplate adoTemplate, IList namedResultSetProcessors) + { + this.adoTemplate = adoTemplate; + this.namedResultSetProcessors = namedResultSetProcessors; + } + + public object DoInCommand(IDbCommand command) + { + IDictionary returnedResults = new Hashtable(); + int resultSetIndex = 0; + IDataReader reader = null; + try + { + reader = adoTemplate.CreateDataReaderWrapper(command.ExecuteReader()); + + //TODO On >= .NET 2.0 platforms make use of DbDataReader.HasRows property to + // see if there is a result set. now currently assuming matching + // NamedResultSetProcessor/ResultSet pairs. + + do + { + if (namedResultSetProcessors.Count == 0) + { + //We could just have output parameters and/or return value, that is, no result sets + //If we didn't register a result set processor, it is likely that a result set wasn't expected. + break; + } + NamedResultSetProcessor firstResultSetProcessor = null; + NamedResultSetProcessor secondResultSetProcessor = null; + NamedResultSetProcessor otherResultSetProcessor = null; + try + { + if (resultSetIndex == 0) + { + firstResultSetProcessor = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; + //Will only have possibility of run-time type error if using QueryWithCommandCreator + if (firstResultSetProcessor == null) + { + + LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + + ", is not of expected type NamedResultSetProcessor Type = " + + namedResultSetProcessors[resultSetIndex].GetType() + + "; Skipping processing for this result set."); + continue; + } + } else if (resultSetIndex == 1) + { + secondResultSetProcessor + = namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; + if (secondResultSetProcessor == null) + { + + LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + + ", is not of expected type NamedResultSetProcessor Type = " + + namedResultSetProcessors[resultSetIndex].GetType() + + "; Skipping processing for this result set."); + continue; + } + } else + { + otherResultSetProcessor = + namedResultSetProcessors[resultSetIndex] as NamedResultSetProcessor; + if (otherResultSetProcessor == null) + { + + LOG.Error("NamedResultSetProcessor for result set index " + resultSetIndex + + ", is not of expected type NamedResultSetProcessor Type = " + + namedResultSetProcessors[resultSetIndex].GetType() + + "; Skipping processing for this result set."); + continue; + } + } + + } + catch (IndexOutOfRangeException e) + { + LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); + continue; + } + catch (ArgumentOutOfRangeException e) + { + LOG.Error("No NamedResultSetProcessor associated with result set index " + resultSetIndex, e); + continue; + } + + if (resultSetIndex == 0) + { + ProcessFirstGenericResultSetProcessor(firstResultSetProcessor, reader, returnedResults); + } + else if (resultSetIndex == 1) + { + string parameterName = secondResultSetProcessor.Name; + if (secondResultSetProcessor.ResultSetExtractor != null) + { + IResultSetExtractor rse = secondResultSetProcessor.ResultSetExtractor; + U result = rse.ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (secondResultSetProcessor.RowMapper != null) + { + IRowMapper rowMapper = secondResultSetProcessor.RowMapper; + object result = (new RowMapperResultSetExtractor(rowMapper)).ExtractData(reader); + returnedResults.Add(parameterName, result); + } + else if (secondResultSetProcessor.RowCallback != null) + { + //In this case a dummy type parameter would need to be specified a better alternative would + //be to to use the single type parameterization of this callback. + IRowCallback rowCallback = secondResultSetProcessor.RowCallback; + (new RowCallbackResultSetExtractor(rowCallback)).ExtractData(reader); + returnedResults.Add(parameterName, "ResultSet returned was processed by an IRowCallback"); + } + } + else + { + ProcessNonGenericResultSetProcessor(otherResultSetProcessor, reader, returnedResults); + } + resultSetIndex++; + + } while (reader.NextResult()); + } + finally + { + AdoUtils.CloseReader(reader); + } + ParameterUtils.ExtractOutputParameters(returnedResults, command); + return returnedResults; + } + + + } + #endregion + + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/CommandDelegate.cs b/src/Spring/Spring.Data/Data/Generic/CommandDelegate.cs index f924380f..ecfbe4c2 100644 --- a/src/Spring/Spring.Data/Data/Generic/CommandDelegate.cs +++ b/src/Spring/Spring.Data/Data/Generic/CommandDelegate.cs @@ -1,49 +1,49 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data.Common; - -namespace Spring.Data.Generic -{ - /// - /// Generic callback delegate for code that operates on a DbCommand. - /// - /// - ///

Allows you to execute any number of operations - /// on a single DbCommand, for example a single ExecuteScalar - /// call or repeated execute calls with varying parameters. - ///

- ///

Used internally by AdoTemplate, but also useful for - /// application code. Note that the passed in DbCommand - /// has been created by the framework and will have its - /// Connection property set and the Transaction property - /// set based on the transaction context.

- ///
- /// The return type from executing the - /// callback - /// The ADO.NET DbCommand object - /// The object returned from processing with the - /// provided DbCommand - /// Mark Pollack - public delegate T CommandDelegate(DbCommand command); -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data.Common; + +namespace Spring.Data.Generic +{ + /// + /// Generic callback delegate for code that operates on a DbCommand. + /// + /// + ///

Allows you to execute any number of operations + /// on a single DbCommand, for example a single ExecuteScalar + /// call or repeated execute calls with varying parameters. + ///

+ ///

Used internally by AdoTemplate, but also useful for + /// application code. Note that the passed in DbCommand + /// has been created by the framework and will have its + /// Connection property set and the Transaction property + /// set based on the transaction context.

+ ///
+ /// The return type from executing the + /// callback + /// The ADO.NET DbCommand object + /// The object returned from processing with the + /// provided DbCommand + /// Mark Pollack + public delegate T CommandDelegate(DbCommand command); +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/DataAdapterDelegate.cs b/src/Spring/Spring.Data/Data/Generic/DataAdapterDelegate.cs index 2ac0ee66..30742890 100644 --- a/src/Spring/Spring.Data/Data/Generic/DataAdapterDelegate.cs +++ b/src/Spring/Spring.Data/Data/Generic/DataAdapterDelegate.cs @@ -1,39 +1,39 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Called by AdoTemplate.Execute with an preconfigured - /// ADO.NET IDbDataAdapter instance with its SelectCommand - /// property populated with CommandType and Text values - /// along with Connection/Transaction properties based on the - /// calling transaction context. - /// - /// An active IDbDataAdapter instance - /// The result object - public delegate T DataAdapterDelegate(IDbDataAdapter dataAdapter); - -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Called by AdoTemplate.Execute with an preconfigured + /// ADO.NET IDbDataAdapter instance with its SelectCommand + /// property populated with CommandType and Text values + /// along with Connection/Transaction properties based on the + /// calling transaction context. + /// + /// An active IDbDataAdapter instance + /// The result object + public delegate T DataAdapterDelegate(IDbDataAdapter dataAdapter); + +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/IAdoOperations.cs b/src/Spring/Spring.Data/Data/Generic/IAdoOperations.cs index 9c37910b..a5ce6a94 100644 --- a/src/Spring/Spring.Data/Data/Generic/IAdoOperations.cs +++ b/src/Spring/Spring.Data/Data/Generic/IAdoOperations.cs @@ -1,237 +1,236 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using Spring.Data.Common; - -namespace Spring.Data.Generic -{ - /// - /// Interface that defines ADO.NET related database operations using generics - /// - /// Mark Pollack (.NET) - /// $Id: IAdoOperations.cs,v 1.9 2007/12/04 06:48:21 markpollack Exp $ - public interface IAdoOperations : ICommonAdoOperations - { - - #region General Execute Callback Methods - - - /// - /// Execute a ADO.NET operation on a command object using a generic interface based callback. - /// - /// The type of object returned from the callback. - /// the callback to execute based on DbCommand - /// An object returned from callback - T Execute(ICommandCallback action); - - /// - /// Execute a ADO.NET operation on a command object using a generic interface based callback. - /// - /// The type of object returned from the callback. - /// The callback to execute based on IDbCommand - /// An object returned from callback - T Execute(IDbCommandCallback action); - - /// - /// Execute a ADO.NET operation on a command object using a generic delegate callback. - /// - /// The type of object returned from the callback. - /// This allows for implementing arbitrary data access operations - /// on a single command within Spring's managed ADO.NET environment. - /// The delegate called with a DbCommand object. - /// A result object returned by the action or null - T Execute(CommandDelegate del); - - /// - /// Execute a ADO.NET operation on a command object using a generic delegate callback. - /// - /// The type of object returned from the callback. - /// This allows for implementing arbitrary data access operations - /// on a single command within Spring's managed ADO.NET environment. - /// The delegate called with a IDbCommand object. - /// A result object returned by the action or null - T Execute(IDbCommandDelegate del); - - /// - /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, - /// using the interface based callback IDbCommandCallback. - /// - /// The type of object returned from the callback. - /// The command creator. - /// The callback to execute based on IDbCommand - /// A result object returned by the action or null - T Execute(IDbCommandCreator commandCreator, IDbCommandCallback action); - - /// - /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. - /// - /// This allows for implementing abritrary data access operations - /// on a single DataAdapter within Spring's managed ADO.NET environment. - /// - /// The type of object returned from the callback. - /// The data adapter callback. - /// A result object returned by the callback or null - T Execute(IDataAdapterCallback dataAdapterCallback); - - /// - /// Execute ADO.NET operations on a IDbDataAdapter object using an delgate based callback. - /// - /// This allows for implementing abritrary data access operations - /// on a single DataAdapter within Spring's managed ADO.NET environment. - /// - /// The type of object returned from the callback. - /// The delegate called with a IDbDataAdapter object. - /// A result object returned by the callback or null - T Execute(DataAdapterDelegate del); - - #endregion - - #region Queries with RowMapper - - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper); - - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, - ICommandSetter commandSetter); - - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, - string parameterName, Enum dbType, int size, object parameterValue); - - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, - IDbParameters parameters); - - - #endregion - - #region Queries with RowMapperDelegate - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate); - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - ICommandSetter commandSetter); - - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - string parameterName, Enum dbType, int size, object parameterValue); - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - IDbParameters parameters); - - - #endregion - - #region Queries with ResultSetExtractor - - T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor); - - T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - string name, Enum dbType, int size, object parameterValue); - - T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - IDbParameters parameters); - - T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - ICommandSetter commandSetter); - - T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - CommandSetterDelegate commandSetterDelegate); - #endregion - - - #region Queries with ResultSetExtractorDelegate - - T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor); - - T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, - string paramenterName, Enum dbType, int size, object parameterValue); - - T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, - IDbParameters parameters); - - T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, - ICommandSetter commandSetter); - - T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, - CommandSetterDelegate commandSetterDelegate); - #endregion - - #region Queries for Object - - T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper); - - - T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper, ICommandSetter commandSetter); - - - T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper, IDbParameters parameters); - - - T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper, - string name, Enum dbType, int size, object parameterValue); - - - - #endregion - - #region Queries for ObjectDelegate - - T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper); - - - T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper, ICommandSetter commandSetter); - - - T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper, IDbParameters parameters); - - - T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper, - string name, Enum dbType, int size, object parameterValue); - - - - #endregion - - #region Query With CommandCreator - - T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse); - - IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper); - - T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse, IDictionary returnedParameters); - - IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper, - IDictionary returnedParameters); - - - IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors); - - IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors); - - #endregion - - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using Spring.Data.Common; + +namespace Spring.Data.Generic +{ + /// + /// Interface that defines ADO.NET related database operations using generics + /// + /// Mark Pollack (.NET) + public interface IAdoOperations : ICommonAdoOperations + { + + #region General Execute Callback Methods + + + /// + /// Execute a ADO.NET operation on a command object using a generic interface based callback. + /// + /// The type of object returned from the callback. + /// the callback to execute based on DbCommand + /// An object returned from callback + T Execute(ICommandCallback action); + + /// + /// Execute a ADO.NET operation on a command object using a generic interface based callback. + /// + /// The type of object returned from the callback. + /// The callback to execute based on IDbCommand + /// An object returned from callback + T Execute(IDbCommandCallback action); + + /// + /// Execute a ADO.NET operation on a command object using a generic delegate callback. + /// + /// The type of object returned from the callback. + /// This allows for implementing arbitrary data access operations + /// on a single command within Spring's managed ADO.NET environment. + /// The delegate called with a DbCommand object. + /// A result object returned by the action or null + T Execute(CommandDelegate del); + + /// + /// Execute a ADO.NET operation on a command object using a generic delegate callback. + /// + /// The type of object returned from the callback. + /// This allows for implementing arbitrary data access operations + /// on a single command within Spring's managed ADO.NET environment. + /// The delegate called with a IDbCommand object. + /// A result object returned by the action or null + T Execute(IDbCommandDelegate del); + + /// + /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, + /// using the interface based callback IDbCommandCallback. + /// + /// The type of object returned from the callback. + /// The command creator. + /// The callback to execute based on IDbCommand + /// A result object returned by the action or null + T Execute(IDbCommandCreator commandCreator, IDbCommandCallback action); + + /// + /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. + /// + /// This allows for implementing abritrary data access operations + /// on a single DataAdapter within Spring's managed ADO.NET environment. + /// + /// The type of object returned from the callback. + /// The data adapter callback. + /// A result object returned by the callback or null + T Execute(IDataAdapterCallback dataAdapterCallback); + + /// + /// Execute ADO.NET operations on a IDbDataAdapter object using an delgate based callback. + /// + /// This allows for implementing abritrary data access operations + /// on a single DataAdapter within Spring's managed ADO.NET environment. + /// + /// The type of object returned from the callback. + /// The delegate called with a IDbDataAdapter object. + /// A result object returned by the callback or null + T Execute(DataAdapterDelegate del); + + #endregion + + #region Queries with RowMapper + + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper); + + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, + ICommandSetter commandSetter); + + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, + string parameterName, Enum dbType, int size, object parameterValue); + + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, + IDbParameters parameters); + + + #endregion + + #region Queries with RowMapperDelegate + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate); + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + ICommandSetter commandSetter); + + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + string parameterName, Enum dbType, int size, object parameterValue); + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + IDbParameters parameters); + + + #endregion + + #region Queries with ResultSetExtractor + + T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor); + + T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + string name, Enum dbType, int size, object parameterValue); + + T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + IDbParameters parameters); + + T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + ICommandSetter commandSetter); + + T QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + CommandSetterDelegate commandSetterDelegate); + #endregion + + + #region Queries with ResultSetExtractorDelegate + + T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor); + + T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, + string paramenterName, Enum dbType, int size, object parameterValue); + + T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, + IDbParameters parameters); + + T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, + ICommandSetter commandSetter); + + T QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractor, + CommandSetterDelegate commandSetterDelegate); + #endregion + + #region Queries for Object + + T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper); + + + T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper, ICommandSetter commandSetter); + + + T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper, IDbParameters parameters); + + + T QueryForObject(CommandType cmdType, string sql, IRowMapper rowMapper, + string name, Enum dbType, int size, object parameterValue); + + + + #endregion + + #region Queries for ObjectDelegate + + T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper); + + + T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper, ICommandSetter commandSetter); + + + T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper, IDbParameters parameters); + + + T QueryForObjectDelegate(CommandType cmdType, string sql, RowMapperDelegate rowMapper, + string name, Enum dbType, int size, object parameterValue); + + + + #endregion + + #region Query With CommandCreator + + T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse); + + IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper); + + T QueryWithCommandCreator(IDbCommandCreator cc, IResultSetExtractor rse, IDictionary returnedParameters); + + IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper, + IDictionary returnedParameters); + + + IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors); + + IDictionary QueryWithCommandCreator(IDbCommandCreator cc, IList namedResultSetProcessors); + + #endregion + + + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/ICommandCallback.cs b/src/Spring/Spring.Data/Data/Generic/ICommandCallback.cs index ccbf2ec2..d33355f8 100644 --- a/src/Spring/Spring.Data/Data/Generic/ICommandCallback.cs +++ b/src/Spring/Spring.Data/Data/Generic/ICommandCallback.cs @@ -1,60 +1,60 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data.Common; - -namespace Spring.Data.Generic -{ - - /// - /// Generic callback interface for code that operates on a - /// DbCommand. - /// - /// The return type from executing the - /// callback - /// - ///

Allows you to execute any number of operations - /// on a single DbCommand, for example a single ExecuteScalar - /// call or repeated execute calls with varying parameters. - ///

- ///

Used internally by AdoTemplate, but also useful for - /// application code. Note that the passed in DbCommand - /// has been created by the framework and will have its - /// Connection property set and the Transaction property - /// set based on the transaction context.

- ///
- /// Mark Pollack - public interface ICommandCallback - { - /// - /// Called by AdoTemplate.Execute with an active ADO.NET IDbCommand. - /// The calling code does not need to care about closing the - /// command or the connection, or - /// about handling transactions: this will all be handled by - /// Spring's AdoTemplate - /// - /// An active IDbCommand instance - /// The result object - T DoInCommand(DbCommand command); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data.Common; + +namespace Spring.Data.Generic +{ + + /// + /// Generic callback interface for code that operates on a + /// DbCommand. + /// + /// The return type from executing the + /// callback + /// + ///

Allows you to execute any number of operations + /// on a single DbCommand, for example a single ExecuteScalar + /// call or repeated execute calls with varying parameters. + ///

+ ///

Used internally by AdoTemplate, but also useful for + /// application code. Note that the passed in DbCommand + /// has been created by the framework and will have its + /// Connection property set and the Transaction property + /// set based on the transaction context.

+ ///
+ /// Mark Pollack + public interface ICommandCallback + { + /// + /// Called by AdoTemplate.Execute with an active ADO.NET IDbCommand. + /// The calling code does not need to care about closing the + /// command or the connection, or + /// about handling transactions: this will all be handled by + /// Spring's AdoTemplate + /// + /// An active IDbCommand instance + /// The result object + T DoInCommand(DbCommand command); + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/IDataAdapterCallback.cs b/src/Spring/Spring.Data/Data/Generic/IDataAdapterCallback.cs index 5663c770..3626e70c 100644 --- a/src/Spring/Spring.Data/Data/Generic/IDataAdapterCallback.cs +++ b/src/Spring/Spring.Data/Data/Generic/IDataAdapterCallback.cs @@ -1,62 +1,61 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Generic callback interface for code that operates on a - /// IDbDataAdapter. - /// - /// - ///

Allows you to execute any number of operations - /// on a IDbDataAdapter, for example to Fill a DataSet - /// or other more advanced operations such as the transfering - /// data between two different DataSets. - ///

- ///

Note that the passed in IDbDataAdapter - /// has been created by the framework and its SelectCommand - /// will be populated with values for CommandType and Text properties - /// along with Connection/Transaction properties based on the - /// calling transaction context. - ///

- /// Execute(IDataAdapterCallback dataAdapterCallback) - /// method. - ///
- /// Mark Pollack (.NET) - /// $Id: IDataAdapterCallback.cs,v 1.1 2007/12/04 06:48:21 markpollack Exp $ - public interface IDataAdapterCallback - { - /// - /// Called by AdoTemplate.Execute with an preconfigured - /// ADO.NET IDbDataAdapter instance with its SelectCommand - /// property populated with CommandType and Text values - /// along with Connection/Transaction properties based on the - /// calling transaction context. - /// - /// An active IDbDataAdapter instance - /// The result object - T DoInDataAdapter(IDbDataAdapter dataAdapter); - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Generic callback interface for code that operates on a + /// IDbDataAdapter. + /// + /// + ///

Allows you to execute any number of operations + /// on a IDbDataAdapter, for example to Fill a DataSet + /// or other more advanced operations such as the transfering + /// data between two different DataSets. + ///

+ ///

Note that the passed in IDbDataAdapter + /// has been created by the framework and its SelectCommand + /// will be populated with values for CommandType and Text properties + /// along with Connection/Transaction properties based on the + /// calling transaction context. + ///

+ /// Execute(IDataAdapterCallback dataAdapterCallback) + /// method. + ///
+ /// Mark Pollack (.NET) + public interface IDataAdapterCallback + { + /// + /// Called by AdoTemplate.Execute with an preconfigured + /// ADO.NET IDbDataAdapter instance with its SelectCommand + /// property populated with CommandType and Text values + /// along with Connection/Transaction properties based on the + /// calling transaction context. + /// + /// An active IDbDataAdapter instance + /// The result object + T DoInDataAdapter(IDbDataAdapter dataAdapter); + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/IDbCommandCallback.cs b/src/Spring/Spring.Data/Data/Generic/IDbCommandCallback.cs index d23859b9..43cbe130 100644 --- a/src/Spring/Spring.Data/Data/Generic/IDbCommandCallback.cs +++ b/src/Spring/Spring.Data/Data/Generic/IDbCommandCallback.cs @@ -1,66 +1,66 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Generic callback interface for code that operates on a - /// IDbCommand. - /// - /// The return type from executing the - /// callback - /// - ///

Allows you to execute any number of operations - /// on a single IDbCommand, for example a single ExecuteScalar - /// call or repeated execute calls with varying parameters. - ///

- ///

Used internally by AdoTemplate, but also useful for - /// application code. Note that the passed in IDbCommand - /// has been created by the framework and will have its - /// Connection property set and the Transaction property - /// set based on the transaction context.

- ///

As an alternative to using this interface you can use - /// the delegate version which is particularly nice when using - /// anonymous delegates for writing more terse code and having - /// easy access to the variables in the calling class.

- ///

See for a version that has the - /// base class DbCommand as the callback argument.

- ///
- /// Mark Pollack - public interface IDbCommandCallback - { - /// - /// Called by AdoTemplate.Execute with an active ADO.NET IDbCommand. - /// The calling code does not need to care about closing the - /// command or the connection, or - /// about handling transactions: this will all be handled by - /// Spring's AdoTemplate - /// - /// An active IDbCommand instance - /// The result object - T DoInCommand(IDbCommand command); - } -} - +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Generic callback interface for code that operates on a + /// IDbCommand. + /// + /// The return type from executing the + /// callback + /// + ///

Allows you to execute any number of operations + /// on a single IDbCommand, for example a single ExecuteScalar + /// call or repeated execute calls with varying parameters. + ///

+ ///

Used internally by AdoTemplate, but also useful for + /// application code. Note that the passed in IDbCommand + /// has been created by the framework and will have its + /// Connection property set and the Transaction property + /// set based on the transaction context.

+ ///

As an alternative to using this interface you can use + /// the delegate version which is particularly nice when using + /// anonymous delegates for writing more terse code and having + /// easy access to the variables in the calling class.

+ ///

See for a version that has the + /// base class DbCommand as the callback argument.

+ ///
+ /// Mark Pollack + public interface IDbCommandCallback + { + /// + /// Called by AdoTemplate.Execute with an active ADO.NET IDbCommand. + /// The calling code does not need to care about closing the + /// command or the connection, or + /// about handling transactions: this will all be handled by + /// Spring's AdoTemplate + /// + /// An active IDbCommand instance + /// The result object + T DoInCommand(IDbCommand command); + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/IDbCommandDelegate.cs b/src/Spring/Spring.Data/Data/Generic/IDbCommandDelegate.cs index f8751d84..eb2ac4d2 100644 --- a/src/Spring/Spring.Data/Data/Generic/IDbCommandDelegate.cs +++ b/src/Spring/Spring.Data/Data/Generic/IDbCommandDelegate.cs @@ -1,50 +1,49 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Generic callback delegate for code that operates on a IDbCommand. - /// - /// - ///

Allows you to execute any number of operations - /// on a single IDbCommand, for example a single ExecuteScalar - /// call or repeated execute calls with varying parameters. - ///

- ///

Used internally by AdoTemplate, but also useful for - /// application code. Note that the passed in DbCommand - /// has been created by the framework and will have its - /// Connection property set and the Transaction property - /// set based on the transaction context.

- ///
- /// The return type from executing the - /// callback - /// The ADO.NET DbCommand object - /// The object returned from processing with the - /// provided DbCommand - /// Mark Pollack - /// $Id: IDbCommandDelegate.cs,v 1.1 2007/06/27 21:41:57 markpollack Exp $ - public delegate T IDbCommandDelegate(IDbCommand command); -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Generic callback delegate for code that operates on a IDbCommand. + /// + /// + ///

Allows you to execute any number of operations + /// on a single IDbCommand, for example a single ExecuteScalar + /// call or repeated execute calls with varying parameters. + ///

+ ///

Used internally by AdoTemplate, but also useful for + /// application code. Note that the passed in DbCommand + /// has been created by the framework and will have its + /// Connection property set and the Transaction property + /// set based on the transaction context.

+ ///
+ /// The return type from executing the + /// callback + /// The ADO.NET DbCommand object + /// The object returned from processing with the + /// provided DbCommand + /// Mark Pollack + public delegate T IDbCommandDelegate(IDbCommand command); +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/IResultSetExtractor.cs b/src/Spring/Spring.Data/Data/Generic/IResultSetExtractor.cs index 810b0114..4cdbaa2b 100644 --- a/src/Spring/Spring.Data/Data/Generic/IResultSetExtractor.cs +++ b/src/Spring/Spring.Data/Data/Generic/IResultSetExtractor.cs @@ -1,63 +1,63 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Callback interface to process all results sets and rows in - /// an AdoTemplate query method. - /// - /// Implementations of this interface perform the work - /// of extracting results but don't need worry about managing - /// ADO.NET resources, such as closing the reader. - ///

- /// This interface is mainly used within the ADO.NET - /// framework. An IResultSetExtractor is usually a simpler choice - /// for result set (DataReader) processing, in particular a - /// RowMapperResultSetExtractor in combination with a IRowMapper. - ///

- /// Note: in contracts to a IRowCallbackHandler, a ResultSetExtractor - /// is usually stateless and thus reusable, as long as it doesn't access - /// stateful resources or keep result state within the object. - /// - ///
- /// - public interface IResultSetExtractor - { - /// - /// Implementations must implement this method to process all - /// result set and rows in the IDataReader. - /// - /// The IDataReader to extract data from. - /// Implementations should not close this: it will be closed - /// by the AdoTemplate. - /// An arbitrary result object or null if none. The - /// extractor will typically be stateful in the latter case. - T ExtractData(IDataReader reader); - - - } -} - +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Callback interface to process all results sets and rows in + /// an AdoTemplate query method. + /// + /// Implementations of this interface perform the work + /// of extracting results but don't need worry about managing + /// ADO.NET resources, such as closing the reader. + ///

+ /// This interface is mainly used within the ADO.NET + /// framework. An IResultSetExtractor is usually a simpler choice + /// for result set (DataReader) processing, in particular a + /// RowMapperResultSetExtractor in combination with a IRowMapper. + ///

+ /// Note: in contracts to a IRowCallbackHandler, a ResultSetExtractor + /// is usually stateless and thus reusable, as long as it doesn't access + /// stateful resources or keep result state within the object. + /// + ///
+ /// + public interface IResultSetExtractor + { + /// + /// Implementations must implement this method to process all + /// result set and rows in the IDataReader. + /// + /// The IDataReader to extract data from. + /// Implementations should not close this: it will be closed + /// by the AdoTemplate. + /// An arbitrary result object or null if none. The + /// extractor will typically be stateful in the latter case. + T ExtractData(IDataReader reader); + + + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Generic/IRowMapper.cs b/src/Spring/Spring.Data/Data/Generic/IRowMapper.cs index e4e635f2..56c7d974 100644 --- a/src/Spring/Spring.Data/Data/Generic/IRowMapper.cs +++ b/src/Spring/Spring.Data/Data/Generic/IRowMapper.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Generic callback to process each row of data in a result set to an object. - /// - /// Implementations of this interface perform the actual work - /// of mapping rows, but don't need worry about managing - /// ADO.NET resources, such as closing the reader. - ///

- /// Typically used for AdoTemplate's query methods (with RowMapperResultSetExtractor - /// adapters). RowMapper objects are typically stateless and thus - /// reusable; they are ideal choices for implementing row-mapping logic in a single - /// place. - ///

- ///

Alternatively, consider subclassing MappingSqlQuery from the Spring.Data.Object - /// namespace: Instead of working with separate AdoTemplate and RowMapper objects, - /// you can have executable query objects (containing row-mapping logic) there. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: IRowMapper.cs,v 1.4 2007/06/28 18:48:18 markpollack Exp $ - public interface IRowMapper - { - /// - /// Implementations must implement this method to map each row of data in the - /// result set (DataReader). This method should not call Next() on the - /// DataReader; it should only extract the values of the current row. - /// - /// The IDataReader to map (pre-initialized to the current row) - /// The number of the current row.. - /// The specific typed result object for the current row. - T MapRow(IDataReader reader, int rowNum); - } -} - -#endif +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Generic callback to process each row of data in a result set to an object. + /// + /// Implementations of this interface perform the actual work + /// of mapping rows, but don't need worry about managing + /// ADO.NET resources, such as closing the reader. + ///

+ /// Typically used for AdoTemplate's query methods (with RowMapperResultSetExtractor + /// adapters). RowMapper objects are typically stateless and thus + /// reusable; they are ideal choices for implementing row-mapping logic in a single + /// place. + ///

+ ///

Alternatively, consider subclassing MappingSqlQuery from the Spring.Data.Object + /// namespace: Instead of working with separate AdoTemplate and RowMapper objects, + /// you can have executable query objects (containing row-mapping logic) there. + ///

+ ///
+ /// Mark Pollack (.NET) + public interface IRowMapper + { + /// + /// Implementations must implement this method to map each row of data in the + /// result set (DataReader). This method should not call Next() on the + /// DataReader; it should only extract the values of the current row. + /// + /// The IDataReader to map (pre-initialized to the current row) + /// The number of the current row.. + /// The specific typed result object for the current row. + T MapRow(IDataReader reader, int rowNum); + } +} + +#endif diff --git a/src/Spring/Spring.Data/Data/Generic/NamedResultSetProcessor.cs b/src/Spring/Spring.Data/Data/Generic/NamedResultSetProcessor.cs index 31dc1d57..cbd4acba 100644 --- a/src/Spring/Spring.Data/Data/Generic/NamedResultSetProcessor.cs +++ b/src/Spring/Spring.Data/Data/Generic/NamedResultSetProcessor.cs @@ -1,123 +1,122 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - - - -#endregion - -using Spring.Data.Support; - -namespace Spring.Data.Generic -{ - /// - /// Provides a name to a ResultSetProcessor for use with AdoOperation subclasses - /// such as StoredProcedure. - /// - /// Mark Pollack (.NET) - /// $Id: NamedResultSetProcessor.cs,v 1.2 2007/07/25 13:32:31 oakinger Exp $ - public class NamedResultSetProcessor - { - #region Fields - - private IRowCallback rowCallback; - private IRowMapper rowMapper; - private IResultSetExtractor resultSetExtractor; - private string name; - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class with a - /// IRowCallback instance - /// - /// The name of the associated row callback for use with output - /// result set mappers. - /// A row callback instance. - public NamedResultSetProcessor(string name, IRowCallback rowcallback) - { - this.name = name; - this.rowCallback = rowcallback; - } - - /// - /// Initializes a new instance of the class with a - /// IRowMapper instance - /// - /// The name of the associated row mapper. - /// A IRowMapper instance. - public NamedResultSetProcessor(string name, IRowMapper rowMapper) - { - this.name = name; - this.rowMapper = rowMapper; - } - - /// - /// Initializes a new instance of the class with a - /// IResultSetExtractor instance - /// - /// The name of the associated result set extractor. - /// A IResultSetExtractor instance. - public NamedResultSetProcessor(string name, IResultSetExtractor resultSetExtractor) - { - this.name = name; - this.resultSetExtractor = resultSetExtractor; - } - - - #endregion - - #region Properties - public string Name - { - get - { - return name; - } - } - - - public IRowCallback RowCallback - { - get { return rowCallback; } - } - - public IRowMapper RowMapper - { - get { return rowMapper; } - } - - public IResultSetExtractor ResultSetExtractor - { - get { return resultSetExtractor; } - } - - #endregion - - - } -} - -#endif +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + + + +#endregion + +using Spring.Data.Support; + +namespace Spring.Data.Generic +{ + /// + /// Provides a name to a ResultSetProcessor for use with AdoOperation subclasses + /// such as StoredProcedure. + /// + /// Mark Pollack (.NET) + public class NamedResultSetProcessor + { + #region Fields + + private IRowCallback rowCallback; + private IRowMapper rowMapper; + private IResultSetExtractor resultSetExtractor; + private string name; + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class with a + /// IRowCallback instance + /// + /// The name of the associated row callback for use with output + /// result set mappers. + /// A row callback instance. + public NamedResultSetProcessor(string name, IRowCallback rowcallback) + { + this.name = name; + this.rowCallback = rowcallback; + } + + /// + /// Initializes a new instance of the class with a + /// IRowMapper instance + /// + /// The name of the associated row mapper. + /// A IRowMapper instance. + public NamedResultSetProcessor(string name, IRowMapper rowMapper) + { + this.name = name; + this.rowMapper = rowMapper; + } + + /// + /// Initializes a new instance of the class with a + /// IResultSetExtractor instance + /// + /// The name of the associated result set extractor. + /// A IResultSetExtractor instance. + public NamedResultSetProcessor(string name, IResultSetExtractor resultSetExtractor) + { + this.name = name; + this.resultSetExtractor = resultSetExtractor; + } + + + #endregion + + #region Properties + public string Name + { + get + { + return name; + } + } + + + public IRowCallback RowCallback + { + get { return rowCallback; } + } + + public IRowMapper RowMapper + { + get { return rowMapper; } + } + + public IResultSetExtractor ResultSetExtractor + { + get { return resultSetExtractor; } + } + + #endregion + + + } +} + +#endif diff --git a/src/Spring/Spring.Data/Data/Generic/ResultSetExtractorDelegate.cs b/src/Spring/Spring.Data/Data/Generic/ResultSetExtractorDelegate.cs index baa348e0..1141ffcd 100644 --- a/src/Spring/Spring.Data/Data/Generic/ResultSetExtractorDelegate.cs +++ b/src/Spring/Spring.Data/Data/Generic/ResultSetExtractorDelegate.cs @@ -1,40 +1,40 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - - /// - /// Callback delegate to process all result sets and row in an - /// AdoTemplate query method. - /// - /// The type returned from the result set mapping. - /// The IDataReader to extract data from. - /// Implementations should not close this: it will be closed - /// by the AdoTemplate. - /// An arbitrary result object or null if none. - public delegate T ResultSetExtractorDelegate(IDataReader reader); -} - -#endif +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + + /// + /// Callback delegate to process all result sets and row in an + /// AdoTemplate query method. + /// + /// The type returned from the result set mapping. + /// The IDataReader to extract data from. + /// Implementations should not close this: it will be closed + /// by the AdoTemplate. + /// An arbitrary result object or null if none. + public delegate T ResultSetExtractorDelegate(IDataReader reader); +} + +#endif diff --git a/src/Spring/Spring.Data/Data/Generic/RowMapperDelegate.cs b/src/Spring/Spring.Data/Data/Generic/RowMapperDelegate.cs index 6a0fea16..4a02569e 100644 --- a/src/Spring/Spring.Data/Data/Generic/RowMapperDelegate.cs +++ b/src/Spring/Spring.Data/Data/Generic/RowMapperDelegate.cs @@ -1,38 +1,38 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -using System.Data; - -namespace Spring.Data.Generic -{ - /// - /// Callback delegate to process each row of data in a result set to an object. - /// - /// The type of the object returned from the mapping operation. - /// The IDataReader to map - /// the number of the current row. - /// An abrirary object, typically derived from data - /// in the result set. - public delegate T RowMapperDelegate(IDataReader dataReader, int rowNum); -} - -#endif +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +using System.Data; + +namespace Spring.Data.Generic +{ + /// + /// Callback delegate to process each row of data in a result set to an object. + /// + /// The type of the object returned from the mapping operation. + /// The IDataReader to map + /// the number of the current row. + /// An abrirary object, typically derived from data + /// in the result set. + public delegate T RowMapperDelegate(IDataReader dataReader, int rowNum); +} + +#endif diff --git a/src/Spring/Spring.Data/Data/Generic/RowMapperResultSetExtractor.cs b/src/Spring/Spring.Data/Data/Generic/RowMapperResultSetExtractor.cs index b0ae3e42..2fd1033d 100644 --- a/src/Spring/Spring.Data/Data/Generic/RowMapperResultSetExtractor.cs +++ b/src/Spring/Spring.Data/Data/Generic/RowMapperResultSetExtractor.cs @@ -1,151 +1,150 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System.Collections.Generic; -using System.Data; -using Spring.Data.Support; -using Spring.Util; - -#endregion - -namespace Spring.Data.Generic -{ - /// - /// Adapter implementation of the ResultSetExtractor interface that delegates - /// to a RowMapper which is supposed to create an object for each row. - /// Each object is added to the results List of this ResultSetExtractor. - /// - /// - /// Useful for the typical case of one object per row in the database table. - /// The number of entries in the results list will match the number of rows. - ///

- /// Note that a RowMapper object is typically stateless and thus reusable; - /// just the RowMapperResultSetExtractor adapter is stateful. - ///

- ///

- /// As an alternative consider subclassing MappingAdoQuery from the - /// Spring.Data.Objects namespace: Instead of working with separate - /// AdoTemplate and IRowMapper objects you can have executable - /// query objects (containing row-mapping logic) there. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: RowMapperResultSetExtractor.cs,v 1.4 2007/08/03 19:51:10 markpollack Exp $ - public class RowMapperResultSetExtractor : IResultSetExtractor> - { - #region Fields - - private IRowMapper rowMapper; - - private RowMapperDelegate rowMapperDelegate; - - private int rowsExpected; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public RowMapperResultSetExtractor(IRowMapper rowMapper) : this(rowMapper,0, null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The row mapper. - /// The rows expected. - public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected) : this(rowMapper, rowsExpected, null) - { - } - public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected, IDataReaderWrapper dataReaderWrapper) - { - //TODO use datareaderwrapper - AssertUtils.ArgumentNotNull(rowMapper, "rowMapper"); - - this.rowMapper = rowMapper; - this.rowsExpected = rowsExpected; - } - - public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate) - : this(rowMapperDelegate, 0, null) - { - } - - public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected) - : this(rowMapperDelegate, rowsExpected, null) - { - } - public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected, IDataReaderWrapper dataReaderWrapper) - { - //TODO use datareaderwrapper - - AssertUtils.ArgumentNotNull(rowMapperDelegate, "rowMapperDelegate"); - - this.rowMapperDelegate = rowMapperDelegate; - this.rowsExpected = rowsExpected; - } - - #endregion - - #region IResultSetExtractor Members - - public IList ExtractData(IDataReader reader) - { - // Use the more efficient collection if we know how many rows to expect: - // ArrayList in case of a known row count, LinkedList if unknown - //IList results = (rowsExpected > 0) ? new List(rowsExpected) : new LinkedList(); - - //how come LinkedList doesn't implement IList ?!?!?! - //some web entries claim slow indexer... need to write our own again? return ICollection instead? - //http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx - //We did not implement IList on LinkedList because the indexer would be - //very slow. If you really need the interface, you probably can inherit from - //LinkedList and implement the interface on the subtype. - IList results = new List(); - int rowNum = 0; - if (rowMapper != null) - { - while (reader.Read()) - { - results.Add(rowMapper.MapRow(reader, rowNum++)); - } - } - else - { - while (reader.Read()) - { - results.Add(rowMapperDelegate(reader, rowNum++)); - } - } - - return results; - } - - #endregion - } -} - +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System.Collections.Generic; +using System.Data; +using Spring.Data.Support; +using Spring.Util; + +#endregion + +namespace Spring.Data.Generic +{ + /// + /// Adapter implementation of the ResultSetExtractor interface that delegates + /// to a RowMapper which is supposed to create an object for each row. + /// Each object is added to the results List of this ResultSetExtractor. + /// + /// + /// Useful for the typical case of one object per row in the database table. + /// The number of entries in the results list will match the number of rows. + ///

+ /// Note that a RowMapper object is typically stateless and thus reusable; + /// just the RowMapperResultSetExtractor adapter is stateful. + ///

+ ///

+ /// As an alternative consider subclassing MappingAdoQuery from the + /// Spring.Data.Objects namespace: Instead of working with separate + /// AdoTemplate and IRowMapper objects you can have executable + /// query objects (containing row-mapping logic) there. + ///

+ ///
+ /// Mark Pollack (.NET) + public class RowMapperResultSetExtractor : IResultSetExtractor> + { + #region Fields + + private IRowMapper rowMapper; + + private RowMapperDelegate rowMapperDelegate; + + private int rowsExpected; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public RowMapperResultSetExtractor(IRowMapper rowMapper) : this(rowMapper,0, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The row mapper. + /// The rows expected. + public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected) : this(rowMapper, rowsExpected, null) + { + } + public RowMapperResultSetExtractor(IRowMapper rowMapper, int rowsExpected, IDataReaderWrapper dataReaderWrapper) + { + //TODO use datareaderwrapper + AssertUtils.ArgumentNotNull(rowMapper, "rowMapper"); + + this.rowMapper = rowMapper; + this.rowsExpected = rowsExpected; + } + + public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate) + : this(rowMapperDelegate, 0, null) + { + } + + public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected) + : this(rowMapperDelegate, rowsExpected, null) + { + } + public RowMapperResultSetExtractor(RowMapperDelegate rowMapperDelegate, int rowsExpected, IDataReaderWrapper dataReaderWrapper) + { + //TODO use datareaderwrapper + + AssertUtils.ArgumentNotNull(rowMapperDelegate, "rowMapperDelegate"); + + this.rowMapperDelegate = rowMapperDelegate; + this.rowsExpected = rowsExpected; + } + + #endregion + + #region IResultSetExtractor Members + + public IList ExtractData(IDataReader reader) + { + // Use the more efficient collection if we know how many rows to expect: + // ArrayList in case of a known row count, LinkedList if unknown + //IList results = (rowsExpected > 0) ? new List(rowsExpected) : new LinkedList(); + + //how come LinkedList doesn't implement IList ?!?!?! + //some web entries claim slow indexer... need to write our own again? return ICollection instead? + //http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx + //We did not implement IList on LinkedList because the indexer would be + //very slow. If you really need the interface, you probably can inherit from + //LinkedList and implement the interface on the subtype. + IList results = new List(); + int rowNum = 0; + if (rowMapper != null) + { + while (reader.Read()) + { + results.Add(rowMapper.MapRow(reader, rowNum++)); + } + } + else + { + while (reader.Read()) + { + results.Add(rowMapperDelegate(reader, rowNum++)); + } + } + + return results; + } + + #endregion + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/IAdoOperations.cs b/src/Spring/Spring.Data/Data/IAdoOperations.cs index c22b9cff..21bf9471 100644 --- a/src/Spring/Spring.Data/Data/IAdoOperations.cs +++ b/src/Spring/Spring.Data/Data/IAdoOperations.cs @@ -1,747 +1,746 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data -{ - /// - /// Interface that defines ADO.NET related database operations. - /// - /// Mark Pollack (.NET) - /// $Id: IAdoOperations.cs,v 1.24 2007/12/04 06:52:19 markpollack Exp $ - public interface IAdoOperations : ICommonAdoOperations - { - - #region General Execute Methods with Callbacks - /// - /// Execute a ADO.NET operation on a command object using a delegate callback. - /// - /// This allows for implementing arbitrary data access operations - /// on a single command within Spring's managed ADO.NET environment. - /// The delegate called with a command object. - /// A result object returned by the action or null - object Execute(CommandDelegate del); - - /// - /// Execute a ADO.NET operation on a command object using an interface based callback. - /// - /// the callback to execute - /// object returned from callback - object Execute(ICommandCallback action); - - /// - /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, - /// using the interface based callback IDbCommandCallback. - /// - /// The command creator. - /// The callback to execute based on IDbCommand - /// A result object returned by the action or null - object Execute(IDbCommandCreator commandCreator, ICommandCallback action); - - /// - /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. - /// - /// This allows for implementing abritrary data access operations - /// on a single DataAdapter within Spring's managed ADO.NET environment. - /// - /// The data adapter callback. - /// A result object returned by the callback or null - object Execute(IDataAdapterCallback dataAdapterCallback); - - #endregion - - - - - - #region Queries With ResultSetExtractor - - // Static Queries - - /// - /// Execute a query given IDbCommand's type and text, processing a - /// single result set with an instance of IResultSetExtractor - /// - /// The type of command - /// The text of the query. - /// Object that will extract all rows of a result set - /// An arbitrary result object, as returned by the IResultSetExtractor - /// - /// If there is any problem executing the query. - /// - object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor); - - - // Parameterized Queries - - - //only input parameters can be used... - - - /// - /// Execute a query given IDbCommand's type and text with parameters set - /// via the command setter, processing a - /// single result set with an instance of IResultSetExtractor - /// - /// The command type. - /// The command text to execute. - /// The result set extractor. - /// The command setter. - /// An arbitrary result object, as returned by the IResultSetExtractor - /// - /// If there is any problem executing the query. - /// - object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, - ICommandSetter commandSetter); - - //only input parameters can be used. - object QueryWithResultSetExtractor(CommandType commandType, string cmdText, IResultSetExtractor resultSetExtractor, - string parameterName, Enum dbType, int size, object parameterValue); - - //iterate over one or more result sets and then assign output parameters. - object QueryWithResultSetExtractor(CommandType commandType, string cmdText, IResultSetExtractor resultSetExtractor, - IDbParameters parameters); - - - #endregion - - #region Queries With ResultSetExtractorDelegate - - // Static Queries - - /// - /// Execute a query given static SQL/Stored Procedure name - /// and process a single result set with an instance of ResultSetExtractorDelegate - /// - /// The type of command. - /// The command text. - /// Delegate that will extract all rows of a result set - /// An arbitrary result object, as returned by the IResultSetExtractor - /// - /// If there is any problem executing the query. - /// - object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate); - - - // Parameterized Queries - - - //only input parameters can be used... - object QueryWithResultSetExtractorDelegate(CommandType commandType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate, - ICommandSetter commandSetter); - - //only input parameters can be used. - object QueryWithResultSetExtractorDelegate(CommandType commandType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate, - string parameterName, Enum dbType, int size, object parameterValue); - - //iterate over one or more result sets and then assign output parameters. - object QueryWithResultSetExtractorDelegate(CommandType commandType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate, - IDbParameters parameter); - - - #endregion - - #region Queries with RowMapperDelegate - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate); - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate, ICommandSetter commandSetter); - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate, - string parameterName, Enum dbType, int size, object parameterValue); - - IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate, IDbParameters parameter); - - - #endregion - - #region Queries with RowMapper - - // Static Queries - - - /// - /// Execute a query given static SQL, mapping each row to a .NET object - /// iva a RowMapper - /// - /// The type of command - /// SQL query to execute - /// object that will map one object per row - /// the result list containing mapped objects - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper); - - // Parameterized Queries - - //Using IRowMapper to process 1 result set - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter); - - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, - string name, Enum dbType, int size, object parameterValue); - - IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameter); - - - - #endregion - - #region Query for Object - - - - - - /// - /// Execute a query with the specified command text, mapping a single result - /// row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper); - - - /// - /// Execute a query with the specified command text and parameters set via the - /// command setter, mapping a single result row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The command setter. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter); - - /// - /// Execute a query with the specified command text and parameters, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The parameter collection to use in the query. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters); - - /// - /// Execute a query with the specified command text and parameter, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// object that will map one object per row - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, - string parameterName, Enum dbType, int size, object parameterValue); - - - /* - /// - /// Execute a query for a result list, given static SQL. - /// - /// - /// The results will be mapped to a List (one entry for each row) - /// of IDictionaries (one entry for each column using he column - /// name as the key). Each element in the list will be of the form - /// returned by ths interfaces QueryForMap() methods. - /// - /// The type of the command. - /// The SQL query to execute - /// - IList QueryForList(CommandType cmdType, string sql); - */ - //IDictionary QueryForDictionary(CommandType cmdType, string sql); - //TODO - - //Object QueryForObject(CommandType cmdType, String sql, Type requiredType) throws DataAccessException; - //IDictionary QueryForDictionary - //IList QueryForList - - #endregion - - #region Query for ObjectDelegate - - /// - /// Execute a query with the specified command text, mapping a single result - /// row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate); - - - - /// - /// Execute a query with the specified command text and parameters set via the - /// command setter, mapping a single result row to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The command setter. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter); - - - /// - /// Execute a query with the specified command text and parameters, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The parameter collection to use in the query. - /// The single mapped object. - /// - /// If the query does not return exactly one row. - /// - /// - /// If there is any problem executing the query. - /// - object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, IDbParameters parameters); - - - /// - /// Execute a query with the specified command text and parameter, mapping a single result row - /// to an object via a RowMapper. - /// - /// The command type. - /// The command text to execute. - /// delegate that will map one object per row - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// - object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, - string parameterName, Enum dbType, int size, object parameterValue); - - - #endregion - - #region Query With CommandCreator - - // Using IResultSetExtractor to process one result set. - object QueryWithCommandCreator(IDbCommandCreator commandCreator, IResultSetExtractor resultSetExtractor); - - IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper); - - // Using IResultSetExtractor to return one result set, multiple output parameters. - object QueryWithCommandCreator(IDbCommandCreator commandCreator, IResultSetExtractor resultSetExtractor, IDictionary returnedParameters); - - // Using IRowMapper to return one result set, multiple output parameters. - IList QueryWithCommandCreator(IDbCommandCreator commandCreator, IRowMapper rowMapper, IDictionary returnedParameters); - - - // Multiple return result sets, (A list of lists) - // each with either a IRowMapper, IResultSetExtractor, IRowCallback - // and multiple output parameters. - IDictionary QueryWithCommandCreator(IDbCommandCreator commandCreator, IList resultProcessors); - - //TODO - //Object QueryForObject(... Type requiredType) - //IDictionary QueryForDictionary - //IList QueryForList - - #endregion - - // *************************************************************** - // NB: Complex DataSet/DataTable operations are best handled with - // DataSetOperations class in Spring.Data.Objects - // *************************************************************** - - #region DataTable Create operations without parameters - - DataTable DataTableCreate(CommandType commandType, string sql); - - DataTable DataTableCreate(CommandType commandType, string sql, - string tableMappingName); - - DataTable DataTableCreate(CommandType commandType, string sql, - ITableMapping tableMapping); - - DataTable DataTableCreate(CommandType commandType, string sql, - ITableMapping tableMapping, - IDataAdapterSetter setter); - - #endregion - - #region DataTable Create operations with parameters - - DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters); - - DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - string tableMappingName); - - DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping); - - DataTable DataTableCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping, - IDataAdapterSetter dataAdapterSetter); - - - //TODO - /* - DataTable DataTableCreateWithParams(IDbDataAdapterCreator dataAdapterCreator); - */ - - #endregion - - #region DataTable Fill operations without parameters - /// - /// Fill a based on a select command that requires no parameters. - /// - /// The to populate - /// The type of command - /// SQL query to execute - /// The number of rows successfully added to or refreshed in the - int DataTableFill(DataTable dataTable, CommandType commandType, string sql); - - int DataTableFill(DataTable dataTable, CommandType commandType, string sql, - string tableMappingName); - - int DataTableFill(DataTable dataTable, CommandType commandType, string sql, - ITableMapping tableMapping); - - int DataTableFill(DataTable dataTable, CommandType commandType, string sql, - ITableMapping tableMapping, - IDataAdapterSetter setter); - - - #endregion - - #region DataTable Fill operations with parameters - - int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters); - - int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters, - string tableName); - - int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping); - - int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, - IDbParameters parameters, - ITableMapping tableMapping, - IDataAdapterSetter dataAdapterSetter); - - //TODO - /* - int DataTableFillWithParams(DataTable dataTable, - IDbDataAdapterCreator dataAdapterCreator); - - */ - #endregion - - #region DataTable Update operations - //TODO conflict options... - - int DataTableUpdateWithCommandBuilder(DataTable dataTable, - CommandType commandType, - string selectSql, - IDbParameters parameters, - string tableName); - - int DataTableUpdateWithCommandBuilder(DataTable dataTable, - CommandType commandType, - string selectSql, - IDbParameters parameters, - string tableName, - IDataAdapterSetter dataAdapterSetter); - - int DataTableUpdateWithCommandBuilder(DataTable dataTable, - CommandType commandType, - string selectSql, - IDbParameters parameters, - ITableMapping tableMapping, - IDataAdapterSetter dataAdapterSetter); - - int DataTableUpdate(DataTable dataTable, - string tableName, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters); - - int DataTableUpdate(DataTable dataTable, - string tableName, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, - IDataAdapterSetter dataAdapterSetter); - - int DataTableUpdate(DataTable dataTable, - ITableMapping tableMapping, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, - IDataAdapterSetter dataAdapterSetter); - - - - #endregion - - #region DataSet Create operations without parameters - - DataSet DataSetCreate(CommandType commandType, string sql); - - DataSet DataSetCreate(CommandType commandType, string sql, - string[] tableNames); - - DataSet DataSetCreate(CommandType commandType, string sql, - ITableMappingCollection tableMapping); - - DataSet DataSetCreate(CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter); - - DataSet DataSetCreate(CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor); - #endregion - - #region DataSet Create operations with parameters - - DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters); - - DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - string[] tableNames); - - DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping); - - DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter); - - DataSet DataSetCreateWithParams(CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor); - - #endregion - - #region DataSet Fill operations without parameters - - /// - /// Fill a based on a select command that requires no parameters. - /// - /// The to populate - /// The type of command - /// SQL query to execute - /// The number of rows successfully added to or refreshed in the - int DataSetFill(DataSet dataSet, CommandType commandType, string sql); - - /// - /// Fill a based on a select command that requires no parameters - /// that returns one or more result sets that are added as - /// s to the - /// - /// The to populate - /// The type of command - /// SQL query to execute - /// The mapping of table names for each - /// created - /// - int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - string[] tableNames); - - int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - ITableMappingCollection tableMapping); - - int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter); - - int DataSetFill(DataSet dataSet, CommandType commandType, string sql, - ITableMappingCollection tableMapping, - IDataAdapterSetter setter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor); - - #endregion - - #region DataSet Fill operations with parameters - - int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters); - - int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - string[] tableNames); - - int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping); - - int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter); - - int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, - IDbParameters parameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter, - IDataSetFillLifecycleProcessor fillLifecycleProcessor); - - #endregion - - #region DataSet Update operations - //TODO expose RowUpdate event in a generic manner - //TODO any way to integrate Accept/RejectChanges based on tx outcome? - - int DataSetUpdateWithCommandBuilder(DataSet dataSet, - CommandType commandType, - string selectSql, - IDbParameters selectParameters, - string tableName); - - int DataSetUpdateWithCommandBuilder(DataSet dataSet, - CommandType commandType, - string selectSql, - IDbParameters selectParameters, - string tableName, - IDataAdapterSetter dataAdapterSetter); - - int DataSetUpdateWithCommandBuilder(DataSet dataSet, - CommandType commandType, - string selectSql, - IDbParameters selectParameters, - ITableMappingCollection tableMapping, - IDataAdapterSetter dataAdapterSetter); - - - int DataSetUpdate(DataSet dataSet, - string tableName, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand); - - - int DataSetUpdate(DataSet dataSet, - string tableName, - CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, - CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, - CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters); - - - int DataSetUpdate(DataSet dataSet, - string tableName, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand, - IDataAdapterSetter dataAdapterSetter); - - int DataSetUpdate(DataSet dataSet, - ITableMappingCollection tableMapping, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand); - - int DataSetUpdate(DataSet dataSet, - ITableMappingCollection tableMapping, - IDbCommand insertCommand, - IDbCommand updateCommand, - IDbCommand deleteCommand, - IDataAdapterSetter dataAdapterSetter); - - #endregion - - #region Parameter Creation Helper Methods - - IDbParameters CreateDbParameters(); - - /// - /// Note that output parameters are marked input/output after derivation.... - /// (TODO - double check....) - /// - /// - /// - IDataParameter[] DeriveParameters(string procedureName); - - IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter); - - #endregion - } - - -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data +{ + /// + /// Interface that defines ADO.NET related database operations. + /// + /// Mark Pollack (.NET) + public interface IAdoOperations : ICommonAdoOperations + { + + #region General Execute Methods with Callbacks + /// + /// Execute a ADO.NET operation on a command object using a delegate callback. + /// + /// This allows for implementing arbitrary data access operations + /// on a single command within Spring's managed ADO.NET environment. + /// The delegate called with a command object. + /// A result object returned by the action or null + object Execute(CommandDelegate del); + + /// + /// Execute a ADO.NET operation on a command object using an interface based callback. + /// + /// the callback to execute + /// object returned from callback + object Execute(ICommandCallback action); + + /// + /// Executes ADO.NET operations on a command object, created by the provided IDbCommandCreator, + /// using the interface based callback IDbCommandCallback. + /// + /// The command creator. + /// The callback to execute based on IDbCommand + /// A result object returned by the action or null + object Execute(IDbCommandCreator commandCreator, ICommandCallback action); + + /// + /// Execute ADO.NET operations on a IDbDataAdapter object using an interface based callback. + /// + /// This allows for implementing abritrary data access operations + /// on a single DataAdapter within Spring's managed ADO.NET environment. + /// + /// The data adapter callback. + /// A result object returned by the callback or null + object Execute(IDataAdapterCallback dataAdapterCallback); + + #endregion + + + + + + #region Queries With ResultSetExtractor + + // Static Queries + + /// + /// Execute a query given IDbCommand's type and text, processing a + /// single result set with an instance of IResultSetExtractor + /// + /// The type of command + /// The text of the query. + /// Object that will extract all rows of a result set + /// An arbitrary result object, as returned by the IResultSetExtractor + /// + /// If there is any problem executing the query. + /// + object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor); + + + // Parameterized Queries + + + //only input parameters can be used... + + + /// + /// Execute a query given IDbCommand's type and text with parameters set + /// via the command setter, processing a + /// single result set with an instance of IResultSetExtractor + /// + /// The command type. + /// The command text to execute. + /// The result set extractor. + /// The command setter. + /// An arbitrary result object, as returned by the IResultSetExtractor + /// + /// If there is any problem executing the query. + /// + object QueryWithResultSetExtractor(CommandType cmdType, string cmdText, IResultSetExtractor resultSetExtractor, + ICommandSetter commandSetter); + + //only input parameters can be used. + object QueryWithResultSetExtractor(CommandType commandType, string cmdText, IResultSetExtractor resultSetExtractor, + string parameterName, Enum dbType, int size, object parameterValue); + + //iterate over one or more result sets and then assign output parameters. + object QueryWithResultSetExtractor(CommandType commandType, string cmdText, IResultSetExtractor resultSetExtractor, + IDbParameters parameters); + + + #endregion + + #region Queries With ResultSetExtractorDelegate + + // Static Queries + + /// + /// Execute a query given static SQL/Stored Procedure name + /// and process a single result set with an instance of ResultSetExtractorDelegate + /// + /// The type of command. + /// The command text. + /// Delegate that will extract all rows of a result set + /// An arbitrary result object, as returned by the IResultSetExtractor + /// + /// If there is any problem executing the query. + /// + object QueryWithResultSetExtractorDelegate(CommandType cmdType, string cmdText, ResultSetExtractorDelegate resultSetExtractorDelegate); + + + // Parameterized Queries + + + //only input parameters can be used... + object QueryWithResultSetExtractorDelegate(CommandType commandType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate, + ICommandSetter commandSetter); + + //only input parameters can be used. + object QueryWithResultSetExtractorDelegate(CommandType commandType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate, + string parameterName, Enum dbType, int size, object parameterValue); + + //iterate over one or more result sets and then assign output parameters. + object QueryWithResultSetExtractorDelegate(CommandType commandType, string sql, ResultSetExtractorDelegate resultSetExtractorDelegate, + IDbParameters parameter); + + + #endregion + + #region Queries with RowMapperDelegate + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate); + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate, ICommandSetter commandSetter); + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate, + string parameterName, Enum dbType, int size, object parameterValue); + + IList QueryWithRowMapperDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate, IDbParameters parameter); + + + #endregion + + #region Queries with RowMapper + + // Static Queries + + + /// + /// Execute a query given static SQL, mapping each row to a .NET object + /// iva a RowMapper + /// + /// The type of command + /// SQL query to execute + /// object that will map one object per row + /// the result list containing mapped objects + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper); + + // Parameterized Queries + + //Using IRowMapper to process 1 result set + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter); + + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, + string name, Enum dbType, int size, object parameterValue); + + IList QueryWithRowMapper(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameter); + + + + #endregion + + #region Query for Object + + + + + + /// + /// Execute a query with the specified command text, mapping a single result + /// row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper); + + + /// + /// Execute a query with the specified command text and parameters set via the + /// command setter, mapping a single result row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The command setter. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, ICommandSetter commandSetter); + + /// + /// Execute a query with the specified command text and parameters, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The parameter collection to use in the query. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, IDbParameters parameters); + + /// + /// Execute a query with the specified command text and parameter, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// object that will map one object per row + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObject(CommandType cmdType, string cmdText, IRowMapper rowMapper, + string parameterName, Enum dbType, int size, object parameterValue); + + + /* + /// + /// Execute a query for a result list, given static SQL. + /// + /// + /// The results will be mapped to a List (one entry for each row) + /// of IDictionaries (one entry for each column using he column + /// name as the key). Each element in the list will be of the form + /// returned by ths interfaces QueryForMap() methods. + /// + /// The type of the command. + /// The SQL query to execute + /// + IList QueryForList(CommandType cmdType, string sql); + */ + //IDictionary QueryForDictionary(CommandType cmdType, string sql); + //TODO - + //Object QueryForObject(CommandType cmdType, String sql, Type requiredType) throws DataAccessException; + //IDictionary QueryForDictionary + //IList QueryForList + + #endregion + + #region Query for ObjectDelegate + + /// + /// Execute a query with the specified command text, mapping a single result + /// row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelgate); + + + + /// + /// Execute a query with the specified command text and parameters set via the + /// command setter, mapping a single result row to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The command setter. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, ICommandSetter commandSetter); + + + /// + /// Execute a query with the specified command text and parameters, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The parameter collection to use in the query. + /// The single mapped object. + /// + /// If the query does not return exactly one row. + /// + /// + /// If there is any problem executing the query. + /// + object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, IDbParameters parameters); + + + /// + /// Execute a query with the specified command text and parameter, mapping a single result row + /// to an object via a RowMapper. + /// + /// The command type. + /// The command text to execute. + /// delegate that will map one object per row + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// + object QueryForObjectDelegate(CommandType cmdType, string cmdText, RowMapperDelegate rowMapperDelegate, + string parameterName, Enum dbType, int size, object parameterValue); + + + #endregion + + #region Query With CommandCreator + + // Using IResultSetExtractor to process one result set. + object QueryWithCommandCreator(IDbCommandCreator commandCreator, IResultSetExtractor resultSetExtractor); + + IList QueryWithCommandCreator(IDbCommandCreator cc, IRowMapper rowMapper); + + // Using IResultSetExtractor to return one result set, multiple output parameters. + object QueryWithCommandCreator(IDbCommandCreator commandCreator, IResultSetExtractor resultSetExtractor, IDictionary returnedParameters); + + // Using IRowMapper to return one result set, multiple output parameters. + IList QueryWithCommandCreator(IDbCommandCreator commandCreator, IRowMapper rowMapper, IDictionary returnedParameters); + + + // Multiple return result sets, (A list of lists) + // each with either a IRowMapper, IResultSetExtractor, IRowCallback + // and multiple output parameters. + IDictionary QueryWithCommandCreator(IDbCommandCreator commandCreator, IList resultProcessors); + + //TODO + //Object QueryForObject(... Type requiredType) + //IDictionary QueryForDictionary + //IList QueryForList + + #endregion + + // *************************************************************** + // NB: Complex DataSet/DataTable operations are best handled with + // DataSetOperations class in Spring.Data.Objects + // *************************************************************** + + #region DataTable Create operations without parameters + + DataTable DataTableCreate(CommandType commandType, string sql); + + DataTable DataTableCreate(CommandType commandType, string sql, + string tableMappingName); + + DataTable DataTableCreate(CommandType commandType, string sql, + ITableMapping tableMapping); + + DataTable DataTableCreate(CommandType commandType, string sql, + ITableMapping tableMapping, + IDataAdapterSetter setter); + + #endregion + + #region DataTable Create operations with parameters + + DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters); + + DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + string tableMappingName); + + DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping); + + DataTable DataTableCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping, + IDataAdapterSetter dataAdapterSetter); + + + //TODO + /* + DataTable DataTableCreateWithParams(IDbDataAdapterCreator dataAdapterCreator); + */ + + #endregion + + #region DataTable Fill operations without parameters + /// + /// Fill a based on a select command that requires no parameters. + /// + /// The to populate + /// The type of command + /// SQL query to execute + /// The number of rows successfully added to or refreshed in the + int DataTableFill(DataTable dataTable, CommandType commandType, string sql); + + int DataTableFill(DataTable dataTable, CommandType commandType, string sql, + string tableMappingName); + + int DataTableFill(DataTable dataTable, CommandType commandType, string sql, + ITableMapping tableMapping); + + int DataTableFill(DataTable dataTable, CommandType commandType, string sql, + ITableMapping tableMapping, + IDataAdapterSetter setter); + + + #endregion + + #region DataTable Fill operations with parameters + + int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters); + + int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters, + string tableName); + + int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping); + + int DataTableFillWithParams(DataTable dataTable, CommandType commandType, string sql, + IDbParameters parameters, + ITableMapping tableMapping, + IDataAdapterSetter dataAdapterSetter); + + //TODO + /* + int DataTableFillWithParams(DataTable dataTable, + IDbDataAdapterCreator dataAdapterCreator); + + */ + #endregion + + #region DataTable Update operations + //TODO conflict options... + + int DataTableUpdateWithCommandBuilder(DataTable dataTable, + CommandType commandType, + string selectSql, + IDbParameters parameters, + string tableName); + + int DataTableUpdateWithCommandBuilder(DataTable dataTable, + CommandType commandType, + string selectSql, + IDbParameters parameters, + string tableName, + IDataAdapterSetter dataAdapterSetter); + + int DataTableUpdateWithCommandBuilder(DataTable dataTable, + CommandType commandType, + string selectSql, + IDbParameters parameters, + ITableMapping tableMapping, + IDataAdapterSetter dataAdapterSetter); + + int DataTableUpdate(DataTable dataTable, + string tableName, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters); + + int DataTableUpdate(DataTable dataTable, + string tableName, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, + IDataAdapterSetter dataAdapterSetter); + + int DataTableUpdate(DataTable dataTable, + ITableMapping tableMapping, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters, + IDataAdapterSetter dataAdapterSetter); + + + + #endregion + + #region DataSet Create operations without parameters + + DataSet DataSetCreate(CommandType commandType, string sql); + + DataSet DataSetCreate(CommandType commandType, string sql, + string[] tableNames); + + DataSet DataSetCreate(CommandType commandType, string sql, + ITableMappingCollection tableMapping); + + DataSet DataSetCreate(CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter); + + DataSet DataSetCreate(CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor); + #endregion + + #region DataSet Create operations with parameters + + DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters); + + DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + string[] tableNames); + + DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping); + + DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter); + + DataSet DataSetCreateWithParams(CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor); + + #endregion + + #region DataSet Fill operations without parameters + + /// + /// Fill a based on a select command that requires no parameters. + /// + /// The to populate + /// The type of command + /// SQL query to execute + /// The number of rows successfully added to or refreshed in the + int DataSetFill(DataSet dataSet, CommandType commandType, string sql); + + /// + /// Fill a based on a select command that requires no parameters + /// that returns one or more result sets that are added as + /// s to the + /// + /// The to populate + /// The type of command + /// SQL query to execute + /// The mapping of table names for each + /// created + /// + int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + string[] tableNames); + + int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + ITableMappingCollection tableMapping); + + int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter); + + int DataSetFill(DataSet dataSet, CommandType commandType, string sql, + ITableMappingCollection tableMapping, + IDataAdapterSetter setter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor); + + #endregion + + #region DataSet Fill operations with parameters + + int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters); + + int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + string[] tableNames); + + int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping); + + int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter); + + int DataSetFillWithParameters(DataSet dataSet, CommandType commandType, string sql, + IDbParameters parameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter, + IDataSetFillLifecycleProcessor fillLifecycleProcessor); + + #endregion + + #region DataSet Update operations + //TODO expose RowUpdate event in a generic manner + //TODO any way to integrate Accept/RejectChanges based on tx outcome? + + int DataSetUpdateWithCommandBuilder(DataSet dataSet, + CommandType commandType, + string selectSql, + IDbParameters selectParameters, + string tableName); + + int DataSetUpdateWithCommandBuilder(DataSet dataSet, + CommandType commandType, + string selectSql, + IDbParameters selectParameters, + string tableName, + IDataAdapterSetter dataAdapterSetter); + + int DataSetUpdateWithCommandBuilder(DataSet dataSet, + CommandType commandType, + string selectSql, + IDbParameters selectParameters, + ITableMappingCollection tableMapping, + IDataAdapterSetter dataAdapterSetter); + + + int DataSetUpdate(DataSet dataSet, + string tableName, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand); + + + int DataSetUpdate(DataSet dataSet, + string tableName, + CommandType insertCommandtype, string insertSql, IDbParameters insertParameters, + CommandType updateCommandtype, string updateSql, IDbParameters updateParameters, + CommandType deleteCommandtype, string deleteSql, IDbParameters deleteParameters); + + + int DataSetUpdate(DataSet dataSet, + string tableName, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand, + IDataAdapterSetter dataAdapterSetter); + + int DataSetUpdate(DataSet dataSet, + ITableMappingCollection tableMapping, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand); + + int DataSetUpdate(DataSet dataSet, + ITableMappingCollection tableMapping, + IDbCommand insertCommand, + IDbCommand updateCommand, + IDbCommand deleteCommand, + IDataAdapterSetter dataAdapterSetter); + + #endregion + + #region Parameter Creation Helper Methods + + IDbParameters CreateDbParameters(); + + /// + /// Note that output parameters are marked input/output after derivation.... + /// (TODO - double check....) + /// + /// + /// + IDataParameter[] DeriveParameters(string procedureName); + + IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter); + + #endregion + } + + +} diff --git a/src/Spring/Spring.Data/Data/ICommandCallback.cs b/src/Spring/Spring.Data/Data/ICommandCallback.cs index 3ba7f388..a9d51a10 100644 --- a/src/Spring/Spring.Data/Data/ICommandCallback.cs +++ b/src/Spring/Spring.Data/Data/ICommandCallback.cs @@ -1,53 +1,53 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; - -namespace Spring.Data -{ - /// - /// Generic callback interface for code that operates on a - /// IDbCommand. - /// - /// - ///

Allows you to execute any number of operations - /// on a single IDbCommand, for example a single ExecuteScalar - /// call or repeated execute calls with varying parameters. - ///

- ///

Used internally by AdoTemplate, but also useful for - /// application code. Note that the passed in IDbCommand - /// has been created by the framework.

- ///
- /// Mark Pollack - public interface ICommandCallback - { - /// - /// Called by AdoTemplate.Execute with an active ADO.NET IDbCommand. - /// The calling code does not need to care about closing the - /// command or the connection, or - /// about handling transactions: this will all be handled by - /// Spring's AdoTemplate - /// - /// An active IDbCommand instance - /// The result object - object DoInCommand(IDbCommand command); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; + +namespace Spring.Data +{ + /// + /// Generic callback interface for code that operates on a + /// IDbCommand. + /// + /// + ///

Allows you to execute any number of operations + /// on a single IDbCommand, for example a single ExecuteScalar + /// call or repeated execute calls with varying parameters. + ///

+ ///

Used internally by AdoTemplate, but also useful for + /// application code. Note that the passed in IDbCommand + /// has been created by the framework.

+ ///
+ /// Mark Pollack + public interface ICommandCallback + { + /// + /// Called by AdoTemplate.Execute with an active ADO.NET IDbCommand. + /// The calling code does not need to care about closing the + /// command or the connection, or + /// about handling transactions: this will all be handled by + /// Spring's AdoTemplate + /// + /// An active IDbCommand instance + /// The result object + object DoInCommand(IDbCommand command); + } +} diff --git a/src/Spring/Spring.Data/Data/ICommandSetter.cs b/src/Spring/Spring.Data/Data/ICommandSetter.cs index 71d3ce58..7455d497 100644 --- a/src/Spring/Spring.Data/Data/ICommandSetter.cs +++ b/src/Spring/Spring.Data/Data/ICommandSetter.cs @@ -1,43 +1,42 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - - /// - /// Called by the AdoTemplate class to allow implementations - /// to set any necessary parameters on the command object. - /// The CommandType and CommandText will have already been supplied. - /// - /// Mark Pollack (.NET) - /// $Id: ICommandSetter.cs,v 1.5 2006/12/02 07:35:23 markpollack Exp $ - public interface ICommandSetter - { - - - void SetValues(IDbCommand dbCommand); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + + /// + /// Called by the AdoTemplate class to allow implementations + /// to set any necessary parameters on the command object. + /// The CommandType and CommandText will have already been supplied. + /// + /// Mark Pollack (.NET) + public interface ICommandSetter + { + + + void SetValues(IDbCommand dbCommand); + } +} diff --git a/src/Spring/Spring.Data/Data/ICommandTextProvider.cs b/src/Spring/Spring.Data/Data/ICommandTextProvider.cs index 9d19b423..fa35c089 100644 --- a/src/Spring/Spring.Data/Data/ICommandTextProvider.cs +++ b/src/Spring/Spring.Data/Data/ICommandTextProvider.cs @@ -1,39 +1,39 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Data -{ - /// - /// Interface to be implemented by objects that can provide SQL strings - /// - /// Typically implemented by IDbCommandCreator and - /// ICommandCallbacks that want to expose the CommandText they - /// use to create their ADO.NET commands, to allow for better - /// contextual information in case of exceptions - /// Mark Pollack(.NET) - /// Juergen Hoeller - public interface ICommandTextProvider - { - string CommandText - { - get; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Data +{ + /// + /// Interface to be implemented by objects that can provide SQL strings + /// + /// Typically implemented by IDbCommandCreator and + /// ICommandCallbacks that want to expose the CommandText they + /// use to create their ADO.NET commands, to allow for better + /// contextual information in case of exceptions + /// Mark Pollack(.NET) + /// Juergen Hoeller + public interface ICommandTextProvider + { + string CommandText + { + get; + } + } +} diff --git a/src/Spring/Spring.Data/Data/ICommonAdoOperations.cs b/src/Spring/Spring.Data/Data/ICommonAdoOperations.cs index 18658692..2f8ed6ac 100644 --- a/src/Spring/Spring.Data/Data/ICommonAdoOperations.cs +++ b/src/Spring/Spring.Data/Data/ICommonAdoOperations.cs @@ -1,248 +1,248 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data -{ - public interface ICommonAdoOperations - { - #region ExecuteScalar - - /// - /// Execute the query with the specified command text returning a scalar result - /// - /// No parameters are used. As with - /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the resultset - /// returned by the query. Extra columns or row are ignored. - /// The command type - /// The command text to execute. - /// The first column of the first row in the result set. - object ExecuteScalar(CommandType cmdType, string cmdText); - - - /// - /// Execute the query with the specified command text and parameter returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The first column of the first row in the result set - object ExecuteScalar(CommandType cmdType, string cmdText, - string parameterName, Enum dbType, int size, object parameterValue); - - /// - /// Execute the query with the specified command text and parameters returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The parameter collection to map. - /// The first column of the first row in the result set - object ExecuteScalar(CommandType cmdType, string cmdText, - IDbParameters parameters); - - /// - /// Execute the query with the specified command text and parameters set via the - /// command setter, returning a scalar result - /// - /// The command type - /// The command text to execute. - /// The command setter. - /// The first column of the first row in the result set - object ExecuteScalar(CommandType cmdType, - string cmdText, - ICommandSetter commandSetter); - - /// - /// Execute the query with a command created via IDbCommandCreator and - /// parameters - /// - /// Output parameters can be retrieved via the returned - /// dictionary. - /// - /// More commonly used as a lower level support method within the framework, - /// for example StoredProcedure/AdoScalar. - /// - /// - /// The callback to create a IDbCommand. - /// A dictionary containing output parameters, if any - IDictionary ExecuteScalar(IDbCommandCreator commandCreator); - - #endregion - - #region ExecuteNonQuery - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The number of rows affected. - int ExecuteNonQuery(CommandType cmdType, string cmdText); - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - /// The number of rows affected. - int ExecuteNonQuery(CommandType cmdType, string cmdText, - string parameterName, Enum dbType, int size, object parameterValue); - - /// - /// Executes a non query returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The parameter collection to map. - /// The number of rows affected. - int ExecuteNonQuery(CommandType cmdType, string cmdText, - IDbParameters parameters); - - /// - /// Executes a non query with parameters set via the - /// command setter, returning the number of rows affected. - /// - /// The command type. - /// The command text to execute. - /// The command setter. - /// The number of rows affected. - int ExecuteNonQuery(CommandType cmdType, string cmdText, - ICommandSetter commandSetter); - - - /// - /// Executes a non query with a command created via IDbCommandCreator and - /// parameters. - /// - /// Output parameters can be retrieved via the returned - /// dictionary. - /// - /// More commonly used as a lower level support method within the framework, - /// for example StoredProcedure/AdoScalar. - /// - /// - /// The callback to create a IDbCommand. - /// The number of rows affected. - IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator); - - - #endregion - - #region Query with RowCallback - - /// - /// Execute a query given IDbCommand's type and text, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command. - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback); - - - /// - /// Execute a query given IDbCommand's type and text and provided parameter - /// information, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - /// The name of the parameter to map. - /// One of the database parameter type enumerations. - /// The length of the parameter. 0 if not applicable to parameter type. - /// The parameter value. - void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - string parameterName, Enum dbType, int size, object parameterValue); - - /// - /// Execute a query given IDbCommand's type and text and provided IDbParameters, - /// reading a single result set on a per-row basis with a . - /// - /// Type of the command. - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// The parameter collection to map. - void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, - IDbParameters parameters); - - /// - /// Execute a query given IDbCommand's type and text by - /// passing the created IDbCommand to a ICommandSetter implementation - /// that knows how to bind values to the IDbCommand, reading a - /// single result set on a per-row basis with a . - /// - /// The type of command - /// The text of the query. - /// callback that will extract results - /// one row at a time. - /// - /// The command setter. - void QueryWithRowCallback(CommandType cmdType, String cmdText, IRowCallback rowCallback, - ICommandSetter commandSetter); - - - #endregion - - #region Query with RowCallback Delegate - - void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate); - - void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter); - - - void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, - string name, Enum dbType, int size, object parameterValue); - - - void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters); - - #endregion - - #region Query with CommandCreator - - void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback); - - void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters); - - #endregion - - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data +{ + public interface ICommonAdoOperations + { + #region ExecuteScalar + + /// + /// Execute the query with the specified command text returning a scalar result + /// + /// No parameters are used. As with + /// IDbCommand.ExecuteScalar, it returns the first column of the first row in the resultset + /// returned by the query. Extra columns or row are ignored. + /// The command type + /// The command text to execute. + /// The first column of the first row in the result set. + object ExecuteScalar(CommandType cmdType, string cmdText); + + + /// + /// Execute the query with the specified command text and parameter returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The first column of the first row in the result set + object ExecuteScalar(CommandType cmdType, string cmdText, + string parameterName, Enum dbType, int size, object parameterValue); + + /// + /// Execute the query with the specified command text and parameters returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The parameter collection to map. + /// The first column of the first row in the result set + object ExecuteScalar(CommandType cmdType, string cmdText, + IDbParameters parameters); + + /// + /// Execute the query with the specified command text and parameters set via the + /// command setter, returning a scalar result + /// + /// The command type + /// The command text to execute. + /// The command setter. + /// The first column of the first row in the result set + object ExecuteScalar(CommandType cmdType, + string cmdText, + ICommandSetter commandSetter); + + /// + /// Execute the query with a command created via IDbCommandCreator and + /// parameters + /// + /// Output parameters can be retrieved via the returned + /// dictionary. + /// + /// More commonly used as a lower level support method within the framework, + /// for example StoredProcedure/AdoScalar. + /// + /// + /// The callback to create a IDbCommand. + /// A dictionary containing output parameters, if any + IDictionary ExecuteScalar(IDbCommandCreator commandCreator); + + #endregion + + #region ExecuteNonQuery + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The number of rows affected. + int ExecuteNonQuery(CommandType cmdType, string cmdText); + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + /// The number of rows affected. + int ExecuteNonQuery(CommandType cmdType, string cmdText, + string parameterName, Enum dbType, int size, object parameterValue); + + /// + /// Executes a non query returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The parameter collection to map. + /// The number of rows affected. + int ExecuteNonQuery(CommandType cmdType, string cmdText, + IDbParameters parameters); + + /// + /// Executes a non query with parameters set via the + /// command setter, returning the number of rows affected. + /// + /// The command type. + /// The command text to execute. + /// The command setter. + /// The number of rows affected. + int ExecuteNonQuery(CommandType cmdType, string cmdText, + ICommandSetter commandSetter); + + + /// + /// Executes a non query with a command created via IDbCommandCreator and + /// parameters. + /// + /// Output parameters can be retrieved via the returned + /// dictionary. + /// + /// More commonly used as a lower level support method within the framework, + /// for example StoredProcedure/AdoScalar. + /// + /// + /// The callback to create a IDbCommand. + /// The number of rows affected. + IDictionary ExecuteNonQuery(IDbCommandCreator commandCreator); + + + #endregion + + #region Query with RowCallback + + /// + /// Execute a query given IDbCommand's type and text, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command. + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback); + + + /// + /// Execute a query given IDbCommand's type and text and provided parameter + /// information, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + /// The name of the parameter to map. + /// One of the database parameter type enumerations. + /// The length of the parameter. 0 if not applicable to parameter type. + /// The parameter value. + void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + string parameterName, Enum dbType, int size, object parameterValue); + + /// + /// Execute a query given IDbCommand's type and text and provided IDbParameters, + /// reading a single result set on a per-row basis with a . + /// + /// Type of the command. + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// The parameter collection to map. + void QueryWithRowCallback(CommandType cmdType, string cmdText, IRowCallback rowCallback, + IDbParameters parameters); + + /// + /// Execute a query given IDbCommand's type and text by + /// passing the created IDbCommand to a ICommandSetter implementation + /// that knows how to bind values to the IDbCommand, reading a + /// single result set on a per-row basis with a . + /// + /// The type of command + /// The text of the query. + /// callback that will extract results + /// one row at a time. + /// + /// The command setter. + void QueryWithRowCallback(CommandType cmdType, String cmdText, IRowCallback rowCallback, + ICommandSetter commandSetter); + + + #endregion + + #region Query with RowCallback Delegate + + void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate); + + void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, ICommandSetter commandSetter); + + + void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, + string name, Enum dbType, int size, object parameterValue); + + + void QueryWithRowCallbackDelegate(CommandType cmdType, string sql, RowCallbackDelegate rowCallbackDelegate, IDbParameters parameters); + + #endregion + + #region Query with CommandCreator + + void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback); + + void QueryWithCommandCreator(IDbCommandCreator cc, IRowCallback rowCallback, IDictionary returnedParameters); + + #endregion + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/IDataAdapterCallback.cs b/src/Spring/Spring.Data/Data/IDataAdapterCallback.cs index 987df433..6a45b6cd 100644 --- a/src/Spring/Spring.Data/Data/IDataAdapterCallback.cs +++ b/src/Spring/Spring.Data/Data/IDataAdapterCallback.cs @@ -1,63 +1,62 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - /// - /// Generic callback interface for code that operates on a - /// IDbDataAdapter. - /// - /// - ///

Allows you to execute any number of operations - /// on a IDbDataAdapter, for example to Fill a DataSet - /// or other more advanced operations such as the transfering - /// data between two different DataSets. - ///

- ///

Note that the passed in IDbDataAdapter - /// has been created by the framework and its SelectCommand - /// will be populated with values for CommandType and Text properties - /// along with Connection/Transaction properties based on the - /// calling transaction context. - ///

- /// Execute(IDataAdapterCallback dataAdapterCallback) - /// method. - ///
- /// Mark Pollack (.NET) - /// $Id: IDataAdapterCallback.cs,v 1.3 2007/12/04 06:49:17 markpollack Exp $ - public interface IDataAdapterCallback - { - /// - /// Called by AdoTemplate.Execute with an preconfigured - /// ADO.NET IDbDataAdapter instance with its SelectCommand - /// property populated with CommandType and Text values - /// along with Connection/Transaction properties based on the - /// calling transaction context. - /// - /// An active IDbDataAdapter instance - /// The result object - object DoInDataAdapter(IDbDataAdapter dataAdapter); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + /// + /// Generic callback interface for code that operates on a + /// IDbDataAdapter. + /// + /// + ///

Allows you to execute any number of operations + /// on a IDbDataAdapter, for example to Fill a DataSet + /// or other more advanced operations such as the transfering + /// data between two different DataSets. + ///

+ ///

Note that the passed in IDbDataAdapter + /// has been created by the framework and its SelectCommand + /// will be populated with values for CommandType and Text properties + /// along with Connection/Transaction properties based on the + /// calling transaction context. + ///

+ /// Execute(IDataAdapterCallback dataAdapterCallback) + /// method. + ///
+ /// Mark Pollack (.NET) + public interface IDataAdapterCallback + { + /// + /// Called by AdoTemplate.Execute with an preconfigured + /// ADO.NET IDbDataAdapter instance with its SelectCommand + /// property populated with CommandType and Text values + /// along with Connection/Transaction properties based on the + /// calling transaction context. + /// + /// An active IDbDataAdapter instance + /// The result object + object DoInDataAdapter(IDbDataAdapter dataAdapter); + } +} diff --git a/src/Spring/Spring.Data/Data/IDataAdapterSetter.cs b/src/Spring/Spring.Data/Data/IDataAdapterSetter.cs index 30403a90..dcd33547 100644 --- a/src/Spring/Spring.Data/Data/IDataAdapterSetter.cs +++ b/src/Spring/Spring.Data/Data/IDataAdapterSetter.cs @@ -1,56 +1,55 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - /// - /// Called by the AdoTemplate class to allow implementations - /// to set any necessary properties on the DbDataAdapter object. - /// - /// - ///

For example, this callback can be used to set the - /// AcceptChangesDuringFill property, register an event handler - /// for the FillErrors event, set update batch sizes if your provider - /// supports such functionality, set the ContinueUpdateOnError property, - /// or in .NET 2.0 to set the property AcceptChangesDuringUpdate. - ///

- ///

- /// Downcast to the appropriate subtype to access vendor specific - /// functionality.

- ///

- /// The DataAdapter SelectCommand will be already be - /// populated with values for CommandType and Text properties - /// along with Connection/Transaction properties based on the - /// calling transaction context. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: IDataAdapterSetter.cs,v 1.3 2006/11/29 07:18:45 markpollack Exp $ - public interface IDataAdapterSetter - { - void SetValues(IDbDataAdapter dataAdapter); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + /// + /// Called by the AdoTemplate class to allow implementations + /// to set any necessary properties on the DbDataAdapter object. + /// + /// + ///

For example, this callback can be used to set the + /// AcceptChangesDuringFill property, register an event handler + /// for the FillErrors event, set update batch sizes if your provider + /// supports such functionality, set the ContinueUpdateOnError property, + /// or in .NET 2.0 to set the property AcceptChangesDuringUpdate. + ///

+ ///

+ /// Downcast to the appropriate subtype to access vendor specific + /// functionality.

+ ///

+ /// The DataAdapter SelectCommand will be already be + /// populated with values for CommandType and Text properties + /// along with Connection/Transaction properties based on the + /// calling transaction context. + ///

+ ///
+ /// Mark Pollack (.NET) + public interface IDataAdapterSetter + { + void SetValues(IDbDataAdapter dataAdapter); + } +} diff --git a/src/Spring/Spring.Data/Data/IDataReaderWrapper.cs b/src/Spring/Spring.Data/Data/IDataReaderWrapper.cs index b38c0c04..94999be0 100644 --- a/src/Spring/Spring.Data/Data/IDataReaderWrapper.cs +++ b/src/Spring/Spring.Data/Data/IDataReaderWrapper.cs @@ -1,54 +1,53 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - /// - /// Custom data reader implementations often delegate to an underlying - /// instance. This interface captures that relationship for reuse in - /// the framework. - /// - /// Implementations will typically add behavior to standard IDataReader methods, - /// for example, by providing default values for DbNull values. - /// See as an example. - /// - /// Mark Pollack (.NET) - /// $Id: IDataReaderWrapper.cs,v 1.2 2007/10/30 15:24:44 markpollack Exp $ - public interface IDataReaderWrapper : IDataReader - { - /// - /// The underlying reader implementation to delegate to for accessing data - /// from a returned result sets. - /// - /// The wrapped reader. - IDataReader WrappedReader - { - get; - set; - } - - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + /// + /// Custom data reader implementations often delegate to an underlying + /// instance. This interface captures that relationship for reuse in + /// the framework. + /// + /// Implementations will typically add behavior to standard IDataReader methods, + /// for example, by providing default values for DbNull values. + /// See as an example. + /// + /// Mark Pollack (.NET) + public interface IDataReaderWrapper : IDataReader + { + /// + /// The underlying reader implementation to delegate to for accessing data + /// from a returned result sets. + /// + /// The wrapped reader. + IDataReader WrappedReader + { + get; + set; + } + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/IDataSetFillLifecycleProcessor.cs b/src/Spring/Spring.Data/Data/IDataSetFillLifecycleProcessor.cs index ddbd63bb..c73ff4be 100644 --- a/src/Spring/Spring.Data/Data/IDataSetFillLifecycleProcessor.cs +++ b/src/Spring/Spring.Data/Data/IDataSetFillLifecycleProcessor.cs @@ -1,66 +1,65 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - /// - /// Lifecycle callback methods that can be registered when - /// performing Fill operations with AdoTemplate. - /// - /// - ///

- /// The methods let you set various properties and invoke - /// methods on the DataSet before and after it gets filled by a DataAdapter. - /// For example, EnforceConstraints, BeginLoadData, and EndLoadData - /// can be called to optimize the loading of large DataSets with - /// many related tables. - ///

- ///

Vendors may expose other propriety methods on their DataSet - /// implementation, downcast to access this specific functionality. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: IDataSetFillLifecycleProcessor.cs,v 1.3 2006/11/29 07:18:45 markpollack Exp $ - public interface IDataSetFillLifecycleProcessor - { - /// - /// Called before a DataAdapter is used to fill a DataSet - /// the the provided tablename. - /// - /// The DataSet to be filled with a DataTable - /// The table collection to be filled - void BeforeFill(DataSet ds, ITableMappingCollection tableMappingCollection); - - /// - /// Called after a DataAdapter is used to fill a DataSet - /// the the provided tablename. - /// - /// The DataSet to be filled with a DataTable - /// The table collection to be filled - void AfterFill(DataSet ds, ITableMappingCollection tableMappingCollection); - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + /// + /// Lifecycle callback methods that can be registered when + /// performing Fill operations with AdoTemplate. + /// + /// + ///

+ /// The methods let you set various properties and invoke + /// methods on the DataSet before and after it gets filled by a DataAdapter. + /// For example, EnforceConstraints, BeginLoadData, and EndLoadData + /// can be called to optimize the loading of large DataSets with + /// many related tables. + ///

+ ///

Vendors may expose other propriety methods on their DataSet + /// implementation, downcast to access this specific functionality. + ///

+ ///
+ /// Mark Pollack (.NET) + public interface IDataSetFillLifecycleProcessor + { + /// + /// Called before a DataAdapter is used to fill a DataSet + /// the the provided tablename. + /// + /// The DataSet to be filled with a DataTable + /// The table collection to be filled + void BeforeFill(DataSet ds, ITableMappingCollection tableMappingCollection); + + /// + /// Called after a DataAdapter is used to fill a DataSet + /// the the provided tablename. + /// + /// The DataSet to be filled with a DataTable + /// The table collection to be filled + void AfterFill(DataSet ds, ITableMappingCollection tableMappingCollection); + + } +} diff --git a/src/Spring/Spring.Data/Data/IDbCommandCreator.cs b/src/Spring/Spring.Data/Data/IDbCommandCreator.cs index 8242e1d5..0f771aad 100644 --- a/src/Spring/Spring.Data/Data/IDbCommandCreator.cs +++ b/src/Spring/Spring.Data/Data/IDbCommandCreator.cs @@ -1,48 +1,47 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data -{ - /// - /// One of the central callback interfaces used by the AdoTemplate class - /// This interface creates a IDbCommand. Implementations are responsible - /// for configuring the created command with command type, command text and - /// any necessary parameters. - /// - /// Mark Pollack (.NET) - /// $Id: IDbCommandCreator.cs,v 1.6 2007/08/06 20:13:39 markpollack Exp $ - public interface IDbCommandCreator - { - /// - /// Creates a IDbCommand. - /// - /// The IDbProvider reference that can be used to create the command in a - /// provider independent manner. The provider supplied is the same as used in configuration of AdoTemplate. - /// - IDbCommand CreateDbCommand(IDbProvider dbProvider); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data +{ + /// + /// One of the central callback interfaces used by the AdoTemplate class + /// This interface creates a IDbCommand. Implementations are responsible + /// for configuring the created command with command type, command text and + /// any necessary parameters. + /// + /// Mark Pollack (.NET) + public interface IDbCommandCreator + { + /// + /// Creates a IDbCommand. + /// + /// The IDbProvider reference that can be used to create the command in a + /// provider independent manner. The provider supplied is the same as used in configuration of AdoTemplate. + /// + IDbCommand CreateDbCommand(IDbProvider dbProvider); + } +} diff --git a/src/Spring/Spring.Data/Data/IDbCommandCreatorFactory.cs b/src/Spring/Spring.Data/Data/IDbCommandCreatorFactory.cs index 3fa344d4..3505867f 100644 --- a/src/Spring/Spring.Data/Data/IDbCommandCreatorFactory.cs +++ b/src/Spring/Spring.Data/Data/IDbCommandCreatorFactory.cs @@ -1,232 +1,231 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using Spring.Dao; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data -{ - /// - /// Helper class that can efficiently create multiple IDbCommand - /// objects with different parameters based on a SQL statement and a single - /// set of parameter declarations. - /// - /// Mark Pollack (.NET) - /// $Id: IDbCommandCreatorFactory.cs,v 1.11 2007/08/06 20:13:39 markpollack Exp $ - public class IDbCommandCreatorFactory - { - #region Fields - - private String sql; - - private IDbParameters declaredParameters; - - private IDbProvider dbProvider; - - private CommandType commandType; - - #endregion - - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public IDbCommandCreatorFactory(IDbProvider dbProvider, CommandType commandType, string sql, IDbParameters declaredParameters) - { - this.dbProvider = dbProvider; - this.sql = sql; - this.commandType = commandType; - this.declaredParameters = declaredParameters; - } - - #endregion - - #region Properties - - public IDbParameters DeclaredParameters - { - get - { - return declaredParameters; - } - } - - public string Sql - { - get { return sql; } - } - - public IDbProvider DbProvider - { - get { return dbProvider; } - } - - public CommandType CommandType - { - get { return commandType; } - } - #endregion - - #region Methods - - public IDbCommandCreator NewDbCommandCreatorWithParamValues(params object[] inParamValues) - { - - return new CommandCreatorWithParamValues(this, inParamValues != null ? ArrayList.Adapter(inParamValues) : new ArrayList()); - } - - - public IDbCommandCreator NewDbCommandCreator(IDictionary inParameters) - { - - return new CommandCreatorImpl(this, inParameters != null ? inParameters : new Hashtable()); - } - - #endregion - - private class CommandCreatorWithParamValues : IDbCommandCreator - { - private IDbCommandCreatorFactory factory; - private IList inParamValues; - - public CommandCreatorWithParamValues(IDbCommandCreatorFactory factory, IList inParamValues) - { - this.factory = factory; - this.inParamValues = inParamValues; - } - - public IDbCommand CreateDbCommand(IDbProvider provider) - { - IDbCommand command = factory.dbProvider.CreateCommand(); - command.CommandText = factory.sql; - command.CommandType = factory.commandType; - if (factory.declaredParameters != null) - { - int parameterIndex = 0; - foreach ( IDbDataParameter declaredParameter in factory.declaredParameters.DataParameterCollection) - { - IDbDataParameter clonedParameter = (IDbDataParameter)((ICloneable)declaredParameter).Clone(); - if (!(clonedParameter.Direction == ParameterDirection.Output) && - !(clonedParameter.Direction == ParameterDirection.ReturnValue)) - { - if (clonedParameter.Direction == ParameterDirection.InputOutput) - { - //heuristic for case when have output parameter from stored procedure discovery classified - //as in-out. Assume out parameters come last in the stored proc definition and ignore - //setting values if there are not enough input values as passed in by the user. - if (parameterIndex < inParamValues.Count) - { - //The value may still be null - Object inValue = inParamValues[parameterIndex]; - clonedParameter.Value = (inValue == null) ? DBNull.Value : inValue; - } else - { - //Since it thinks it is an input-output value and we have no value from the user - pass in null - //as a workaround. - clonedParameter.Value = DBNull.Value; - } - - } - else - { - //The value may still be null - Object inValue = inParamValues[parameterIndex]; - clonedParameter.Value = (inValue == null) ? DBNull.Value : inValue; - } - // only increment index if we could assign a value from the user specified inputs. - parameterIndex++; - } - - command.Parameters.Add(clonedParameter); - - } - } - return command; - } - - } - private class CommandCreatorImpl : IDbCommandCreator{ - - private IDbCommandCreatorFactory factory; - private IDictionary inParams; - - - public CommandCreatorImpl(IDbCommandCreatorFactory factory, IDictionary inParameters) - { - this.factory = factory; - this.inParams = inParameters; - } - - public IDbCommand CreateDbCommand(IDbProvider provider) - { - IDbCommand command = factory.dbProvider.CreateCommand(); - command.CommandText = factory.sql; - command.CommandType = factory.commandType; - if (factory.declaredParameters != null) - { - foreach ( IDbDataParameter declaredParameter in factory.declaredParameters.DataParameterCollection) - { - IDbDataParameter clonedParameter = (IDbDataParameter)((ICloneable)declaredParameter).Clone(); - - if (IsInputParamter(clonedParameter) && !inParams.Contains(clonedParameter.ParameterName)) - { - throw new InvalidDataAccessApiUsageException("Required input parameter '" + - clonedParameter.ParameterName + "' is missing"); - } - //The value may still be null -// Object inValue = -// inParams[factory.dbProvider.CreateParameterName(clonedParameter.ParameterName)]; - - // TODO: The above code doesn't work as it duplicates parameter prefix, thus failing - // to obtain parameter values. The whole parameter handling mechanism should be refactored - // not to require parameter prefix to be specified when populating named parameters collection - // within AdoOperations. Code below is just a temporary workaround until this issue is resolved. - - Object inValue = inParams[clonedParameter.ParameterName]; - if (!(clonedParameter.Direction == ParameterDirection.Output) && - !(clonedParameter.Direction == ParameterDirection.ReturnValue)) - { - clonedParameter.Value = (inValue == null) ? DBNull.Value : inValue; - } - - command.Parameters.Add(clonedParameter); - } - } - return command; - } - - private bool IsInputParamter(IDataParameter parameter) - { - //Due to quirk in DeriveParameters can only verify Input parameter as output parameters - //are incorrectly listed as InputOutput - return (parameter.Direction == ParameterDirection.Input); - } - - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using Spring.Dao; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data +{ + /// + /// Helper class that can efficiently create multiple IDbCommand + /// objects with different parameters based on a SQL statement and a single + /// set of parameter declarations. + /// + /// Mark Pollack (.NET) + public class IDbCommandCreatorFactory + { + #region Fields + + private String sql; + + private IDbParameters declaredParameters; + + private IDbProvider dbProvider; + + private CommandType commandType; + + #endregion + + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public IDbCommandCreatorFactory(IDbProvider dbProvider, CommandType commandType, string sql, IDbParameters declaredParameters) + { + this.dbProvider = dbProvider; + this.sql = sql; + this.commandType = commandType; + this.declaredParameters = declaredParameters; + } + + #endregion + + #region Properties + + public IDbParameters DeclaredParameters + { + get + { + return declaredParameters; + } + } + + public string Sql + { + get { return sql; } + } + + public IDbProvider DbProvider + { + get { return dbProvider; } + } + + public CommandType CommandType + { + get { return commandType; } + } + #endregion + + #region Methods + + public IDbCommandCreator NewDbCommandCreatorWithParamValues(params object[] inParamValues) + { + + return new CommandCreatorWithParamValues(this, inParamValues != null ? ArrayList.Adapter(inParamValues) : new ArrayList()); + } + + + public IDbCommandCreator NewDbCommandCreator(IDictionary inParameters) + { + + return new CommandCreatorImpl(this, inParameters != null ? inParameters : new Hashtable()); + } + + #endregion + + private class CommandCreatorWithParamValues : IDbCommandCreator + { + private IDbCommandCreatorFactory factory; + private IList inParamValues; + + public CommandCreatorWithParamValues(IDbCommandCreatorFactory factory, IList inParamValues) + { + this.factory = factory; + this.inParamValues = inParamValues; + } + + public IDbCommand CreateDbCommand(IDbProvider provider) + { + IDbCommand command = factory.dbProvider.CreateCommand(); + command.CommandText = factory.sql; + command.CommandType = factory.commandType; + if (factory.declaredParameters != null) + { + int parameterIndex = 0; + foreach ( IDbDataParameter declaredParameter in factory.declaredParameters.DataParameterCollection) + { + IDbDataParameter clonedParameter = (IDbDataParameter)((ICloneable)declaredParameter).Clone(); + if (!(clonedParameter.Direction == ParameterDirection.Output) && + !(clonedParameter.Direction == ParameterDirection.ReturnValue)) + { + if (clonedParameter.Direction == ParameterDirection.InputOutput) + { + //heuristic for case when have output parameter from stored procedure discovery classified + //as in-out. Assume out parameters come last in the stored proc definition and ignore + //setting values if there are not enough input values as passed in by the user. + if (parameterIndex < inParamValues.Count) + { + //The value may still be null + Object inValue = inParamValues[parameterIndex]; + clonedParameter.Value = (inValue == null) ? DBNull.Value : inValue; + } else + { + //Since it thinks it is an input-output value and we have no value from the user - pass in null + //as a workaround. + clonedParameter.Value = DBNull.Value; + } + + } + else + { + //The value may still be null + Object inValue = inParamValues[parameterIndex]; + clonedParameter.Value = (inValue == null) ? DBNull.Value : inValue; + } + // only increment index if we could assign a value from the user specified inputs. + parameterIndex++; + } + + command.Parameters.Add(clonedParameter); + + } + } + return command; + } + + } + private class CommandCreatorImpl : IDbCommandCreator{ + + private IDbCommandCreatorFactory factory; + private IDictionary inParams; + + + public CommandCreatorImpl(IDbCommandCreatorFactory factory, IDictionary inParameters) + { + this.factory = factory; + this.inParams = inParameters; + } + + public IDbCommand CreateDbCommand(IDbProvider provider) + { + IDbCommand command = factory.dbProvider.CreateCommand(); + command.CommandText = factory.sql; + command.CommandType = factory.commandType; + if (factory.declaredParameters != null) + { + foreach ( IDbDataParameter declaredParameter in factory.declaredParameters.DataParameterCollection) + { + IDbDataParameter clonedParameter = (IDbDataParameter)((ICloneable)declaredParameter).Clone(); + + if (IsInputParamter(clonedParameter) && !inParams.Contains(clonedParameter.ParameterName)) + { + throw new InvalidDataAccessApiUsageException("Required input parameter '" + + clonedParameter.ParameterName + "' is missing"); + } + //The value may still be null +// Object inValue = +// inParams[factory.dbProvider.CreateParameterName(clonedParameter.ParameterName)]; + + // TODO: The above code doesn't work as it duplicates parameter prefix, thus failing + // to obtain parameter values. The whole parameter handling mechanism should be refactored + // not to require parameter prefix to be specified when populating named parameters collection + // within AdoOperations. Code below is just a temporary workaround until this issue is resolved. + + Object inValue = inParams[clonedParameter.ParameterName]; + if (!(clonedParameter.Direction == ParameterDirection.Output) && + !(clonedParameter.Direction == ParameterDirection.ReturnValue)) + { + clonedParameter.Value = (inValue == null) ? DBNull.Value : inValue; + } + + command.Parameters.Add(clonedParameter); + } + } + return command; + } + + private bool IsInputParamter(IDataParameter parameter) + { + //Due to quirk in DeriveParameters can only verify Input parameter as output parameters + //are incorrectly listed as InputOutput + return (parameter.Direction == ParameterDirection.Input); + } + + } + } +} diff --git a/src/Spring/Spring.Data/Data/IDbDataAdapterCreator.cs b/src/Spring/Spring.Data/Data/IDbDataAdapterCreator.cs index 7f82b897..04055f74 100644 --- a/src/Spring/Spring.Data/Data/IDbDataAdapterCreator.cs +++ b/src/Spring/Spring.Data/Data/IDbDataAdapterCreator.cs @@ -1,49 +1,48 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - /// - /// This interface creates a IDbDataAdapterCommand. - /// Implementations are responsible - /// for configuring the created command with appropriate - /// select and actions commands along with their parameters. - /// - /// - /// Generally used to to support the DataSet functionality in - /// the Spring.Data.Objects namespace. - /// - /// Mark Pollack (.NET) - /// $Id: IDbDataAdapterCreator.cs,v 1.3 2007/12/07 08:09:52 markpollack Exp $ - public interface IDbDataAdapterCreator - { - /// - /// Creates the data adapter. - /// - /// A new IDbDataAdapter instance - IDbDataAdapter CreateDataAdapter(); - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + /// + /// This interface creates a IDbDataAdapterCommand. + /// Implementations are responsible + /// for configuring the created command with appropriate + /// select and actions commands along with their parameters. + /// + /// + /// Generally used to to support the DataSet functionality in + /// the Spring.Data.Objects namespace. + /// + /// Mark Pollack (.NET) + public interface IDbDataAdapterCreator + { + /// + /// Creates the data adapter. + /// + /// A new IDbDataAdapter instance + IDbDataAdapter CreateDataAdapter(); + } +} diff --git a/src/Spring/Spring.Data/Data/IResultSetExtractor.cs b/src/Spring/Spring.Data/Data/IResultSetExtractor.cs index fd8c3c5a..89ee4fa3 100644 --- a/src/Spring/Spring.Data/Data/IResultSetExtractor.cs +++ b/src/Spring/Spring.Data/Data/IResultSetExtractor.cs @@ -1,60 +1,60 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - - -using System.Data; - -namespace Spring.Data -{ - /// - /// Callback interface to process all result sets and rows in - /// an AdoTemplate query method. - /// - /// Implementations of this interface perform the work - /// of extracting results but don't need worry about managing - /// ADO.NET resources, such as closing the reader or transaction management. - ///

- /// This interface is mainly used within the ADO.NET - /// framework. An IResultSetExtractor is usually a simpler choice - /// for result set (DataReader) processing, in particular a - /// RowMapperResultSetExtractor in combination with a IRowMapper. - ///

- /// Note: in contracts to a IRowCallbackHandler, a ResultSetExtractor - /// is usually stateless and thus reusable, as long as it doesn't access - /// stateful resources or keep result state within the object. - /// - ///
- /// - public interface IResultSetExtractor - { - /// - /// Implementations must implement this method to process all - /// result set and rows in the IDataReader. - /// - /// The IDataReader to extract data from. - /// Implementations should not close this: it will be closed - /// by the AdoTemplate. - /// An arbitrary result object or null if none. The - /// extractor will typically be stateful in the latter case. - object ExtractData(IDataReader reader); - - - } +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + + +using System.Data; + +namespace Spring.Data +{ + /// + /// Callback interface to process all result sets and rows in + /// an AdoTemplate query method. + /// + /// Implementations of this interface perform the work + /// of extracting results but don't need worry about managing + /// ADO.NET resources, such as closing the reader or transaction management. + ///

+ /// This interface is mainly used within the ADO.NET + /// framework. An IResultSetExtractor is usually a simpler choice + /// for result set (DataReader) processing, in particular a + /// RowMapperResultSetExtractor in combination with a IRowMapper. + ///

+ /// Note: in contracts to a IRowCallbackHandler, a ResultSetExtractor + /// is usually stateless and thus reusable, as long as it doesn't access + /// stateful resources or keep result state within the object. + /// + ///
+ /// + public interface IResultSetExtractor + { + /// + /// Implementations must implement this method to process all + /// result set and rows in the IDataReader. + /// + /// The IDataReader to extract data from. + /// Implementations should not close this: it will be closed + /// by the AdoTemplate. + /// An arbitrary result object or null if none. The + /// extractor will typically be stateful in the latter case. + object ExtractData(IDataReader reader); + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/IRowCallback.cs b/src/Spring/Spring.Data/Data/IRowCallback.cs index 08f08a0b..7733d198 100644 --- a/src/Spring/Spring.Data/Data/IRowCallback.cs +++ b/src/Spring/Spring.Data/Data/IRowCallback.cs @@ -1,35 +1,35 @@ - - -using System.Data; - -namespace Spring.Data -{ - /// - /// Callback to process each row of data in an AdoOperation's Query method. - /// - /// - /// Implementations of this interface perform the actual work of extracting - /// results. In contrast to a IResultSetExtractor, a IRowCallback object is typically - /// stateful. It keeps the result state within the object, to be available - /// for later inspection. - /// - /// - public interface IRowCallback - { - /// - /// Implementations must implement this method to process each row of data - /// in the data reader. - /// - /// - /// This method should not advance the cursor by calling Read() - /// on IDataReader but only extract the current values. The - /// caller does not need to care about closing the reader, command, connection, or - /// about handling transactions: this will all be handled by - /// Spring's AdoTemplate - /// - /// An active IDataReader instance - /// The result object - void ProcessRow(IDataReader reader); - - } -} + + +using System.Data; + +namespace Spring.Data +{ + /// + /// Callback to process each row of data in an AdoOperation's Query method. + /// + /// + /// Implementations of this interface perform the actual work of extracting + /// results. In contrast to a IResultSetExtractor, a IRowCallback object is typically + /// stateful. It keeps the result state within the object, to be available + /// for later inspection. + /// + /// + public interface IRowCallback + { + /// + /// Implementations must implement this method to process each row of data + /// in the data reader. + /// + /// + /// This method should not advance the cursor by calling Read() + /// on IDataReader but only extract the current values. The + /// caller does not need to care about closing the reader, command, connection, or + /// about handling transactions: this will all be handled by + /// Spring's AdoTemplate + /// + /// An active IDataReader instance + /// The result object + void ProcessRow(IDataReader reader); + + } +} diff --git a/src/Spring/Spring.Data/Data/IRowMapper.cs b/src/Spring/Spring.Data/Data/IRowMapper.cs index 4f2aa3e0..7f36ddde 100644 --- a/src/Spring/Spring.Data/Data/IRowMapper.cs +++ b/src/Spring/Spring.Data/Data/IRowMapper.cs @@ -1,60 +1,59 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Data; - -#endregion - -namespace Spring.Data -{ - /// - /// Callback to process each row of data in a result set to an object. - /// - /// Implementations of this interface perform the actual work - /// of mapping rows, but don't need worry about managing - /// ADO.NET resources, such as closing the reader. - ///

- /// Typically used for AdoTemplate's query methods (with RowMapperResultSetExtractor - /// adapters). RowMapper objects are typically stateless and thus - /// reusable; they are ideal choices for implementing row-mapping logic in a single - /// place. - ///

- ///

Alternatively, consider subclassing MappingSqlQuery from the Spring.Data.Object - /// namespace: Instead of working with separate AdoTemplate and RowMapper objects, - /// you can have executable query objects (containing row-mapping logic) there. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: IRowMapper.cs,v 1.6 2007/06/28 18:48:19 markpollack Exp $ - public interface IRowMapper - { - /// - /// Implementations must implement this method to map each row of data in the - /// result set (DataReader). This method should not call Next() on the - /// DataReader; it should only extract the values of the current row. - /// - /// The IDataReader to map (pre-initialized for the current row) - /// The number of the current row. - /// The result object for the current row. - object MapRow(IDataReader reader, int rowNum); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Data; + +#endregion + +namespace Spring.Data +{ + /// + /// Callback to process each row of data in a result set to an object. + /// + /// Implementations of this interface perform the actual work + /// of mapping rows, but don't need worry about managing + /// ADO.NET resources, such as closing the reader. + ///

+ /// Typically used for AdoTemplate's query methods (with RowMapperResultSetExtractor + /// adapters). RowMapper objects are typically stateless and thus + /// reusable; they are ideal choices for implementing row-mapping logic in a single + /// place. + ///

+ ///

Alternatively, consider subclassing MappingSqlQuery from the Spring.Data.Object + /// namespace: Instead of working with separate AdoTemplate and RowMapper objects, + /// you can have executable query objects (containing row-mapping logic) there. + ///

+ ///
+ /// Mark Pollack (.NET) + public interface IRowMapper + { + /// + /// Implementations must implement this method to map each row of data in the + /// result set (DataReader). This method should not call Next() on the + /// DataReader; it should only extract the values of the current row. + /// + /// The IDataReader to map (pre-initialized for the current row) + /// The number of the current row. + /// The result object for the current row. + object MapRow(IDataReader reader, int rowNum); + } +} diff --git a/src/Spring/Spring.Data/Data/InvalidResultSetAccessException.cs b/src/Spring/Spring.Data/Data/InvalidResultSetAccessException.cs index a2442bf4..e25caf2b 100644 --- a/src/Spring/Spring.Data/Data/InvalidResultSetAccessException.cs +++ b/src/Spring/Spring.Data/Data/InvalidResultSetAccessException.cs @@ -1,138 +1,137 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Dao; - -#endregion - -namespace Spring.Data -{ - /// - /// Exception thrown when a result set has been accessed in an invalid fashion. - /// - /// Mark Pollack (.NET) - /// $Id: InvalidResultSetAccessException.cs,v 1.2 2007/12/07 08:09:52 markpollack Exp $ - [Serializable] - public class InvalidResultSetAccessException : InvalidDataAccessResourceUsageException, ISerializable - { - #region Fields - - /// - /// SQL that led to the problem - /// - private string sql; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public InvalidResultSetAccessException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - public InvalidResultSetAccessException(string message): base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - /// The inner exception. - public InvalidResultSetAccessException(string message, Exception inner): base(message, inner) - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// name of the current task. - /// The offending SQL statment - /// The root cause. - public InvalidResultSetAccessException(string task, String sql, Exception ex) : base(task + "; invalid ResultSet access for SQL [" + sql + "]; " + ex.Message, ex) - { - this.sql = sql; - } - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected InvalidResultSetAccessException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - - #endregion - - #region Properties - - /// - /// Gets the SQL that caused the exception - /// - /// The SQL that caused the exception. - public string Sql - { - get - { - return sql; - } - } - #endregion - - #region Methods - - #endregion - - #region ISerializable Members - - /// - /// When overridden in a derived class, sets the - /// with information about the exception. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is a null reference ( in Visual Basic). - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "sql", sql ); - base.GetObjectData( info, context ); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Dao; + +#endregion + +namespace Spring.Data +{ + /// + /// Exception thrown when a result set has been accessed in an invalid fashion. + /// + /// Mark Pollack (.NET) + [Serializable] + public class InvalidResultSetAccessException : InvalidDataAccessResourceUsageException, ISerializable + { + #region Fields + + /// + /// SQL that led to the problem + /// + private string sql; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public InvalidResultSetAccessException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + public InvalidResultSetAccessException(string message): base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + /// The inner exception. + public InvalidResultSetAccessException(string message, Exception inner): base(message, inner) + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// name of the current task. + /// The offending SQL statment + /// The root cause. + public InvalidResultSetAccessException(string task, String sql, Exception ex) : base(task + "; invalid ResultSet access for SQL [" + sql + "]; " + ex.Message, ex) + { + this.sql = sql; + } + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected InvalidResultSetAccessException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + + #endregion + + #region Properties + + /// + /// Gets the SQL that caused the exception + /// + /// The SQL that caused the exception. + public string Sql + { + get + { + return sql; + } + } + #endregion + + #region Methods + + #endregion + + #region ISerializable Members + + /// + /// When overridden in a derived class, sets the + /// with information about the exception. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is a null reference ( in Visual Basic). + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "sql", sql ); + base.GetObjectData( info, context ); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Data/Objects/AbstractAdoOperation.cs b/src/Spring/Spring.Data/Data/Objects/AbstractAdoOperation.cs index d8eb4830..2e1b7a1a 100644 --- a/src/Spring/Spring.Data/Data/Objects/AbstractAdoOperation.cs +++ b/src/Spring/Spring.Data/Data/Objects/AbstractAdoOperation.cs @@ -1,330 +1,329 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Collections; -using System.Data; -using Common.Logging; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Objects.Factory; - -namespace Spring.Data.Objects -{ - /// - /// Abstract base class providing common functionality for generic and non - /// generic implementations of "AdoOperation" subclasses. - /// - /// Mark Pollack (.NET) - /// $Id: AbstractAdoOperation.cs,v 1.2 2008/05/30 21:09:22 markpollack Exp $ - public abstract class AbstractAdoOperation : IInitializingObject - { - #region Logging Definition - - protected readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #endregion - - #region Fields - - private string sql; - - private CommandType commandType = CommandType.Text; - - private IDbParameters declaredParameters; - - - /// - /// Has this operation been compiled? Compilation means at - /// least checking that a IDbProvider and sql have been provided, - /// but subclasses may also implement their own custom validation. - /// - protected bool compiled; - - /// - /// Object enabling us to create IDbCommands - /// efficiently, based on this class's declared parameters. - /// - private IDbCommandCreatorFactory commandFactory; - - #endregion - - - #region Properties - - - /// - /// Gets or sets the type of the command. - /// - /// The type of the command. - public CommandType CommandType - { - get { return commandType; } - set { commandType = value; } - } - - /// - /// Gets or sets the db provider. - /// - /// The db provider. - public abstract IDbProvider DbProvider - { - get; set; - } - - /// - /// Gets or sets the SQL to execute - /// - /// The SQL. - public string Sql - { - get - { - return sql; - } - set - { - sql = value; - } - } - - /// - /// Gets or sets the declared parameters. - /// - /// The declared parameters. - public IDbParameters DeclaredParameters - { - get - { - return declaredParameters; - } - set - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add parameters once operation is compiled"); - } - declaredParameters = value; - } - } - - /// - /// Gets a value indicating whether this is compiled. - /// - /// Compilation means that the operation is fully configured, - /// and ready to use. The exact meaning of compilation will vary between subclasses. - /// true if compiled; otherwise, false. - public bool Compiled - { - get { return compiled; } - } - - /// - /// Sets the command timeout for IDbCommands that this AdoTemplate executes. - /// - /// Default is 0, indicating to use the database provider's default. - /// Any timeout specified here will be overridden by the remaining - /// transaction timeout when executing within a transaction that has a - /// timeout specified at the transaction level. - /// - /// The command timeout. - public abstract int CommandTimeout - { - set; - } - - - #endregion - - #region Methods - - /// - /// Ensures compilation if used in an IApplicationContext - /// - public void AfterPropertiesSet() - { - Compile(); - } - - /// - /// Compiles this operation. Ignores subsequent attempts to compile. - /// - public abstract void Compile(); - - - - - /// - /// Check whether this operation has been compiled already; - /// lazily compile it if not already compiled. - /// - /// Automatically called by ValidateParameters and ValidateNamedParameters - protected void CheckCompiled() - { - if (!Compiled) - { - log.Debug("ADO operation not compiled before execution - invoking compile"); - Compile(); - } - } - - - protected virtual void ValidateParameters(params object[] inParamValues) - { - CheckCompiled(); - int declaredInParameters = 0; - if (DeclaredParameters != null) - { - for (int i = 0; i < declaredParameters.Count; i++) - { - IDataParameter declaredParameter = DeclaredParameters[i]; - if (IsInputParameter(declaredParameter)) - { - declaredInParameters++; - } - } - } - - if (inParamValues != null) - { - if (DeclaredParameters == null) - { - throw new InvalidDataAccessApiUsageException( - "Didn't expect any parameters: none were declared"); - } - if (inParamValues.Length < declaredInParameters) - { - throw new InvalidDataAccessApiUsageException( - inParamValues.Length + " parameters were supplied, but " + - declaredInParameters + " in parameters were declared in class [" + - GetType().AssemblyQualifiedName + "]"); - } - if (inParamValues.Length > declaredInParameters) - { - throw new InvalidDataAccessApiUsageException( - inParamValues.Length + " parameters were supplied, but " + - DeclaredParameters.Count + " parameters were declared " + - "in class [" + GetType().AssemblyQualifiedName + "]"); - } - } - else - { - // No parameters were supplied - if (DeclaredParameters != null && !(DeclaredParameters.Count == 0)) - { - throw new InvalidDataAccessApiUsageException( - DeclaredParameters.Count + " parameters must be supplied"); - } - } - } - - protected virtual bool IsInputParameter(IDataParameter parameter) - { - return (parameter.Direction == ParameterDirection.Input - || parameter.Direction == ParameterDirection.InputOutput); - } - - /// - /// Validates the named parameters passed to an AdoTemplate ExecuteXXX method based on - /// declared parameters. - /// - /// - /// Subclasses should invoke this method very every ExecuteXXX method. - /// - /// The parameter dictionary supplied. May by null. - protected virtual void ValidateNamedParameters(IDictionary parameters) - { - CheckCompiled(); - IDictionary paramsToUse = (parameters != null ? parameters : new Hashtable()); - - if (declaredParameters != null) - { - for (int i = 0; i < declaredParameters.Count; i++) - { - IDataParameter declaredParameter = DeclaredParameters[i]; - if (declaredParameter.ParameterName == null) - { - throw new InvalidDataAccessApiUsageException( - "All parameters must have name specified when using the methods " + - "dedicated to named parameter support"); - } - if (IsInputParameter(declaredParameter) && !paramsToUse.Contains(declaredParameter.ParameterName)) - { - throw new InvalidDataAccessApiUsageException( - "The parameter named '" + declaredParameter + - "' was not among the parameters supplied: " + paramsToUse.Keys); - } - } - } - - - if (DeclaredParameters != null && DeclaredParameters.Count > 0) - { - if (DeclaredParameters == null) - { - throw new InvalidDataAccessApiUsageException( - "Didn't expect any parameters: none were declared"); - } - } - else - { - // No parameters were supplied - if (DeclaredParameters != null && !(DeclaredParameters.Count == 0)) - { - throw new InvalidDataAccessApiUsageException( - "Parameters must be supplied"); - } - } - - } - - /// - /// Subclasses must implement to perform their own compilation. - /// Invoked after this class's compilation is complete. - /// Subclasses can assume that SQL has been supplied and that - /// a IDbProvider has been supplied. - /// - protected virtual void CompileInternal() - { - commandFactory = new IDbCommandCreatorFactory(DbProvider, CommandType, Sql, DeclaredParameters); - OnCompileInternal(); - - - } - /// - /// Hook method that subclasses may override to react to compilation. - /// This implementation does nothing. - /// - protected virtual void OnCompileInternal() - { - } - - protected virtual IDbCommandCreator NewCommandCreator(IDictionary inParams) - { - return commandFactory.NewDbCommandCreator(inParams); - } - - protected virtual IDbCommandCreator NewCommandCreatorWithParamValues(params object[] inParams) - { - return commandFactory.NewDbCommandCreatorWithParamValues(inParams); - } - - #endregion - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Collections; +using System.Data; +using Common.Logging; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Objects.Factory; + +namespace Spring.Data.Objects +{ + /// + /// Abstract base class providing common functionality for generic and non + /// generic implementations of "AdoOperation" subclasses. + /// + /// Mark Pollack (.NET) + public abstract class AbstractAdoOperation : IInitializingObject + { + #region Logging Definition + + protected readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + #endregion + + #region Fields + + private string sql; + + private CommandType commandType = CommandType.Text; + + private IDbParameters declaredParameters; + + + /// + /// Has this operation been compiled? Compilation means at + /// least checking that a IDbProvider and sql have been provided, + /// but subclasses may also implement their own custom validation. + /// + protected bool compiled; + + /// + /// Object enabling us to create IDbCommands + /// efficiently, based on this class's declared parameters. + /// + private IDbCommandCreatorFactory commandFactory; + + #endregion + + + #region Properties + + + /// + /// Gets or sets the type of the command. + /// + /// The type of the command. + public CommandType CommandType + { + get { return commandType; } + set { commandType = value; } + } + + /// + /// Gets or sets the db provider. + /// + /// The db provider. + public abstract IDbProvider DbProvider + { + get; set; + } + + /// + /// Gets or sets the SQL to execute + /// + /// The SQL. + public string Sql + { + get + { + return sql; + } + set + { + sql = value; + } + } + + /// + /// Gets or sets the declared parameters. + /// + /// The declared parameters. + public IDbParameters DeclaredParameters + { + get + { + return declaredParameters; + } + set + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add parameters once operation is compiled"); + } + declaredParameters = value; + } + } + + /// + /// Gets a value indicating whether this is compiled. + /// + /// Compilation means that the operation is fully configured, + /// and ready to use. The exact meaning of compilation will vary between subclasses. + /// true if compiled; otherwise, false. + public bool Compiled + { + get { return compiled; } + } + + /// + /// Sets the command timeout for IDbCommands that this AdoTemplate executes. + /// + /// Default is 0, indicating to use the database provider's default. + /// Any timeout specified here will be overridden by the remaining + /// transaction timeout when executing within a transaction that has a + /// timeout specified at the transaction level. + /// + /// The command timeout. + public abstract int CommandTimeout + { + set; + } + + + #endregion + + #region Methods + + /// + /// Ensures compilation if used in an IApplicationContext + /// + public void AfterPropertiesSet() + { + Compile(); + } + + /// + /// Compiles this operation. Ignores subsequent attempts to compile. + /// + public abstract void Compile(); + + + + + /// + /// Check whether this operation has been compiled already; + /// lazily compile it if not already compiled. + /// + /// Automatically called by ValidateParameters and ValidateNamedParameters + protected void CheckCompiled() + { + if (!Compiled) + { + log.Debug("ADO operation not compiled before execution - invoking compile"); + Compile(); + } + } + + + protected virtual void ValidateParameters(params object[] inParamValues) + { + CheckCompiled(); + int declaredInParameters = 0; + if (DeclaredParameters != null) + { + for (int i = 0; i < declaredParameters.Count; i++) + { + IDataParameter declaredParameter = DeclaredParameters[i]; + if (IsInputParameter(declaredParameter)) + { + declaredInParameters++; + } + } + } + + if (inParamValues != null) + { + if (DeclaredParameters == null) + { + throw new InvalidDataAccessApiUsageException( + "Didn't expect any parameters: none were declared"); + } + if (inParamValues.Length < declaredInParameters) + { + throw new InvalidDataAccessApiUsageException( + inParamValues.Length + " parameters were supplied, but " + + declaredInParameters + " in parameters were declared in class [" + + GetType().AssemblyQualifiedName + "]"); + } + if (inParamValues.Length > declaredInParameters) + { + throw new InvalidDataAccessApiUsageException( + inParamValues.Length + " parameters were supplied, but " + + DeclaredParameters.Count + " parameters were declared " + + "in class [" + GetType().AssemblyQualifiedName + "]"); + } + } + else + { + // No parameters were supplied + if (DeclaredParameters != null && !(DeclaredParameters.Count == 0)) + { + throw new InvalidDataAccessApiUsageException( + DeclaredParameters.Count + " parameters must be supplied"); + } + } + } + + protected virtual bool IsInputParameter(IDataParameter parameter) + { + return (parameter.Direction == ParameterDirection.Input + || parameter.Direction == ParameterDirection.InputOutput); + } + + /// + /// Validates the named parameters passed to an AdoTemplate ExecuteXXX method based on + /// declared parameters. + /// + /// + /// Subclasses should invoke this method very every ExecuteXXX method. + /// + /// The parameter dictionary supplied. May by null. + protected virtual void ValidateNamedParameters(IDictionary parameters) + { + CheckCompiled(); + IDictionary paramsToUse = (parameters != null ? parameters : new Hashtable()); + + if (declaredParameters != null) + { + for (int i = 0; i < declaredParameters.Count; i++) + { + IDataParameter declaredParameter = DeclaredParameters[i]; + if (declaredParameter.ParameterName == null) + { + throw new InvalidDataAccessApiUsageException( + "All parameters must have name specified when using the methods " + + "dedicated to named parameter support"); + } + if (IsInputParameter(declaredParameter) && !paramsToUse.Contains(declaredParameter.ParameterName)) + { + throw new InvalidDataAccessApiUsageException( + "The parameter named '" + declaredParameter + + "' was not among the parameters supplied: " + paramsToUse.Keys); + } + } + } + + + if (DeclaredParameters != null && DeclaredParameters.Count > 0) + { + if (DeclaredParameters == null) + { + throw new InvalidDataAccessApiUsageException( + "Didn't expect any parameters: none were declared"); + } + } + else + { + // No parameters were supplied + if (DeclaredParameters != null && !(DeclaredParameters.Count == 0)) + { + throw new InvalidDataAccessApiUsageException( + "Parameters must be supplied"); + } + } + + } + + /// + /// Subclasses must implement to perform their own compilation. + /// Invoked after this class's compilation is complete. + /// Subclasses can assume that SQL has been supplied and that + /// a IDbProvider has been supplied. + /// + protected virtual void CompileInternal() + { + commandFactory = new IDbCommandCreatorFactory(DbProvider, CommandType, Sql, DeclaredParameters); + OnCompileInternal(); + + + } + /// + /// Hook method that subclasses may override to react to compilation. + /// This implementation does nothing. + /// + protected virtual void OnCompileInternal() + { + } + + protected virtual IDbCommandCreator NewCommandCreator(IDictionary inParams) + { + return commandFactory.NewDbCommandCreator(inParams); + } + + protected virtual IDbCommandCreator NewCommandCreatorWithParamValues(params object[] inParams) + { + return commandFactory.NewDbCommandCreatorWithParamValues(inParams); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/AdoNonQuery.cs b/src/Spring/Spring.Data/Data/Objects/AdoNonQuery.cs index ab5baee2..5eb83844 100644 --- a/src/Spring/Spring.Data/Data/Objects/AdoNonQuery.cs +++ b/src/Spring/Spring.Data/Data/Objects/AdoNonQuery.cs @@ -1,84 +1,83 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// Encapsulate Command.ExecuteNonQuery operations within a reusable class. - /// - /// Mark Pollack (.NET) - /// The default CommandType is CommandType.Text - /// $Id: AdoNonQuery.cs,v 1.3 2007/07/25 08:25:20 markpollack Exp $ - public class AdoNonQuery : AdoOperation - { - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public AdoNonQuery() - {} - - /// - /// Initializes a new instance of the class. - /// - public AdoNonQuery(IDbProvider provider) - : base(provider) - {} - - /// - /// Initializes a new instance of the class. - /// - public AdoNonQuery(IDbProvider dbProvider, string sql) - : base(dbProvider, sql) - {} - - #endregion - - #region Properties - - #endregion - - #region Methods - - public IDictionary ExecuteNonQuery(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.ExecuteNonQuery(NewCommandCreatorWithParamValues(inParameterValues)); - } - - - public IDictionary ExecuteNonQueryByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.ExecuteNonQuery(NewCommandCreator(inParams)); - } - - #endregion - } -} +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// Encapsulate Command.ExecuteNonQuery operations within a reusable class. + /// + /// Mark Pollack (.NET) + /// The default CommandType is CommandType.Text + public class AdoNonQuery : AdoOperation + { + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public AdoNonQuery() + {} + + /// + /// Initializes a new instance of the class. + /// + public AdoNonQuery(IDbProvider provider) + : base(provider) + {} + + /// + /// Initializes a new instance of the class. + /// + public AdoNonQuery(IDbProvider dbProvider, string sql) + : base(dbProvider, sql) + {} + + #endregion + + #region Properties + + #endregion + + #region Methods + + public IDictionary ExecuteNonQuery(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.ExecuteNonQuery(NewCommandCreatorWithParamValues(inParameterValues)); + } + + + public IDictionary ExecuteNonQueryByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.ExecuteNonQuery(NewCommandCreator(inParams)); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Data/Objects/AdoOperation.cs b/src/Spring/Spring.Data/Data/Objects/AdoOperation.cs index e9416d48..d1c807b4 100644 --- a/src/Spring/Spring.Data/Data/Objects/AdoOperation.cs +++ b/src/Spring/Spring.Data/Data/Objects/AdoOperation.cs @@ -1,199 +1,198 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Data.Core; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// A "AdoOperation" is a thread-safe, reusable object representing - /// an ADO Query, "NonQuery" (Create, Update, Delete), stored procedure - /// or DataSet manipualtions. - /// - /// - /// Subclasses should set Command Text and add parameters before invoking - /// Compile(). The order in which parameters are added is generally - /// significant when using providers or functionality that do not use - /// named parameters. - /// - /// - /// Mark Pollack (.NET) - /// $Id: AdoOperation.cs,v 1.15 2008/05/30 21:09:22 markpollack Exp $ - public abstract class AdoOperation : AbstractAdoOperation - { - - #region Fields - - private AdoTemplate adoTemplate = new AdoTemplate(); - - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - /// A DbProvider, SQL and any parameters must be supplied - /// before invoking the compile method and using this object. - /// - public AdoOperation() - {} - - /// - /// Initializes a new instance of the class. - /// - /// A DbProvider, SQL and any parameters must be supplied - /// before invoking the compile method and using this object. - /// - /// Database provider to use. - public AdoOperation(IDbProvider provider) - : this(provider, null) - {} - - /// - /// Initializes a new instance of the class. - /// - /// A DbProvider, SQL and any parameters must be supplied - /// before invoking the compile method and using this object. - /// - /// Database provider to use. - /// SQL query or stored procedure name. - public AdoOperation(IDbProvider provider, String sql) - { - //intialized AdoTemplate with the DbProvider - DbProvider = provider; - Sql = sql; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the ADO template. - /// - /// The ADO template. - public AdoTemplate AdoTemplate - { - set - { - if (value == null) - { - throw new ArgumentNullException("AdoTemplate"); - } - adoTemplate = value; - } - get - { - return adoTemplate; - } - } - - - /// - /// Gets or sets the db provider. - /// - /// The db provider. - public override IDbProvider DbProvider - { - set - { - adoTemplate.DbProvider = value; - if (DeclaredParameters == null) - { - DeclaredParameters = new DbParameters(value); - } - } - get - { - return adoTemplate.DbProvider; - } - } - - - - /// - /// Sets the command timeout for IDbCommands that this AdoTemplate executes. - /// - /// Default is 0, indicating to use the database provider's default. - /// Any timeout specified here will be overridden by the remaining - /// transaction timeout when executing within a transaction that has a - /// timeout specified at the transaction level. - /// - /// The command timeout. - public override int CommandTimeout - { - set { adoTemplate.CommandTimeout = value; } - } - - #endregion - - #region Methods - - - /// - /// Compiles this operation. Ignores subsequent attempts to compile. - /// - public override void Compile() - { - if (!Compiled) - { - if (Sql == null) - { - throw new InvalidDataAccessApiUsageException("Setting of Sql is required"); - } - if (CommandType == 0) - { - throw new InvalidDataAccessApiUsageException("Setting of CommandType is required"); - } - - try - { - adoTemplate.AfterPropertiesSet(); - } - catch (ArgumentException ex) - { - throw new InvalidDataAccessApiUsageException(ex.Message); - } - - - CompileInternal(); - compiled = true; - - - } - } - - - - - - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Data.Core; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// A "AdoOperation" is a thread-safe, reusable object representing + /// an ADO Query, "NonQuery" (Create, Update, Delete), stored procedure + /// or DataSet manipualtions. + /// + /// + /// Subclasses should set Command Text and add parameters before invoking + /// Compile(). The order in which parameters are added is generally + /// significant when using providers or functionality that do not use + /// named parameters. + /// + /// + /// Mark Pollack (.NET) + public abstract class AdoOperation : AbstractAdoOperation + { + + #region Fields + + private AdoTemplate adoTemplate = new AdoTemplate(); + + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + /// A DbProvider, SQL and any parameters must be supplied + /// before invoking the compile method and using this object. + /// + public AdoOperation() + {} + + /// + /// Initializes a new instance of the class. + /// + /// A DbProvider, SQL and any parameters must be supplied + /// before invoking the compile method and using this object. + /// + /// Database provider to use. + public AdoOperation(IDbProvider provider) + : this(provider, null) + {} + + /// + /// Initializes a new instance of the class. + /// + /// A DbProvider, SQL and any parameters must be supplied + /// before invoking the compile method and using this object. + /// + /// Database provider to use. + /// SQL query or stored procedure name. + public AdoOperation(IDbProvider provider, String sql) + { + //intialized AdoTemplate with the DbProvider + DbProvider = provider; + Sql = sql; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the ADO template. + /// + /// The ADO template. + public AdoTemplate AdoTemplate + { + set + { + if (value == null) + { + throw new ArgumentNullException("AdoTemplate"); + } + adoTemplate = value; + } + get + { + return adoTemplate; + } + } + + + /// + /// Gets or sets the db provider. + /// + /// The db provider. + public override IDbProvider DbProvider + { + set + { + adoTemplate.DbProvider = value; + if (DeclaredParameters == null) + { + DeclaredParameters = new DbParameters(value); + } + } + get + { + return adoTemplate.DbProvider; + } + } + + + + /// + /// Sets the command timeout for IDbCommands that this AdoTemplate executes. + /// + /// Default is 0, indicating to use the database provider's default. + /// Any timeout specified here will be overridden by the remaining + /// transaction timeout when executing within a transaction that has a + /// timeout specified at the transaction level. + /// + /// The command timeout. + public override int CommandTimeout + { + set { adoTemplate.CommandTimeout = value; } + } + + #endregion + + #region Methods + + + /// + /// Compiles this operation. Ignores subsequent attempts to compile. + /// + public override void Compile() + { + if (!Compiled) + { + if (Sql == null) + { + throw new InvalidDataAccessApiUsageException("Setting of Sql is required"); + } + if (CommandType == 0) + { + throw new InvalidDataAccessApiUsageException("Setting of CommandType is required"); + } + + try + { + adoTemplate.AfterPropertiesSet(); + } + catch (ArgumentException ex) + { + throw new InvalidDataAccessApiUsageException(ex.Message); + } + + + CompileInternal(); + compiled = true; + + + } + } + + + + + + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Data/Objects/AdoQuery.cs b/src/Spring/Spring.Data/Data/Objects/AdoQuery.cs index de09700c..5ffb9f89 100644 --- a/src/Spring/Spring.Data/Data/Objects/AdoQuery.cs +++ b/src/Spring/Spring.Data/Data/Objects/AdoQuery.cs @@ -1,112 +1,111 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using Spring.Dao.Support; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// Place together the mapping logic to a plain .NET object - /// for one result set within the same class. - /// - /// Mark Pollack (.NET) - /// $Id: AdoQuery.cs,v 1.8 2008/05/30 21:09:22 markpollack Exp $ - public abstract class AdoQuery : AdoOperation - { - #region Fields - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public AdoQuery() - { - - } - - public AdoQuery(IDbProvider provider, string sql) - { - DbProvider = provider; - Sql = sql; - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - public IList Query() - { - return QueryByNamedParam(null); - } - - public IList QueryByNamedParam(IDictionary inParams) - { - return QueryByNamedParam(inParams, null); - } - - public IList QueryByNamedParam(IDictionary inParams, IDictionary returnedParameters) - { - return QueryByNamedParam(inParams, returnedParameters, null); - } - - public IList QueryByNamedParam(IDictionary inParams, IDictionary returnedParameters, IDictionary callingContext) - { - ValidateNamedParameters(inParams); - IRowMapper rowMapper = NewRowMapper(inParams, callingContext); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), rowMapper, returnedParameters); - } - - public object QueryForObject(IDictionary inParams) - { - IList results = QueryByNamedParam(inParams); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public object QueryForObject(IDictionary inParams, IDictionary returnedParameters) - { - IList results = QueryByNamedParam(inParams, returnedParameters); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public object QueryForObject(IDictionary inParams, IDictionary returnedParameters, IDictionary callingContext) - { - IList results = QueryByNamedParam(inParams, returnedParameters, callingContext); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - - protected abstract IRowMapper NewRowMapper(IDictionary inParams, IDictionary callingContext); - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using Spring.Dao.Support; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// Place together the mapping logic to a plain .NET object + /// for one result set within the same class. + /// + /// Mark Pollack (.NET) + public abstract class AdoQuery : AdoOperation + { + #region Fields + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public AdoQuery() + { + + } + + public AdoQuery(IDbProvider provider, string sql) + { + DbProvider = provider; + Sql = sql; + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + public IList Query() + { + return QueryByNamedParam(null); + } + + public IList QueryByNamedParam(IDictionary inParams) + { + return QueryByNamedParam(inParams, null); + } + + public IList QueryByNamedParam(IDictionary inParams, IDictionary returnedParameters) + { + return QueryByNamedParam(inParams, returnedParameters, null); + } + + public IList QueryByNamedParam(IDictionary inParams, IDictionary returnedParameters, IDictionary callingContext) + { + ValidateNamedParameters(inParams); + IRowMapper rowMapper = NewRowMapper(inParams, callingContext); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), rowMapper, returnedParameters); + } + + public object QueryForObject(IDictionary inParams) + { + IList results = QueryByNamedParam(inParams); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public object QueryForObject(IDictionary inParams, IDictionary returnedParameters) + { + IList results = QueryByNamedParam(inParams, returnedParameters); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public object QueryForObject(IDictionary inParams, IDictionary returnedParameters, IDictionary callingContext) + { + IList results = QueryByNamedParam(inParams, returnedParameters, callingContext); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + + protected abstract IRowMapper NewRowMapper(IDictionary inParams, IDictionary callingContext); + + #endregion + + } +} diff --git a/src/Spring/Spring.Data/Data/Objects/AdoScalar.cs b/src/Spring/Spring.Data/Data/Objects/AdoScalar.cs index 721d1e19..c372c5fe 100644 --- a/src/Spring/Spring.Data/Data/Objects/AdoScalar.cs +++ b/src/Spring/Spring.Data/Data/Objects/AdoScalar.cs @@ -1,79 +1,78 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// Encapsulate Command ExecuteScalar operations within a reusable class. - /// - /// The default CommandType is CommandType.Text - /// Mark Pollack (.NET) - /// $Id: AdoScalar.cs,v 1.3 2007/07/25 08:25:20 markpollack Exp $ - public class AdoScalar : AdoOperation - { - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public AdoScalar() - {} - - /// - /// Initializes a new instance of the class. - /// - public AdoScalar(IDbProvider provider) - : base(provider) - {} - - /// - /// Initializes a new instance of the class. - /// - public AdoScalar(IDbProvider dbProvider, string sql) - : base(dbProvider, sql) - {} - - #endregion - - #region Methods - - public IDictionary ExecuteScalar(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.ExecuteScalar(NewCommandCreatorWithParamValues(inParameterValues)); - } - - public IDictionary ExecuteScalarByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.ExecuteScalar(NewCommandCreator(inParams)); - } - - #endregion - } +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// Encapsulate Command ExecuteScalar operations within a reusable class. + /// + /// The default CommandType is CommandType.Text + /// Mark Pollack (.NET) + public class AdoScalar : AdoOperation + { + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public AdoScalar() + {} + + /// + /// Initializes a new instance of the class. + /// + public AdoScalar(IDbProvider provider) + : base(provider) + {} + + /// + /// Initializes a new instance of the class. + /// + public AdoScalar(IDbProvider dbProvider, string sql) + : base(dbProvider, sql) + {} + + #endregion + + #region Methods + + public IDictionary ExecuteScalar(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.ExecuteScalar(NewCommandCreatorWithParamValues(inParameterValues)); + } + + public IDictionary ExecuteScalarByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.ExecuteScalar(NewCommandCreator(inParams)); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/Generic/AdoOperation.cs b/src/Spring/Spring.Data/Data/Objects/Generic/AdoOperation.cs index 4f9a354a..00e9f577 100644 --- a/src/Spring/Spring.Data/Data/Objects/Generic/AdoOperation.cs +++ b/src/Spring/Spring.Data/Data/Objects/Generic/AdoOperation.cs @@ -1,202 +1,201 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System; -using Spring.Dao; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects.Generic -{ - /// - /// A "AdoOperation" is a thread-safe, reusable object representing - /// an ADO Query, "NonQuery" (Create, Update, Delete), stored procedure - /// or DataSet manipualtions. - /// - /// - /// Subclasses should set Command Text and add parameters before invoking - /// Compile(). The order in which parameters are added is generally - /// significant when using providers or functionality that do not use - /// named parameters. - /// - /// - /// Mark Pollack (.NET) - /// $Id: AdoOperation.cs,v 1.3 2008/05/30 21:09:32 markpollack Exp $ - public abstract class AdoOperation : AbstractAdoOperation - { - - #region Fields - - private Data.Generic.AdoTemplate adoTemplate = new Data.Generic.AdoTemplate(); - - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - /// A DbProvider, SQL and any parameters must be supplied - /// before invoking the compile method and using this object. - /// - public AdoOperation() - {} - - /// - /// Initializes a new instance of the class. - /// - /// A DbProvider, SQL and any parameters must be supplied - /// before invoking the compile method and using this object. - /// - /// Database provider to use. - public AdoOperation(IDbProvider provider) - : this(provider, null) - {} - - /// - /// Initializes a new instance of the class. - /// - /// A DbProvider, SQL and any parameters must be supplied - /// before invoking the compile method and using this object. - /// - /// Database provider to use. - /// SQL query or stored procedure name. - public AdoOperation(IDbProvider provider, String sql) - { - //intialized AdoTemplate with the DbProvider - DbProvider = provider; - Sql = sql; - } - - #endregion - - #region Properties - - /// - /// Gets or sets the ADO template. - /// - /// The ADO template. - public Data.Generic.AdoTemplate AdoTemplate - { - set - { - if (value == null) - { - throw new ArgumentNullException("AdoTemplate"); - } - adoTemplate = value; - } - get - { - return adoTemplate; - } - } - - - /// - /// Gets or sets the db provider. - /// - /// The db provider. - public override IDbProvider DbProvider - { - set - { - adoTemplate.DbProvider = value; - if (DeclaredParameters == null) - { - DeclaredParameters = new DbParameters(value); - } - } - get - { - return adoTemplate.DbProvider; - } - } - - - - /// - /// Sets the command timeout for IDbCommands that this AdoTemplate executes. - /// - /// Default is 0, indicating to use the database provider's default. - /// Any timeout specified here will be overridden by the remaining - /// transaction timeout when executing within a transaction that has a - /// timeout specified at the transaction level. - /// - /// The command timeout. - public override int CommandTimeout - { - set { adoTemplate.CommandTimeout = value; } - } - - #endregion - - #region Methods - - - /// - /// Compiles this operation. Ignores subsequent attempts to compile. - /// - public override void Compile() - { - if (!Compiled) - { - if (Sql == null) - { - throw new InvalidDataAccessApiUsageException("Setting of Sql is required"); - } - if (CommandType == 0) - { - throw new InvalidDataAccessApiUsageException("Setting of CommandType is required"); - } - - try - { - adoTemplate.AfterPropertiesSet(); - } - catch (ArgumentException ex) - { - throw new InvalidDataAccessApiUsageException(ex.Message); - } - - - CompileInternal(); - compiled = true; - - - } - } - - - - - - - #endregion - } -} - +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System; +using Spring.Dao; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects.Generic +{ + /// + /// A "AdoOperation" is a thread-safe, reusable object representing + /// an ADO Query, "NonQuery" (Create, Update, Delete), stored procedure + /// or DataSet manipualtions. + /// + /// + /// Subclasses should set Command Text and add parameters before invoking + /// Compile(). The order in which parameters are added is generally + /// significant when using providers or functionality that do not use + /// named parameters. + /// + /// + /// Mark Pollack (.NET) + public abstract class AdoOperation : AbstractAdoOperation + { + + #region Fields + + private Data.Generic.AdoTemplate adoTemplate = new Data.Generic.AdoTemplate(); + + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + /// A DbProvider, SQL and any parameters must be supplied + /// before invoking the compile method and using this object. + /// + public AdoOperation() + {} + + /// + /// Initializes a new instance of the class. + /// + /// A DbProvider, SQL and any parameters must be supplied + /// before invoking the compile method and using this object. + /// + /// Database provider to use. + public AdoOperation(IDbProvider provider) + : this(provider, null) + {} + + /// + /// Initializes a new instance of the class. + /// + /// A DbProvider, SQL and any parameters must be supplied + /// before invoking the compile method and using this object. + /// + /// Database provider to use. + /// SQL query or stored procedure name. + public AdoOperation(IDbProvider provider, String sql) + { + //intialized AdoTemplate with the DbProvider + DbProvider = provider; + Sql = sql; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the ADO template. + /// + /// The ADO template. + public Data.Generic.AdoTemplate AdoTemplate + { + set + { + if (value == null) + { + throw new ArgumentNullException("AdoTemplate"); + } + adoTemplate = value; + } + get + { + return adoTemplate; + } + } + + + /// + /// Gets or sets the db provider. + /// + /// The db provider. + public override IDbProvider DbProvider + { + set + { + adoTemplate.DbProvider = value; + if (DeclaredParameters == null) + { + DeclaredParameters = new DbParameters(value); + } + } + get + { + return adoTemplate.DbProvider; + } + } + + + + /// + /// Sets the command timeout for IDbCommands that this AdoTemplate executes. + /// + /// Default is 0, indicating to use the database provider's default. + /// Any timeout specified here will be overridden by the remaining + /// transaction timeout when executing within a transaction that has a + /// timeout specified at the transaction level. + /// + /// The command timeout. + public override int CommandTimeout + { + set { adoTemplate.CommandTimeout = value; } + } + + #endregion + + #region Methods + + + /// + /// Compiles this operation. Ignores subsequent attempts to compile. + /// + public override void Compile() + { + if (!Compiled) + { + if (Sql == null) + { + throw new InvalidDataAccessApiUsageException("Setting of Sql is required"); + } + if (CommandType == 0) + { + throw new InvalidDataAccessApiUsageException("Setting of CommandType is required"); + } + + try + { + adoTemplate.AfterPropertiesSet(); + } + catch (ArgumentException ex) + { + throw new InvalidDataAccessApiUsageException(ex.Message); + } + + + CompileInternal(); + compiled = true; + + + } + } + + + + + + + #endregion + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/Generic/AdoQuery.cs b/src/Spring/Spring.Data/Data/Objects/Generic/AdoQuery.cs index afa1054a..d2955038 100644 --- a/src/Spring/Spring.Data/Data/Objects/Generic/AdoQuery.cs +++ b/src/Spring/Spring.Data/Data/Objects/Generic/AdoQuery.cs @@ -1,152 +1,151 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System.Collections.Generic; -using Spring.Dao.Support.Generic; -using Spring.Data.Common; -using Spring.Data.Generic; - -#endregion - -namespace Spring.Data.Objects.Generic -{ - /// - /// Place together the mapping logic to a plain .NET object - /// for one result set within the same class. - /// - /// Mark Pollack (.NET) - /// $Id: AdoQuery.cs,v 1.3 2007/07/25 13:32:39 oakinger Exp $ - public abstract class AdoQuery : AdoOperation - { - #region Fields - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public AdoQuery() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// The database provider. - /// The SQL to execute - public AdoQuery(IDbProvider provider, string sql) - { - DbProvider = provider; - Sql = sql; - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - - /// - /// Convenient method to execute query without parameters or calling context. - /// - /// The type parameter for the returned collection - /// List of mapped objects - public IList Query() - { - return QueryByNamedParam(null); - } - - /// - /// Convenient method to execute query with parameters but without calling context. - /// - /// The type parameter for the returned collection - /// The parameters for the query. - /// - public IList QueryByNamedParam(System.Collections.IDictionary inParams) - { - return QueryByNamedParam(inParams, null); - } - - /// - /// Convenient method to execute query with parameters and access to output parameter values. - /// - /// The type parameter for the returned collection - /// The parameters for the query. - /// The returned output parameters. - /// - public IList QueryByNamedParam(System.Collections.IDictionary inParams, - System.Collections.IDictionary outParams) - { - return QueryByNamedParam(inParams, outParams, null); - } - - /// - /// Central execution method. All named parameter execution goes through this method. - /// - /// the type parameter for the returned collection - /// The in params. - /// The out params. - /// The calling context. - /// - public IList QueryByNamedParam(System.Collections.IDictionary inParams, - System.Collections.IDictionary outParams, - System.Collections.IDictionary callingContext) - { - ValidateNamedParameters(inParams); - IRowMapper rowMapper = NewRowMapper(inParams, callingContext); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), rowMapper, outParams); - } - - public T QueryForObject(System.Collections.IDictionary inParams) - { - IList results = QueryByNamedParam(inParams); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public T QueryForObject(System.Collections.IDictionary inParams, System.Collections.IDictionary returnedParameters) - { - IList results = QueryByNamedParam(inParams, returnedParameters); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - public T QueryForObject(System.Collections.IDictionary inParams, System.Collections.IDictionary returnedParameters, System.Collections.IDictionary callingContext) - { - IList results = QueryByNamedParam(inParams, returnedParameters, callingContext); - return DataAccessUtils.RequiredUniqueResultSet(results); - } - - - protected abstract IRowMapper NewRowMapper(System.Collections.IDictionary inParams, System.Collections.IDictionary callingContext); - - #endregion - - } -} - +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System.Collections.Generic; +using Spring.Dao.Support.Generic; +using Spring.Data.Common; +using Spring.Data.Generic; + +#endregion + +namespace Spring.Data.Objects.Generic +{ + /// + /// Place together the mapping logic to a plain .NET object + /// for one result set within the same class. + /// + /// Mark Pollack (.NET) + public abstract class AdoQuery : AdoOperation + { + #region Fields + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public AdoQuery() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The database provider. + /// The SQL to execute + public AdoQuery(IDbProvider provider, string sql) + { + DbProvider = provider; + Sql = sql; + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + + /// + /// Convenient method to execute query without parameters or calling context. + /// + /// The type parameter for the returned collection + /// List of mapped objects + public IList Query() + { + return QueryByNamedParam(null); + } + + /// + /// Convenient method to execute query with parameters but without calling context. + /// + /// The type parameter for the returned collection + /// The parameters for the query. + /// + public IList QueryByNamedParam(System.Collections.IDictionary inParams) + { + return QueryByNamedParam(inParams, null); + } + + /// + /// Convenient method to execute query with parameters and access to output parameter values. + /// + /// The type parameter for the returned collection + /// The parameters for the query. + /// The returned output parameters. + /// + public IList QueryByNamedParam(System.Collections.IDictionary inParams, + System.Collections.IDictionary outParams) + { + return QueryByNamedParam(inParams, outParams, null); + } + + /// + /// Central execution method. All named parameter execution goes through this method. + /// + /// the type parameter for the returned collection + /// The in params. + /// The out params. + /// The calling context. + /// + public IList QueryByNamedParam(System.Collections.IDictionary inParams, + System.Collections.IDictionary outParams, + System.Collections.IDictionary callingContext) + { + ValidateNamedParameters(inParams); + IRowMapper rowMapper = NewRowMapper(inParams, callingContext); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), rowMapper, outParams); + } + + public T QueryForObject(System.Collections.IDictionary inParams) + { + IList results = QueryByNamedParam(inParams); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public T QueryForObject(System.Collections.IDictionary inParams, System.Collections.IDictionary returnedParameters) + { + IList results = QueryByNamedParam(inParams, returnedParameters); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + public T QueryForObject(System.Collections.IDictionary inParams, System.Collections.IDictionary returnedParameters, System.Collections.IDictionary callingContext) + { + IList results = QueryByNamedParam(inParams, returnedParameters, callingContext); + return DataAccessUtils.RequiredUniqueResultSet(results); + } + + + protected abstract IRowMapper NewRowMapper(System.Collections.IDictionary inParams, System.Collections.IDictionary callingContext); + + #endregion + + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQuery.cs b/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQuery.cs index 956f79cf..9fb617d0 100644 --- a/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQuery.cs +++ b/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQuery.cs @@ -1,76 +1,75 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects.Generic -{ - /// - /// Reusable query in which concrete subclasses must implement the - /// MapRow method to map each row of a single result set into an - /// object. - /// - /// - /// Simplifies MappingSqlQueryWithContext API by dropping parameters and - /// context. Most subclasses won't care about parameters. If you don't use - /// contextual information, subclass this instead of MappingSqlQueryWithContext. - /// - /// Mark Pollack (.NET) - /// $Id: MappingAdoQuery.cs,v 1.2 2007/07/25 13:32:39 oakinger Exp $ - public abstract class MappingAdoQuery : MappingAdoQueryWithContext - { - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - public MappingAdoQuery() - { - } - - public MappingAdoQuery(IDbProvider dbProvider, string sql) : base(dbProvider, sql) - { - } - - #endregion - - #region Methods - - protected override T MapRow(IDataReader reader, int rowNum, IDictionary inParams, - IDictionary callingContext) - { - return MapRow(reader, rowNum); - } - - protected abstract T MapRow(IDataReader reader, int num); - - #endregion - } -} - +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects.Generic +{ + /// + /// Reusable query in which concrete subclasses must implement the + /// MapRow method to map each row of a single result set into an + /// object. + /// + /// + /// Simplifies MappingSqlQueryWithContext API by dropping parameters and + /// context. Most subclasses won't care about parameters. If you don't use + /// contextual information, subclass this instead of MappingSqlQueryWithContext. + /// + /// Mark Pollack (.NET) + public abstract class MappingAdoQuery : MappingAdoQueryWithContext + { + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + public MappingAdoQuery() + { + } + + public MappingAdoQuery(IDbProvider dbProvider, string sql) : base(dbProvider, sql) + { + } + + #endregion + + #region Methods + + protected override T MapRow(IDataReader reader, int rowNum, IDictionary inParams, + IDictionary callingContext) + { + return MapRow(reader, rowNum); + } + + protected abstract T MapRow(IDataReader reader, int num); + + #endregion + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQueryWithContext.cs b/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQueryWithContext.cs index b773cc15..6a82df36 100644 --- a/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQueryWithContext.cs +++ b/src/Spring/Spring.Data/Data/Objects/Generic/MappingAdoQueryWithContext.cs @@ -1,102 +1,101 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Data.Common; -using Spring.Data.Generic; - -#endregion - -namespace Spring.Data.Objects.Generic -{ - /// - /// Reusable query in which concrete subclasses must implement the - /// abstract MapRow method to map each row of a single result set into an - /// object. - /// - /// The MapRow method is also passed the input parameters and - /// a dictionary to provide the method with calling context information - /// (if necessary). If you do not need these additional parameters, use - /// the subclass MappingAdoQuery. - /// - /// Mark Pollack (.NET) - /// $Id: MappingAdoQueryWithContext.cs,v 1.2 2007/07/25 13:32:39 oakinger Exp $ - public abstract class MappingAdoQueryWithContext : AdoQuery - { - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public MappingAdoQueryWithContext() - { - - } - - public MappingAdoQueryWithContext(IDbProvider dbProvider, string sql) : base(dbProvider, sql) - { - - } - #endregion - - #region Properties - - #endregion - - #region Methods - - protected override IRowMapper NewRowMapper(System.Collections.IDictionary inParams, - System.Collections.IDictionary callingContext) - { - return new RowMapperImpl(this, inParams, callingContext); - } - - protected abstract T MapRow(IDataReader reader, int rowNum, IDictionary inParams, IDictionary callingContext); - - - #endregion - - private class RowMapperImpl : IRowMapper - { - private MappingAdoQueryWithContext outer; - private IDictionary inParams; - private IDictionary callingContext; - - public RowMapperImpl(MappingAdoQueryWithContext mappingAdoQueryWithContext, IDictionary inParams, IDictionary callingContext) - { - outer = mappingAdoQueryWithContext; - this.inParams = inParams; - this.callingContext = callingContext; - } - - public T MapRow(IDataReader dataReader, int rowNum) - { - return outer.MapRow(dataReader, rowNum, inParams, callingContext); - } - } - - } -} - +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Data.Common; +using Spring.Data.Generic; + +#endregion + +namespace Spring.Data.Objects.Generic +{ + /// + /// Reusable query in which concrete subclasses must implement the + /// abstract MapRow method to map each row of a single result set into an + /// object. + /// + /// The MapRow method is also passed the input parameters and + /// a dictionary to provide the method with calling context information + /// (if necessary). If you do not need these additional parameters, use + /// the subclass MappingAdoQuery. + /// + /// Mark Pollack (.NET) + public abstract class MappingAdoQueryWithContext : AdoQuery + { + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public MappingAdoQueryWithContext() + { + + } + + public MappingAdoQueryWithContext(IDbProvider dbProvider, string sql) : base(dbProvider, sql) + { + + } + #endregion + + #region Properties + + #endregion + + #region Methods + + protected override IRowMapper NewRowMapper(System.Collections.IDictionary inParams, + System.Collections.IDictionary callingContext) + { + return new RowMapperImpl(this, inParams, callingContext); + } + + protected abstract T MapRow(IDataReader reader, int rowNum, IDictionary inParams, IDictionary callingContext); + + + #endregion + + private class RowMapperImpl : IRowMapper + { + private MappingAdoQueryWithContext outer; + private IDictionary inParams; + private IDictionary callingContext; + + public RowMapperImpl(MappingAdoQueryWithContext mappingAdoQueryWithContext, IDictionary inParams, IDictionary callingContext) + { + outer = mappingAdoQueryWithContext; + this.inParams = inParams; + this.callingContext = callingContext; + } + + public T MapRow(IDataReader dataReader, int rowNum) + { + return outer.MapRow(dataReader, rowNum, inParams, callingContext); + } + } + + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/Generic/StoredProcedure.cs b/src/Spring/Spring.Data/Data/Objects/Generic/StoredProcedure.cs index 1b5603c5..c3e5d20c 100644 --- a/src/Spring/Spring.Data/Data/Objects/Generic/StoredProcedure.cs +++ b/src/Spring/Spring.Data/Data/Objects/Generic/StoredProcedure.cs @@ -1,255 +1,254 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#if NET_2_0 - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Collections; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Data.Generic; -using Spring.Data.Support; - -#endregion - -namespace Spring.Data.Objects.Generic -{ - /// - /// A superclass for object based abstractions of RDBMS stored procedures. - /// - /// Mark Pollack (.NET) - /// $Id: StoredProcedure.cs,v 1.3 2007/07/25 13:32:39 oakinger Exp $ - public abstract class StoredProcedure : AdoOperation - { - #region Fields - - //A collection of NamedResultSetProcessor - - private IList resultProcessors = new LinkedList(); - private bool usingDerivedParameters = false; - - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public StoredProcedure() - { - CommandType = CommandType.StoredProcedure; - } - - public StoredProcedure(IDbProvider dbProvider, string procedureName) : base(dbProvider, procedureName) - { - CommandType = CommandType.StoredProcedure; - } - - - - #endregion - - #region Properties - - #endregion - - #region Methods - - public void DeriveParameters() - { - DeriveParameters(false); - } - - - public void DeriveParameters(bool includeReturnParameter) - { - //TODO does this account for offsets? - IDataParameter[] derivedParameters = AdoTemplate.DeriveParameters(Sql, includeReturnParameter); - for (int i = 0; i < derivedParameters.Length; i++) - { - IDataParameter parameter = derivedParameters[i]; - DeclaredParameters.AddParameter(parameter); - } - usingDerivedParameters = true; - } - - - #region Non-generic result set processors - public void AddResultSetExtractor(string name, IResultSetExtractor resultSetExtractor) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add ResultSetExtractors once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name, resultSetExtractor)); - } - - public void AddRowCallback(string name, IRowCallback rowCallback) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add RowCallbacks once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name, rowCallback)); - } - - public void AddRowMapper(string name, IRowMapper rowMapper) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add RowMappers once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name, rowMapper)); - } - - #endregion - - #region Generic result set processors - - public void AddResultSetExtractor(string name, IResultSetExtractor resultSetExtractor) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add ResultSetExtractors once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name, resultSetExtractor)); - } - - - public void AddRowMapper(string name, IRowMapper rowMapper) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add RowMappers once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name,rowMapper)); - } - #endregion - - #region Operations that use derived parameters - protected virtual IDictionary ExecuteScalar(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.ExecuteScalar(NewCommandCreatorWithParamValues(inParameterValues)); - } - - protected virtual IDictionary ExecuteNonQuery(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.ExecuteNonQuery(NewCommandCreatorWithParamValues(inParameterValues)); - } - - - public System.Collections.Generic.IList QueryWithRowMapper(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - if (resultProcessors.Count == 0) - { - throw new InvalidDataAccessApiUsageException("No row mapper is specified."); - } - - NamedResultSetProcessor resultSetProcessor = resultProcessors[0] as NamedResultSetProcessor; - if (resultSetProcessor == null) - { - throw new InvalidDataAccessApiUsageException("No row mapper is specified."); - } - - if (resultSetProcessor.RowMapper == null) - { - throw new InvalidDataAccessApiUsageException("No row mapper is specified as first result set processor."); - } - IDictionary outParams = Query(inParameterValues); - return outParams[resultSetProcessor.Name] as System.Collections.Generic.IList; - - } - - protected virtual IDictionary Query(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreatorWithParamValues(inParameterValues), resultProcessors); - - } - - protected virtual IDictionary Query(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreatorWithParamValues(inParameterValues), resultProcessors); - - } - - #endregion - - - #region Operations that used provided named parameters - /// - /// Execute the stored procedure using 'ExecuteScalar' - /// - /// Value of input parameters. - /// Dictionary with any named output parameters and the value of the - /// scalar under the key "scalar". - protected virtual IDictionary ExecuteScalarByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.ExecuteScalar(NewCommandCreator(inParams)); - } - - protected virtual IDictionary ExecuteNonQueryByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.ExecuteNonQuery(NewCommandCreator(inParams)); - } - - - protected virtual IDictionary QueryByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), resultProcessors); - } - - protected virtual IDictionary QueryByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), resultProcessors); - } - - #endregion - - protected override bool IsInputParameter(IDataParameter parameter) - { - if (usingDerivedParameters) - { - //Can only count Input, derived output parameters are incorrectly classified as input-output - return (parameter.Direction == ParameterDirection.Input); - } - else - { - return base.IsInputParameter(parameter); - } - } - - #endregion - - } -} - +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#if NET_2_0 + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Collections; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Data.Generic; +using Spring.Data.Support; + +#endregion + +namespace Spring.Data.Objects.Generic +{ + /// + /// A superclass for object based abstractions of RDBMS stored procedures. + /// + /// Mark Pollack (.NET) + public abstract class StoredProcedure : AdoOperation + { + #region Fields + + //A collection of NamedResultSetProcessor + + private IList resultProcessors = new LinkedList(); + private bool usingDerivedParameters = false; + + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public StoredProcedure() + { + CommandType = CommandType.StoredProcedure; + } + + public StoredProcedure(IDbProvider dbProvider, string procedureName) : base(dbProvider, procedureName) + { + CommandType = CommandType.StoredProcedure; + } + + + + #endregion + + #region Properties + + #endregion + + #region Methods + + public void DeriveParameters() + { + DeriveParameters(false); + } + + + public void DeriveParameters(bool includeReturnParameter) + { + //TODO does this account for offsets? + IDataParameter[] derivedParameters = AdoTemplate.DeriveParameters(Sql, includeReturnParameter); + for (int i = 0; i < derivedParameters.Length; i++) + { + IDataParameter parameter = derivedParameters[i]; + DeclaredParameters.AddParameter(parameter); + } + usingDerivedParameters = true; + } + + + #region Non-generic result set processors + public void AddResultSetExtractor(string name, IResultSetExtractor resultSetExtractor) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add ResultSetExtractors once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name, resultSetExtractor)); + } + + public void AddRowCallback(string name, IRowCallback rowCallback) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add RowCallbacks once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name, rowCallback)); + } + + public void AddRowMapper(string name, IRowMapper rowMapper) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add RowMappers once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name, rowMapper)); + } + + #endregion + + #region Generic result set processors + + public void AddResultSetExtractor(string name, IResultSetExtractor resultSetExtractor) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add ResultSetExtractors once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name, resultSetExtractor)); + } + + + public void AddRowMapper(string name, IRowMapper rowMapper) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add RowMappers once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name,rowMapper)); + } + #endregion + + #region Operations that use derived parameters + protected virtual IDictionary ExecuteScalar(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.ExecuteScalar(NewCommandCreatorWithParamValues(inParameterValues)); + } + + protected virtual IDictionary ExecuteNonQuery(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.ExecuteNonQuery(NewCommandCreatorWithParamValues(inParameterValues)); + } + + + public System.Collections.Generic.IList QueryWithRowMapper(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + if (resultProcessors.Count == 0) + { + throw new InvalidDataAccessApiUsageException("No row mapper is specified."); + } + + NamedResultSetProcessor resultSetProcessor = resultProcessors[0] as NamedResultSetProcessor; + if (resultSetProcessor == null) + { + throw new InvalidDataAccessApiUsageException("No row mapper is specified."); + } + + if (resultSetProcessor.RowMapper == null) + { + throw new InvalidDataAccessApiUsageException("No row mapper is specified as first result set processor."); + } + IDictionary outParams = Query(inParameterValues); + return outParams[resultSetProcessor.Name] as System.Collections.Generic.IList; + + } + + protected virtual IDictionary Query(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreatorWithParamValues(inParameterValues), resultProcessors); + + } + + protected virtual IDictionary Query(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreatorWithParamValues(inParameterValues), resultProcessors); + + } + + #endregion + + + #region Operations that used provided named parameters + /// + /// Execute the stored procedure using 'ExecuteScalar' + /// + /// Value of input parameters. + /// Dictionary with any named output parameters and the value of the + /// scalar under the key "scalar". + protected virtual IDictionary ExecuteScalarByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.ExecuteScalar(NewCommandCreator(inParams)); + } + + protected virtual IDictionary ExecuteNonQueryByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.ExecuteNonQuery(NewCommandCreator(inParams)); + } + + + protected virtual IDictionary QueryByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), resultProcessors); + } + + protected virtual IDictionary QueryByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), resultProcessors); + } + + #endregion + + protected override bool IsInputParameter(IDataParameter parameter) + { + if (usingDerivedParameters) + { + //Can only count Input, derived output parameters are incorrectly classified as input-output + return (parameter.Direction == ParameterDirection.Input); + } + else + { + return base.IsInputParameter(parameter); + } + } + + #endregion + + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Objects/MappingAdoQuery.cs b/src/Spring/Spring.Data/Data/Objects/MappingAdoQuery.cs index e56743dc..e9fb114d 100644 --- a/src/Spring/Spring.Data/Data/Objects/MappingAdoQuery.cs +++ b/src/Spring/Spring.Data/Data/Objects/MappingAdoQuery.cs @@ -1,75 +1,74 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// Reusable query in which concrete subclasses must implement the - /// MapRow method to map each row of a single result set into an - /// object. - /// - /// - /// Simplifies MappingAdoQueryWithContext API by dropping parameters and - /// context. Most subclasses won't care about parameters. If you don't use - /// contextual information, subclass this instead of MappingSqlQueryWithContext. - /// - /// Mark Pollack (.NET) - /// $Id: MappingAdoQuery.cs,v 1.5 2008/05/29 17:26:35 markpollack Exp $ - public abstract class MappingAdoQuery : MappingAdoQueryWithContext - { - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public MappingAdoQuery() - { - - } - - public MappingAdoQuery(IDbProvider dbProvider, string sql) : base(dbProvider, sql) - { - - } - - #endregion - - #region Methods - - protected override object MapRow(IDataReader reader, int rowNum, IDictionary inParams, - IDictionary callingContext) - { - return MapRow(reader, rowNum); - } - - protected abstract object MapRow(IDataReader reader, int num); - - #endregion - - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// Reusable query in which concrete subclasses must implement the + /// MapRow method to map each row of a single result set into an + /// object. + /// + /// + /// Simplifies MappingAdoQueryWithContext API by dropping parameters and + /// context. Most subclasses won't care about parameters. If you don't use + /// contextual information, subclass this instead of MappingSqlQueryWithContext. + /// + /// Mark Pollack (.NET) + public abstract class MappingAdoQuery : MappingAdoQueryWithContext + { + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public MappingAdoQuery() + { + + } + + public MappingAdoQuery(IDbProvider dbProvider, string sql) : base(dbProvider, sql) + { + + } + + #endregion + + #region Methods + + protected override object MapRow(IDataReader reader, int rowNum, IDictionary inParams, + IDictionary callingContext) + { + return MapRow(reader, rowNum); + } + + protected abstract object MapRow(IDataReader reader, int num); + + #endregion + + + } +} diff --git a/src/Spring/Spring.Data/Data/Objects/MappingAdoQueryWithContext.cs b/src/Spring/Spring.Data/Data/Objects/MappingAdoQueryWithContext.cs index bde0ded0..075a5d3b 100644 --- a/src/Spring/Spring.Data/Data/Objects/MappingAdoQueryWithContext.cs +++ b/src/Spring/Spring.Data/Data/Objects/MappingAdoQueryWithContext.cs @@ -1,97 +1,96 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// Reusable query in which concrete subclasses must implement the - /// MapRow method to map each row of a single result set into an - /// object. - /// - /// The MapRow method is also passed the input parameters and - /// a dictionary to provide the method with calling context information - /// (if necessary). If you do not need these additional parameters, use - /// the subclass MappingAdoQuery. - /// - /// Mark Pollack (.NET) - /// $Id: MappingAdoQueryWithContext.cs,v 1.4 2008/05/29 17:26:35 markpollack Exp $ - public abstract class MappingAdoQueryWithContext : AdoQuery - { - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public MappingAdoQueryWithContext() - { - - } - - public MappingAdoQueryWithContext(IDbProvider dbProvider, string sql) : base(dbProvider, sql) - { - - } - #endregion - - #region Properties - - #endregion - - #region Methods - - protected override IRowMapper NewRowMapper(IDictionary inParams, IDictionary callingContext) - { - return new RowMapperImpl(this, inParams, callingContext); - } - - protected abstract Object MapRow(IDataReader reader, int rowNum, IDictionary inParams, IDictionary callingContext); - - - #endregion - - private class RowMapperImpl : IRowMapper - { - private MappingAdoQueryWithContext outer; - private IDictionary inParams; - private IDictionary callingContext; - - public RowMapperImpl(MappingAdoQueryWithContext mappingAdoQueryWithContext, IDictionary inParams, IDictionary callingContext) - { - outer = mappingAdoQueryWithContext; - this.inParams = inParams; - this.callingContext = callingContext; - } - - public object MapRow(IDataReader dataReader, int rowNum) - { - return outer.MapRow(dataReader, rowNum, inParams, callingContext); - } - } - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// Reusable query in which concrete subclasses must implement the + /// MapRow method to map each row of a single result set into an + /// object. + /// + /// The MapRow method is also passed the input parameters and + /// a dictionary to provide the method with calling context information + /// (if necessary). If you do not need these additional parameters, use + /// the subclass MappingAdoQuery. + /// + /// Mark Pollack (.NET) + public abstract class MappingAdoQueryWithContext : AdoQuery + { + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public MappingAdoQueryWithContext() + { + + } + + public MappingAdoQueryWithContext(IDbProvider dbProvider, string sql) : base(dbProvider, sql) + { + + } + #endregion + + #region Properties + + #endregion + + #region Methods + + protected override IRowMapper NewRowMapper(IDictionary inParams, IDictionary callingContext) + { + return new RowMapperImpl(this, inParams, callingContext); + } + + protected abstract Object MapRow(IDataReader reader, int rowNum, IDictionary inParams, IDictionary callingContext); + + + #endregion + + private class RowMapperImpl : IRowMapper + { + private MappingAdoQueryWithContext outer; + private IDictionary inParams; + private IDictionary callingContext; + + public RowMapperImpl(MappingAdoQueryWithContext mappingAdoQueryWithContext, IDictionary inParams, IDictionary callingContext) + { + outer = mappingAdoQueryWithContext; + this.inParams = inParams; + this.callingContext = callingContext; + } + + public object MapRow(IDataReader dataReader, int rowNum) + { + return outer.MapRow(dataReader, rowNum, inParams, callingContext); + } + } + + } +} diff --git a/src/Spring/Spring.Data/Data/Objects/StoredProcedure.cs b/src/Spring/Spring.Data/Data/Objects/StoredProcedure.cs index 876abb7e..0231e46f 100644 --- a/src/Spring/Spring.Data/Data/Objects/StoredProcedure.cs +++ b/src/Spring/Spring.Data/Data/Objects/StoredProcedure.cs @@ -1,180 +1,179 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Collections; -using System.Data; -using Spring.Collections; -using Spring.Dao; -using Spring.Data.Common; -using Spring.Data.Support; - -#endregion - -namespace Spring.Data.Objects -{ - /// - /// A superclass for object based abstractions of RDBMS stored procedures. - /// - /// Mark Pollack (.NET) - /// $Id: StoredProcedure.cs,v 1.9 2007/07/25 08:25:20 markpollack Exp $ - public abstract class StoredProcedure : AdoOperation - { - #region Fields - - //A collection of NamedResultSetProcessor - private IList resultProcessors = new LinkedList(); - private bool usingDerivedParameters = false; - - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public StoredProcedure() - { - CommandType = CommandType.StoredProcedure; - } - - public StoredProcedure(IDbProvider dbProvider, string procedureName) : base(dbProvider, procedureName) - { - CommandType = CommandType.StoredProcedure; - } - - - - #endregion - - #region Properties - - #endregion - - #region Methods - - public void DeriveParameters() - { - DeriveParameters(false); - } - - - public void DeriveParameters(bool includeReturnParameter) - { - //TODO does this account for offsets? - IDataParameter[] derivedParameters = AdoTemplate.DeriveParameters(Sql, includeReturnParameter); - for (int i = 0; i < derivedParameters.Length; i++) - { - IDataParameter parameter = derivedParameters[i]; - DeclaredParameters.AddParameter(parameter); - } - usingDerivedParameters = true; - } - - - public void AddResultSetExtractor(string name, IResultSetExtractor resultSetExtractor) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add ResultSetExtractors once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name, resultSetExtractor)); - } - - public void AddRowCallback(string name, IRowCallback rowCallback) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add RowCallbacks once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name,rowCallback)); - } - - public void AddRowMapper(string name, IRowMapper rowMapper) - { - if (Compiled) - { - throw new InvalidDataAccessApiUsageException("Cannot add RowMappers once operation is compiled"); - } - resultProcessors.Add(new NamedResultSetProcessor(name,rowMapper)); - } - - - protected virtual IDictionary ExecuteScalar(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.ExecuteScalar(NewCommandCreatorWithParamValues(inParameterValues)); - } - - protected virtual IDictionary ExecuteNonQuery(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.ExecuteNonQuery(NewCommandCreatorWithParamValues(inParameterValues)); - } - - protected virtual IDictionary Query(params object[] inParameterValues) - { - ValidateParameters(inParameterValues); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreatorWithParamValues(inParameterValues), resultProcessors); - } - - /// - /// Execute the stored procedure using 'ExecuteScalar' - /// - /// Value of input parameters. - /// Dictionary with any named output parameters and the value of the - /// scalar under the key "scalar". - protected virtual IDictionary ExecuteScalarByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.ExecuteScalar(NewCommandCreator(inParams)); - } - - protected virtual IDictionary ExecuteNonQueryByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.ExecuteNonQuery(NewCommandCreator(inParams)); - } - - - protected virtual IDictionary QueryByNamedParam(IDictionary inParams) - { - ValidateNamedParameters(inParams); - return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), resultProcessors); - } - - protected override bool IsInputParameter(IDataParameter parameter) - { - if (usingDerivedParameters) - { - //Can only count Input, derived output parameters are incorrectly classified as input-output - return (parameter.Direction == ParameterDirection.Input); - } - else - { - return base.IsInputParameter(parameter); - } - } - - #endregion - - } -} +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Collections; +using System.Data; +using Spring.Collections; +using Spring.Dao; +using Spring.Data.Common; +using Spring.Data.Support; + +#endregion + +namespace Spring.Data.Objects +{ + /// + /// A superclass for object based abstractions of RDBMS stored procedures. + /// + /// Mark Pollack (.NET) + public abstract class StoredProcedure : AdoOperation + { + #region Fields + + //A collection of NamedResultSetProcessor + private IList resultProcessors = new LinkedList(); + private bool usingDerivedParameters = false; + + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public StoredProcedure() + { + CommandType = CommandType.StoredProcedure; + } + + public StoredProcedure(IDbProvider dbProvider, string procedureName) : base(dbProvider, procedureName) + { + CommandType = CommandType.StoredProcedure; + } + + + + #endregion + + #region Properties + + #endregion + + #region Methods + + public void DeriveParameters() + { + DeriveParameters(false); + } + + + public void DeriveParameters(bool includeReturnParameter) + { + //TODO does this account for offsets? + IDataParameter[] derivedParameters = AdoTemplate.DeriveParameters(Sql, includeReturnParameter); + for (int i = 0; i < derivedParameters.Length; i++) + { + IDataParameter parameter = derivedParameters[i]; + DeclaredParameters.AddParameter(parameter); + } + usingDerivedParameters = true; + } + + + public void AddResultSetExtractor(string name, IResultSetExtractor resultSetExtractor) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add ResultSetExtractors once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name, resultSetExtractor)); + } + + public void AddRowCallback(string name, IRowCallback rowCallback) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add RowCallbacks once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name,rowCallback)); + } + + public void AddRowMapper(string name, IRowMapper rowMapper) + { + if (Compiled) + { + throw new InvalidDataAccessApiUsageException("Cannot add RowMappers once operation is compiled"); + } + resultProcessors.Add(new NamedResultSetProcessor(name,rowMapper)); + } + + + protected virtual IDictionary ExecuteScalar(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.ExecuteScalar(NewCommandCreatorWithParamValues(inParameterValues)); + } + + protected virtual IDictionary ExecuteNonQuery(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.ExecuteNonQuery(NewCommandCreatorWithParamValues(inParameterValues)); + } + + protected virtual IDictionary Query(params object[] inParameterValues) + { + ValidateParameters(inParameterValues); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreatorWithParamValues(inParameterValues), resultProcessors); + } + + /// + /// Execute the stored procedure using 'ExecuteScalar' + /// + /// Value of input parameters. + /// Dictionary with any named output parameters and the value of the + /// scalar under the key "scalar". + protected virtual IDictionary ExecuteScalarByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.ExecuteScalar(NewCommandCreator(inParams)); + } + + protected virtual IDictionary ExecuteNonQueryByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.ExecuteNonQuery(NewCommandCreator(inParams)); + } + + + protected virtual IDictionary QueryByNamedParam(IDictionary inParams) + { + ValidateNamedParameters(inParams); + return AdoTemplate.QueryWithCommandCreator(NewCommandCreator(inParams), resultProcessors); + } + + protected override bool IsInputParameter(IDataParameter parameter) + { + if (usingDerivedParameters) + { + //Can only count Input, derived output parameters are incorrectly classified as input-output + return (parameter.Direction == ParameterDirection.Input); + } + else + { + return base.IsInputParameter(parameter); + } + } + + #endregion + + } +} diff --git a/src/Spring/Spring.Data/Data/ResultSetExtractorDelegate.cs b/src/Spring/Spring.Data/Data/ResultSetExtractorDelegate.cs index ac9eaf28..cdb3e093 100644 --- a/src/Spring/Spring.Data/Data/ResultSetExtractorDelegate.cs +++ b/src/Spring/Spring.Data/Data/ResultSetExtractorDelegate.cs @@ -1,40 +1,40 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; - - -namespace Spring.Data -{ - /// - /// Callback delegate to process all result sets and row in an - /// AdoTemplate query method. - /// - /// - /// Implementations of this delegate perform the work - /// of extracting results but don't need worry about managing - /// ADO.NET resources, such as closing the reader, or transaction management. - /// - /// The IDataReader to extract data from. - /// Implementations should not close this: it will be closed - /// by the AdoTemplate. - /// An arbitrary result object or null if none. - public delegate object ResultSetExtractorDelegate(IDataReader reader); -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; + + +namespace Spring.Data +{ + /// + /// Callback delegate to process all result sets and row in an + /// AdoTemplate query method. + /// + /// + /// Implementations of this delegate perform the work + /// of extracting results but don't need worry about managing + /// ADO.NET resources, such as closing the reader, or transaction management. + /// + /// The IDataReader to extract data from. + /// Implementations should not close this: it will be closed + /// by the AdoTemplate. + /// An arbitrary result object or null if none. + public delegate object ResultSetExtractorDelegate(IDataReader reader); +} diff --git a/src/Spring/Spring.Data/Data/RowCallbackDelegate.cs b/src/Spring/Spring.Data/Data/RowCallbackDelegate.cs index 775e1349..a738162c 100644 --- a/src/Spring/Spring.Data/Data/RowCallbackDelegate.cs +++ b/src/Spring/Spring.Data/Data/RowCallbackDelegate.cs @@ -1,8 +1,8 @@ - - -using System.Data; - -namespace Spring.Data -{ - public delegate void RowCallbackDelegate(IDataReader dataReader); -} + + +using System.Data; + +namespace Spring.Data +{ + public delegate void RowCallbackDelegate(IDataReader dataReader); +} diff --git a/src/Spring/Spring.Data/Data/RowMapperDelegate.cs b/src/Spring/Spring.Data/Data/RowMapperDelegate.cs index 1f4c5dbf..4ded5f2c 100644 --- a/src/Spring/Spring.Data/Data/RowMapperDelegate.cs +++ b/src/Spring/Spring.Data/Data/RowMapperDelegate.cs @@ -1,35 +1,35 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - - -using System.Data; - -namespace Spring.Data -{ - /// - /// Callback delegate to process each row of data in a result set to an object. - /// - /// The IDataReader to map - /// the number of the current row. - /// An abrirary object, typically derived from data - /// in the result set. - public delegate object RowMapperDelegate(IDataReader dataReader, int rowNum); - -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + + +using System.Data; + +namespace Spring.Data +{ + /// + /// Callback delegate to process each row of data in a result set to an object. + /// + /// The IDataReader to map + /// the number of the current row. + /// An abrirary object, typically derived from data + /// in the result set. + public delegate object RowMapperDelegate(IDataReader dataReader, int rowNum); + +} diff --git a/src/Spring/Spring.Data/Data/Support/AdoTransactionObjectSupport.cs b/src/Spring/Spring.Data/Data/Support/AdoTransactionObjectSupport.cs index 7e5862d0..2cf66cb1 100644 --- a/src/Spring/Spring.Data/Data/Support/AdoTransactionObjectSupport.cs +++ b/src/Spring/Spring.Data/Data/Support/AdoTransactionObjectSupport.cs @@ -1,170 +1,169 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; -using Common.Logging; -using Spring.Transaction; -using Spring.Transaction.Support; - -#endregion - -namespace Spring.Data.Support -{ - /// - /// Convenient base class for ADO.NET transaction aware objects. - /// - /// - /// Can contain a ConnectionHolder object. - /// - /// Mark Pollack (.NET) - /// $Id: AdoTransactionObjectSupport.cs,v 1.7 2007/11/28 05:54:47 markpollack Exp $ - public abstract class AdoTransactionObjectSupport : ISavepointManager, ISmartTransactionObject - { - #region Fields - - private ConnectionHolder connectionHolder; - - private IsolationLevel previousIsolationLevel; - - private bool savepointAllowed; - - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (AdoTransactionObjectSupport)); - - #endregion - - #region Properties - - public ConnectionHolder ConnectionHolder - { - get { return connectionHolder; } - set { connectionHolder = value; } - } - - public bool HasConnectionHolder - { - get { return (connectionHolder != null); } - } - - public IsolationLevel PreviousIsolationLevel - { - get { return previousIsolationLevel; } - set { previousIsolationLevel = value; } - } - - public bool SavepointAllowed - { - get { return savepointAllowed; } - set { savepointAllowed = value; } - } - - /// - /// Return whether the transaction is internally marked as rollback-only. - /// - /// - /// True of the transaction is marked as rollback-only. - public abstract bool RollbackOnly { get; } - - #endregion - - /// - /// Create a new savepoint. - /// - /// - /// The name of the savepoint to create. - /// - /// - /// You can roll back to a specific savepoint - /// via , - /// and explicitly release a savepoint that you don't need anymore via - /// . - ///

- /// Note that most transaction managers will automatically release - /// savepoints at transaction completion. - ///

- ///
- /// - /// If the savepoint could not be created, - /// either because the backend does not support it or because the - /// transaction is not in an appropriate state. - /// - /// - /// A savepoint object, to be passed into - /// - /// or . - /// - public virtual void CreateSavepoint(string savepointName) - { - throw new NestedTransactionNotSupportedException( - "Cannot create a nested transaction because savepoints have not been implemented in the metadata for the DbProvider."); - } - - /// - /// Roll back to the given savepoint. - /// - /// - /// The savepoint will be automatically released afterwards. - /// - /// The savepoint to roll back to. - /// - /// If the rollback failed. - /// - public virtual void RollbackToSavepoint(string savepoint) - { - throw new NestedTransactionNotSupportedException( - "Cannot rollback to a savepoint in a nested transaction because savepoints have not been implemented in the metadata for the DbProvider."); - - } - - /// - /// Explicitly release the given savepoint. - /// - /// - ///

- /// Note that most transaction managers will automatically release - /// savepoints at transaction completion. - ///

- ///

- /// Implementations should fail as silently as possible if - /// proper resource cleanup will still happen at transaction completion. - ///

- ///
- /// The savepoint to release. - /// - /// If the release failed. - /// - public virtual void ReleaseSavepoint(string savepoint) - { - throw new NestedTransactionNotSupportedException( - "Cannot release a savepoint in a nested transaction because savepoints have not been implemented in the metadata for the DbProvider."); - - } - } +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; +using Common.Logging; +using Spring.Transaction; +using Spring.Transaction.Support; + +#endregion + +namespace Spring.Data.Support +{ + /// + /// Convenient base class for ADO.NET transaction aware objects. + /// + /// + /// Can contain a ConnectionHolder object. + /// + /// Mark Pollack (.NET) + public abstract class AdoTransactionObjectSupport : ISavepointManager, ISmartTransactionObject + { + #region Fields + + private ConnectionHolder connectionHolder; + + private IsolationLevel previousIsolationLevel; + + private bool savepointAllowed; + + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (AdoTransactionObjectSupport)); + + #endregion + + #region Properties + + public ConnectionHolder ConnectionHolder + { + get { return connectionHolder; } + set { connectionHolder = value; } + } + + public bool HasConnectionHolder + { + get { return (connectionHolder != null); } + } + + public IsolationLevel PreviousIsolationLevel + { + get { return previousIsolationLevel; } + set { previousIsolationLevel = value; } + } + + public bool SavepointAllowed + { + get { return savepointAllowed; } + set { savepointAllowed = value; } + } + + /// + /// Return whether the transaction is internally marked as rollback-only. + /// + /// + /// True of the transaction is marked as rollback-only. + public abstract bool RollbackOnly { get; } + + #endregion + + /// + /// Create a new savepoint. + /// + /// + /// The name of the savepoint to create. + /// + /// + /// You can roll back to a specific savepoint + /// via , + /// and explicitly release a savepoint that you don't need anymore via + /// . + ///

+ /// Note that most transaction managers will automatically release + /// savepoints at transaction completion. + ///

+ ///
+ /// + /// If the savepoint could not be created, + /// either because the backend does not support it or because the + /// transaction is not in an appropriate state. + /// + /// + /// A savepoint object, to be passed into + /// + /// or . + /// + public virtual void CreateSavepoint(string savepointName) + { + throw new NestedTransactionNotSupportedException( + "Cannot create a nested transaction because savepoints have not been implemented in the metadata for the DbProvider."); + } + + /// + /// Roll back to the given savepoint. + /// + /// + /// The savepoint will be automatically released afterwards. + /// + /// The savepoint to roll back to. + /// + /// If the rollback failed. + /// + public virtual void RollbackToSavepoint(string savepoint) + { + throw new NestedTransactionNotSupportedException( + "Cannot rollback to a savepoint in a nested transaction because savepoints have not been implemented in the metadata for the DbProvider."); + + } + + /// + /// Explicitly release the given savepoint. + /// + /// + ///

+ /// Note that most transaction managers will automatically release + /// savepoints at transaction completion. + ///

+ ///

+ /// Implementations should fail as silently as possible if + /// proper resource cleanup will still happen at transaction completion. + ///

+ ///
+ /// The savepoint to release. + /// + /// If the release failed. + /// + public virtual void ReleaseSavepoint(string savepoint) + { + throw new NestedTransactionNotSupportedException( + "Cannot release a savepoint in a nested transaction because savepoints have not been implemented in the metadata for the DbProvider."); + + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/AdoUtils.cs b/src/Spring/Spring.Data/Data/Support/AdoUtils.cs index c49775ab..920fce62 100644 --- a/src/Spring/Spring.Data/Data/Support/AdoUtils.cs +++ b/src/Spring/Spring.Data/Data/Support/AdoUtils.cs @@ -1,89 +1,89 @@ -using System; -using System.Data; -using Common.Logging; - -namespace Spring.Data.Support -{ - /// - /// Summary description for AdoUtils. - /// - public abstract class AdoUtils - { - #region Logging - - private static readonly ILog LOG = LogManager.GetLogger(typeof (AdoUtils)); - - #endregion - - #region Constants - - /// - /// Order value for TransactionSynchronization objects that clean up - /// ADO.NET Connections. - /// - public static readonly int CONNECTION_SYNCHRONIZATION_ORDER = 1000; - - #endregion - /// - /// Property dispose of the command. Useful in finally or catch blocks. - /// - /// command to dispose - public static void DisposeCommand(IDbCommand command) - { - if (command != null) - { - DoDisposeCommand(command); - } - } - - - public static void DisposeDataAdapterCommands(IDbDataAdapter adapter) - { - if (adapter.SelectCommand != null) - { - DoDisposeCommand(adapter.SelectCommand); - } - if (adapter.InsertCommand != null) - { - DoDisposeCommand(adapter.InsertCommand); - } - if (adapter.UpdateCommand != null) - { - DoDisposeCommand(adapter.UpdateCommand); - } - if (adapter.DeleteCommand != null) - { - DoDisposeCommand(adapter.DeleteCommand); - } - - } - public static void CloseReader(IDataReader reader) - { - if (reader != null) - { - try - { - reader.Close(); - } - catch (Exception e) - { - LOG.Warn("Could not close IDataRader", e); - } - } - } - - private static void DoDisposeCommand(IDbCommand command) - { - try - { - command.Dispose(); - } - catch (Exception e) - { - LOG.Warn("Could not dispose of command", e); - } - } - - } - -} +using System; +using System.Data; +using Common.Logging; + +namespace Spring.Data.Support +{ + /// + /// Summary description for AdoUtils. + /// + public abstract class AdoUtils + { + #region Logging + + private static readonly ILog LOG = LogManager.GetLogger(typeof (AdoUtils)); + + #endregion + + #region Constants + + /// + /// Order value for TransactionSynchronization objects that clean up + /// ADO.NET Connections. + /// + public static readonly int CONNECTION_SYNCHRONIZATION_ORDER = 1000; + + #endregion + /// + /// Property dispose of the command. Useful in finally or catch blocks. + /// + /// command to dispose + public static void DisposeCommand(IDbCommand command) + { + if (command != null) + { + DoDisposeCommand(command); + } + } + + + public static void DisposeDataAdapterCommands(IDbDataAdapter adapter) + { + if (adapter.SelectCommand != null) + { + DoDisposeCommand(adapter.SelectCommand); + } + if (adapter.InsertCommand != null) + { + DoDisposeCommand(adapter.InsertCommand); + } + if (adapter.UpdateCommand != null) + { + DoDisposeCommand(adapter.UpdateCommand); + } + if (adapter.DeleteCommand != null) + { + DoDisposeCommand(adapter.DeleteCommand); + } + + } + public static void CloseReader(IDataReader reader) + { + if (reader != null) + { + try + { + reader.Close(); + } + catch (Exception e) + { + LOG.Warn("Could not close IDataRader", e); + } + } + } + + private static void DoDisposeCommand(IDbCommand command) + { + try + { + command.Dispose(); + } + catch (Exception e) + { + LOG.Warn("Could not dispose of command", e); + } + } + + } + +} diff --git a/src/Spring/Spring.Data/Data/Support/ConnectionHolder.cs b/src/Spring/Spring.Data/Data/Support/ConnectionHolder.cs index 7e65fd72..e97a3fb5 100644 --- a/src/Spring/Spring.Data/Data/Support/ConnectionHolder.cs +++ b/src/Spring/Spring.Data/Data/Support/ConnectionHolder.cs @@ -1,72 +1,72 @@ -using System.Data; -using Spring.Transaction.Support; - -namespace Spring.Data.Support -{ - /// - /// Connection holder, wrapping a ADO.NET connection and transaction. - /// - /// AdoTransactionManager binds instances of this class to the - /// thread for a given DbProvider. - /// Jurgen Hoeller - /// Mark Pollack (.NET) - public class ConnectionHolder : ResourceHolderSupport - { - private IDbConnection currentConnection; - - private IDbTransaction currentTransaction; - - private bool transactionActive = false; - - /// - /// Create a new ConnectionHolder - /// - /// The connection to hold - /// The transaction to hold - public ConnectionHolder(IDbConnection conn, IDbTransaction transaction) - { - //TODO assert conn is not null. - currentConnection = conn; - currentTransaction = transaction; - } - - public IDbConnection Connection - { - get - { - return currentConnection; - } - set - { - currentConnection = value; - } - - } - - public IDbTransaction Transaction - { - get { return currentTransaction; } - set { currentTransaction = value; } - } - - public bool HasConnection - { - get - { - return (currentConnection != null); - } - } - - public bool TransactionActive - { - get { return transactionActive; } - set { transactionActive = value; } - } - - public override void Clear() - { - base.Clear(); - transactionActive = false; - } - } -} +using System.Data; +using Spring.Transaction.Support; + +namespace Spring.Data.Support +{ + /// + /// Connection holder, wrapping a ADO.NET connection and transaction. + /// + /// AdoTransactionManager binds instances of this class to the + /// thread for a given DbProvider. + /// Jurgen Hoeller + /// Mark Pollack (.NET) + public class ConnectionHolder : ResourceHolderSupport + { + private IDbConnection currentConnection; + + private IDbTransaction currentTransaction; + + private bool transactionActive = false; + + /// + /// Create a new ConnectionHolder + /// + /// The connection to hold + /// The transaction to hold + public ConnectionHolder(IDbConnection conn, IDbTransaction transaction) + { + //TODO assert conn is not null. + currentConnection = conn; + currentTransaction = transaction; + } + + public IDbConnection Connection + { + get + { + return currentConnection; + } + set + { + currentConnection = value; + } + + } + + public IDbTransaction Transaction + { + get { return currentTransaction; } + set { currentTransaction = value; } + } + + public bool HasConnection + { + get + { + return (currentConnection != null); + } + } + + public bool TransactionActive + { + get { return transactionActive; } + set { transactionActive = value; } + } + + public override void Clear() + { + base.Clear(); + transactionActive = false; + } + } +} diff --git a/src/Spring/Spring.Data/Data/Support/ConnectionSynchronization.cs b/src/Spring/Spring.Data/Data/Support/ConnectionSynchronization.cs index d8a7e3d3..7cc36bff 100644 --- a/src/Spring/Spring.Data/Data/Support/ConnectionSynchronization.cs +++ b/src/Spring/Spring.Data/Data/Support/ConnectionSynchronization.cs @@ -1,129 +1,129 @@ -using Spring.Data.Common; -using Spring.Transaction.Support; - -namespace Spring.Data.Support -{ - /// - /// Callback for resource cleanup at end of transaction. - /// - public class ConnectionSynchronization : TransactionSynchronizationAdapter - { - - private ConnectionHolder connectionHolder; - - private IDbProvider dbProvider; - - private bool holderActive = true; - - private int order; - /// - /// Create a new instance. - /// - /// - /// - public ConnectionSynchronization(ConnectionHolder connHolder, IDbProvider provider) - { - connectionHolder = connHolder; - dbProvider = provider; - order = ConnectionUtils.CONNECTION_SYNCHRONIZATION_ORDER; - } - - - /// - /// Compares the current instance with another object of the same type. - /// - /// An object to compare with this instance. - /// - /// The value of the order property. - /// - public override int CompareTo(object obj) - { - return order; - } - /// - /// Suspend this synchronization. - /// - /// - ///

- /// Supposed to unbind resources from - /// - /// if managing any. - ///

- ///
- public override void Suspend() - { - if (holderActive) - { - TransactionSynchronizationManager.UnbindResource(dbProvider); - - //TODO do we need to reset the connection inside the conHolder to null? - } - } - - /// - /// Resume this synchronization. - /// - /// - ///

- /// Supposed to unbind resources from - /// - /// if managing any. - ///

- ///
- public override void Resume() - { - if (holderActive) - { - TransactionSynchronizationManager.BindResource(dbProvider, connectionHolder); - } - } - - /// - /// Invoked before transaction commit/rollback (after - /// , - /// even if - /// - /// threw an exception). - /// - /// - ///

- /// Can e.g. perform resource cleanup. - ///

- ///

- /// Note that exceptions will get propagated to the commit caller - /// and cause a rollback of the transaction. - ///

- ///
- public override void BeforeCompletion() - { - if (connectionHolder.IsOpen ) - { - TransactionSynchronizationManager.UnbindResource(dbProvider); - holderActive= false; - ConnectionUtils.DisposeConnection(connectionHolder.Connection, dbProvider); - } - } - - /// - /// Invoked after transaction commit/rollback. - /// - /// Status according to - /// - /// Can e.g. perform resource cleanup, in this case after transaction completion. - ///

- /// Note that exceptions will get propagated to the commit or rollback - /// caller, although they will not influence the outcome of the transaction. - ///

- ///
- public override void AfterCompletion(TransactionSynchronizationStatus status) - { - if (TransactionSynchronizationManager.HasResource(dbProvider)) - { - TransactionSynchronizationManager.UnbindResource(dbProvider); - holderActive = false; - ConnectionUtils.DisposeConnection(connectionHolder.Connection, dbProvider); - } - } - - } -} +using Spring.Data.Common; +using Spring.Transaction.Support; + +namespace Spring.Data.Support +{ + /// + /// Callback for resource cleanup at end of transaction. + /// + public class ConnectionSynchronization : TransactionSynchronizationAdapter + { + + private ConnectionHolder connectionHolder; + + private IDbProvider dbProvider; + + private bool holderActive = true; + + private int order; + /// + /// Create a new instance. + /// + /// + /// + public ConnectionSynchronization(ConnectionHolder connHolder, IDbProvider provider) + { + connectionHolder = connHolder; + dbProvider = provider; + order = ConnectionUtils.CONNECTION_SYNCHRONIZATION_ORDER; + } + + + /// + /// Compares the current instance with another object of the same type. + /// + /// An object to compare with this instance. + /// + /// The value of the order property. + /// + public override int CompareTo(object obj) + { + return order; + } + /// + /// Suspend this synchronization. + /// + /// + ///

+ /// Supposed to unbind resources from + /// + /// if managing any. + ///

+ ///
+ public override void Suspend() + { + if (holderActive) + { + TransactionSynchronizationManager.UnbindResource(dbProvider); + + //TODO do we need to reset the connection inside the conHolder to null? + } + } + + /// + /// Resume this synchronization. + /// + /// + ///

+ /// Supposed to unbind resources from + /// + /// if managing any. + ///

+ ///
+ public override void Resume() + { + if (holderActive) + { + TransactionSynchronizationManager.BindResource(dbProvider, connectionHolder); + } + } + + /// + /// Invoked before transaction commit/rollback (after + /// , + /// even if + /// + /// threw an exception). + /// + /// + ///

+ /// Can e.g. perform resource cleanup. + ///

+ ///

+ /// Note that exceptions will get propagated to the commit caller + /// and cause a rollback of the transaction. + ///

+ ///
+ public override void BeforeCompletion() + { + if (connectionHolder.IsOpen ) + { + TransactionSynchronizationManager.UnbindResource(dbProvider); + holderActive= false; + ConnectionUtils.DisposeConnection(connectionHolder.Connection, dbProvider); + } + } + + /// + /// Invoked after transaction commit/rollback. + /// + /// Status according to + /// + /// Can e.g. perform resource cleanup, in this case after transaction completion. + ///

+ /// Note that exceptions will get propagated to the commit or rollback + /// caller, although they will not influence the outcome of the transaction. + ///

+ ///
+ public override void AfterCompletion(TransactionSynchronizationStatus status) + { + if (TransactionSynchronizationManager.HasResource(dbProvider)) + { + TransactionSynchronizationManager.UnbindResource(dbProvider); + holderActive = false; + ConnectionUtils.DisposeConnection(connectionHolder.Connection, dbProvider); + } + } + + } +} diff --git a/src/Spring/Spring.Data/Data/Support/ConnectionTxPair.cs b/src/Spring/Spring.Data/Data/Support/ConnectionTxPair.cs index 0ae2808e..4289a6df 100644 --- a/src/Spring/Spring.Data/Data/Support/ConnectionTxPair.cs +++ b/src/Spring/Spring.Data/Data/Support/ConnectionTxPair.cs @@ -1,64 +1,64 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; - -namespace Spring.Data.Support -{ - /// - /// A simple holder for the current Connection/Transaction objects - /// to use within a given AdoTemplate Execute operation. Used internally. - /// - public class ConnectionTxPair - { - private IDbConnection connection; - private IDbTransaction transaction; - - /// - /// Initializes a new instance of the class. - /// - /// The connection. - /// The transaction. - public ConnectionTxPair(IDbConnection connection, IDbTransaction transaction) - { - this.connection = connection; - this.transaction = transaction; - } - - /// - /// Gets the connection. - /// - /// The connection. - public IDbConnection Connection - { - get { return connection; } - set { connection = value; } - } - - /// - /// Gets the transaction. - /// - /// The transaction. - public IDbTransaction Transaction - { - get { return transaction; } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; + +namespace Spring.Data.Support +{ + /// + /// A simple holder for the current Connection/Transaction objects + /// to use within a given AdoTemplate Execute operation. Used internally. + /// + public class ConnectionTxPair + { + private IDbConnection connection; + private IDbTransaction transaction; + + /// + /// Initializes a new instance of the class. + /// + /// The connection. + /// The transaction. + public ConnectionTxPair(IDbConnection connection, IDbTransaction transaction) + { + this.connection = connection; + this.transaction = transaction; + } + + /// + /// Gets the connection. + /// + /// The connection. + public IDbConnection Connection + { + get { return connection; } + set { connection = value; } + } + + /// + /// Gets the transaction. + /// + /// The transaction. + public IDbTransaction Transaction + { + get { return transaction; } + } + } +} diff --git a/src/Spring/Spring.Data/Data/Support/ConnectionUtils.cs b/src/Spring/Spring.Data/Data/Support/ConnectionUtils.cs index 40e82181..c7e6f60b 100644 --- a/src/Spring/Spring.Data/Data/Support/ConnectionUtils.cs +++ b/src/Spring/Spring.Data/Data/Support/ConnectionUtils.cs @@ -1,246 +1,246 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using Common.Logging; -using Spring.Data.Common; -using Spring.Transaction.Support; -using Spring.Util; - -namespace Spring.Data.Support -{ - /// - /// Summary description for DbProviderUtils. - /// - public abstract class ConnectionUtils - { - #region Logging - - private static readonly ILog LOG = LogManager.GetLogger(typeof (ConnectionUtils)); - - #endregion - - public static readonly int CONNECTION_SYNCHRONIZATION_ORDER = 1000; - /// - /// Dispose of the given Connection, created via the given IDbProvider, - /// if it is not managed externally (that is, not bound to the thread). - /// - /// The connection to close if necessary. If - /// this is null the call will be ignored. - /// The IDbProvider the connection came from - public static void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) - { - try - { - DoDisposeConnection(conn, dbProvider); - } catch (Exception e) - { - LOG.Warn("Could not close connection", e); - } - - } - private static void DoDisposeConnection(IDbConnection conn, IDbProvider dbProvider) - { - if (conn == null) - { - return; - } - - if (dbProvider != null) - { - ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.GetResource(dbProvider); - if (conHolder != null && connectionEquals(conHolder.Connection, conn)) - { - // It's the transactional connection bound to the thread so don't close it. - conHolder.Released(); - return; - } - } - if (LOG.IsDebugEnabled) - { - LOG.Debug("Disposing of IDbConnection with connection string = [" + dbProvider.ConnectionString + "]"); - } - conn.Dispose(); - } - - - /// - /// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider. - /// Changes any exception into the Spring hierarchy of generic data access - /// exceptions, simplifying calling code and making any exception that is - /// thrown more meaningful. - /// - /// - /// Is aware of a corresponding Connection/Transaction bound to the current thread, for example - /// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread - /// if transaction synchronization is active - /// - /// The provider. - /// A Connection/Transaction pair. - public static ConnectionTxPair GetConnectionTxPair(IDbProvider provider) - { - try - { - return DoGetConnection(provider); - } catch (Exception e) - { - throw new CannotGetAdoConnectionException("Could not get ADO.NET connection.", e); - } - - } - - - /// - /// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider. - /// Same as but throwing original provider - /// exception. - /// - /// - /// Is aware of a corresponding Connection/Transaction bound to the current thread, for example - /// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread - /// if transaction synchronization is active - /// - /// The provider. - /// - public static ConnectionTxPair DoGetConnection(IDbProvider provider) - { - AssertUtils.ArgumentNotNull(provider, "provider"); - ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(provider); - if (conHolder != null && (conHolder.HasConnection || conHolder.SynchronizedWithTransaction)) - { - conHolder.Requested(); - if (!conHolder.HasConnection) - { - if (LOG.IsDebugEnabled) - { - LOG.Debug("Fetching resumed ADO.NET connection from DbProvider"); - } - conHolder.Connection = provider.CreateConnection(); - } - return new ConnectionTxPair(conHolder.Connection, conHolder.Transaction); - } - - // Else we either got no holder or an empty thread-bound holder here. - if (LOG.IsDebugEnabled) - { - LOG.Debug("Fetching Connection from DbProvider"); - } - IDbConnection conn = provider.CreateConnection(); - conn.Open(); - - if (TransactionSynchronizationManager.SynchronizationActive) - { - LOG.Debug("Registering transaction synchronization for IDbConnection"); - //Use same connection for further ADO.NET actions with the transaction. - //Thread-bound object will get removed by manager at transaction completion. - - //TODO investigate creating tx object... - ConnectionHolder holderToUse = conHolder; - if (holderToUse == null) - { - holderToUse = new ConnectionHolder(conn, null); - } - else - { - holderToUse.Connection = conn; - } - holderToUse.Requested(); - TransactionSynchronizationManager.RegisterSynchronization( - new ConnectionSynchronization(holderToUse, provider)); - holderToUse.SynchronizedWithTransaction = true; - if (holderToUse != conHolder) - { - TransactionSynchronizationManager.BindResource(provider, holderToUse); - } - - } - return new ConnectionTxPair(conn, null); - } - - //TODO exception translation? - /// - /// Do the connection mgmt. - /// - /// - /// - public static IDbConnection GetConnection(IDbProvider provider) - { - AssertUtils.ArgumentNotNull(provider, "provider"); - - return GetConnectionTxPair(provider).Connection; - - } - - private static bool connectionEquals(IDbConnection heldCon, IDbConnection passedInCon) - { - return (heldCon == passedInCon || heldCon.Equals(passedInCon) || - getTargetConnection(heldCon).Equals(passedInCon)); - } - - private static IDbConnection getTargetConnection(IDbConnection con) - { - IDbConnection conToUse = con; - /* - while (conToUse is ConnectionProxy) - { - conToUse = (ConnectionProxy)conToUse.getTargetConnection(); - } - */ - return conToUse; - } - - /// - /// Applies the current transaction timeout, if any, to the given ADO.NET IDbCommand object. - /// - /// The command. - /// The db provider. - public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider) - { - ApplyTransactionTimeout(command, dbProvider, 0); - } - - /// - /// Applies the specified timeout - overridden by the current transaction timeout, if any, to to the - /// given ADO.NET IDb command object. - /// - /// The command. - /// The db provider the command was obtained from. - /// The timeout to apply (or 0 for no timeout outside of a transaction. - public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider, int timeout) - { - AssertUtils.ArgumentNotNull(command, "command", "No IDbCommand specified."); - AssertUtils.ArgumentNotNull(dbProvider, "dbProvider", "No IDbProvider specified."); - - ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider); - if (conHolder != null && conHolder.HasTimeout) - { - // Remaining transaction timeout overrides specified value. - command.CommandTimeout = conHolder.TimeToLiveInSeconds; - } - else if (timeout > 0) - { - // No current transaction timeout -> apply specified value. - command.CommandTimeout = timeout; - } - - } - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using Common.Logging; +using Spring.Data.Common; +using Spring.Transaction.Support; +using Spring.Util; + +namespace Spring.Data.Support +{ + /// + /// Summary description for DbProviderUtils. + /// + public abstract class ConnectionUtils + { + #region Logging + + private static readonly ILog LOG = LogManager.GetLogger(typeof (ConnectionUtils)); + + #endregion + + public static readonly int CONNECTION_SYNCHRONIZATION_ORDER = 1000; + /// + /// Dispose of the given Connection, created via the given IDbProvider, + /// if it is not managed externally (that is, not bound to the thread). + /// + /// The connection to close if necessary. If + /// this is null the call will be ignored. + /// The IDbProvider the connection came from + public static void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) + { + try + { + DoDisposeConnection(conn, dbProvider); + } catch (Exception e) + { + LOG.Warn("Could not close connection", e); + } + + } + private static void DoDisposeConnection(IDbConnection conn, IDbProvider dbProvider) + { + if (conn == null) + { + return; + } + + if (dbProvider != null) + { + ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.GetResource(dbProvider); + if (conHolder != null && connectionEquals(conHolder.Connection, conn)) + { + // It's the transactional connection bound to the thread so don't close it. + conHolder.Released(); + return; + } + } + if (LOG.IsDebugEnabled) + { + LOG.Debug("Disposing of IDbConnection with connection string = [" + dbProvider.ConnectionString + "]"); + } + conn.Dispose(); + } + + + /// + /// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider. + /// Changes any exception into the Spring hierarchy of generic data access + /// exceptions, simplifying calling code and making any exception that is + /// thrown more meaningful. + /// + /// + /// Is aware of a corresponding Connection/Transaction bound to the current thread, for example + /// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread + /// if transaction synchronization is active + /// + /// The provider. + /// A Connection/Transaction pair. + public static ConnectionTxPair GetConnectionTxPair(IDbProvider provider) + { + try + { + return DoGetConnection(provider); + } catch (Exception e) + { + throw new CannotGetAdoConnectionException("Could not get ADO.NET connection.", e); + } + + } + + + /// + /// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider. + /// Same as but throwing original provider + /// exception. + /// + /// + /// Is aware of a corresponding Connection/Transaction bound to the current thread, for example + /// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread + /// if transaction synchronization is active + /// + /// The provider. + /// + public static ConnectionTxPair DoGetConnection(IDbProvider provider) + { + AssertUtils.ArgumentNotNull(provider, "provider"); + ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(provider); + if (conHolder != null && (conHolder.HasConnection || conHolder.SynchronizedWithTransaction)) + { + conHolder.Requested(); + if (!conHolder.HasConnection) + { + if (LOG.IsDebugEnabled) + { + LOG.Debug("Fetching resumed ADO.NET connection from DbProvider"); + } + conHolder.Connection = provider.CreateConnection(); + } + return new ConnectionTxPair(conHolder.Connection, conHolder.Transaction); + } + + // Else we either got no holder or an empty thread-bound holder here. + if (LOG.IsDebugEnabled) + { + LOG.Debug("Fetching Connection from DbProvider"); + } + IDbConnection conn = provider.CreateConnection(); + conn.Open(); + + if (TransactionSynchronizationManager.SynchronizationActive) + { + LOG.Debug("Registering transaction synchronization for IDbConnection"); + //Use same connection for further ADO.NET actions with the transaction. + //Thread-bound object will get removed by manager at transaction completion. + + //TODO investigate creating tx object... + ConnectionHolder holderToUse = conHolder; + if (holderToUse == null) + { + holderToUse = new ConnectionHolder(conn, null); + } + else + { + holderToUse.Connection = conn; + } + holderToUse.Requested(); + TransactionSynchronizationManager.RegisterSynchronization( + new ConnectionSynchronization(holderToUse, provider)); + holderToUse.SynchronizedWithTransaction = true; + if (holderToUse != conHolder) + { + TransactionSynchronizationManager.BindResource(provider, holderToUse); + } + + } + return new ConnectionTxPair(conn, null); + } + + //TODO exception translation? + /// + /// Do the connection mgmt. + /// + /// + /// + public static IDbConnection GetConnection(IDbProvider provider) + { + AssertUtils.ArgumentNotNull(provider, "provider"); + + return GetConnectionTxPair(provider).Connection; + + } + + private static bool connectionEquals(IDbConnection heldCon, IDbConnection passedInCon) + { + return (heldCon == passedInCon || heldCon.Equals(passedInCon) || + getTargetConnection(heldCon).Equals(passedInCon)); + } + + private static IDbConnection getTargetConnection(IDbConnection con) + { + IDbConnection conToUse = con; + /* + while (conToUse is ConnectionProxy) + { + conToUse = (ConnectionProxy)conToUse.getTargetConnection(); + } + */ + return conToUse; + } + + /// + /// Applies the current transaction timeout, if any, to the given ADO.NET IDbCommand object. + /// + /// The command. + /// The db provider. + public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider) + { + ApplyTransactionTimeout(command, dbProvider, 0); + } + + /// + /// Applies the specified timeout - overridden by the current transaction timeout, if any, to to the + /// given ADO.NET IDb command object. + /// + /// The command. + /// The db provider the command was obtained from. + /// The timeout to apply (or 0 for no timeout outside of a transaction. + public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider, int timeout) + { + AssertUtils.ArgumentNotNull(command, "command", "No IDbCommand specified."); + AssertUtils.ArgumentNotNull(dbProvider, "dbProvider", "No IDbProvider specified."); + + ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider); + if (conHolder != null && conHolder.HasTimeout) + { + // Remaining transaction timeout overrides specified value. + command.CommandTimeout = conHolder.TimeToLiveInSeconds; + } + else if (timeout > 0) + { + // No current transaction timeout -> apply specified value. + command.CommandTimeout = timeout; + } + + } + } +} diff --git a/src/Spring/Spring.Data/Data/Support/DefaultServiceDomainAdapter.cs b/src/Spring/Spring.Data/Data/Support/DefaultServiceDomainAdapter.cs index 3a28ae0f..8ccb868f 100644 --- a/src/Spring/Spring.Data/Data/Support/DefaultServiceDomainAdapter.cs +++ b/src/Spring/Spring.Data/Data/Support/DefaultServiceDomainAdapter.cs @@ -1,95 +1,94 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -using System.EnterpriseServices; - -namespace Spring.Data.Support -{ - /// - /// Implementation that delegates to ServiceDomain and ContextUtil for all functionality. - /// - /// Introduced for purposes of unit testing. - /// Mark Pollack (.NET) - /// $Id $ - public class DefaultServiceDomainAdapter : IServiceDomainAdapter - { - - /// - /// Creates the context specified by the ServiceConfig object and pushes it onto the context stack to - /// become the current context. - /// - /// A ServiceConfig that contains the configuration information for the services to be used within the enclosed code. - public void Enter(SimpleServiceConfig config) - { - ServiceConfig serviceConfig = config.CreateServiceConfig(); - ServiceDomain.Enter(serviceConfig); - } - - /// - /// Leaves this ServiceDomain. The current context is then popped from the context stack, and the - /// context that was running when Enter was called becomes the current context. - /// - /// One of the TransactionStatus values - public TransactionStatus Leave() - { - return ServiceDomain.Leave(); - } - - /// - /// Sets the consistent bit and the done bit to true in the COM+ context - /// - public void SetComplete() - { - ContextUtil.SetComplete(); - } - - /// - /// Sets the consistent bit to false and the done bit to true in the COM+ context. - /// - public void SetAbort() - { - ContextUtil.SetAbort(); - } - - /// - /// Gets or sets the consistent bit in the COM+ context. - /// - /// My transaction vote. - public TransactionVote MyTransactionVote - { - get { return ContextUtil.MyTransactionVote; } - set { ContextUtil.MyTransactionVote = value; } - } - - /// - /// Gets a value indicating whether the current context is transactional. - /// - /// - /// true if this instance is existing transaction; otherwise, false. - /// - public bool IsInTransaction - { - get { return ContextUtil.IsInTransaction; } - } - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +using System.EnterpriseServices; + +namespace Spring.Data.Support +{ + /// + /// Implementation that delegates to ServiceDomain and ContextUtil for all functionality. + /// + /// Introduced for purposes of unit testing. + /// Mark Pollack (.NET) + public class DefaultServiceDomainAdapter : IServiceDomainAdapter + { + + /// + /// Creates the context specified by the ServiceConfig object and pushes it onto the context stack to + /// become the current context. + /// + /// A ServiceConfig that contains the configuration information for the services to be used within the enclosed code. + public void Enter(SimpleServiceConfig config) + { + ServiceConfig serviceConfig = config.CreateServiceConfig(); + ServiceDomain.Enter(serviceConfig); + } + + /// + /// Leaves this ServiceDomain. The current context is then popped from the context stack, and the + /// context that was running when Enter was called becomes the current context. + /// + /// One of the TransactionStatus values + public TransactionStatus Leave() + { + return ServiceDomain.Leave(); + } + + /// + /// Sets the consistent bit and the done bit to true in the COM+ context + /// + public void SetComplete() + { + ContextUtil.SetComplete(); + } + + /// + /// Sets the consistent bit to false and the done bit to true in the COM+ context. + /// + public void SetAbort() + { + ContextUtil.SetAbort(); + } + + /// + /// Gets or sets the consistent bit in the COM+ context. + /// + /// My transaction vote. + public TransactionVote MyTransactionVote + { + get { return ContextUtil.MyTransactionVote; } + set { ContextUtil.MyTransactionVote = value; } + } + + /// + /// Gets a value indicating whether the current context is transactional. + /// + /// + /// true if this instance is existing transaction; otherwise, false. + /// + public bool IsInTransaction + { + get { return ContextUtil.IsInTransaction; } + } + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs b/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs index 9bb8c6cb..29d340da 100644 --- a/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs +++ b/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs @@ -1,109 +1,108 @@ -#if NET_2_0 - -#region License - -/* - * Copyright 2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Transactions; - -namespace Spring.Data.Support -{ - /// - /// Uses and System.Transactions.Transaction.Current to provide - /// necessary state and operations to TxScopeTransactionManager. - /// - /// Mark Pollack (.NET) - /// $Id: DefaultTransactionScopeAdapter.cs,v 1.1 2007/11/30 18:38:47 markpollack Exp $ - public class DefaultTransactionScopeAdapter : ITransactionScopeAdapter - { - private TransactionScope txScope; - - /// - /// Call Complete() on the TransactionScope object created by this instance. - /// - public void Complete() - { - txScope.Complete(); - } - - /// - /// Call Disponse() on the TransactionScope object created by this instance. - /// - public void Dispose() - { - txScope.Dispose(); - } - - - /// - /// Gets a value indicating whether there is a new transaction or an existing transaction. - /// - /// - /// true if this instance is existing transaction; otherwise, false. - /// - public bool IsExistingTransaction - { - get { - if (System.Transactions.Transaction.Current != null) - { - return true; - } - else - { - return false; - } - } - } - - /// - /// Gets a value indicating whether rollback only has been called (i.e. Rollback() on the - /// Transaction object) and therefore voting that the transaction will be aborted. - /// - /// true if rollback only; otherwise, false. - public bool RollbackOnly - { - get - { - if (System.Transactions.Transaction.Current != null && - System.Transactions.Transaction.Current.TransactionInformation != null && - System.Transactions.Transaction.Current.TransactionInformation.Status == TransactionStatus.Aborted) - { - return true; - } - else - { - return false; - } - } - } - - /// - /// Creates the transaction scope. - /// - /// The tx scope option. - /// The tx options. - /// The interop option. - public void CreateTransactionScope(TransactionScopeOption txScopeOption, TransactionOptions txOptions, - EnterpriseServicesInteropOption interopOption) - { - txScope = new TransactionScope(txScopeOption, txOptions, interopOption); - } - } -} +#if NET_2_0 + +#region License + +/* + * Copyright 2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Transactions; + +namespace Spring.Data.Support +{ + /// + /// Uses and System.Transactions.Transaction.Current to provide + /// necessary state and operations to TxScopeTransactionManager. + /// + /// Mark Pollack (.NET) + public class DefaultTransactionScopeAdapter : ITransactionScopeAdapter + { + private TransactionScope txScope; + + /// + /// Call Complete() on the TransactionScope object created by this instance. + /// + public void Complete() + { + txScope.Complete(); + } + + /// + /// Call Disponse() on the TransactionScope object created by this instance. + /// + public void Dispose() + { + txScope.Dispose(); + } + + + /// + /// Gets a value indicating whether there is a new transaction or an existing transaction. + /// + /// + /// true if this instance is existing transaction; otherwise, false. + /// + public bool IsExistingTransaction + { + get { + if (System.Transactions.Transaction.Current != null) + { + return true; + } + else + { + return false; + } + } + } + + /// + /// Gets a value indicating whether rollback only has been called (i.e. Rollback() on the + /// Transaction object) and therefore voting that the transaction will be aborted. + /// + /// true if rollback only; otherwise, false. + public bool RollbackOnly + { + get + { + if (System.Transactions.Transaction.Current != null && + System.Transactions.Transaction.Current.TransactionInformation != null && + System.Transactions.Transaction.Current.TransactionInformation.Status == TransactionStatus.Aborted) + { + return true; + } + else + { + return false; + } + } + } + + /// + /// Creates the transaction scope. + /// + /// The tx scope option. + /// The tx options. + /// The interop option. + public void CreateTransactionScope(TransactionScopeOption txScopeOption, TransactionOptions txOptions, + EnterpriseServicesInteropOption interopOption) + { + txScope = new TransactionScope(txScopeOption, txOptions, interopOption); + } + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs b/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs index 5724bbf1..01d3b4f4 100644 --- a/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs +++ b/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs @@ -1,301 +1,300 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Common.Logging; -using Spring.Dao; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Support -{ - /// - /// Implementation of IAdoExceptionTranslator that analyzes provider specific - /// error codes and translates into the DAO exception hierarchy. - /// - /// This class loads the obtains error codes from - /// the IDbProvider metadata property ErrorCodes - /// which defines error code mappings for various providers. - /// - /// Mark Pollack (.NET) - /// $Id: ErrorCodeExceptionTranslator.cs,v 1.11 2007/12/06 20:14:30 markpollack Exp $ - public class ErrorCodeExceptionTranslator : IAdoExceptionTranslator - { - #region Fields - - private ErrorCodes errorCodes; - - private IAdoExceptionTranslator fallbackTranslator; - - private IDbProvider dbProvider; - - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (ErrorCodeExceptionTranslator)); - - #endregion - - #region Constructor (s) - - /// - /// Initializes a new instance of the class. - /// - /// The data provider. - public ErrorCodeExceptionTranslator(IDbProvider provider) - { - DbProvider = provider; - } - - - - /// - /// Initializes a new instance of the class. - /// - /// The data provider. - /// The error code collection. - public ErrorCodeExceptionTranslator(IDbProvider provider, ErrorCodes ec) - { - DbProvider = provider; - errorCodes = ec; - } - - - - #endregion - - #region Properties - - /// - /// Sets the db provider. - /// - /// The db provider. - public IDbProvider DbProvider - { - set - { - dbProvider = value; - fallbackTranslator = new FallbackExceptionTranslator(); - errorCodes = dbProvider.DbMetadata.ErrorCodes; - - } - } - - /// - /// Gets the error codes for the provider - /// - /// The error codes. - public ErrorCodes ErrorCodes - { - get - { - return errorCodes; - } - } - - #endregion - - /// - /// Gets or sets the fallback translator to use in case error code based translation - /// fails. - /// - /// The fallback translator. - public IAdoExceptionTranslator FallbackTranslator - { - get - { - return fallbackTranslator; - } - set - { - fallbackTranslator = value; - } - } - - - #region Methods - - #endregion - - /// - /// Translate the given into a generic data access exception. - /// - /// A readable string describing the task being attempted. - /// The SQL query or update that caused the problem. May be null. - /// - /// The encountered by the ADO.NET implementation. - /// - /// - /// A appropriate for the supplied - /// . - /// - public virtual DataAccessException Translate(string task, string sql, Exception exception) - { - if (task == null) - { - task = ""; - } - if (sql == null) - { - sql = ""; - } - string errorCode = ExtractErrorCode(exception); - - // First, try custom translation from overridden method. - DataAccessException dex = TranslateException(task, sql, errorCode, exception); - if (dex != null) - { - return dex; - } - - - if (errorCodes != null) - { - - if (errorCode != null) - { - if (Array.IndexOf(errorCodes.BadSqlGrammarCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new BadSqlGrammarException(task, sql, exception); - } - else if (Array.IndexOf(errorCodes.InvalidResultSetAccessCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new InvalidResultSetAccessException(task, sql, exception); - } - else if (Array.IndexOf(errorCodes.DataAccessResourceFailureCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new DataAccessResourceFailureException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.PermissionDeniedCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new PermissionDeniedDataAccessException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.DataIntegrityViolationCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new DataIntegrityViolationException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.CannotAcquireLockCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new CannotAcquireLockException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.DeadlockLoserCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new DeadlockLoserDataAccessException(BuildMessage(task, sql, exception), exception); - } - else if (Array.IndexOf(errorCodes.CannotSerializeTransactionCodes, errorCode) >= 0) - { - LogTranslation(task, sql, errorCode, exception, false); - return new CannotSerializeTransactionException(BuildMessage(task, sql, exception), exception); - } - } - } - if (log.IsDebugEnabled) - { - log.Debug("Unable to translate exception eith errorCode '" + errorCode + "', will use the fallback translator"); - } - return fallbackTranslator.Translate(task, sql, exception); - } - - /// - /// Subclasses can override this method to attempt a custom mapping from a data access Exception - /// to DataAccessException. - /// - /// Readable text describing the task being attempted. - /// SQL query or update that caused the problem. May be null. - /// The error code extracted from the generic data access exception for - /// a particular provider. - /// The exception thrown from a data access operation. - /// - /// null if no custom translation was possible, otherwise a DataAccessException - /// resulting from custom translation. This exception should include the exception parameter - /// as a nested root cause. This implementation always returns null, meaning that - /// the translator always falls back to the default error codes. - /// - protected virtual DataAccessException TranslateException(string task, string sql, string errorCode, Exception exception) - { - return null; - } - - - /// - /// Builds the message. - /// - /// The task. - /// The SQL. - /// The exception. - /// - protected virtual string BuildMessage(string task, string sql, Exception exception) - { - return task + "; SQL [" + sql + "]; " + exception.Message; - } - - /// - /// Determines whether the specified exception is valid data access exception. - /// - /// The exception. - /// - /// true if is valid data access exception; otherwise, false. - /// - public bool IsValidDataAccessException(Exception e) - { - return dbProvider.IsDataAccessException(e); - } - - /// - /// Logs the translation. - /// - /// The task. - /// The SQL. - /// The error code. - /// The exception. - /// if set to true [b]. - private void LogTranslation(string task, string sql, string errorCode, Exception exception, bool b) - { - if (log.IsDebugEnabled) - { - String intro = "Translating"; - log.Debug(intro + " ADO exception with error code '" + errorCode - + "', message [" + exception.Message + - "]; SQL was [" + sql + "] for task [" + task + "]"); - } - } - - private string ExtractErrorCode(Exception exception) - { - // Use provider specific reflection information to extract error code. - return dbProvider.ExtractError(exception); - } - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Common.Logging; +using Spring.Dao; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Support +{ + /// + /// Implementation of IAdoExceptionTranslator that analyzes provider specific + /// error codes and translates into the DAO exception hierarchy. + /// + /// This class loads the obtains error codes from + /// the IDbProvider metadata property ErrorCodes + /// which defines error code mappings for various providers. + /// + /// Mark Pollack (.NET) + public class ErrorCodeExceptionTranslator : IAdoExceptionTranslator + { + #region Fields + + private ErrorCodes errorCodes; + + private IAdoExceptionTranslator fallbackTranslator; + + private IDbProvider dbProvider; + + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (ErrorCodeExceptionTranslator)); + + #endregion + + #region Constructor (s) + + /// + /// Initializes a new instance of the class. + /// + /// The data provider. + public ErrorCodeExceptionTranslator(IDbProvider provider) + { + DbProvider = provider; + } + + + + /// + /// Initializes a new instance of the class. + /// + /// The data provider. + /// The error code collection. + public ErrorCodeExceptionTranslator(IDbProvider provider, ErrorCodes ec) + { + DbProvider = provider; + errorCodes = ec; + } + + + + #endregion + + #region Properties + + /// + /// Sets the db provider. + /// + /// The db provider. + public IDbProvider DbProvider + { + set + { + dbProvider = value; + fallbackTranslator = new FallbackExceptionTranslator(); + errorCodes = dbProvider.DbMetadata.ErrorCodes; + + } + } + + /// + /// Gets the error codes for the provider + /// + /// The error codes. + public ErrorCodes ErrorCodes + { + get + { + return errorCodes; + } + } + + #endregion + + /// + /// Gets or sets the fallback translator to use in case error code based translation + /// fails. + /// + /// The fallback translator. + public IAdoExceptionTranslator FallbackTranslator + { + get + { + return fallbackTranslator; + } + set + { + fallbackTranslator = value; + } + } + + + #region Methods + + #endregion + + /// + /// Translate the given into a generic data access exception. + /// + /// A readable string describing the task being attempted. + /// The SQL query or update that caused the problem. May be null. + /// + /// The encountered by the ADO.NET implementation. + /// + /// + /// A appropriate for the supplied + /// . + /// + public virtual DataAccessException Translate(string task, string sql, Exception exception) + { + if (task == null) + { + task = ""; + } + if (sql == null) + { + sql = ""; + } + string errorCode = ExtractErrorCode(exception); + + // First, try custom translation from overridden method. + DataAccessException dex = TranslateException(task, sql, errorCode, exception); + if (dex != null) + { + return dex; + } + + + if (errorCodes != null) + { + + if (errorCode != null) + { + if (Array.IndexOf(errorCodes.BadSqlGrammarCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new BadSqlGrammarException(task, sql, exception); + } + else if (Array.IndexOf(errorCodes.InvalidResultSetAccessCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new InvalidResultSetAccessException(task, sql, exception); + } + else if (Array.IndexOf(errorCodes.DataAccessResourceFailureCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new DataAccessResourceFailureException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.PermissionDeniedCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new PermissionDeniedDataAccessException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.DataIntegrityViolationCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new DataIntegrityViolationException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.CannotAcquireLockCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new CannotAcquireLockException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.DeadlockLoserCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new DeadlockLoserDataAccessException(BuildMessage(task, sql, exception), exception); + } + else if (Array.IndexOf(errorCodes.CannotSerializeTransactionCodes, errorCode) >= 0) + { + LogTranslation(task, sql, errorCode, exception, false); + return new CannotSerializeTransactionException(BuildMessage(task, sql, exception), exception); + } + } + } + if (log.IsDebugEnabled) + { + log.Debug("Unable to translate exception eith errorCode '" + errorCode + "', will use the fallback translator"); + } + return fallbackTranslator.Translate(task, sql, exception); + } + + /// + /// Subclasses can override this method to attempt a custom mapping from a data access Exception + /// to DataAccessException. + /// + /// Readable text describing the task being attempted. + /// SQL query or update that caused the problem. May be null. + /// The error code extracted from the generic data access exception for + /// a particular provider. + /// The exception thrown from a data access operation. + /// + /// null if no custom translation was possible, otherwise a DataAccessException + /// resulting from custom translation. This exception should include the exception parameter + /// as a nested root cause. This implementation always returns null, meaning that + /// the translator always falls back to the default error codes. + /// + protected virtual DataAccessException TranslateException(string task, string sql, string errorCode, Exception exception) + { + return null; + } + + + /// + /// Builds the message. + /// + /// The task. + /// The SQL. + /// The exception. + /// + protected virtual string BuildMessage(string task, string sql, Exception exception) + { + return task + "; SQL [" + sql + "]; " + exception.Message; + } + + /// + /// Determines whether the specified exception is valid data access exception. + /// + /// The exception. + /// + /// true if is valid data access exception; otherwise, false. + /// + public bool IsValidDataAccessException(Exception e) + { + return dbProvider.IsDataAccessException(e); + } + + /// + /// Logs the translation. + /// + /// The task. + /// The SQL. + /// The error code. + /// The exception. + /// if set to true [b]. + private void LogTranslation(string task, string sql, string errorCode, Exception exception, bool b) + { + if (log.IsDebugEnabled) + { + String intro = "Translating"; + log.Debug(intro + " ADO exception with error code '" + errorCode + + "', message [" + exception.Message + + "]; SQL was [" + sql + "] for task [" + task + "]"); + } + } + + private string ExtractErrorCode(Exception exception) + { + // Use provider specific reflection information to extract error code. + return dbProvider.ExtractError(exception); + } + } +} diff --git a/src/Spring/Spring.Data/Data/Support/FallbackExceptionTranslator.cs b/src/Spring/Spring.Data/Data/Support/FallbackExceptionTranslator.cs index 73e3e9f4..28a24977 100644 --- a/src/Spring/Spring.Data/Data/Support/FallbackExceptionTranslator.cs +++ b/src/Spring/Spring.Data/Data/Support/FallbackExceptionTranslator.cs @@ -1,71 +1,70 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Dao; - -#endregion - -namespace Spring.Data.Support -{ - /// - /// Translates all exceptions to an UncategorizedAdoException. - /// - /// - /// This exception translator used when an exception is thrown using the - /// "primary" implementation of IAdoExceptionTranslator, i.e. AdoExceptionTranslator. - /// - /// Mark Pollack (.NET) - /// $Id: FallbackExceptionTranslator.cs,v 1.6 2007/01/01 22:22:50 markpollack Exp $ - public class FallbackExceptionTranslator : IAdoExceptionTranslator - { - - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public FallbackExceptionTranslator() - { - } - - #endregion - - - /// - /// Translate the given into a generic data access exception. - /// - /// A readable string describing the task being attempted. - /// The SQL query or update that caused the problem. May be null. - /// - /// The encountered by the ADO.NET implementation. - /// - /// - /// A appropriate for the supplied - /// . - /// - public DataAccessException Translate(string task, string sql, Exception exception) - { - throw new UncategorizedAdoException(task, sql, "", exception); - } - } -} +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Dao; + +#endregion + +namespace Spring.Data.Support +{ + /// + /// Translates all exceptions to an UncategorizedAdoException. + /// + /// + /// This exception translator used when an exception is thrown using the + /// "primary" implementation of IAdoExceptionTranslator, i.e. AdoExceptionTranslator. + /// + /// Mark Pollack (.NET) + public class FallbackExceptionTranslator : IAdoExceptionTranslator + { + + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public FallbackExceptionTranslator() + { + } + + #endregion + + + /// + /// Translate the given into a generic data access exception. + /// + /// A readable string describing the task being attempted. + /// The SQL query or update that caused the problem. May be null. + /// + /// The encountered by the ADO.NET implementation. + /// + /// + /// A appropriate for the supplied + /// . + /// + public DataAccessException Translate(string task, string sql, Exception exception) + { + throw new UncategorizedAdoException(task, sql, "", exception); + } + } +} diff --git a/src/Spring/Spring.Data/Data/Support/IAdoExceptionTranslator.cs b/src/Spring/Spring.Data/Data/Support/IAdoExceptionTranslator.cs index e73270d4..529e5569 100644 --- a/src/Spring/Spring.Data/Data/Support/IAdoExceptionTranslator.cs +++ b/src/Spring/Spring.Data/Data/Support/IAdoExceptionTranslator.cs @@ -1,56 +1,55 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Dao; - -namespace Spring.Data.Support -{ - /// - /// Interface to be implemented by classes that can translate between properietary SQL exceptions - /// and Spring.NET's data access strategy-agnostic . - /// - /// - ///

- /// Implementations can be generic (for example, ADO.NET Exceptions) or proprietary (for example, - /// using SQL Server or Oracle error codes) for greater precision. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// Mark Pollack - /// $Id: IAdoExceptionTranslator.cs,v 1.2 2006/11/29 07:18:46 markpollack Exp $ - public interface IAdoExceptionTranslator - { - /// - /// Translate the given into a generic data access exception. - /// - /// A readable string describing the task being attempted. - /// The SQL query or update that caused the problem. May be null. - /// - /// The encountered by the ADO.NET implementation. - /// - /// - /// A appropriate for the supplied - /// . - /// - DataAccessException Translate( string task, string sql, Exception exception ); - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Dao; + +namespace Spring.Data.Support +{ + /// + /// Interface to be implemented by classes that can translate between properietary SQL exceptions + /// and Spring.NET's data access strategy-agnostic . + /// + /// + ///

+ /// Implementations can be generic (for example, ADO.NET Exceptions) or proprietary (for example, + /// using SQL Server or Oracle error codes) for greater precision. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + /// Mark Pollack + public interface IAdoExceptionTranslator + { + /// + /// Translate the given into a generic data access exception. + /// + /// A readable string describing the task being attempted. + /// The SQL query or update that caused the problem. May be null. + /// + /// The encountered by the ADO.NET implementation. + /// + /// + /// A appropriate for the supplied + /// . + /// + DataAccessException Translate( string task, string sql, Exception exception ); + } +} diff --git a/src/Spring/Spring.Data/Data/Support/IServiceDomainAdapter.cs b/src/Spring/Spring.Data/Data/Support/IServiceDomainAdapter.cs index 68ed2566..dc19a349 100644 --- a/src/Spring/Spring.Data/Data/Support/IServiceDomainAdapter.cs +++ b/src/Spring/Spring.Data/Data/Support/IServiceDomainAdapter.cs @@ -1,77 +1,76 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -using System.EnterpriseServices; - -namespace Spring.Data.Support -{ - /// - /// Provides the necessary transactional state and operations for ServiceDomainTransactionManager to - /// work with ServiceDomain and ContextUtil. - /// - /// Introduced for purposes of unit testing. - /// Mark Pollack (.NET) - /// $Id $ - public interface IServiceDomainAdapter - { - /// - /// Creates the context specified by the ServiceConfig object and pushes it onto the context stack to - /// become the current context. - /// - /// A ServiceConfig that contains the configuration information for the services to be used within the enclosed code. - void Enter(SimpleServiceConfig config); - - /// - /// Leaves this ServiceDomain. The current context is then popped from the context stack, and the - /// context that was running when Enter was called becomes the current context. - /// - /// One of the TransactionStatus values - TransactionStatus Leave(); - - /// - /// Sets the consistent bit and the done bit to true in the COM+ context - /// - void SetComplete(); - - /// - /// Sets the consistent bit to false and the done bit to true in the COM+ context. - /// - void SetAbort(); - - /// - /// Gets or sets the consistent bit in the COM+ context. - /// - /// My transaction vote. - TransactionVote MyTransactionVote { get; set;} - - /// - /// Gets a value indicating whether the current context is transactional. - /// - /// - /// true if this instance is existing transaction; otherwise, false. - /// - bool IsInTransaction { get; } - - } -} - +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +using System.EnterpriseServices; + +namespace Spring.Data.Support +{ + /// + /// Provides the necessary transactional state and operations for ServiceDomainTransactionManager to + /// work with ServiceDomain and ContextUtil. + /// + /// Introduced for purposes of unit testing. + /// Mark Pollack (.NET) + public interface IServiceDomainAdapter + { + /// + /// Creates the context specified by the ServiceConfig object and pushes it onto the context stack to + /// become the current context. + /// + /// A ServiceConfig that contains the configuration information for the services to be used within the enclosed code. + void Enter(SimpleServiceConfig config); + + /// + /// Leaves this ServiceDomain. The current context is then popped from the context stack, and the + /// context that was running when Enter was called becomes the current context. + /// + /// One of the TransactionStatus values + TransactionStatus Leave(); + + /// + /// Sets the consistent bit and the done bit to true in the COM+ context + /// + void SetComplete(); + + /// + /// Sets the consistent bit to false and the done bit to true in the COM+ context. + /// + void SetAbort(); + + /// + /// Gets or sets the consistent bit in the COM+ context. + /// + /// My transaction vote. + TransactionVote MyTransactionVote { get; set;} + + /// + /// Gets a value indicating whether the current context is transactional. + /// + /// + /// true if this instance is existing transaction; otherwise, false. + /// + bool IsInTransaction { get; } + + } +} + #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs b/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs index 71e23650..765901f3 100644 --- a/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs +++ b/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs @@ -1,74 +1,73 @@ -#if NET_2_0 - -#region License - -/* - * Copyright 2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Transactions; - -namespace Spring.Data.Support -{ - /// - /// Provides the necessary transactional state and operations for TxScopeTransactionManager to - /// work with TransactionScope and Transaction.Current. - /// - /// Introduced for purposes of unit testing. - /// Mark Pollack (.NET) - /// $Id: ITransactionScopeAdapter.cs,v 1.1 2007/11/30 18:38:47 markpollack Exp $ - public interface ITransactionScopeAdapter - { - /// - /// Creates the transaction scope. - /// - /// The tx scope option. - /// The tx options. - /// The interop option. - void CreateTransactionScope(TransactionScopeOption txScopeOption, TransactionOptions txOptions, EnterpriseServicesInteropOption interopOption); - - /// - /// Call Complete() on the TransactionScope object created by this instance. - /// - void Complete(); - - - /// - /// Call Disponse() on the TransactionScope object created by this instance. - /// - void Dispose(); - - - /// - /// Gets a value indicating whether there is a new transaction or an existing transaction. - /// - /// - /// true if this instance is existing transaction; otherwise, false. - /// - bool IsExistingTransaction { get; } - - - /// - /// Gets a value indicating whether rollback only has been called (i.e. Rollback() on the - /// Transaction object) and therefore voting that the transaction will be aborted. - /// - /// true if rollback only; otherwise, false. - bool RollbackOnly { get; } - } - -} +#if NET_2_0 + +#region License + +/* + * Copyright 2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Transactions; + +namespace Spring.Data.Support +{ + /// + /// Provides the necessary transactional state and operations for TxScopeTransactionManager to + /// work with TransactionScope and Transaction.Current. + /// + /// Introduced for purposes of unit testing. + /// Mark Pollack (.NET) + public interface ITransactionScopeAdapter + { + /// + /// Creates the transaction scope. + /// + /// The tx scope option. + /// The tx options. + /// The interop option. + void CreateTransactionScope(TransactionScopeOption txScopeOption, TransactionOptions txOptions, EnterpriseServicesInteropOption interopOption); + + /// + /// Call Complete() on the TransactionScope object created by this instance. + /// + void Complete(); + + + /// + /// Call Disponse() on the TransactionScope object created by this instance. + /// + void Dispose(); + + + /// + /// Gets a value indicating whether there is a new transaction or an existing transaction. + /// + /// + /// true if this instance is existing transaction; otherwise, false. + /// + bool IsExistingTransaction { get; } + + + /// + /// Gets a value indicating whether rollback only has been called (i.e. Rollback() on the + /// Transaction object) and therefore voting that the transaction will be aborted. + /// + /// true if rollback only; otherwise, false. + bool RollbackOnly { get; } + } + +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/NamedResultSetProcessor.cs b/src/Spring/Spring.Data/Data/Support/NamedResultSetProcessor.cs index 52a74603..05cb7691 100644 --- a/src/Spring/Spring.Data/Data/Support/NamedResultSetProcessor.cs +++ b/src/Spring/Spring.Data/Data/Support/NamedResultSetProcessor.cs @@ -1,106 +1,105 @@ -#region Licence - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - - -#endregion - -namespace Spring.Data.Support -{ - /// - /// Provides a name to a ResultSetProcessor for use with AdoOperation subclasses - /// such as StoredProcedure. - /// - /// Mark Pollack (.NET) - /// $Id: NamedResultSetProcessor.cs,v 1.3 2006/11/29 07:18:46 markpollack Exp $ - public class NamedResultSetProcessor - { - #region Fields - - private object resultSetProcessor; - private string name; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class with a - /// IRowCallback instance - /// - /// The name of the associated row callback for use with output - /// result set mappers. - /// A row callback instance. - public NamedResultSetProcessor(string name, IRowCallback rowcallback) - { - this.name = name; - resultSetProcessor = rowcallback; - } - - /// - /// Initializes a new instance of the class with a - /// IRowMapper instance - /// - /// The name of the associated row mapper. - /// A IRowMapper instance. - public NamedResultSetProcessor(string name, IRowMapper rowMapper) - { - this.name = name; - resultSetProcessor = rowMapper; - } - - /// - /// Initializes a new instance of the class with a - /// IResultSetExtractor instance - /// - /// The name of the associated result set extractor. - /// A IResultSetExtractor instance. - public NamedResultSetProcessor(string name, IResultSetExtractor resultSetExtractor) - { - this.name = name; - resultSetProcessor = resultSetExtractor; - } - - - #endregion - - #region Properties - public string Name - { - get - { - return name; - } - } - - public object ResultSetProcessor - { - get - { - return resultSetProcessor; - } - } - - #endregion - - - } -} +#region Licence + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + + +#endregion + +namespace Spring.Data.Support +{ + /// + /// Provides a name to a ResultSetProcessor for use with AdoOperation subclasses + /// such as StoredProcedure. + /// + /// Mark Pollack (.NET) + public class NamedResultSetProcessor + { + #region Fields + + private object resultSetProcessor; + private string name; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class with a + /// IRowCallback instance + /// + /// The name of the associated row callback for use with output + /// result set mappers. + /// A row callback instance. + public NamedResultSetProcessor(string name, IRowCallback rowcallback) + { + this.name = name; + resultSetProcessor = rowcallback; + } + + /// + /// Initializes a new instance of the class with a + /// IRowMapper instance + /// + /// The name of the associated row mapper. + /// A IRowMapper instance. + public NamedResultSetProcessor(string name, IRowMapper rowMapper) + { + this.name = name; + resultSetProcessor = rowMapper; + } + + /// + /// Initializes a new instance of the class with a + /// IResultSetExtractor instance + /// + /// The name of the associated result set extractor. + /// A IResultSetExtractor instance. + public NamedResultSetProcessor(string name, IResultSetExtractor resultSetExtractor) + { + this.name = name; + resultSetProcessor = resultSetExtractor; + } + + + #endregion + + #region Properties + public string Name + { + get + { + return name; + } + } + + public object ResultSetProcessor + { + get + { + return resultSetProcessor; + } + } + + #endregion + + + } +} diff --git a/src/Spring/Spring.Data/Data/Support/NullMappingDataReader.cs b/src/Spring/Spring.Data/Data/Support/NullMappingDataReader.cs index 00a4ecbe..8fb1e641 100644 --- a/src/Spring/Spring.Data/Data/Support/NullMappingDataReader.cs +++ b/src/Spring/Spring.Data/Data/Support/NullMappingDataReader.cs @@ -1,348 +1,347 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; - -#endregion - -namespace Spring.Data.Support -{ - /// - /// A data reader implementation that mapps DBNull values to sensible defaults. - /// - /// IDataRecord methods are virtual. - /// Mark Pollack (.NET) - /// $Id: NullMappingDataReader.cs,v 1.2 2006/10/08 04:56:06 markpollack Exp $ - public class NullMappingDataReader : IDataReaderWrapper - { - #region Fields - - protected IDataReader dataReader; - private bool alreadyDisposed = false; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public NullMappingDataReader() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// The data reader to delegate operations to. - public NullMappingDataReader(IDataReader dataReader) - { - this.dataReader = dataReader; - } - - #endregion - - ~NullMappingDataReader() - { - Dispose(false); - } - #region Methods - protected virtual void Dispose(bool isDisposing) - { - // Don't dispose more than once - if (alreadyDisposed) - { - return; - } - if (isDisposing) - { - //free managed resourced - dataReader.Dispose(); - } - alreadyDisposed = true; - } - #endregion - - #region IDataReaderWrapper Members - - public IDataReader WrappedReader - { - get - { - return dataReader; - } - set - { - dataReader = value; - } - } - - #endregion - - #region IDataReader Members - - public int RecordsAffected - { - get - { - return this.dataReader.RecordsAffected; - } - } - - public bool IsClosed - { - get - { - return this.dataReader.IsClosed; - } - } - - public bool NextResult() - { - return dataReader.NextResult(); - } - - public void Close() - { - dataReader.Close(); - } - - public bool Read() - { - return dataReader.Read(); - } - - public int Depth - { - get - { - return dataReader.Depth; - } - } - - public DataTable GetSchemaTable() - { - return dataReader.GetSchemaTable(); - } - - #endregion - - #region IDisposable Members - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(true); - } - - #endregion - - #region IDataRecord Members - - /// - /// Gets the 32-bit signed integer value of the specified field. - /// - /// The index of the field to find. - /// - /// The 32-bit signed integer value of the specified field or 0 if null - /// - /// The index passed was outside the range of 0 through . - public virtual int GetInt32(int i) - { - if (dataReader.IsDBNull(i)) - { - return 0; - } - else - { - return dataReader.GetInt32(i); - } - } - - - /// - /// Gets the with the specified name. - /// Returns null if value equals DBNull.Value - /// - /// - public virtual object this[string name] - { - get - { - object objectValue = dataReader[name]; - return DBNull.Value.Equals(objectValue) ? null : objectValue; - } - } - - - /// - /// Gets the with the specified i. - /// Returns null if value equals DBNull.Value - /// - /// Return the object or null if the value equals DBNull.Value - public virtual object this[int i] - { - get - { - - return dataReader.IsDBNull(i) ? null : dataReader[i]; - } - } - - /// - /// Return the value of the specified field, null if value equals DBNull.Value - /// - /// The index of the field to find. - /// - /// The which will contain the field value upon return. - /// Returns null if value equals DBNull.Value - /// - /// - /// The index passed was outside the range of 0 through . - /// - public virtual object GetValue(int i) - { - return dataReader.IsDBNull(i) ? null : dataReader.GetValue(i); - } - - /// - /// Return whether the specified field is set to null. - /// - /// The index of the field to find. - /// - /// if the specified field is set to null, otherwise - /// . - /// - /// The index passed was outside the range of 0 through . - public virtual bool IsDBNull(int i) - { - return dataReader.IsDBNull(i); - } - - public virtual long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) - { - return dataReader.IsDBNull(i) ? 0 : dataReader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); - } - - public virtual byte GetByte(int i) - { - return dataReader.IsDBNull(i) ? (byte)0 : dataReader.GetByte(i); - } - - public virtual Type GetFieldType(int i) - { - return dataReader.GetFieldType(i); - } - - public virtual decimal GetDecimal(int i) - { - return dataReader.IsDBNull(i) ? 0 : dataReader.GetDecimal(i); - } - - public virtual int GetValues(object[] values) - { - return dataReader.GetValues(values); - } - - public virtual string GetName(int i) - { - return dataReader.GetName(i); - } - - public virtual int FieldCount - { - get - { - return dataReader.FieldCount; - } - } - - public virtual long GetInt64(int i) - { - return dataReader.IsDBNull(i) ? 0 : dataReader.GetInt64(i); - } - - public virtual double GetDouble(int i) - { - return dataReader.IsDBNull(i) ? 0 : dataReader.GetDouble(i); - } - - public virtual bool GetBoolean(int i) - { - return dataReader.IsDBNull(i) ? false : dataReader.GetBoolean(i); - } - - public virtual Guid GetGuid(int i) - { - return dataReader.IsDBNull(i) ? Guid.Empty : dataReader.GetGuid(i); - } - - public virtual DateTime GetDateTime(int i) - { - return dataReader.IsDBNull(i) ? DateTime.MinValue : dataReader.GetDateTime(i); - } - - public virtual int GetOrdinal(string name) - { - return dataReader.GetOrdinal(name); - } - - public virtual string GetDataTypeName(int i) - { - return dataReader.GetDataTypeName(i); - } - - public virtual float GetFloat(int i) - { - return dataReader.IsDBNull(i) ? 0 : dataReader.GetFloat(i); - } - - public virtual IDataReader GetData(int i) - { - return dataReader.GetData(i); - } - - public virtual long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) - { - return dataReader.IsDBNull(i) ? 0 : dataReader.GetChars(i, fieldoffset, buffer, bufferoffset, length); - } - - public virtual string GetString(int i) - { - return dataReader.IsDBNull(i) ? string.Empty : dataReader.GetString(i); - } - - public virtual char GetChar(int i) - { - return dataReader.IsDBNull(i) ? char.MinValue : dataReader.GetChar(i); - } - - public virtual short GetInt16(int i) - { - return dataReader.IsDBNull(i) ? (short)0 : dataReader.GetInt16(i); - } - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; + +#endregion + +namespace Spring.Data.Support +{ + /// + /// A data reader implementation that mapps DBNull values to sensible defaults. + /// + /// IDataRecord methods are virtual. + /// Mark Pollack (.NET) + public class NullMappingDataReader : IDataReaderWrapper + { + #region Fields + + protected IDataReader dataReader; + private bool alreadyDisposed = false; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public NullMappingDataReader() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The data reader to delegate operations to. + public NullMappingDataReader(IDataReader dataReader) + { + this.dataReader = dataReader; + } + + #endregion + + ~NullMappingDataReader() + { + Dispose(false); + } + #region Methods + protected virtual void Dispose(bool isDisposing) + { + // Don't dispose more than once + if (alreadyDisposed) + { + return; + } + if (isDisposing) + { + //free managed resourced + dataReader.Dispose(); + } + alreadyDisposed = true; + } + #endregion + + #region IDataReaderWrapper Members + + public IDataReader WrappedReader + { + get + { + return dataReader; + } + set + { + dataReader = value; + } + } + + #endregion + + #region IDataReader Members + + public int RecordsAffected + { + get + { + return this.dataReader.RecordsAffected; + } + } + + public bool IsClosed + { + get + { + return this.dataReader.IsClosed; + } + } + + public bool NextResult() + { + return dataReader.NextResult(); + } + + public void Close() + { + dataReader.Close(); + } + + public bool Read() + { + return dataReader.Read(); + } + + public int Depth + { + get + { + return dataReader.Depth; + } + } + + public DataTable GetSchemaTable() + { + return dataReader.GetSchemaTable(); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(true); + } + + #endregion + + #region IDataRecord Members + + /// + /// Gets the 32-bit signed integer value of the specified field. + /// + /// The index of the field to find. + /// + /// The 32-bit signed integer value of the specified field or 0 if null + /// + /// The index passed was outside the range of 0 through . + public virtual int GetInt32(int i) + { + if (dataReader.IsDBNull(i)) + { + return 0; + } + else + { + return dataReader.GetInt32(i); + } + } + + + /// + /// Gets the with the specified name. + /// Returns null if value equals DBNull.Value + /// + /// + public virtual object this[string name] + { + get + { + object objectValue = dataReader[name]; + return DBNull.Value.Equals(objectValue) ? null : objectValue; + } + } + + + /// + /// Gets the with the specified i. + /// Returns null if value equals DBNull.Value + /// + /// Return the object or null if the value equals DBNull.Value + public virtual object this[int i] + { + get + { + + return dataReader.IsDBNull(i) ? null : dataReader[i]; + } + } + + /// + /// Return the value of the specified field, null if value equals DBNull.Value + /// + /// The index of the field to find. + /// + /// The which will contain the field value upon return. + /// Returns null if value equals DBNull.Value + /// + /// + /// The index passed was outside the range of 0 through . + /// + public virtual object GetValue(int i) + { + return dataReader.IsDBNull(i) ? null : dataReader.GetValue(i); + } + + /// + /// Return whether the specified field is set to null. + /// + /// The index of the field to find. + /// + /// if the specified field is set to null, otherwise + /// . + /// + /// The index passed was outside the range of 0 through . + public virtual bool IsDBNull(int i) + { + return dataReader.IsDBNull(i); + } + + public virtual long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + return dataReader.IsDBNull(i) ? 0 : dataReader.GetBytes(i, fieldOffset, buffer, bufferoffset, length); + } + + public virtual byte GetByte(int i) + { + return dataReader.IsDBNull(i) ? (byte)0 : dataReader.GetByte(i); + } + + public virtual Type GetFieldType(int i) + { + return dataReader.GetFieldType(i); + } + + public virtual decimal GetDecimal(int i) + { + return dataReader.IsDBNull(i) ? 0 : dataReader.GetDecimal(i); + } + + public virtual int GetValues(object[] values) + { + return dataReader.GetValues(values); + } + + public virtual string GetName(int i) + { + return dataReader.GetName(i); + } + + public virtual int FieldCount + { + get + { + return dataReader.FieldCount; + } + } + + public virtual long GetInt64(int i) + { + return dataReader.IsDBNull(i) ? 0 : dataReader.GetInt64(i); + } + + public virtual double GetDouble(int i) + { + return dataReader.IsDBNull(i) ? 0 : dataReader.GetDouble(i); + } + + public virtual bool GetBoolean(int i) + { + return dataReader.IsDBNull(i) ? false : dataReader.GetBoolean(i); + } + + public virtual Guid GetGuid(int i) + { + return dataReader.IsDBNull(i) ? Guid.Empty : dataReader.GetGuid(i); + } + + public virtual DateTime GetDateTime(int i) + { + return dataReader.IsDBNull(i) ? DateTime.MinValue : dataReader.GetDateTime(i); + } + + public virtual int GetOrdinal(string name) + { + return dataReader.GetOrdinal(name); + } + + public virtual string GetDataTypeName(int i) + { + return dataReader.GetDataTypeName(i); + } + + public virtual float GetFloat(int i) + { + return dataReader.IsDBNull(i) ? 0 : dataReader.GetFloat(i); + } + + public virtual IDataReader GetData(int i) + { + return dataReader.GetData(i); + } + + public virtual long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + return dataReader.IsDBNull(i) ? 0 : dataReader.GetChars(i, fieldoffset, buffer, bufferoffset, length); + } + + public virtual string GetString(int i) + { + return dataReader.IsDBNull(i) ? string.Empty : dataReader.GetString(i); + } + + public virtual char GetChar(int i) + { + return dataReader.IsDBNull(i) ? char.MinValue : dataReader.GetChar(i); + } + + public virtual short GetInt16(int i) + { + return dataReader.IsDBNull(i) ? (short)0 : dataReader.GetInt16(i); + } + + #endregion + + } +} diff --git a/src/Spring/Spring.Data/Data/Support/ParameterUtils.cs b/src/Spring/Spring.Data/Data/Support/ParameterUtils.cs index 754bf3ea..110ccf89 100644 --- a/src/Spring/Spring.Data/Data/Support/ParameterUtils.cs +++ b/src/Spring/Spring.Data/Data/Support/ParameterUtils.cs @@ -1,174 +1,173 @@ -#region License - -/* - * Copyright © 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Data; -using Common.Logging; -using Spring.Data.Common; - -#endregion - -namespace Spring.Data.Support -{ - /// - /// Miscellaneous utility methods for manipulating parameter objects. - /// - /// Mark Pollack (.NET) - /// $Id: ParameterUtils.cs,v 1.12 2007/10/11 04:41:00 markpollack Exp $ - public class ParameterUtils - { - #region Fields - - #endregion - - #region Constants - - /// - /// The shared log instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (ParameterUtils)); - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public ParameterUtils() - { - - } - - #endregion - - #region Properties - - #endregion - - #region Methods - - - /// - /// Copies the parameters from IDbParameters to the parameter collection in IDbCommand - /// - /// The command. - /// The spring param collection. - public static void CopyParameters(IDbCommand command, IDbParameters springParamCollection) - { - if (springParamCollection != null) - { - IDataParameterCollection collection = springParamCollection.DataParameterCollection; - - foreach (IDbDataParameter parameter in collection) - { - IDbDataParameter pClone = (IDbDataParameter)((ICloneable)parameter).Clone(); - command.Parameters.Add(pClone); - } - } - } - - public static IDataParameter[] CloneParameters(IDbCommand command) - { - IDataParameter[] returnParameters = new IDataParameter[command.Parameters.Count]; - for (int i = 0; i < command.Parameters.Count; i++) - { - IDbDataParameter pClone = (IDbDataParameter)((ICloneable)command.Parameters[i]).Clone(); - returnParameters[i] = pClone; - } - return returnParameters; - } - - - /// - /// Copies the parameters in IDbCommand to IDbParameters - /// - /// The spring param collection. - /// The command. - public static void CopyParameters(IDbParameters springParamCollection, - IDbCommand command) - { - if (springParamCollection != null) - { - IDataParameterCollection cmdParameterCollection = command.Parameters; - //TODO investigate copying only the values over, not a full clone. - int count = 0; - foreach (IDbDataParameter dbDataParameter in cmdParameterCollection) - { - springParamCollection[count] = (IDbDataParameter)((ICloneable)dbDataParameter).Clone();; - count++; - } - } - } - - #endregion - - public static void ExtractOutputParameters(IDictionary returnedParameters, IDbCommand command) - { - if (returnedParameters == null) - { - return; - } - IDataParameterCollection paramCollection = command.Parameters; - int count = 0; - foreach (IDbDataParameter dbDataParameter in paramCollection) - { - if (dbDataParameter.Direction == ParameterDirection.Output - || dbDataParameter.Direction == ParameterDirection.InputOutput) - { - if (dbDataParameter.ParameterName == null) - { - returnedParameters.Add("P" + count, dbDataParameter.Value); - } - else - { - returnedParameters.Add(dbDataParameter.ParameterName, dbDataParameter.Value); - } - } - if (dbDataParameter.Direction == ParameterDirection.ReturnValue) - { - returnedParameters.Add("RETURN_VALUE", dbDataParameter.Value); - } - count++; - } - /* - for (int i = 0; i < declaredParameters.Count; i++) - { - IDataParameter declaredParameter = declaredParameters[i]; - if (declaredParameter.Direction == ParameterDirection.Output - || declaredParameter.Direction == ParameterDirection.InputOutput) - { - IDataParameter outParameter = (IDataParameter)command.Parameters[i]; - if (declaredParameter.ParameterName == null) - { - returnedParameters.Add("P" + i, outParameter.Value); - } - else - { - returnedParameters.Add(outParameter.ParameterName, outParameter.Value); - } - } - }*/ - } - } -} +#region License + +/* + * Copyright © 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Data; +using Common.Logging; +using Spring.Data.Common; + +#endregion + +namespace Spring.Data.Support +{ + /// + /// Miscellaneous utility methods for manipulating parameter objects. + /// + /// Mark Pollack (.NET) + public class ParameterUtils + { + #region Fields + + #endregion + + #region Constants + + /// + /// The shared log instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof (ParameterUtils)); + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public ParameterUtils() + { + + } + + #endregion + + #region Properties + + #endregion + + #region Methods + + + /// + /// Copies the parameters from IDbParameters to the parameter collection in IDbCommand + /// + /// The command. + /// The spring param collection. + public static void CopyParameters(IDbCommand command, IDbParameters springParamCollection) + { + if (springParamCollection != null) + { + IDataParameterCollection collection = springParamCollection.DataParameterCollection; + + foreach (IDbDataParameter parameter in collection) + { + IDbDataParameter pClone = (IDbDataParameter)((ICloneable)parameter).Clone(); + command.Parameters.Add(pClone); + } + } + } + + public static IDataParameter[] CloneParameters(IDbCommand command) + { + IDataParameter[] returnParameters = new IDataParameter[command.Parameters.Count]; + for (int i = 0; i < command.Parameters.Count; i++) + { + IDbDataParameter pClone = (IDbDataParameter)((ICloneable)command.Parameters[i]).Clone(); + returnParameters[i] = pClone; + } + return returnParameters; + } + + + /// + /// Copies the parameters in IDbCommand to IDbParameters + /// + /// The spring param collection. + /// The command. + public static void CopyParameters(IDbParameters springParamCollection, + IDbCommand command) + { + if (springParamCollection != null) + { + IDataParameterCollection cmdParameterCollection = command.Parameters; + //TODO investigate copying only the values over, not a full clone. + int count = 0; + foreach (IDbDataParameter dbDataParameter in cmdParameterCollection) + { + springParamCollection[count] = (IDbDataParameter)((ICloneable)dbDataParameter).Clone();; + count++; + } + } + } + + #endregion + + public static void ExtractOutputParameters(IDictionary returnedParameters, IDbCommand command) + { + if (returnedParameters == null) + { + return; + } + IDataParameterCollection paramCollection = command.Parameters; + int count = 0; + foreach (IDbDataParameter dbDataParameter in paramCollection) + { + if (dbDataParameter.Direction == ParameterDirection.Output + || dbDataParameter.Direction == ParameterDirection.InputOutput) + { + if (dbDataParameter.ParameterName == null) + { + returnedParameters.Add("P" + count, dbDataParameter.Value); + } + else + { + returnedParameters.Add(dbDataParameter.ParameterName, dbDataParameter.Value); + } + } + if (dbDataParameter.Direction == ParameterDirection.ReturnValue) + { + returnedParameters.Add("RETURN_VALUE", dbDataParameter.Value); + } + count++; + } + /* + for (int i = 0; i < declaredParameters.Count; i++) + { + IDataParameter declaredParameter = declaredParameters[i]; + if (declaredParameter.Direction == ParameterDirection.Output + || declaredParameter.Direction == ParameterDirection.InputOutput) + { + IDataParameter outParameter = (IDataParameter)command.Parameters[i]; + if (declaredParameter.ParameterName == null) + { + returnedParameters.Add("P" + i, outParameter.Value); + } + else + { + returnedParameters.Add(outParameter.ParameterName, outParameter.Value); + } + } + }*/ + } + } +} diff --git a/src/Spring/Spring.Data/Data/Support/RowCallbackResultSetExtractor.cs b/src/Spring/Spring.Data/Data/Support/RowCallbackResultSetExtractor.cs index 38bf549c..3ab0698e 100644 --- a/src/Spring/Spring.Data/Data/Support/RowCallbackResultSetExtractor.cs +++ b/src/Spring/Spring.Data/Data/Support/RowCallbackResultSetExtractor.cs @@ -1,88 +1,87 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; -using Spring.Util; - -namespace Spring.Data.Support -{ - /// - /// Adapter to enable use of a IRowCallback inside a ResultSetExtractor. - /// - /// We don't use it for navigating since this could lead to unpredictable consequences. - /// Mark Pollack - /// $Id: RowCallbackResultSetExtractor.cs,v 1.1 2007/07/25 08:27:08 markpollack Exp $ - public class RowCallbackResultSetExtractor : IResultSetExtractor - { - private IRowCallback rowCallback; - - private RowCallbackDelegate rowCallbackDelegate; - - /// - /// Initializes a new instance of the class. - /// - /// The row callback. - public RowCallbackResultSetExtractor(IRowCallback rowCallback) - { - AssertUtils.ArgumentNotNull(rowCallback, "rowCallback"); - this.rowCallback = rowCallback; - } - - /// - /// Initializes a new instance of the class. - /// - /// The row callback delegate. - public RowCallbackResultSetExtractor(RowCallbackDelegate rowCallbackDelegate) - { - AssertUtils.ArgumentNotNull(rowCallbackDelegate, "rowCallbackDelegate"); - this.rowCallbackDelegate = rowCallbackDelegate; - } - - /// - /// All rows of the data reader are passed to the IRowCallback - /// associated with this class. - /// - /// The IDataReader to extract data from. - /// Implementations should not close this: it will be closed - /// by the AdoTemplate. - /// - /// Null is returned since IRowCallback manages its own state. - /// - public object ExtractData(IDataReader reader) - { - if (rowCallback != null) - { - while (reader.Read()) - { - rowCallback.ProcessRow(reader); - } - } - else - { - while (reader.Read()) - { - rowCallbackDelegate(reader); - } - } - - return null; - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; +using Spring.Util; + +namespace Spring.Data.Support +{ + /// + /// Adapter to enable use of a IRowCallback inside a ResultSetExtractor. + /// + /// We don't use it for navigating since this could lead to unpredictable consequences. + /// Mark Pollack + public class RowCallbackResultSetExtractor : IResultSetExtractor + { + private IRowCallback rowCallback; + + private RowCallbackDelegate rowCallbackDelegate; + + /// + /// Initializes a new instance of the class. + /// + /// The row callback. + public RowCallbackResultSetExtractor(IRowCallback rowCallback) + { + AssertUtils.ArgumentNotNull(rowCallback, "rowCallback"); + this.rowCallback = rowCallback; + } + + /// + /// Initializes a new instance of the class. + /// + /// The row callback delegate. + public RowCallbackResultSetExtractor(RowCallbackDelegate rowCallbackDelegate) + { + AssertUtils.ArgumentNotNull(rowCallbackDelegate, "rowCallbackDelegate"); + this.rowCallbackDelegate = rowCallbackDelegate; + } + + /// + /// All rows of the data reader are passed to the IRowCallback + /// associated with this class. + /// + /// The IDataReader to extract data from. + /// Implementations should not close this: it will be closed + /// by the AdoTemplate. + /// + /// Null is returned since IRowCallback manages its own state. + /// + public object ExtractData(IDataReader reader) + { + if (rowCallback != null) + { + while (reader.Read()) + { + rowCallback.ProcessRow(reader); + } + } + else + { + while (reader.Read()) + { + rowCallbackDelegate(reader); + } + } + + return null; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/SimpleServiceConfig.cs b/src/Spring/Spring.Data/Data/Support/SimpleServiceConfig.cs index 3cc11052..826a24be 100644 --- a/src/Spring/Spring.Data/Data/Support/SimpleServiceConfig.cs +++ b/src/Spring/Spring.Data/Data/Support/SimpleServiceConfig.cs @@ -1,127 +1,126 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -using System.EnterpriseServices; - -namespace Spring.Data.Support -{ - /// - /// A class that contains the properties of ServiceConfig used by ServiceDomainPlatformTransactionManager. - /// - /// This is done to enhance testability of the transaction manager since ServiceConfig does not override Equals or Hashcode - /// Mark Pollack (.NET) - /// $Id $ - public class SimpleServiceConfig - { - private string transactionDescription; - private bool trackingEnabled = true; - private string trackingAppName; - private string trackingComponentName; - private TransactionOption transactionOption; - private TransactionIsolationLevel isolationLevel; - private int transactionTimeout; - - - public string TransactionDescription - { - get { return transactionDescription; } - set { transactionDescription = value; } - } - - public bool TrackingEnabled - { - get { return trackingEnabled; } - set { trackingEnabled = value; } - } - - public string TrackingAppName - { - get { return trackingAppName; } - set { trackingAppName = value; } - } - - public string TrackingComponentName - { - get { return trackingComponentName; } - set { trackingComponentName = value; } - } - - public TransactionOption TransactionOption - { - get { return transactionOption; } - set { transactionOption = value; } - } - - public TransactionIsolationLevel IsolationLevel - { - get { return isolationLevel; } - set { isolationLevel = value; } - } - - public int TransactionTimeout - { - get { return transactionTimeout; } - set { transactionTimeout = value; } - } - - public ServiceConfig CreateServiceConfig() - { - ServiceConfig serviceConfig = new ServiceConfig(); - serviceConfig.TransactionDescription = this.transactionDescription; - serviceConfig.TrackingEnabled = this.trackingEnabled; - serviceConfig.TrackingAppName = this.trackingAppName; - serviceConfig.TrackingComponentName = this.trackingComponentName; - serviceConfig.Transaction = this.transactionOption; - serviceConfig.IsolationLevel = this.isolationLevel; - serviceConfig.TransactionTimeout = this.transactionTimeout; - return serviceConfig; - } - - public override bool Equals(object obj) - { - if (this == obj) return true; - SimpleServiceConfig simpleServiceConfig = obj as SimpleServiceConfig; - if (simpleServiceConfig == null) return false; - if (!Equals(transactionDescription, simpleServiceConfig.transactionDescription)) return false; - if (!Equals(trackingEnabled, simpleServiceConfig.trackingEnabled)) return false; - if (!Equals(trackingAppName, simpleServiceConfig.trackingAppName)) return false; - if (!Equals(trackingComponentName, simpleServiceConfig.trackingComponentName)) return false; - if (!Equals(transactionOption, simpleServiceConfig.transactionOption)) return false; - if (!Equals(isolationLevel, simpleServiceConfig.isolationLevel)) return false; - if (transactionTimeout != simpleServiceConfig.transactionTimeout) return false; - return true; - } - - public override int GetHashCode() - { - int result = transactionDescription != null ? transactionDescription.GetHashCode() : 0; - result = 29*result + trackingEnabled.GetHashCode(); - result = 29*result + (trackingAppName != null ? trackingAppName.GetHashCode() : 0); - result = 29*result + (trackingComponentName != null ? trackingComponentName.GetHashCode() : 0); - result = 29*result + transactionOption.GetHashCode(); - result = 29*result + isolationLevel.GetHashCode(); - result = 29*result + transactionTimeout; - return result; - } - } -} +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +using System.EnterpriseServices; + +namespace Spring.Data.Support +{ + /// + /// A class that contains the properties of ServiceConfig used by ServiceDomainPlatformTransactionManager. + /// + /// This is done to enhance testability of the transaction manager since ServiceConfig does not override Equals or Hashcode + /// Mark Pollack (.NET) + public class SimpleServiceConfig + { + private string transactionDescription; + private bool trackingEnabled = true; + private string trackingAppName; + private string trackingComponentName; + private TransactionOption transactionOption; + private TransactionIsolationLevel isolationLevel; + private int transactionTimeout; + + + public string TransactionDescription + { + get { return transactionDescription; } + set { transactionDescription = value; } + } + + public bool TrackingEnabled + { + get { return trackingEnabled; } + set { trackingEnabled = value; } + } + + public string TrackingAppName + { + get { return trackingAppName; } + set { trackingAppName = value; } + } + + public string TrackingComponentName + { + get { return trackingComponentName; } + set { trackingComponentName = value; } + } + + public TransactionOption TransactionOption + { + get { return transactionOption; } + set { transactionOption = value; } + } + + public TransactionIsolationLevel IsolationLevel + { + get { return isolationLevel; } + set { isolationLevel = value; } + } + + public int TransactionTimeout + { + get { return transactionTimeout; } + set { transactionTimeout = value; } + } + + public ServiceConfig CreateServiceConfig() + { + ServiceConfig serviceConfig = new ServiceConfig(); + serviceConfig.TransactionDescription = this.transactionDescription; + serviceConfig.TrackingEnabled = this.trackingEnabled; + serviceConfig.TrackingAppName = this.trackingAppName; + serviceConfig.TrackingComponentName = this.trackingComponentName; + serviceConfig.Transaction = this.transactionOption; + serviceConfig.IsolationLevel = this.isolationLevel; + serviceConfig.TransactionTimeout = this.transactionTimeout; + return serviceConfig; + } + + public override bool Equals(object obj) + { + if (this == obj) return true; + SimpleServiceConfig simpleServiceConfig = obj as SimpleServiceConfig; + if (simpleServiceConfig == null) return false; + if (!Equals(transactionDescription, simpleServiceConfig.transactionDescription)) return false; + if (!Equals(trackingEnabled, simpleServiceConfig.trackingEnabled)) return false; + if (!Equals(trackingAppName, simpleServiceConfig.trackingAppName)) return false; + if (!Equals(trackingComponentName, simpleServiceConfig.trackingComponentName)) return false; + if (!Equals(transactionOption, simpleServiceConfig.transactionOption)) return false; + if (!Equals(isolationLevel, simpleServiceConfig.isolationLevel)) return false; + if (transactionTimeout != simpleServiceConfig.transactionTimeout) return false; + return true; + } + + public override int GetHashCode() + { + int result = transactionDescription != null ? transactionDescription.GetHashCode() : 0; + result = 29*result + trackingEnabled.GetHashCode(); + result = 29*result + (trackingAppName != null ? trackingAppName.GetHashCode() : 0); + result = 29*result + (trackingComponentName != null ? trackingComponentName.GetHashCode() : 0); + result = 29*result + transactionOption.GetHashCode(); + result = 29*result + isolationLevel.GetHashCode(); + result = 29*result + transactionTimeout; + return result; + } + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/TypedDataSetUtils.cs b/src/Spring/Spring.Data/Data/Support/TypedDataSetUtils.cs index 72224ed4..78240606 100644 --- a/src/Spring/Spring.Data/Data/Support/TypedDataSetUtils.cs +++ b/src/Spring/Spring.Data/Data/Support/TypedDataSetUtils.cs @@ -1,170 +1,169 @@ -#if NET_2_0 - -#region License - -/* - * Copyright 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; -using System.Reflection; -using Common.Logging; -using Spring.Data.Common; - -namespace Spring.Data.Support -{ - /// - /// Using reflection on VS.NET 2005 a generated typed dataset, apply the - /// connection/transaction pair associated with the current Spring based - /// transaction scope. - /// - /// This avoids the limitations of using System.Transaction - /// based transaction scope for multiple operation on typed datasets withone one - /// transaction. Reflection was used rather than partial classes to provide - /// a general solution that can be written and applied once. - /// Usage within a DAO method, FindAll() is shown below. Note: Convenience methods - /// to simplify calling syntax maybe provided in the future, it is a trade off on type - /// safety calling the typed adapter defined outside the anonymous method as - /// compared to casting inside a "DoInDbAdapter(object dbAdapter) method. - /// - /// public PrintGroupMappingDataSet FindAll() - /// { - /// - /// PrintGroupMappingTableAdapter adapter = new PrintGroupMappingTableAdapter(); - /// PrintGroupMappingDataSet printGroupMappingDataSet = new PrintGroupMappingDataSet(); - /// - /// - /// printGroupMappingDataSet = AdoTemplate.Execute(delegate(IDbCommand command) - /// { - /// TypedDataSetUtils.ApplyConnectionAndTx(adapter, command); - /// adapter.Fill(printGroupMappingDataSet.PrintGroupMapping); - /// return printGroupMappingDataSet; - /// }) - /// as PrintGroupMappingDataSet; - /// - /// return printGroupMappingDataSet; - /// } - /// - /// See http://www.code-magazine.com/articleprint.aspx?quickid=0605031 for a - /// more complete discussion. - /// - /// - /// $Id: - public abstract class TypedDataSetUtils - { - private static readonly ILog LOG = LogManager.GetLogger(typeof (TypedDataSetUtils)); - - - /// - /// Applies the connection and tx to the provided typed dataset. The connection and transaction - /// used are taken from the Spring's current transactional context. See ConnectionUtils.GetConnectionTxPair - /// for more information - /// - /// The typed data set adapter. - /// The db provider. - public static void ApplyConnectionAndTx(object typedDataSetAdapter, IDbProvider dbProvider) - { - ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(dbProvider); - ApplyConnectionAndTxToDataAdapter(typedDataSetAdapter, connectionTxPairToUse.Connection, connectionTxPairToUse.Transaction); - } - - /// - /// Applies the connection and tx to the provided typed dataset. - /// - /// Generated dataset to not inherit from a common base - /// class so that we must pass in the generic object type. - /// The typed data set adapter. - /// The IDbCommand managed by Spring and set with - /// the connection/transaction of the current Spring transaction scope. - public static void ApplyConnectionAndTx(object typedDataSetAdapter, IDbCommand sourceCommand) - { - if (sourceCommand != null) - { - ApplyConnectionAndTxToDataAdapter(typedDataSetAdapter, sourceCommand.Connection, sourceCommand.Transaction); - } - } - - private static IDbCommand[] GetCommandCollection(object typedDataSetAdapter) - { - PropertyInfo pi = - typedDataSetAdapter.GetType().GetProperty("CommandCollection", - BindingFlags.NonPublic | BindingFlags.Instance); - MethodInfo mi = pi.GetGetMethod(true); - return mi.Invoke(typedDataSetAdapter, null) as IDbCommand[]; - } - - private static IDbDataAdapter GetDataAdapter(object typedDataSetAdapter) - { - PropertyInfo api = - typedDataSetAdapter.GetType().GetProperty("Adapter", - BindingFlags.NonPublic | BindingFlags.Instance); - MethodInfo ami = api.GetGetMethod(true); - return ami.Invoke(typedDataSetAdapter, null) as IDbDataAdapter; - } - - private static void ApplyConnectionAndTxToDataAdapter(object typedDataSetAdapter, IDbConnection connection, IDbTransaction transaction) - { - IDbDataAdapter dataAdapter = GetDataAdapter(typedDataSetAdapter); - if (dataAdapter != null) - { - ApplyConnectionAndTxToCommand(dataAdapter.SelectCommand, connection, transaction); - - - ApplyConnectionAndTxToCommand(dataAdapter.InsertCommand, connection, transaction); - - - ApplyConnectionAndTxToCommand(dataAdapter.UpdateCommand, connection, transaction); - - - ApplyConnectionAndTxToCommand(dataAdapter.DeleteCommand, connection, transaction); - } - else - { - LOG.Warn("Could not extract IDbDataAdapter from TypedDataset."); - } - - - IDbCommand[] commandCollection = GetCommandCollection(typedDataSetAdapter); - if (commandCollection != null) - { - //don't know which one to set, so set them all. - foreach (IDbCommand dbCommand in commandCollection) - { - dbCommand.Connection = connection; - dbCommand.Transaction = transaction; - } - } - else - { - LOG.Warn("Could not extract IDbCommand collection from TypedDataset."); - } - } - - - private static void ApplyConnectionAndTxToCommand(IDbCommand targetDbCommand, IDbConnection connection, IDbTransaction transaction) - { - if (targetDbCommand != null) - { - targetDbCommand.Connection = connection; - targetDbCommand.Transaction = transaction; - } - } - - - } -} +#if NET_2_0 + +#region License + +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; +using System.Reflection; +using Common.Logging; +using Spring.Data.Common; + +namespace Spring.Data.Support +{ + /// + /// Using reflection on VS.NET 2005 a generated typed dataset, apply the + /// connection/transaction pair associated with the current Spring based + /// transaction scope. + /// + /// This avoids the limitations of using System.Transaction + /// based transaction scope for multiple operation on typed datasets withone one + /// transaction. Reflection was used rather than partial classes to provide + /// a general solution that can be written and applied once. + /// Usage within a DAO method, FindAll() is shown below. Note: Convenience methods + /// to simplify calling syntax maybe provided in the future, it is a trade off on type + /// safety calling the typed adapter defined outside the anonymous method as + /// compared to casting inside a "DoInDbAdapter(object dbAdapter) method. + /// + /// public PrintGroupMappingDataSet FindAll() + /// { + /// + /// PrintGroupMappingTableAdapter adapter = new PrintGroupMappingTableAdapter(); + /// PrintGroupMappingDataSet printGroupMappingDataSet = new PrintGroupMappingDataSet(); + /// + /// + /// printGroupMappingDataSet = AdoTemplate.Execute(delegate(IDbCommand command) + /// { + /// TypedDataSetUtils.ApplyConnectionAndTx(adapter, command); + /// adapter.Fill(printGroupMappingDataSet.PrintGroupMapping); + /// return printGroupMappingDataSet; + /// }) + /// as PrintGroupMappingDataSet; + /// + /// return printGroupMappingDataSet; + /// } + /// + /// See http://www.code-magazine.com/articleprint.aspx?quickid=0605031 for a + /// more complete discussion. + /// + /// + public abstract class TypedDataSetUtils + { + private static readonly ILog LOG = LogManager.GetLogger(typeof (TypedDataSetUtils)); + + + /// + /// Applies the connection and tx to the provided typed dataset. The connection and transaction + /// used are taken from the Spring's current transactional context. See ConnectionUtils.GetConnectionTxPair + /// for more information + /// + /// The typed data set adapter. + /// The db provider. + public static void ApplyConnectionAndTx(object typedDataSetAdapter, IDbProvider dbProvider) + { + ConnectionTxPair connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(dbProvider); + ApplyConnectionAndTxToDataAdapter(typedDataSetAdapter, connectionTxPairToUse.Connection, connectionTxPairToUse.Transaction); + } + + /// + /// Applies the connection and tx to the provided typed dataset. + /// + /// Generated dataset to not inherit from a common base + /// class so that we must pass in the generic object type. + /// The typed data set adapter. + /// The IDbCommand managed by Spring and set with + /// the connection/transaction of the current Spring transaction scope. + public static void ApplyConnectionAndTx(object typedDataSetAdapter, IDbCommand sourceCommand) + { + if (sourceCommand != null) + { + ApplyConnectionAndTxToDataAdapter(typedDataSetAdapter, sourceCommand.Connection, sourceCommand.Transaction); + } + } + + private static IDbCommand[] GetCommandCollection(object typedDataSetAdapter) + { + PropertyInfo pi = + typedDataSetAdapter.GetType().GetProperty("CommandCollection", + BindingFlags.NonPublic | BindingFlags.Instance); + MethodInfo mi = pi.GetGetMethod(true); + return mi.Invoke(typedDataSetAdapter, null) as IDbCommand[]; + } + + private static IDbDataAdapter GetDataAdapter(object typedDataSetAdapter) + { + PropertyInfo api = + typedDataSetAdapter.GetType().GetProperty("Adapter", + BindingFlags.NonPublic | BindingFlags.Instance); + MethodInfo ami = api.GetGetMethod(true); + return ami.Invoke(typedDataSetAdapter, null) as IDbDataAdapter; + } + + private static void ApplyConnectionAndTxToDataAdapter(object typedDataSetAdapter, IDbConnection connection, IDbTransaction transaction) + { + IDbDataAdapter dataAdapter = GetDataAdapter(typedDataSetAdapter); + if (dataAdapter != null) + { + ApplyConnectionAndTxToCommand(dataAdapter.SelectCommand, connection, transaction); + + + ApplyConnectionAndTxToCommand(dataAdapter.InsertCommand, connection, transaction); + + + ApplyConnectionAndTxToCommand(dataAdapter.UpdateCommand, connection, transaction); + + + ApplyConnectionAndTxToCommand(dataAdapter.DeleteCommand, connection, transaction); + } + else + { + LOG.Warn("Could not extract IDbDataAdapter from TypedDataset."); + } + + + IDbCommand[] commandCollection = GetCommandCollection(typedDataSetAdapter); + if (commandCollection != null) + { + //don't know which one to set, so set them all. + foreach (IDbCommand dbCommand in commandCollection) + { + dbCommand.Connection = connection; + dbCommand.Transaction = transaction; + } + } + else + { + LOG.Warn("Could not extract IDbCommand collection from TypedDataset."); + } + } + + + private static void ApplyConnectionAndTxToCommand(IDbCommand targetDbCommand, IDbConnection connection, IDbTransaction transaction) + { + if (targetDbCommand != null) + { + targetDbCommand.Connection = connection; + targetDbCommand.Transaction = transaction; + } + } + + + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/UncategorizedAdoException.cs b/src/Spring/Spring.Data/Data/UncategorizedAdoException.cs index 62a3711f..1c8d3845 100644 --- a/src/Spring/Spring.Data/Data/UncategorizedAdoException.cs +++ b/src/Spring/Spring.Data/Data/UncategorizedAdoException.cs @@ -1,136 +1,135 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Serialization; -using Spring.Dao; - -#endregion - -namespace Spring.Data -{ - /// - /// Exception thrown when we can't classify a SQLException into - /// one of our generic data access exceptions. - /// - /// Mark Pollack (.NET) - /// $Id: UncategorizedAdoException.cs,v 1.4 2006/11/29 07:18:46 markpollack Exp $ - [Serializable] - public class UncategorizedAdoException : UncategorizedDataAccessException, ISerializable - { - #region Fields - - /// - /// SQL that led to the problem - /// - private readonly string sql; - - /// - /// The error code, if available, that was unable to be categorized. - /// - private readonly string errorCode; - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public UncategorizedAdoException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - public UncategorizedAdoException(string message): base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A message about the exception. - /// The inner exception. - public UncategorizedAdoException(string message, Exception inner): base(message, inner) - { - } - - - /// - /// Initializes a new instance of the class. - /// - /// name of the current task. - /// the underlying error code that could not be translated - /// The offending SQL statment - /// The root cause. - public UncategorizedAdoException(string task, string sql, string errorCode, Exception ex) : base(task + "; uncategorized DataException for SQL [" + sql + "]; " + "ErrorCode [" + errorCode + "]; " + ex.Message, ex) - { - this.sql = sql; - this.errorCode = errorCode; - } - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected UncategorizedAdoException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} - - - - #endregion - - #region Properties - - #endregion - - #region Methods - - #endregion - - #region ISerializable Members - - /// - /// When overridden in a derived class, sets the - /// with information about the exception. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is a null reference ( in Visual Basic). - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "sql", sql ); - info.AddValue( "errorCode", errorCode); - base.GetObjectData( info, context ); - } - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Serialization; +using Spring.Dao; + +#endregion + +namespace Spring.Data +{ + /// + /// Exception thrown when we can't classify a SQLException into + /// one of our generic data access exceptions. + /// + /// Mark Pollack (.NET) + [Serializable] + public class UncategorizedAdoException : UncategorizedDataAccessException, ISerializable + { + #region Fields + + /// + /// SQL that led to the problem + /// + private readonly string sql; + + /// + /// The error code, if available, that was unable to be categorized. + /// + private readonly string errorCode; + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public UncategorizedAdoException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + public UncategorizedAdoException(string message): base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A message about the exception. + /// The inner exception. + public UncategorizedAdoException(string message, Exception inner): base(message, inner) + { + } + + + /// + /// Initializes a new instance of the class. + /// + /// name of the current task. + /// the underlying error code that could not be translated + /// The offending SQL statment + /// The root cause. + public UncategorizedAdoException(string task, string sql, string errorCode, Exception ex) : base(task + "; uncategorized DataException for SQL [" + sql + "]; " + "ErrorCode [" + errorCode + "]; " + ex.Message, ex) + { + this.sql = sql; + this.errorCode = errorCode; + } + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected UncategorizedAdoException( SerializationInfo info, StreamingContext context ) : base( info, context ) {} + + + + #endregion + + #region Properties + + #endregion + + #region Methods + + #endregion + + #region ISerializable Members + + /// + /// When overridden in a derived class, sets the + /// with information about the exception. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is a null reference ( in Visual Basic). + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "sql", sql ); + info.AddValue( "errorCode", errorCode); + base.GetObjectData( info, context ); + } + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Transaction/CannotCreateTransactionException.cs b/src/Spring/Spring.Data/Transaction/CannotCreateTransactionException.cs index 87102da0..c1f725c2 100644 --- a/src/Spring/Spring.Data/Transaction/CannotCreateTransactionException.cs +++ b/src/Spring/Spring.Data/Transaction/CannotCreateTransactionException.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception thrown when a transaction can't be created using an - /// underlying transaction API such as COM+. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: CannotCreateTransactionException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class CannotCreateTransactionException : TransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public CannotCreateTransactionException() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public CannotCreateTransactionException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public CannotCreateTransactionException( string message, Exception rootCause) - : base( message , rootCause ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected CannotCreateTransactionException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception thrown when a transaction can't be created using an + /// underlying transaction API such as COM+. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class CannotCreateTransactionException : TransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public CannotCreateTransactionException() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public CannotCreateTransactionException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public CannotCreateTransactionException( string message, Exception rootCause) + : base( message , rootCause ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected CannotCreateTransactionException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Config/AttributeDrivenObjectDefinitionParser.cs b/src/Spring/Spring.Data/Transaction/Config/AttributeDrivenObjectDefinitionParser.cs index b008dcf5..440d6576 100644 --- a/src/Spring/Spring.Data/Transaction/Config/AttributeDrivenObjectDefinitionParser.cs +++ b/src/Spring/Spring.Data/Transaction/Config/AttributeDrivenObjectDefinitionParser.cs @@ -1,120 +1,120 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Xml; -using Spring.Aop.Config; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Transaction.Interceptor; - -namespace Spring.Transaction.Config -{ - /// - /// IObjectDefinitionParser implementation that allows users to easily configure all the - /// infrastructure objects required to enable attribute-driven transction demarcation. - /// - /// Rob Harrop - /// Juergen Hoeller - /// Mark Pollack (.NET) - public class AttributeDrivenObjectDefinitionParser : AbstractObjectDefinitionParser - { - /// - /// Object property name for injection the TransactionInterceptor - /// - private static readonly string TRANSACTION_INTERCEPTOR = "transactionInterceptor"; - - /// - /// The 'proxy-target-type' attribute - /// - private static readonly string PROXY_TARGET_TYPE = "proxy-target-type"; - - /// - /// The 'order' property/attribute - /// - private static readonly string ORDER = "order"; - - /// - /// Central template method to actually parse the supplied XmlElement - /// into one or more IObjectDefinitions. - /// - /// The element that is to be parsed into one or more s - /// The the object encapsulating the current state of the parsing process; - /// provides access to a - /// - /// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement - /// - protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext) - { - ConfigureAutoProxyCreator(parserContext, element); - - string transactionManagerName = element.GetAttribute(TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE); - Type sourceType = typeof (AttributesTransactionAttributeSource); - - //Create the TransactionInterceptor definition. - RootObjectDefinition interceptorDefinition = new RootObjectDefinition(typeof (TransactionInterceptor)); - interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY, - new RuntimeObjectReference(transactionManagerName)); - interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE, - new RootObjectDefinition(sourceType)); - - //Create the TransactionAttributeSourceAdvisor definition. - RootObjectDefinition advisorDefinition = new RootObjectDefinition(typeof (TransactionAttributeSourceAdvisor)); - advisorDefinition.PropertyValues.Add(TRANSACTION_INTERCEPTOR, interceptorDefinition); - if (element.HasAttribute(ORDER)) - { - advisorDefinition.PropertyValues.Add(ORDER, element.GetAttribute(ORDER)); - } - - return advisorDefinition; - } - - /// - /// Configures the auto proxy creator. - /// - /// The parser context. - /// The element. - private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element) - { - AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element); - - bool proxyTargetClass = - parserContext.ParserHelper.IsTrueStringValue(element.GetAttribute(PROXY_TARGET_TYPE)); - if (proxyTargetClass) - { - AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry); - } - } - - /// - /// Gets a value indicating whether an ID should be generated instead of read - /// from the passed in XmlElement. - /// - /// true if should generate id; otherwise, false. - /// Note that this flag is about always generating an ID; the parser - /// won't even check for an "id" attribute in this case. - /// - protected override bool ShouldGenerateId - { - get { return true; } - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Xml; +using Spring.Aop.Config; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Transaction.Interceptor; + +namespace Spring.Transaction.Config +{ + /// + /// IObjectDefinitionParser implementation that allows users to easily configure all the + /// infrastructure objects required to enable attribute-driven transction demarcation. + /// + /// Rob Harrop + /// Juergen Hoeller + /// Mark Pollack (.NET) + public class AttributeDrivenObjectDefinitionParser : AbstractObjectDefinitionParser + { + /// + /// Object property name for injection the TransactionInterceptor + /// + private static readonly string TRANSACTION_INTERCEPTOR = "transactionInterceptor"; + + /// + /// The 'proxy-target-type' attribute + /// + private static readonly string PROXY_TARGET_TYPE = "proxy-target-type"; + + /// + /// The 'order' property/attribute + /// + private static readonly string ORDER = "order"; + + /// + /// Central template method to actually parse the supplied XmlElement + /// into one or more IObjectDefinitions. + /// + /// The element that is to be parsed into one or more s + /// The the object encapsulating the current state of the parsing process; + /// provides access to a + /// + /// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement + /// + protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext) + { + ConfigureAutoProxyCreator(parserContext, element); + + string transactionManagerName = element.GetAttribute(TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE); + Type sourceType = typeof (AttributesTransactionAttributeSource); + + //Create the TransactionInterceptor definition. + RootObjectDefinition interceptorDefinition = new RootObjectDefinition(typeof (TransactionInterceptor)); + interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY, + new RuntimeObjectReference(transactionManagerName)); + interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE, + new RootObjectDefinition(sourceType)); + + //Create the TransactionAttributeSourceAdvisor definition. + RootObjectDefinition advisorDefinition = new RootObjectDefinition(typeof (TransactionAttributeSourceAdvisor)); + advisorDefinition.PropertyValues.Add(TRANSACTION_INTERCEPTOR, interceptorDefinition); + if (element.HasAttribute(ORDER)) + { + advisorDefinition.PropertyValues.Add(ORDER, element.GetAttribute(ORDER)); + } + + return advisorDefinition; + } + + /// + /// Configures the auto proxy creator. + /// + /// The parser context. + /// The element. + private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element) + { + AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element); + + bool proxyTargetClass = + parserContext.ParserHelper.IsTrueStringValue(element.GetAttribute(PROXY_TARGET_TYPE)); + if (proxyTargetClass) + { + AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry); + } + } + + /// + /// Gets a value indicating whether an ID should be generated instead of read + /// from the passed in XmlElement. + /// + /// true if should generate id; otherwise, false. + /// Note that this flag is about always generating an ID; the parser + /// won't even check for an "id" attribute in this case. + /// + protected override bool ShouldGenerateId + { + get { return true; } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Config/TxAdviceObjectDefinitionParser.cs b/src/Spring/Spring.Data/Transaction/Config/TxAdviceObjectDefinitionParser.cs index 9ea11c8c..749b4c22 100644 --- a/src/Spring/Spring.Data/Transaction/Config/TxAdviceObjectDefinitionParser.cs +++ b/src/Spring/Spring.Data/Transaction/Config/TxAdviceObjectDefinitionParser.cs @@ -1,177 +1,176 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Data; -using System.Xml; -using Spring.Collections; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Xml; -using Spring.Transaction.Interceptor; -using Spring.Util; - -namespace Spring.Transaction.Config -{ - /// - /// The for the <tx:advice> tag. - /// - /// Rob Harrop - /// Juergen Hoeller - /// Adrian Colyer - /// Mark Pollack (.NET) - /// $Id: TxAdviceObjectDefinitionParser.cs,v 1.2 2007/06/18 10:31:19 bbaia Exp $ - public class TxAdviceObjectDefinitionParser : AbstractSingleObjectDefinitionParser - { - private static string TIMEOUT = "timeout"; - - private static string READ_ONLY = "read-only"; - - private static string NAME_MAP = "nameMap"; - - private static string PROPAGATION = "propagation"; - - private static string ISOLATION = "isolation"; - - private static string ROLLBACK_FOR = "rollback-for"; - - private static string NO_ROLLBACK_FOR = "no-rollback-for"; - - protected override Type GetObjectType(XmlElement element) - { - return typeof (TransactionInterceptor); - } - - protected override void DoParse(XmlElement element, ParserContext parserContext, ObjectDefinitionBuilder builder) - { - - builder.AddPropertyReference(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY, - element.GetAttribute(TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE)); - XmlNodeList txAttributes = element.SelectNodes("*[local-name()='attributes' and namespace-uri()='" + element.NamespaceURI + "']"); - if (txAttributes.Count > 1 ) - { - parserContext.ReaderContext.ReportException(element, "tx advice", "Element is allowed at most once inside element "); - } - else if (txAttributes.Count == 1) - { - //using xml defined source - XmlElement attributeSourceElement = txAttributes[0] as XmlElement; - AbstractObjectDefinition attributeSourceDefinition = - ParseAttributeSource(attributeSourceElement, parserContext); - builder.AddPropertyValue(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE, attributeSourceDefinition); - } - else - { - //Assume attibutes source - ObjectDefinitionBuilder txAttributeSourceBuilder = - parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (AttributesTransactionAttributeSource)); - - builder.AddPropertyValue(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE, - txAttributeSourceBuilder.ObjectDefinition); - - } - } - - private AbstractObjectDefinition ParseAttributeSource(XmlElement element, ParserContext parserContext) - { - XmlNodeList methods = element.SelectNodes("*[local-name()='method' and namespace-uri()='" + element.NamespaceURI + "']"); - ManagedDictionary transactionAttributeMap = new ManagedDictionary(); - foreach (XmlElement methodElement in methods) - { - string name = methodElement.GetAttribute("name"); - TypedStringValue nameHolder = new TypedStringValue(name); - - RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute(); - string propagation = methodElement.GetAttribute(PROPAGATION); - string isolation = methodElement.GetAttribute(ISOLATION); - string timeout = methodElement.GetAttribute(TIMEOUT); - string readOnly = methodElement.GetAttribute(READ_ONLY); - if (StringUtils.HasText(propagation)) - { - attribute.PropagationBehavior = (TransactionPropagation) Enum.Parse(typeof (TransactionPropagation), propagation, true); - } - if (StringUtils.HasText(isolation)) - { - attribute.TransactionIsolationLevel = - (IsolationLevel) Enum.Parse(typeof (IsolationLevel), isolation, true); - } - if (StringUtils.HasText(timeout)) - { - try - { - attribute.TransactionTimeout = Int32.Parse(timeout); - } - catch (FormatException ex) - { - parserContext.ReaderContext.ReportException(methodElement,"tx advice","timeout must be an integer value: [" + timeout + "]", ex); - } - } - if (StringUtils.HasText(readOnly)) - { - attribute.ReadOnly = Boolean.Parse(methodElement.GetAttribute(READ_ONLY)); - } - IList rollbackRules = new LinkedList(); - if (methodElement.HasAttribute(ROLLBACK_FOR)) - { - string rollbackForValue = methodElement.GetAttribute(ROLLBACK_FOR); - AddRollbackRuleAttributesTo(rollbackRules, rollbackForValue); - } - if (methodElement.HasAttribute(NO_ROLLBACK_FOR)) - { - string noRollbackForValue = methodElement.GetAttribute(NO_ROLLBACK_FOR); - AddNoRollbackRuleAttributesTo(rollbackRules, noRollbackForValue); - } - attribute.RollbackRules = rollbackRules; - - transactionAttributeMap[nameHolder] = attribute; - - - - } - - ObjectDefinitionBuilder builder = - parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (NameMatchTransactionAttributeSource)); - builder.AddPropertyValue(NAME_MAP, transactionAttributeMap); - return builder.ObjectDefinition; - - } - - - - private void AddRollbackRuleAttributesTo(IList rollbackRules, string rollbackForValue) - { - string[] exceptionTypeNames = StringUtils.CommaDelimitedListToStringArray(rollbackForValue); - foreach (string exceptionTypeName in exceptionTypeNames) - { - rollbackRules.Add(new RollbackRuleAttribute(exceptionTypeName.Trim())); - } - } - - private void AddNoRollbackRuleAttributesTo(IList rollbackRules, string noRollbackForValue) - { - string[] exceptionTypeNames = StringUtils.CommaDelimitedListToStringArray(noRollbackForValue); - foreach (string exceptionTypeName in exceptionTypeNames) - { - rollbackRules.Add(new NoRollbackRuleAttribute(exceptionTypeName.Trim())); - } - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Data; +using System.Xml; +using Spring.Collections; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Xml; +using Spring.Transaction.Interceptor; +using Spring.Util; + +namespace Spring.Transaction.Config +{ + /// + /// The for the <tx:advice> tag. + /// + /// Rob Harrop + /// Juergen Hoeller + /// Adrian Colyer + /// Mark Pollack (.NET) + public class TxAdviceObjectDefinitionParser : AbstractSingleObjectDefinitionParser + { + private static string TIMEOUT = "timeout"; + + private static string READ_ONLY = "read-only"; + + private static string NAME_MAP = "nameMap"; + + private static string PROPAGATION = "propagation"; + + private static string ISOLATION = "isolation"; + + private static string ROLLBACK_FOR = "rollback-for"; + + private static string NO_ROLLBACK_FOR = "no-rollback-for"; + + protected override Type GetObjectType(XmlElement element) + { + return typeof (TransactionInterceptor); + } + + protected override void DoParse(XmlElement element, ParserContext parserContext, ObjectDefinitionBuilder builder) + { + + builder.AddPropertyReference(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY, + element.GetAttribute(TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE)); + XmlNodeList txAttributes = element.SelectNodes("*[local-name()='attributes' and namespace-uri()='" + element.NamespaceURI + "']"); + if (txAttributes.Count > 1 ) + { + parserContext.ReaderContext.ReportException(element, "tx advice", "Element is allowed at most once inside element "); + } + else if (txAttributes.Count == 1) + { + //using xml defined source + XmlElement attributeSourceElement = txAttributes[0] as XmlElement; + AbstractObjectDefinition attributeSourceDefinition = + ParseAttributeSource(attributeSourceElement, parserContext); + builder.AddPropertyValue(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE, attributeSourceDefinition); + } + else + { + //Assume attibutes source + ObjectDefinitionBuilder txAttributeSourceBuilder = + parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (AttributesTransactionAttributeSource)); + + builder.AddPropertyValue(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE, + txAttributeSourceBuilder.ObjectDefinition); + + } + } + + private AbstractObjectDefinition ParseAttributeSource(XmlElement element, ParserContext parserContext) + { + XmlNodeList methods = element.SelectNodes("*[local-name()='method' and namespace-uri()='" + element.NamespaceURI + "']"); + ManagedDictionary transactionAttributeMap = new ManagedDictionary(); + foreach (XmlElement methodElement in methods) + { + string name = methodElement.GetAttribute("name"); + TypedStringValue nameHolder = new TypedStringValue(name); + + RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute(); + string propagation = methodElement.GetAttribute(PROPAGATION); + string isolation = methodElement.GetAttribute(ISOLATION); + string timeout = methodElement.GetAttribute(TIMEOUT); + string readOnly = methodElement.GetAttribute(READ_ONLY); + if (StringUtils.HasText(propagation)) + { + attribute.PropagationBehavior = (TransactionPropagation) Enum.Parse(typeof (TransactionPropagation), propagation, true); + } + if (StringUtils.HasText(isolation)) + { + attribute.TransactionIsolationLevel = + (IsolationLevel) Enum.Parse(typeof (IsolationLevel), isolation, true); + } + if (StringUtils.HasText(timeout)) + { + try + { + attribute.TransactionTimeout = Int32.Parse(timeout); + } + catch (FormatException ex) + { + parserContext.ReaderContext.ReportException(methodElement,"tx advice","timeout must be an integer value: [" + timeout + "]", ex); + } + } + if (StringUtils.HasText(readOnly)) + { + attribute.ReadOnly = Boolean.Parse(methodElement.GetAttribute(READ_ONLY)); + } + IList rollbackRules = new LinkedList(); + if (methodElement.HasAttribute(ROLLBACK_FOR)) + { + string rollbackForValue = methodElement.GetAttribute(ROLLBACK_FOR); + AddRollbackRuleAttributesTo(rollbackRules, rollbackForValue); + } + if (methodElement.HasAttribute(NO_ROLLBACK_FOR)) + { + string noRollbackForValue = methodElement.GetAttribute(NO_ROLLBACK_FOR); + AddNoRollbackRuleAttributesTo(rollbackRules, noRollbackForValue); + } + attribute.RollbackRules = rollbackRules; + + transactionAttributeMap[nameHolder] = attribute; + + + + } + + ObjectDefinitionBuilder builder = + parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (NameMatchTransactionAttributeSource)); + builder.AddPropertyValue(NAME_MAP, transactionAttributeMap); + return builder.ObjectDefinition; + + } + + + + private void AddRollbackRuleAttributesTo(IList rollbackRules, string rollbackForValue) + { + string[] exceptionTypeNames = StringUtils.CommaDelimitedListToStringArray(rollbackForValue); + foreach (string exceptionTypeName in exceptionTypeNames) + { + rollbackRules.Add(new RollbackRuleAttribute(exceptionTypeName.Trim())); + } + } + + private void AddNoRollbackRuleAttributesTo(IList rollbackRules, string noRollbackForValue) + { + string[] exceptionTypeNames = StringUtils.CommaDelimitedListToStringArray(noRollbackForValue); + foreach (string exceptionTypeName in exceptionTypeNames) + { + rollbackRules.Add(new NoRollbackRuleAttribute(exceptionTypeName.Trim())); + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Config/TxNamespaceParser.cs b/src/Spring/Spring.Data/Transaction/Config/TxNamespaceParser.cs index 12061aae..18ef7dfd 100644 --- a/src/Spring/Spring.Data/Transaction/Config/TxNamespaceParser.cs +++ b/src/Spring/Spring.Data/Transaction/Config/TxNamespaceParser.cs @@ -1,59 +1,59 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - - -using Spring.Objects.Factory.Xml; - -namespace Spring.Transaction.Config -{ - /// - /// NamespaceParser allowing for the configuration of - /// declarative transaction management using either XML or using attributes. - /// - /// This namespace handler is the central piece of functionality in the - /// Spring transaction management facilities and offers two appraoches - /// to declaratively manage transactions. - /// - /// One approach uses transaction semantics defined in XML using the - /// <tx:advice> elements, the other uses attributes - /// in combination with the <tx:annotation-driven> element. - /// Both approached are detailed in the Spring reference manual. - /// - [ - NamespaceParser( - Namespace = "http://www.springframework.net/tx", - SchemaLocationAssemblyHint = typeof(TxNamespaceParser), - SchemaLocation = "/Spring.Transaction.Config/spring-tx-1.1.xsd" - ) - ] - public class TxNamespaceParser : NamespaceParserSupport - { - /// - /// Register the for the 'advice' and - /// 'attribute-driven' tags. - /// - public override void Init() - { - RegisterObjectDefinitionParser("advice", new TxAdviceObjectDefinitionParser()); - RegisterObjectDefinitionParser("attribute-driven", new AttributeDrivenObjectDefinitionParser()); - - } - } -} +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + + +using Spring.Objects.Factory.Xml; + +namespace Spring.Transaction.Config +{ + /// + /// NamespaceParser allowing for the configuration of + /// declarative transaction management using either XML or using attributes. + /// + /// This namespace handler is the central piece of functionality in the + /// Spring transaction management facilities and offers two appraoches + /// to declaratively manage transactions. + /// + /// One approach uses transaction semantics defined in XML using the + /// <tx:advice> elements, the other uses attributes + /// in combination with the <tx:annotation-driven> element. + /// Both approached are detailed in the Spring reference manual. + /// + [ + NamespaceParser( + Namespace = "http://www.springframework.net/tx", + SchemaLocationAssemblyHint = typeof(TxNamespaceParser), + SchemaLocation = "/Spring.Transaction.Config/spring-tx-1.1.xsd" + ) + ] + public class TxNamespaceParser : NamespaceParserSupport + { + /// + /// Register the for the 'advice' and + /// 'attribute-driven' tags. + /// + public override void Init() + { + RegisterObjectDefinitionParser("advice", new TxAdviceObjectDefinitionParser()); + RegisterObjectDefinitionParser("attribute-driven", new AttributeDrivenObjectDefinitionParser()); + + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Config/TxNamespaceUtils.cs b/src/Spring/Spring.Data/Transaction/Config/TxNamespaceUtils.cs index f1bfa4e1..a9a57385 100644 --- a/src/Spring/Spring.Data/Transaction/Config/TxNamespaceUtils.cs +++ b/src/Spring/Spring.Data/Transaction/Config/TxNamespaceUtils.cs @@ -1,52 +1,51 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Core; -using Spring.Transaction.Interceptor; - -namespace Spring.Transaction.Config -{ - /// - /// This is a utility class to help in parsing the transaction namespace - /// - /// Mark Pollack - /// $Id: TxNamespaceUtils.cs,v 1.2 2007/12/07 08:10:03 markpollack Exp $ - public sealed class TxNamespaceUtils - { - /// - /// The transaction manager attribute - /// - public const string TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager"; - - /// - /// The source of transaction metadata - /// - public const string TRANSACTION_ATTRIBUTE_SOURCE = "transactionAttributeSource"; - - /// - /// The property asociated with the transaction manager xml element - /// - public static readonly string TRANSACTION_MANAGER_PROPERTY = - Conventions.AttributeNameToPropertyName(TRANSACTION_MANAGER_ATTRIBUTE); - - - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Core; +using Spring.Transaction.Interceptor; + +namespace Spring.Transaction.Config +{ + /// + /// This is a utility class to help in parsing the transaction namespace + /// + /// Mark Pollack + public sealed class TxNamespaceUtils + { + /// + /// The transaction manager attribute + /// + public const string TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager"; + + /// + /// The source of transaction metadata + /// + public const string TRANSACTION_ATTRIBUTE_SOURCE = "transactionAttributeSource"; + + /// + /// The property asociated with the transaction manager xml element + /// + public static readonly string TRANSACTION_MANAGER_PROPERTY = + Conventions.AttributeNameToPropertyName(TRANSACTION_MANAGER_ATTRIBUTE); + + + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/HeuristicCompletionException.cs b/src/Spring/Spring.Data/Transaction/HeuristicCompletionException.cs index ca775a16..7c901b39 100644 --- a/src/Spring/Spring.Data/Transaction/HeuristicCompletionException.cs +++ b/src/Spring/Spring.Data/Transaction/HeuristicCompletionException.cs @@ -1,147 +1,146 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception that represents a transaction failure caused by heuristics. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: HeuristicCompletionException.cs,v 1.6 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class HeuristicCompletionException : TransactionException, ISerializable - { - /// - /// The outcome state of the transaction: have some or all resources been committed? - /// - private TransactionOutcomeState _outcomeState = TransactionOutcomeState.Unknown; - - /// - /// Returns the transaction's outcome state. - /// - public TransactionOutcomeState OutcomeState - { - get { return _outcomeState; } - } - - /// - /// Returns a representation of the supplied - /// . - /// - /// - /// The value that - /// is to be stringified. - /// - /// A representation. - public static string GetStateString( TransactionOutcomeState outcomeState ) - { - return Enum.GetName (typeof (TransactionOutcomeState), outcomeState); - } - - /// - /// Creates a new instance of the - /// class. - /// - public HeuristicCompletionException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public HeuristicCompletionException( string message ) : base( message ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public HeuristicCompletionException( string message, Exception rootCause ) - : base( message, rootCause ) {} - - /// - /// Creates a new instance of the - /// class - /// with the specified - /// and inner exception. - /// - /// - /// The - /// for the transaction. - /// - /// - /// The inner exception that is being wrapped. - /// - public HeuristicCompletionException( - TransactionOutcomeState outcomeState, Exception innerException) - : base( "Heuristic completion: outcome state is " + GetStateString(outcomeState), innerException ) - { - _outcomeState = outcomeState; - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected HeuristicCompletionException( SerializationInfo info, StreamingContext context ) - : base( info, context ) - { - _outcomeState = ( TransactionOutcomeState ) info.GetInt32( "outcomeState" ); - } - - /// - /// Override of - /// to allow for private serialization. - /// - /// - /// The - /// that holds the serialized object data about the exception. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "outcomeState", _outcomeState ); - base.GetObjectData (info, context); - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception that represents a transaction failure caused by heuristics. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class HeuristicCompletionException : TransactionException, ISerializable + { + /// + /// The outcome state of the transaction: have some or all resources been committed? + /// + private TransactionOutcomeState _outcomeState = TransactionOutcomeState.Unknown; + + /// + /// Returns the transaction's outcome state. + /// + public TransactionOutcomeState OutcomeState + { + get { return _outcomeState; } + } + + /// + /// Returns a representation of the supplied + /// . + /// + /// + /// The value that + /// is to be stringified. + /// + /// A representation. + public static string GetStateString( TransactionOutcomeState outcomeState ) + { + return Enum.GetName (typeof (TransactionOutcomeState), outcomeState); + } + + /// + /// Creates a new instance of the + /// class. + /// + public HeuristicCompletionException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public HeuristicCompletionException( string message ) : base( message ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public HeuristicCompletionException( string message, Exception rootCause ) + : base( message, rootCause ) {} + + /// + /// Creates a new instance of the + /// class + /// with the specified + /// and inner exception. + /// + /// + /// The + /// for the transaction. + /// + /// + /// The inner exception that is being wrapped. + /// + public HeuristicCompletionException( + TransactionOutcomeState outcomeState, Exception innerException) + : base( "Heuristic completion: outcome state is " + GetStateString(outcomeState), innerException ) + { + _outcomeState = outcomeState; + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected HeuristicCompletionException( SerializationInfo info, StreamingContext context ) + : base( info, context ) + { + _outcomeState = ( TransactionOutcomeState ) info.GetInt32( "outcomeState" ); + } + + /// + /// Override of + /// to allow for private serialization. + /// + /// + /// The + /// that holds the serialized object data about the exception. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "outcomeState", _outcomeState ); + base.GetObjectData (info, context); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/IPlatformTransactionManager.cs b/src/Spring/Spring.Data/Transaction/IPlatformTransactionManager.cs index bf2cf496..fd6c42fd 100644 --- a/src/Spring/Spring.Data/Transaction/IPlatformTransactionManager.cs +++ b/src/Spring/Spring.Data/Transaction/IPlatformTransactionManager.cs @@ -1,110 +1,109 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction -{ - /// - /// This is the central interface in Spring.NET's transaction support. - /// - /// - ///

- /// Applications can use this directly, but it is not primarily meant as an API. - /// Typically, applications will work with either - /// or the AOP transaction - /// interceptor. - ///

- ///

- /// For implementers, - /// is a good starting point. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: IPlatformTransactionManager.cs,v 1.10 2007/08/01 18:53:05 markpollack Exp $ - public interface IPlatformTransactionManager - { - /// - /// Return a currently active transaction or create a new one. - /// - /// - ///

- /// Note that parameters like isolation level or timeout will only be applied - /// to new transactions, and thus be ignored when participating in active ones. - /// Furthermore, they aren't supported by every transaction manager: - /// a proper implementation should throw an exception when custom values - /// that it doesn't support are specified. - ///

- ///
- /// - /// instance (can be null for - /// defaults), describing propagation behavior, isolation level, timeout etc. - /// - /// - /// In case of lookup, creation, or system errors. - /// - /// - /// A representing the new or current transaction. - /// - ITransactionStatus GetTransaction( ITransactionDefinition definition ); - - /// - /// Commit the given transaction, with regard to its status. - /// - /// - ///

- /// If the transaction has been marked rollback-only programmatically, - /// perform a rollback. - ///

- ///

- /// If the transaction wasn't a new one, omit the commit to take part - /// in the surrounding transaction properly. - ///

- ///
- /// - /// The instance returned by the - /// () method. - /// - /// - /// In case of commit or system errors - /// - void Commit( ITransactionStatus transactionStatus ); - - /// - /// Roll back the given transaction, with regard to its status. - /// - /// - ///

- /// If the transaction wasn't a new one, just set it rollback-only - /// to take part in the surrounding transaction properly. - ///

- ///
- /// - /// The instance returned by the - /// () method. - /// - /// - /// In case of system errors. - /// - void Rollback( ITransactionStatus transactionStatus ); - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction +{ + /// + /// This is the central interface in Spring.NET's transaction support. + /// + /// + ///

+ /// Applications can use this directly, but it is not primarily meant as an API. + /// Typically, applications will work with either + /// or the AOP transaction + /// interceptor. + ///

+ ///

+ /// For implementers, + /// is a good starting point. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + public interface IPlatformTransactionManager + { + /// + /// Return a currently active transaction or create a new one. + /// + /// + ///

+ /// Note that parameters like isolation level or timeout will only be applied + /// to new transactions, and thus be ignored when participating in active ones. + /// Furthermore, they aren't supported by every transaction manager: + /// a proper implementation should throw an exception when custom values + /// that it doesn't support are specified. + ///

+ ///
+ /// + /// instance (can be null for + /// defaults), describing propagation behavior, isolation level, timeout etc. + /// + /// + /// In case of lookup, creation, or system errors. + /// + /// + /// A representing the new or current transaction. + /// + ITransactionStatus GetTransaction( ITransactionDefinition definition ); + + /// + /// Commit the given transaction, with regard to its status. + /// + /// + ///

+ /// If the transaction has been marked rollback-only programmatically, + /// perform a rollback. + ///

+ ///

+ /// If the transaction wasn't a new one, omit the commit to take part + /// in the surrounding transaction properly. + ///

+ ///
+ /// + /// The instance returned by the + /// () method. + /// + /// + /// In case of commit or system errors + /// + void Commit( ITransactionStatus transactionStatus ); + + /// + /// Roll back the given transaction, with regard to its status. + /// + /// + ///

+ /// If the transaction wasn't a new one, just set it rollback-only + /// to take part in the surrounding transaction properly. + ///

+ ///
+ /// + /// The instance returned by the + /// () method. + /// + /// + /// In case of system errors. + /// + void Rollback( ITransactionStatus transactionStatus ); + } +} diff --git a/src/Spring/Spring.Data/Transaction/ISavepointManager.cs b/src/Spring/Spring.Data/Transaction/ISavepointManager.cs index 55495ab9..6f7c98f4 100644 --- a/src/Spring/Spring.Data/Transaction/ISavepointManager.cs +++ b/src/Spring/Spring.Data/Transaction/ISavepointManager.cs @@ -1,99 +1,98 @@ -#region License -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ -#endregion - -using System; - -namespace Spring.Transaction -{ - /// - /// Interface that specifies means to programmatically manage - /// transaction savepoints in a generic fashion. - /// - /// - ///

- /// Note that savepoints can only work within an active transaction. - /// Just use this programmatic savepoint handling for advanced needs; - /// else, a subtransaction with a value - /// of is preferable. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: ISavepointManager.cs,v 1.5 2006/05/17 17:48:25 bbaia Exp $ - public interface ISavepointManager - { - /// - /// Create a new savepoint. - /// - /// - /// The name of the savepoint to create. - /// - /// - /// You can roll back to a specific savepoint - /// via , - /// and explicitly release a savepoint that you don't need anymore via - /// . - ///

- /// Note that most transaction managers will automatically release - /// savepoints at transaction completion. - ///

- ///
- /// - /// If the savepoint could not be created, - /// either because the backend does not support it or because the - /// transaction is not in an appropriate state. - /// - /// - /// A savepoint object, to be passed into - /// - /// or . - /// - void CreateSavepoint( string savepointName ); - - /// - /// Roll back to the given savepoint. - /// - /// - /// The savepoint will be automatically released afterwards. - /// - /// The savepoint to roll back to. - /// - /// If the rollback failed. - /// - void RollbackToSavepoint( string savepoint ); - - /// - /// Explicitly release the given savepoint. - /// - /// - ///

- /// Note that most transaction managers will automatically release - /// savepoints at transaction completion. - ///

- ///

- /// Implementations should fail as silently as possible if - /// proper resource cleanup will still happen at transaction completion. - ///

- ///
- /// The savepoint to release. - /// - /// If the release failed. - /// - void ReleaseSavepoint( string savepoint ); - } -} +#region License +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ +#endregion + +using System; + +namespace Spring.Transaction +{ + /// + /// Interface that specifies means to programmatically manage + /// transaction savepoints in a generic fashion. + /// + /// + ///

+ /// Note that savepoints can only work within an active transaction. + /// Just use this programmatic savepoint handling for advanced needs; + /// else, a subtransaction with a value + /// of is preferable. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + public interface ISavepointManager + { + /// + /// Create a new savepoint. + /// + /// + /// The name of the savepoint to create. + /// + /// + /// You can roll back to a specific savepoint + /// via , + /// and explicitly release a savepoint that you don't need anymore via + /// . + ///

+ /// Note that most transaction managers will automatically release + /// savepoints at transaction completion. + ///

+ ///
+ /// + /// If the savepoint could not be created, + /// either because the backend does not support it or because the + /// transaction is not in an appropriate state. + /// + /// + /// A savepoint object, to be passed into + /// + /// or . + /// + void CreateSavepoint( string savepointName ); + + /// + /// Roll back to the given savepoint. + /// + /// + /// The savepoint will be automatically released afterwards. + /// + /// The savepoint to roll back to. + /// + /// If the rollback failed. + /// + void RollbackToSavepoint( string savepoint ); + + /// + /// Explicitly release the given savepoint. + /// + /// + ///

+ /// Note that most transaction managers will automatically release + /// savepoints at transaction completion. + ///

+ ///

+ /// Implementations should fail as silently as possible if + /// proper resource cleanup will still happen at transaction completion. + ///

+ ///
+ /// The savepoint to release. + /// + /// If the release failed. + /// + void ReleaseSavepoint( string savepoint ); + } +} diff --git a/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs b/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs index 3294ad1d..03110c37 100644 --- a/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs +++ b/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs @@ -1,122 +1,121 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System.Data; - -namespace Spring.Transaction -{ - /// - /// Interface for classes that define transaction properties. Base interface for - /// . - /// - /// - ///

- /// Note that isolation level, timeout and read-only settings will only - /// get applied when starting a new transaction. As only - /// and - /// can actually cause that, it doesn't make sense - /// to specify any of those settings else. Furthermore, not all transaction - /// managers will support those features and thus throw respective exceptions - /// when given non-default values. - ///

- ///
- /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: ITransactionDefinition.cs,v 1.9 2007/12/07 08:10:03 markpollack Exp $ - public interface ITransactionDefinition - { - /// - /// Return the propagation behavior of type - /// . - /// - TransactionPropagation PropagationBehavior { get; } - - /// - /// Return the isolation level of type . - /// - /// - ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// Note that a transaction manager that does not support custom isolation levels - /// will throw an exception when given any other level than - /// . - ///

- ///
- IsolationLevel TransactionIsolationLevel { get; } - - /// - /// Return the transaction timeout. - /// - /// - ///

- /// Must return a number of seconds, or -1. - /// Only makes sense in combination with - /// and - /// . - /// Note that a transaction manager that does not support timeouts will - /// throw an exception when given any other timeout than -1. - ///

- ///
- int TransactionTimeout { get; } - - /// - /// Get whether to optimize as read-only transaction. - /// - /// - ///

- /// This just serves as hint for the actual transaction subsystem, - /// it will not necessarily cause failure of write accesses. - ///

- ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// A transaction manager that cannot interpret the read-only hint - /// will not throw an exception when given ReadOnly=true. - ///

- ///
- bool ReadOnly { get; } - - /// - /// Return the name of this transaction. Can be null. - /// - /// - /// This will be used as a transaction name to be shown in a - /// transaction monitor, if applicable. In the case of Spring - /// declarative transactions, the exposed name will be the fully - /// qualified type name + "." method name + assembly (by default). - /// - string Name { get; } - -#if NET_2_0 - /// - /// Gets the enterprise services interop option. - /// - /// The enterprise services interop option. - System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption { get;} -#endif - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System.Data; + +namespace Spring.Transaction +{ + /// + /// Interface for classes that define transaction properties. Base interface for + /// . + /// + /// + ///

+ /// Note that isolation level, timeout and read-only settings will only + /// get applied when starting a new transaction. As only + /// and + /// can actually cause that, it doesn't make sense + /// to specify any of those settings else. Furthermore, not all transaction + /// managers will support those features and thus throw respective exceptions + /// when given non-default values. + ///

+ ///
+ /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public interface ITransactionDefinition + { + /// + /// Return the propagation behavior of type + /// . + /// + TransactionPropagation PropagationBehavior { get; } + + /// + /// Return the isolation level of type . + /// + /// + ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// Note that a transaction manager that does not support custom isolation levels + /// will throw an exception when given any other level than + /// . + ///

+ ///
+ IsolationLevel TransactionIsolationLevel { get; } + + /// + /// Return the transaction timeout. + /// + /// + ///

+ /// Must return a number of seconds, or -1. + /// Only makes sense in combination with + /// and + /// . + /// Note that a transaction manager that does not support timeouts will + /// throw an exception when given any other timeout than -1. + ///

+ ///
+ int TransactionTimeout { get; } + + /// + /// Get whether to optimize as read-only transaction. + /// + /// + ///

+ /// This just serves as hint for the actual transaction subsystem, + /// it will not necessarily cause failure of write accesses. + ///

+ ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// A transaction manager that cannot interpret the read-only hint + /// will not throw an exception when given ReadOnly=true. + ///

+ ///
+ bool ReadOnly { get; } + + /// + /// Return the name of this transaction. Can be null. + /// + /// + /// This will be used as a transaction name to be shown in a + /// transaction monitor, if applicable. In the case of Spring + /// declarative transactions, the exposed name will be the fully + /// qualified type name + "." method name + assembly (by default). + /// + string Name { get; } + +#if NET_2_0 + /// + /// Gets the enterprise services interop option. + /// + /// The enterprise services interop option. + System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption { get;} +#endif + } +} diff --git a/src/Spring/Spring.Data/Transaction/ITransactionStatus.cs b/src/Spring/Spring.Data/Transaction/ITransactionStatus.cs index 58c98a20..dda46ae9 100644 --- a/src/Spring/Spring.Data/Transaction/ITransactionStatus.cs +++ b/src/Spring/Spring.Data/Transaction/ITransactionStatus.cs @@ -1,85 +1,84 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; - -namespace Spring.Transaction -{ - /// - /// Representation of the status of a transaction, - /// consisting of a transaction object and some status flags. - /// - /// - ///

- /// Transactional code can use this to retrieve status information, - /// and to programmatically request a rollback (instead of throwing - /// an exception that causes an implicit rollback). - ///

- ///

- /// Derives from the interface to provide access - /// to savepoint management facilities. Note that savepoint management - /// is just available if the actual transaction manager supports it. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: ITransactionStatus.cs,v 1.11 2007/08/01 18:53:05 markpollack Exp $ - public interface ITransactionStatus : ISavepointManager - { - /// - /// Returns true if the transaction is new, else false if participating - /// in an existing transaction. - /// - bool IsNewTransaction { get; } - - /// - /// Gets / sets if the transaction is rollback-only. - /// - /// - ///

- /// This instructs the transaction manager that the only possible outcome of - /// the transaction may be a rollback, proceeding with the normal application - /// workflow though (i.e. no exception). - ///

- ///

- /// For transactions managed by a - /// or - /// . - /// An alternative way to trigger a rollback is throwing an transaction exception. - ///

- ///
- bool RollbackOnly { get; set; } - - /// - /// Gets the current transaction object. - /// - /// - /// Returns the current transaction object for a given connection. - ///

- /// Used to associate with the property. - ///

- ///
- object Transaction { get; } - - bool Completed { get; } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; + +namespace Spring.Transaction +{ + /// + /// Representation of the status of a transaction, + /// consisting of a transaction object and some status flags. + /// + /// + ///

+ /// Transactional code can use this to retrieve status information, + /// and to programmatically request a rollback (instead of throwing + /// an exception that causes an implicit rollback). + ///

+ ///

+ /// Derives from the interface to provide access + /// to savepoint management facilities. Note that savepoint management + /// is just available if the actual transaction manager supports it. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public interface ITransactionStatus : ISavepointManager + { + /// + /// Returns true if the transaction is new, else false if participating + /// in an existing transaction. + /// + bool IsNewTransaction { get; } + + /// + /// Gets / sets if the transaction is rollback-only. + /// + /// + ///

+ /// This instructs the transaction manager that the only possible outcome of + /// the transaction may be a rollback, proceeding with the normal application + /// workflow though (i.e. no exception). + ///

+ ///

+ /// For transactions managed by a + /// or + /// . + /// An alternative way to trigger a rollback is throwing an transaction exception. + ///

+ ///
+ bool RollbackOnly { get; set; } + + /// + /// Gets the current transaction object. + /// + /// + /// Returns the current transaction object for a given connection. + ///

+ /// Used to associate with the property. + ///

+ ///
+ object Transaction { get; } + + bool Completed { get; } + } +} diff --git a/src/Spring/Spring.Data/Transaction/IllegalTransactionStateException.cs b/src/Spring/Spring.Data/Transaction/IllegalTransactionStateException.cs index 67581711..ee7f2c76 100644 --- a/src/Spring/Spring.Data/Transaction/IllegalTransactionStateException.cs +++ b/src/Spring/Spring.Data/Transaction/IllegalTransactionStateException.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception thrown when the existence or non-existence of a transaction - /// amounts to an illegal state according to the transaction propagation - /// behavior that applies. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: IllegalTransactionStateException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class IllegalTransactionStateException : CannotCreateTransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public IllegalTransactionStateException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public IllegalTransactionStateException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public IllegalTransactionStateException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected IllegalTransactionStateException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception thrown when the existence or non-existence of a transaction + /// amounts to an illegal state according to the transaction propagation + /// behavior that applies. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class IllegalTransactionStateException : CannotCreateTransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public IllegalTransactionStateException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public IllegalTransactionStateException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public IllegalTransactionStateException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected IllegalTransactionStateException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/AbstractFallbackTransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/AbstractFallbackTransactionAttributeSource.cs index 7902fba0..72e64735 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/AbstractFallbackTransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/AbstractFallbackTransactionAttributeSource.cs @@ -1,299 +1,298 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; - -using Spring.Collections; -using Spring.Util; -using Spring.Core; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Abstract implementation of - /// - /// that caches attributes for methods, and implements a default fallback policy. - /// - /// - ///

- /// The default fallback policy applied by this class is: - /// - /// - /// most specific method - /// - /// - /// target class attribute - /// - /// - /// declaring method - /// - /// - /// declaring class - /// - /// - ///

- ///

- /// Defaults to using class's transaction attribute if none is associated - /// with the target method. Any transaction attribute associated with the - /// target method completely overrides a class transaction attribute. - ///

- ///

- /// This implementation caches attributes by method after they are first used. - /// If it's ever desirable to allow dynamic changing of transaction attributes - /// (unlikely) caching could be made configurable. Caching is desirable because - /// of the cost of evaluating rollback rules. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: AbstractFallbackTransactionAttributeSource.cs,v 1.8 2007/09/20 12:31:01 bbaia Exp $ - public abstract class AbstractFallbackTransactionAttributeSource : ITransactionAttributeSource - { - /// - /// Canonical value held in cache to indicate no transaction attibute was found - /// for this method, and we don't need to look again. - /// - private static readonly object NULL_TX_ATTIBUTE = new object(); - - /// - /// Cache of s, keyed by method and target class. - /// - private IDictionary _transactionAttibuteCache = new Hashtable(); - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - ///

- /// This is an class, and as such exposes no public constructors. - ///

- ///
- protected AbstractFallbackTransactionAttributeSource() - { - } - - #region Protected Abstract Methods - - /// - /// Subclasses should implement this to return all attributes for this method. - /// May return null. - /// - /// - /// We need all because of the need to analyze rollback rules. - /// - /// The method to retrieve attributes for. - /// The transactional attributes associated with the method. - protected abstract Attribute[] FindAllAttributes(MethodInfo method); - - /// - /// Subclasses should implement this to return all attributes for this class. - /// May return null. - /// - /// - /// The to retrieve attributes for. - /// - /// - /// All attributes associated with the supplied . - /// - protected abstract Attribute[] FindAllAttributes(Type targetType); - - #endregion - - #region ITransactionAttributeSource Members - - /// - /// Return the transaction attribute for this method invocation. - /// - /// - /// Defaults to the class's transaction attribute if no method - /// attribute is found - /// - /// method for the current invocation. Can't be null - /// target class for this invocation. May be null. - /// for this method, or null if the method is non-transactional - public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) - { - object cacheKey = getCacheKey(method, targetType); - object cached = null; - - lock (_transactionAttibuteCache) - { - cached = _transactionAttibuteCache[cacheKey]; - - if (cached != null) - { - if (NULL_TX_ATTIBUTE == cached) - { - return null; - } - { - return (ITransactionAttribute)cached; - } - } - else - { - ITransactionAttribute transactionAttribute = computeTransactionAttribute(method, targetType); - if (null == transactionAttribute) - { - _transactionAttibuteCache.Add(cacheKey, NULL_TX_ATTIBUTE); - } - else - { - _transactionAttibuteCache.Add(cacheKey, transactionAttribute); - } - return transactionAttribute; - } - } - } - - #endregion - - /// - /// Return the transaction attribute, given this set of attributes - /// attached to a method or class. Return null if it's not transactional. - /// - /// - /// Protected rather than private as subclasses may want to customize - /// how this is done: for example, returning a - /// - /// affected by the values of other attributes. - /// This implementation takes into account - /// s, if - /// the TransactionAttribute is a RuleBasedTransactionAttribute. - /// - /// - /// Attributes attached to a method or class. May be null, in which case a null - /// will be returned. - /// - /// - /// The configured transaction attribute, or null - /// if none was found. - /// - protected virtual ITransactionAttribute FindTransactionAttribute(Attribute[] attributes) - { - if (null == attributes) - { - return null; - } - ITransactionAttribute transactionAttribute = null; - foreach (Attribute currentAttribute in attributes) - { - transactionAttribute = currentAttribute as ITransactionAttribute; - if (null != transactionAttribute) - { - break; - } - } - - RuleBasedTransactionAttribute ruleBasedTransactionAttribute = transactionAttribute as RuleBasedTransactionAttribute; - if (null != ruleBasedTransactionAttribute) - { - IList rollbackRules = new LinkedList(); - foreach (Attribute currentAttribute in attributes) - { - RollbackRuleAttribute rollbackRuleAttribute = currentAttribute as RollbackRuleAttribute; - if (null != rollbackRuleAttribute) - { - rollbackRules.Add(rollbackRuleAttribute); - } - } - ruleBasedTransactionAttribute.RollbackRules = rollbackRules; - return ruleBasedTransactionAttribute; - } - return transactionAttribute; - } - - #region Private Methods - - private object getCacheKey(MethodBase method, Type targetType) - { - return targetType + String.Empty + method.GetHashCode(); - } - - private ITransactionAttribute computeTransactionAttribute(MethodInfo method, Type targetType) - { - MethodInfo specificMethod; - if (targetType == null) - { - specificMethod = method; - } - else - { - ComposedCriteria searchCriteria = new ComposedCriteria(); - searchCriteria.Add(new MethodNameMatchCriteria(method.Name)); - searchCriteria.Add(new MethodParametersCountCriteria(method.GetParameters().Length)); -#if NET_2_0 - searchCriteria.Add(new MethodGenericArgumentsCountCriteria( - method.GetGenericArguments().Length)); -#endif - searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(method))); - - MemberInfo[] matchingMethods = targetType.FindMembers( - MemberTypes.Method, - BindingFlags.Instance | BindingFlags.Public, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - searchCriteria); - - if (matchingMethods != null && matchingMethods.Length == 1) - { - specificMethod = matchingMethods[0] as MethodInfo; - } - else - { - specificMethod = method; - } - } - - ITransactionAttribute transactionAttribute = getTransactionAttribute(specificMethod); - if (null != transactionAttribute) - { - return transactionAttribute; - } - else if (specificMethod != method) - { - transactionAttribute = getTransactionAttribute(method); - } - return null; - } - - private ITransactionAttribute getTransactionAttribute(MethodInfo methodInfo) - { - ITransactionAttribute transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo)); - - if (null != transactionAttribute) - { - return transactionAttribute; - } - transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo.DeclaringType)); - if (null != transactionAttribute) - { - return transactionAttribute; - } - return null; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; + +using Spring.Collections; +using Spring.Util; +using Spring.Core; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Abstract implementation of + /// + /// that caches attributes for methods, and implements a default fallback policy. + /// + /// + ///

+ /// The default fallback policy applied by this class is: + /// + /// + /// most specific method + /// + /// + /// target class attribute + /// + /// + /// declaring method + /// + /// + /// declaring class + /// + /// + ///

+ ///

+ /// Defaults to using class's transaction attribute if none is associated + /// with the target method. Any transaction attribute associated with the + /// target method completely overrides a class transaction attribute. + ///

+ ///

+ /// This implementation caches attributes by method after they are first used. + /// If it's ever desirable to allow dynamic changing of transaction attributes + /// (unlikely) caching could be made configurable. Caching is desirable because + /// of the cost of evaluating rollback rules. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public abstract class AbstractFallbackTransactionAttributeSource : ITransactionAttributeSource + { + /// + /// Canonical value held in cache to indicate no transaction attibute was found + /// for this method, and we don't need to look again. + /// + private static readonly object NULL_TX_ATTIBUTE = new object(); + + /// + /// Cache of s, keyed by method and target class. + /// + private IDictionary _transactionAttibuteCache = new Hashtable(); + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + ///

+ /// This is an class, and as such exposes no public constructors. + ///

+ ///
+ protected AbstractFallbackTransactionAttributeSource() + { + } + + #region Protected Abstract Methods + + /// + /// Subclasses should implement this to return all attributes for this method. + /// May return null. + /// + /// + /// We need all because of the need to analyze rollback rules. + /// + /// The method to retrieve attributes for. + /// The transactional attributes associated with the method. + protected abstract Attribute[] FindAllAttributes(MethodInfo method); + + /// + /// Subclasses should implement this to return all attributes for this class. + /// May return null. + /// + /// + /// The to retrieve attributes for. + /// + /// + /// All attributes associated with the supplied . + /// + protected abstract Attribute[] FindAllAttributes(Type targetType); + + #endregion + + #region ITransactionAttributeSource Members + + /// + /// Return the transaction attribute for this method invocation. + /// + /// + /// Defaults to the class's transaction attribute if no method + /// attribute is found + /// + /// method for the current invocation. Can't be null + /// target class for this invocation. May be null. + /// for this method, or null if the method is non-transactional + public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) + { + object cacheKey = getCacheKey(method, targetType); + object cached = null; + + lock (_transactionAttibuteCache) + { + cached = _transactionAttibuteCache[cacheKey]; + + if (cached != null) + { + if (NULL_TX_ATTIBUTE == cached) + { + return null; + } + { + return (ITransactionAttribute)cached; + } + } + else + { + ITransactionAttribute transactionAttribute = computeTransactionAttribute(method, targetType); + if (null == transactionAttribute) + { + _transactionAttibuteCache.Add(cacheKey, NULL_TX_ATTIBUTE); + } + else + { + _transactionAttibuteCache.Add(cacheKey, transactionAttribute); + } + return transactionAttribute; + } + } + } + + #endregion + + /// + /// Return the transaction attribute, given this set of attributes + /// attached to a method or class. Return null if it's not transactional. + /// + /// + /// Protected rather than private as subclasses may want to customize + /// how this is done: for example, returning a + /// + /// affected by the values of other attributes. + /// This implementation takes into account + /// s, if + /// the TransactionAttribute is a RuleBasedTransactionAttribute. + /// + /// + /// Attributes attached to a method or class. May be null, in which case a null + /// will be returned. + /// + /// + /// The configured transaction attribute, or null + /// if none was found. + /// + protected virtual ITransactionAttribute FindTransactionAttribute(Attribute[] attributes) + { + if (null == attributes) + { + return null; + } + ITransactionAttribute transactionAttribute = null; + foreach (Attribute currentAttribute in attributes) + { + transactionAttribute = currentAttribute as ITransactionAttribute; + if (null != transactionAttribute) + { + break; + } + } + + RuleBasedTransactionAttribute ruleBasedTransactionAttribute = transactionAttribute as RuleBasedTransactionAttribute; + if (null != ruleBasedTransactionAttribute) + { + IList rollbackRules = new LinkedList(); + foreach (Attribute currentAttribute in attributes) + { + RollbackRuleAttribute rollbackRuleAttribute = currentAttribute as RollbackRuleAttribute; + if (null != rollbackRuleAttribute) + { + rollbackRules.Add(rollbackRuleAttribute); + } + } + ruleBasedTransactionAttribute.RollbackRules = rollbackRules; + return ruleBasedTransactionAttribute; + } + return transactionAttribute; + } + + #region Private Methods + + private object getCacheKey(MethodBase method, Type targetType) + { + return targetType + String.Empty + method.GetHashCode(); + } + + private ITransactionAttribute computeTransactionAttribute(MethodInfo method, Type targetType) + { + MethodInfo specificMethod; + if (targetType == null) + { + specificMethod = method; + } + else + { + ComposedCriteria searchCriteria = new ComposedCriteria(); + searchCriteria.Add(new MethodNameMatchCriteria(method.Name)); + searchCriteria.Add(new MethodParametersCountCriteria(method.GetParameters().Length)); +#if NET_2_0 + searchCriteria.Add(new MethodGenericArgumentsCountCriteria( + method.GetGenericArguments().Length)); +#endif + searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(method))); + + MemberInfo[] matchingMethods = targetType.FindMembers( + MemberTypes.Method, + BindingFlags.Instance | BindingFlags.Public, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + searchCriteria); + + if (matchingMethods != null && matchingMethods.Length == 1) + { + specificMethod = matchingMethods[0] as MethodInfo; + } + else + { + specificMethod = method; + } + } + + ITransactionAttribute transactionAttribute = getTransactionAttribute(specificMethod); + if (null != transactionAttribute) + { + return transactionAttribute; + } + else if (specificMethod != method) + { + transactionAttribute = getTransactionAttribute(method); + } + return null; + } + + private ITransactionAttribute getTransactionAttribute(MethodInfo methodInfo) + { + ITransactionAttribute transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo)); + + if (null != transactionAttribute) + { + return transactionAttribute; + } + transactionAttribute = FindTransactionAttribute(FindAllAttributes(methodInfo.DeclaringType)); + if (null != transactionAttribute) + { + return transactionAttribute; + } + return null; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs index 513bc923..eaaba215 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Reflection; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Implementation of that uses - /// s. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: AttributesTransactionAttributeSource.cs,v 1.6 2007/08/08 20:59:50 markpollack Exp $ - public class AttributesTransactionAttributeSource : AbstractFallbackTransactionAttributeSource - { - - /// - /// Initializes a new instance of the class. - /// - public AttributesTransactionAttributeSource( ) - { - } - - /// - /// - /// implementation. - /// - /// - /// We need all because of the need to analyze rollback rules. - /// - /// The method to retrieve attributes for. - /// The transactional attributes associated with the method. - protected override Attribute[] FindAllAttributes( MethodInfo method ) - { - return Attribute.GetCustomAttributes( method ); - } - - /// - /// - /// implementation. - /// - /// - /// The to retrieve attributes for. - /// - /// - /// All attributes associated with the supplied . - /// - protected override Attribute[] FindAllAttributes( Type targetType ) - { - return Attribute.GetCustomAttributes( targetType ); - } - - protected override ITransactionAttribute FindTransactionAttribute(Attribute[] attributes) - { - if (attributes == null) - { - return null; - } - foreach (Attribute attr in attributes) - { - if (attr is TransactionAttribute) - { - TransactionAttribute ta = (TransactionAttribute)attr; - RuleBasedTransactionAttribute rbta = - new RuleBasedTransactionAttribute(); - - //TODO another reminder to sync property names - rbta.PropagationBehavior = ta.TransactionPropagation; - rbta.TransactionIsolationLevel = ta.IsolationLevel; - rbta.ReadOnly = ta.ReadOnly; - -#if NET_2_0 - rbta.EnterpriseServicesInteropOption = ta.EnterpriseServicesInteropOption; -#endif - Type[] rbf = ta.RollbackFor; - - IList rollBackRules = new ArrayList(); - - if (rbf != null) - { - foreach (Type t in rbf) - { - RollbackRuleAttribute rule = new RollbackRuleAttribute(t); - rollBackRules.Add(rule); - } - } - - - Type[] nrbfc = ta.NoRollbackFor; - - if (nrbfc != null) - { - foreach (Type t in nrbfc) - { - NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(t); - rollBackRules.Add(rule); - } - } - - rbta.RollbackRules = rollBackRules; - - return rbta; - - } - } - return null; - } - - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Implementation of that uses + /// s. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public class AttributesTransactionAttributeSource : AbstractFallbackTransactionAttributeSource + { + + /// + /// Initializes a new instance of the class. + /// + public AttributesTransactionAttributeSource( ) + { + } + + /// + /// + /// implementation. + /// + /// + /// We need all because of the need to analyze rollback rules. + /// + /// The method to retrieve attributes for. + /// The transactional attributes associated with the method. + protected override Attribute[] FindAllAttributes( MethodInfo method ) + { + return Attribute.GetCustomAttributes( method ); + } + + /// + /// + /// implementation. + /// + /// + /// The to retrieve attributes for. + /// + /// + /// All attributes associated with the supplied . + /// + protected override Attribute[] FindAllAttributes( Type targetType ) + { + return Attribute.GetCustomAttributes( targetType ); + } + + protected override ITransactionAttribute FindTransactionAttribute(Attribute[] attributes) + { + if (attributes == null) + { + return null; + } + foreach (Attribute attr in attributes) + { + if (attr is TransactionAttribute) + { + TransactionAttribute ta = (TransactionAttribute)attr; + RuleBasedTransactionAttribute rbta = + new RuleBasedTransactionAttribute(); + + //TODO another reminder to sync property names + rbta.PropagationBehavior = ta.TransactionPropagation; + rbta.TransactionIsolationLevel = ta.IsolationLevel; + rbta.ReadOnly = ta.ReadOnly; + +#if NET_2_0 + rbta.EnterpriseServicesInteropOption = ta.EnterpriseServicesInteropOption; +#endif + Type[] rbf = ta.RollbackFor; + + IList rollBackRules = new ArrayList(); + + if (rbf != null) + { + foreach (Type t in rbf) + { + RollbackRuleAttribute rule = new RollbackRuleAttribute(t); + rollBackRules.Add(rule); + } + } + + + Type[] nrbfc = ta.NoRollbackFor; + + if (nrbfc != null) + { + foreach (Type t in nrbfc) + { + NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(t); + rollBackRules.Add(rule); + } + } + + rbta.RollbackRules = rollBackRules; + + return rbta; + + } + } + return null; + } + + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs index a70271f8..4c0f114e 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs @@ -1,99 +1,98 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Transaction.Support; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Transaction attribute approach to rolling back on all exceptions, no other - /// exceptions by default. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: DefaultTransactionAttribute.cs,v 1.9 2007/12/29 00:28:53 markpollack Exp $ - public class DefaultTransactionAttribute : DefaultTransactionDefinition, ITransactionAttribute - { - /// - /// Prefix for rollback-on-exception rules in description strings. - /// - public static readonly string ROLLBACK_RULE_PREFIX = "-"; - - /// - /// Prefix for commit-on-exception rules in description strings. - /// - public static readonly string COMMIT_RULE_PREFIX = "+"; - - /// - /// Creates a new instance of the - /// - /// class. - /// - public DefaultTransactionAttribute() {} - - /// - /// Creates a new instance of the - /// - /// class, setting the propagation behavior to the supplied value. - /// - /// - /// The desired transaction propagation behaviour. - /// - public DefaultTransactionAttribute( TransactionPropagation propagationBehavior ) - : base (propagationBehavior) {} - - #region ITransactionAttribute Members - /// - /// Decides if rollback is required for the supplied . - /// - /// - ///

- /// The default behavior is to rollback on any exception. - /// Consistent with 's behavior. - ///

- ///
- /// The to evaluate. - /// True if the exception causes a rollback, false otherwise. - public virtual bool RollbackOn(Exception exception) - { - return ( true ); - } - #endregion - - /// - /// Return a description of this transaction attribute. - /// - /// - ///

- /// The format matches the one used by the - /// , - /// to be able to feed any result into a - /// instance's properties. - ///

- ///
- public override string ToString() - { - string result = DefinitionDescription; - result += "," + ROLLBACK_RULE_PREFIX + "System.Exception"; - return result; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Transaction.Support; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Transaction attribute approach to rolling back on all exceptions, no other + /// exceptions by default. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + public class DefaultTransactionAttribute : DefaultTransactionDefinition, ITransactionAttribute + { + /// + /// Prefix for rollback-on-exception rules in description strings. + /// + public static readonly string ROLLBACK_RULE_PREFIX = "-"; + + /// + /// Prefix for commit-on-exception rules in description strings. + /// + public static readonly string COMMIT_RULE_PREFIX = "+"; + + /// + /// Creates a new instance of the + /// + /// class. + /// + public DefaultTransactionAttribute() {} + + /// + /// Creates a new instance of the + /// + /// class, setting the propagation behavior to the supplied value. + /// + /// + /// The desired transaction propagation behaviour. + /// + public DefaultTransactionAttribute( TransactionPropagation propagationBehavior ) + : base (propagationBehavior) {} + + #region ITransactionAttribute Members + /// + /// Decides if rollback is required for the supplied . + /// + /// + ///

+ /// The default behavior is to rollback on any exception. + /// Consistent with 's behavior. + ///

+ ///
+ /// The to evaluate. + /// True if the exception causes a rollback, false otherwise. + public virtual bool RollbackOn(Exception exception) + { + return ( true ); + } + #endregion + + /// + /// Return a description of this transaction attribute. + /// + /// + ///

+ /// The format matches the one used by the + /// , + /// to be able to feed any result into a + /// instance's properties. + ///

+ ///
+ public override string ToString() + { + string result = DefinitionDescription; + result += "," + ROLLBACK_RULE_PREFIX + "System.Exception"; + return result; + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttributeSourceAdvisor.cs b/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttributeSourceAdvisor.cs index a1f73652..6644f3e9 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttributeSourceAdvisor.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttributeSourceAdvisor.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using AopAlliance.Aop; -using Spring.Aop.Framework; -using Spring.Aop.Support; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Advisor driven by a , - /// used to exclude a general advice from methods that - /// are non-transactional. - /// - /// - /// - /// To put it another way, use this advisor when you would like to associate other AOP - /// advice based on the pointcut specified by declarative transaction demarcation, - /// attibute based or otherwise. - /// - ///

- /// Because the AOP framework caches advice calculations, this is normally - /// faster than just letting the - /// run and find out itself that it has no work to do. - ///

- ///
- /// Mark Pollack (.NET) - /// $Id: DefaultTransactionAttributeSourceAdvisor.cs,v 1.1 2007/01/04 05:11:17 markpollack Exp $ - [Serializable] - public class DefaultTransactionAttributeSourceAdvisor : StaticMethodMatcherPointcutAdvisor - { - private ITransactionAttributeSource _transactionAttributeSource; - - /// - /// Creates a new instance of the - /// class. - /// - public DefaultTransactionAttributeSourceAdvisor(ITransactionAttributeSource transactionAttributeSource, IAdvice advice) - : base( advice ) - { - if (transactionAttributeSource == null) - { - throw new AopConfigException("Cannot construct a DefaultTransactionAttributeSourceAdvisor if " + - "TransactionAttributeSource is null."); - } - _transactionAttributeSource = transactionAttributeSource; - } - - /// - /// Tests the input method to see if it's covered by the advisor. - /// - /// The method to match. - /// The to match against. - /// - /// True if the supplied is covered by the advisor. - /// - public override bool Matches(MethodInfo method, Type targetClass) - { - return ( _transactionAttributeSource.ReturnTransactionAttribute( (MethodInfo)method, targetClass ) != null); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using AopAlliance.Aop; +using Spring.Aop.Framework; +using Spring.Aop.Support; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Advisor driven by a , + /// used to exclude a general advice from methods that + /// are non-transactional. + /// + /// + /// + /// To put it another way, use this advisor when you would like to associate other AOP + /// advice based on the pointcut specified by declarative transaction demarcation, + /// attibute based or otherwise. + /// + ///

+ /// Because the AOP framework caches advice calculations, this is normally + /// faster than just letting the + /// run and find out itself that it has no work to do. + ///

+ ///
+ /// Mark Pollack (.NET) + [Serializable] + public class DefaultTransactionAttributeSourceAdvisor : StaticMethodMatcherPointcutAdvisor + { + private ITransactionAttributeSource _transactionAttributeSource; + + /// + /// Creates a new instance of the + /// class. + /// + public DefaultTransactionAttributeSourceAdvisor(ITransactionAttributeSource transactionAttributeSource, IAdvice advice) + : base( advice ) + { + if (transactionAttributeSource == null) + { + throw new AopConfigException("Cannot construct a DefaultTransactionAttributeSourceAdvisor if " + + "TransactionAttributeSource is null."); + } + _transactionAttributeSource = transactionAttributeSource; + } + + /// + /// Tests the input method to see if it's covered by the advisor. + /// + /// The method to match. + /// The to match against. + /// + /// True if the supplied is covered by the advisor. + /// + public override bool Matches(MethodInfo method, Type targetClass) + { + return ( _transactionAttributeSource.ReturnTransactionAttribute( (MethodInfo)method, targetClass ) != null); + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs b/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs index 6e5890e7..7f999eaa 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs @@ -1,176 +1,176 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -#if NET_2_0 -using System.Transactions; -#endif -using IsolationLevel=System.Data.IsolationLevel; - -namespace Spring.Transaction.Interceptor -{ - /// - /// ITransactionAttribute that delegates all calls to a give target attribute except for the - /// name, which is specified in the constructor. - /// - public class DelegatingTransactionAttributeWithName : ITransactionAttribute - { - private ITransactionAttribute targetAttribute; - private string joinpointIdentification; - - /// - /// Initializes a new instance of the class. - /// - /// The target attribute. - /// The identification. - public DelegatingTransactionAttributeWithName(ITransactionAttribute targetAttribute, string identification) - { - this.targetAttribute = targetAttribute; - joinpointIdentification = identification; - } - - /// - /// Decides if rollback is required for the supplied . - /// - /// The to evaluate. - /// - /// True if the exception causes a rollback, false otherwise. - /// - public bool RollbackOn(Exception exception) - { - return targetAttribute.RollbackOn(exception); - } - - /// - /// Return the propagation behavior of type - /// . - /// - /// - public TransactionPropagation PropagationBehavior - { - get { return targetAttribute.PropagationBehavior; } - } - - /// - /// Return the isolation level of type . - /// - /// - /// - ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// Note that a transaction manager that does not support custom isolation levels - /// will throw an exception when given any other level than - /// . - ///

- ///
- public IsolationLevel TransactionIsolationLevel - { - get { return targetAttribute.TransactionIsolationLevel; } - } - - /// - /// Return the transaction timeout. - /// - /// - /// - ///

- /// Must return a number of seconds, or -1. - /// Only makes sense in combination with - /// and - /// . - /// Note that a transaction manager that does not support timeouts will - /// throw an exception when given any other timeout than -1. - ///

- ///
- public int TransactionTimeout - { - get { return targetAttribute.TransactionTimeout; } - } - - /// - /// Get whether to optimize as read-only transaction. - /// - /// - /// - ///

- /// This just serves as hint for the actual transaction subsystem, - /// it will not necessarily cause failure of write accesses. - ///

- ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// A transaction manager that cannot interpret the read-only hint - /// will not throw an exception when given ReadOnly=true. - ///

- ///
- public bool ReadOnly - { - get { return targetAttribute.ReadOnly; } - } - - /// - /// Return the name of this transaction. - /// - /// - /// - /// The exposed name will be the fully - /// qualified type name + "." method name + assembly (by default). - /// - public string Name - { - get { return joinpointIdentification; } - } - -#if NET_2_0 - - /// - /// Gets the enterprise services interop option. - /// - /// The enterprise services interop option. - public EnterpriseServicesInteropOption EnterpriseServicesInteropOption - { - get { return targetAttribute.EnterpriseServicesInteropOption; } - } -#endif - - /// - /// Return a description of this transaction attribute. - /// - /// - ///

- /// The format matches the one used by the - /// , - /// to be able to feed any result into a - /// instance's properties. - ///

- ///
- public override string ToString() - { - return targetAttribute.ToString(); - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +#if NET_2_0 +using System.Transactions; +#endif +using IsolationLevel=System.Data.IsolationLevel; + +namespace Spring.Transaction.Interceptor +{ + /// + /// ITransactionAttribute that delegates all calls to a give target attribute except for the + /// name, which is specified in the constructor. + /// + public class DelegatingTransactionAttributeWithName : ITransactionAttribute + { + private ITransactionAttribute targetAttribute; + private string joinpointIdentification; + + /// + /// Initializes a new instance of the class. + /// + /// The target attribute. + /// The identification. + public DelegatingTransactionAttributeWithName(ITransactionAttribute targetAttribute, string identification) + { + this.targetAttribute = targetAttribute; + joinpointIdentification = identification; + } + + /// + /// Decides if rollback is required for the supplied . + /// + /// The to evaluate. + /// + /// True if the exception causes a rollback, false otherwise. + /// + public bool RollbackOn(Exception exception) + { + return targetAttribute.RollbackOn(exception); + } + + /// + /// Return the propagation behavior of type + /// . + /// + /// + public TransactionPropagation PropagationBehavior + { + get { return targetAttribute.PropagationBehavior; } + } + + /// + /// Return the isolation level of type . + /// + /// + /// + ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// Note that a transaction manager that does not support custom isolation levels + /// will throw an exception when given any other level than + /// . + ///

+ ///
+ public IsolationLevel TransactionIsolationLevel + { + get { return targetAttribute.TransactionIsolationLevel; } + } + + /// + /// Return the transaction timeout. + /// + /// + /// + ///

+ /// Must return a number of seconds, or -1. + /// Only makes sense in combination with + /// and + /// . + /// Note that a transaction manager that does not support timeouts will + /// throw an exception when given any other timeout than -1. + ///

+ ///
+ public int TransactionTimeout + { + get { return targetAttribute.TransactionTimeout; } + } + + /// + /// Get whether to optimize as read-only transaction. + /// + /// + /// + ///

+ /// This just serves as hint for the actual transaction subsystem, + /// it will not necessarily cause failure of write accesses. + ///

+ ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// A transaction manager that cannot interpret the read-only hint + /// will not throw an exception when given ReadOnly=true. + ///

+ ///
+ public bool ReadOnly + { + get { return targetAttribute.ReadOnly; } + } + + /// + /// Return the name of this transaction. + /// + /// + /// + /// The exposed name will be the fully + /// qualified type name + "." method name + assembly (by default). + /// + public string Name + { + get { return joinpointIdentification; } + } + +#if NET_2_0 + + /// + /// Gets the enterprise services interop option. + /// + /// The enterprise services interop option. + public EnterpriseServicesInteropOption EnterpriseServicesInteropOption + { + get { return targetAttribute.EnterpriseServicesInteropOption; } + } +#endif + + /// + /// Return a description of this transaction attribute. + /// + /// + ///

+ /// The format matches the one used by the + /// , + /// to be able to feed any result into a + /// instance's properties. + ///

+ ///
+ public override string ToString() + { + return targetAttribute.ToString(); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttribute.cs index b47686f1..8e284605 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttribute.cs @@ -1,43 +1,42 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.ComponentModel; - -namespace Spring.Transaction.Interceptor -{ - /// - /// This interface adds a - /// - /// specification to . - /// - /// Griffin Caprio (.NET) - /// $Id: ITransactionAttribute.cs,v 1.6 2007/12/29 00:28:53 markpollack Exp $ - [TypeConverter(typeof(TransactionAttributeConverter))] - public interface ITransactionAttribute : ITransactionDefinition - { - /// - /// Decides if rollback is required for the supplied . - /// - /// The to evaluate. - /// True if the exception causes a rollback, false otherwise. - bool RollbackOn( Exception exception ); - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.ComponentModel; + +namespace Spring.Transaction.Interceptor +{ + /// + /// This interface adds a + /// + /// specification to . + /// + /// Griffin Caprio (.NET) + [TypeConverter(typeof(TransactionAttributeConverter))] + public interface ITransactionAttribute : ITransactionDefinition + { + /// + /// Decides if rollback is required for the supplied . + /// + /// The to evaluate. + /// True if the exception causes a rollback, false otherwise. + bool RollbackOn( Exception exception ); + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttributeSource.cs index 92f19889..41e629ae 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/ITransactionAttributeSource.cs @@ -1,56 +1,55 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Interface used by - /// to source transaction attributes. - /// - /// - ///

- /// Implementations know how to source transaction attributes, whether from configuration, - /// metadata attributes at source level, or anywhere else. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: ITransactionAttributeSource.cs,v 1.7 2006/05/18 21:37:51 markpollack Exp $ - public interface ITransactionAttributeSource - { - /// - /// Return the for this - /// method. - /// - /// The method to check. - /// - /// The target . May be null, in which case the declaring - /// class of the supplied must be used. - /// - /// - /// A or - /// null if the method is non-transactional. - /// - ITransactionAttribute ReturnTransactionAttribute( MethodInfo method, Type targetType ); - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Interface used by + /// to source transaction attributes. + /// + /// + ///

+ /// Implementations know how to source transaction attributes, whether from configuration, + /// metadata attributes at source level, or anywhere else. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + public interface ITransactionAttributeSource + { + /// + /// Return the for this + /// method. + /// + /// The method to check. + /// + /// The target . May be null, in which case the declaring + /// class of the supplied must be used. + /// + /// + /// A or + /// null if the method is non-transactional. + /// + ITransactionAttribute ReturnTransactionAttribute( MethodInfo method, Type targetType ); + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/MatchAlwaysTransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/MatchAlwaysTransactionAttributeSource.cs index 29908e41..536e8abf 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/MatchAlwaysTransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/MatchAlwaysTransactionAttributeSource.cs @@ -1,126 +1,125 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Very simple implementation of - /// which will always return the same - /// for all methods fed to it. - /// - /// - ///

- /// The - /// may be specified, but will otherwise default to PROPAGATION_REQUIRED. This may be - /// used in the cases where you want to use the same transaction attribute with all - /// methods being handled by a transaction interceptor. - ///

- ///
- /// Colin Sampaleanu - /// Griffin Caprio (.NET) - /// $Id: MatchAlwaysTransactionAttributeSource.cs,v 1.7 2007/12/29 00:28:53 markpollack Exp $ - [Serializable] - public class MatchAlwaysTransactionAttributeSource : ITransactionAttributeSource - { - private ITransactionAttribute _transactionAttribute; - - /// - /// Creates a new instance of the - /// - /// class. - /// - public MatchAlwaysTransactionAttributeSource() - { - _transactionAttribute = new DefaultTransactionAttribute(); - } - - /// - /// Allows a transaction attribute to be specified, using the - /// form, for example, "PROPAGATION_REQUIRED". - /// - public ITransactionAttribute TransactionAttribute - { - set { _transactionAttribute = value; } - } - - #region ITransactionAttributeSource Members - /// - /// Return the for this - /// method. - /// - /// The method to check. - /// - /// The target . May be null, in which case the declaring - /// class of the supplied must be used. - /// - /// - /// A or - /// null if the method is non-transactional. - /// - public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) - { - return _transactionAttribute; - } - #endregion - - /// - /// Determines whether the specified is equal to the current . - /// - /// The to compare with the current . - /// - /// true if the specified is equal to the current ; otherwise, false. - /// - public override bool Equals(object obj) - { - if (this == obj) return true; - MatchAlwaysTransactionAttributeSource matchAlwaysTransactionAttributeSource = obj as MatchAlwaysTransactionAttributeSource; - if (matchAlwaysTransactionAttributeSource == null) return false; - return Equals(_transactionAttribute, matchAlwaysTransactionAttributeSource._transactionAttribute); - } - - /// - /// Serves as a hash function for a particular type. is suitable for use in hashing algorithms and data structures like a hash table. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return _transactionAttribute != null ? _transactionAttribute.GetHashCode() : 0; - } - - - /// - ///Returns a that represents the current . - /// - /// - /// - ///A that represents the current . - /// - ///2 - public override string ToString() - { - return GetType().Name + ": " + _transactionAttribute; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Very simple implementation of + /// which will always return the same + /// for all methods fed to it. + /// + /// + ///

+ /// The + /// may be specified, but will otherwise default to PROPAGATION_REQUIRED. This may be + /// used in the cases where you want to use the same transaction attribute with all + /// methods being handled by a transaction interceptor. + ///

+ ///
+ /// Colin Sampaleanu + /// Griffin Caprio (.NET) + [Serializable] + public class MatchAlwaysTransactionAttributeSource : ITransactionAttributeSource + { + private ITransactionAttribute _transactionAttribute; + + /// + /// Creates a new instance of the + /// + /// class. + /// + public MatchAlwaysTransactionAttributeSource() + { + _transactionAttribute = new DefaultTransactionAttribute(); + } + + /// + /// Allows a transaction attribute to be specified, using the + /// form, for example, "PROPAGATION_REQUIRED". + /// + public ITransactionAttribute TransactionAttribute + { + set { _transactionAttribute = value; } + } + + #region ITransactionAttributeSource Members + /// + /// Return the for this + /// method. + /// + /// The method to check. + /// + /// The target . May be null, in which case the declaring + /// class of the supplied must be used. + /// + /// + /// A or + /// null if the method is non-transactional. + /// + public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) + { + return _transactionAttribute; + } + #endregion + + /// + /// Determines whether the specified is equal to the current . + /// + /// The to compare with the current . + /// + /// true if the specified is equal to the current ; otherwise, false. + /// + public override bool Equals(object obj) + { + if (this == obj) return true; + MatchAlwaysTransactionAttributeSource matchAlwaysTransactionAttributeSource = obj as MatchAlwaysTransactionAttributeSource; + if (matchAlwaysTransactionAttributeSource == null) return false; + return Equals(_transactionAttribute, matchAlwaysTransactionAttributeSource._transactionAttribute); + } + + /// + /// Serves as a hash function for a particular type. is suitable for use in hashing algorithms and data structures like a hash table. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return _transactionAttribute != null ? _transactionAttribute.GetHashCode() : 0; + } + + + /// + ///Returns a that represents the current . + /// + /// + /// + ///A that represents the current . + /// + ///2 + public override string ToString() + { + return GetType().Name + ": " + _transactionAttribute; + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/MethodMapTransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/MethodMapTransactionAttributeSource.cs index 89870d92..de13d756 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/MethodMapTransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/MethodMapTransactionAttributeSource.cs @@ -1,294 +1,293 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; - -using Common.Logging; -using Spring.Util; -using Spring.Core.TypeResolution; -using Spring.Core; - -#endregion - -namespace Spring.Transaction.Interceptor -{ - /// - /// Simple implementation of the - /// interface that allows attributes to be stored per method in a map. - /// - /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: MethodMapTransactionAttributeSource.cs,v 1.15 2008/05/29 17:26:41 markpollack Exp $ - public class MethodMapTransactionAttributeSource : ITransactionAttributeSource - { - private IDictionary _methodMap; - private IDictionary _nameMap; - - #region Logging Definition - - private static readonly ILog LOG = LogManager.GetLogger(typeof (MethodMapTransactionAttributeSource)); - - #endregion - - /// - /// Creates a new instance of the - /// class. - /// - public MethodMapTransactionAttributeSource() - { - _methodMap = new Hashtable(); - _nameMap = new Hashtable(); - } - - /// - /// Set a name/attribute map, consisting of "FQCN.method, AssemblyName" method names - /// (e.g. "MyNameSpace.MyClass.MyMethod, MyAssembly") and ITransactionAttribute - /// instances (or Strings to be converted to instances). - /// - /// - ///

- /// The key values of the supplied - /// must adhere to the following form:
- /// FQCN.methodName, Assembly. - ///

- /// - /// MyNameSpace.MyClass.MyMethod, MyAssembly - /// - ///
- public IDictionary MethodMap - { - set - { - foreach (DictionaryEntry entry in value) - { - - string name = entry.Key as string; - ITransactionAttribute attribute = null; - //Check if we need to convert from a string to ITransactionAttribute - if (entry.Value is ITransactionAttribute) - { - attribute = entry.Value as ITransactionAttribute; - } - else - { - TransactionAttributeEditor editor = new TransactionAttributeEditor(); - editor.SetAsText(entry.Value.ToString()); - attribute = editor.Value; - } - AddTransactionalMethod( name, attribute ); - - } - - } - } - /// - /// Add an attribute for a transactional method. - /// - /// - /// Method names can end or start with "*" for matching multiple methods. - /// - /// The class and method name, separated by a dot. - /// The attribute to be associated with the method. - public void AddTransactionalMethod( string name, ITransactionAttribute attribute ) - { - AssertUtils.ArgumentNotNull(name, "name"); - int lastCommaIndex = name.LastIndexOf( "," ); - if (lastCommaIndex == -1) - { - throw new ArgumentException("'" + name + "'" + - " is not a valid method name, missing AssemblyName. Format is FQN.MethodName, AssemblyName."); - } - string fqnWithMethod = name.Substring(0, lastCommaIndex); - - int lastDotIndex = fqnWithMethod.LastIndexOf( "." ); - if ( lastDotIndex == -1 ) - { - throw new TransactionUsageException("'" + fqnWithMethod + "' is not a valid method name: format is FQN.methodName"); - } - string className = fqnWithMethod.Substring(0, lastDotIndex ); - string assemblyName = name.Substring(lastCommaIndex + 1); - string methodName = fqnWithMethod.Substring(lastDotIndex + 1 ); - string fqnClassName = className + ", " + assemblyName; - try - { - Type type = TypeResolutionUtils.ResolveType(fqnClassName); - AddTransactionalMethod( type, methodName, attribute ); - } catch ( TypeLoadException exception ) - { - throw new TransactionUsageException( "Type '" + fqnClassName + "' not found.", exception ); - } - } - - /// - /// Add an attribute for a transactional method. - /// - /// - /// Method names can end or start with "*" for matching multiple methods. - /// - /// The target interface or class. - /// The mapped method name. - /// - /// The attribute to be associated with the method. - /// - public void AddTransactionalMethod( - Type type, string mappedName, ITransactionAttribute transactionAttribute ) - { - // TODO address method overloading? At present this will - // simply match all methods that have the given name. - string name = type.Name + "." + mappedName; - MethodInfo[] methods = type.GetMethods(); - IList matchingMethods = new ArrayList(); - for ( int i = 0; i < methods.Length; i++ ) - { - if ( methods[i].Name.Equals( mappedName ) || IsMatch(methods[i].Name, mappedName )) - { - matchingMethods.Add( methods[i] ); - } - } - if ( matchingMethods.Count == 0 ) - { - throw new TransactionUsageException("Couldn't find method '" + mappedName + "' on Type [" + type.Name + "]"); - } - // register all matching methods - foreach ( MethodInfo currentMethod in matchingMethods ) - { - string regularMethodName = (string)_nameMap[currentMethod]; - if ( regularMethodName == null || ( !regularMethodName.Equals(name) && regularMethodName.Length <= name.Length)) - { - // No already registered method name, or more specific - // method name specification now -> (re-)register method. - if (LOG.IsDebugEnabled && regularMethodName != null) - { - LOG.Debug("Replacing attribute for transactional method [" + currentMethod + "]: current name '" + - name + "' is more specific than '" + regularMethodName + "'"); - } - _nameMap.Add( currentMethod, name ); - AddTransactionalMethod( currentMethod, transactionAttribute ); - } - else - { - if (LOG.IsDebugEnabled && regularMethodName != null) - { - LOG.Debug("Keeping attribute for transactional method [" + currentMethod + "]: current name '" + - name + "' is not more specific than '" + regularMethodName + "'"); - } - } - } - } - - /// - /// Add an attribute for a transactional method. - /// - /// The transactional method. - /// - /// The attribute to be associated with the method. - /// - public void AddTransactionalMethod( MethodInfo method, ITransactionAttribute transactionAttribute ) - { - _methodMap.Add( method, transactionAttribute ); - } - - /// - /// Does the supplied match the supplied ? - /// - /// - /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, - /// as well as direct equality. This behaviour can (of course) be overridden in - /// derived classes. - /// - /// The method name of the class. - /// The name in the descriptor. - /// True if the names match. - protected virtual bool IsMatch( string methodName, string mappedName ) - { - return PatternMatchUtils.SimpleMatch(mappedName, methodName); - } - - #region ITransactionAttributeSource Members - /// - /// Return the for this - /// method. - /// - /// The method to check. - /// - /// The target . May be null, in which case the declaring - /// class of the supplied must be used. - /// - /// - /// A or - /// null if the method is non-transactional. - /// - public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) - { - //Might have registered MethodInfo objects whose declaring type is the interface, so 'downcast' - //to the most specific method which is typically what is passed in as the first method argument. - foreach (DictionaryEntry dictionaryEntry in _methodMap) - { - MethodInfo currentMethod = (MethodInfo)dictionaryEntry.Key; - - MethodInfo specificMethod; - if (targetType == null) - { - specificMethod = currentMethod; - } - else - { - ComposedCriteria searchCriteria = new ComposedCriteria(); - searchCriteria.Add(new MethodNameMatchCriteria(currentMethod.Name)); - searchCriteria.Add(new MethodParametersCountCriteria(currentMethod.GetParameters().Length)); -#if NET_2_0 - searchCriteria.Add(new MethodGenericArgumentsCountCriteria( - currentMethod.GetGenericArguments().Length)); -#endif - searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(currentMethod))); - - MemberInfo[] matchingMethods = targetType.FindMembers( - MemberTypes.Method, - BindingFlags.Instance | BindingFlags.Public, - new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), - searchCriteria); - - if (matchingMethods != null && matchingMethods.Length == 1) - { - specificMethod = matchingMethods[0] as MethodInfo; - } - else - { - specificMethod = currentMethod; - } - } - - if (method == specificMethod) - { - return (ITransactionAttribute)dictionaryEntry.Value; - } - } - return (ITransactionAttribute)_methodMap[method]; - } - #endregion - - - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; + +using Common.Logging; +using Spring.Util; +using Spring.Core.TypeResolution; +using Spring.Core; + +#endregion + +namespace Spring.Transaction.Interceptor +{ + /// + /// Simple implementation of the + /// interface that allows attributes to be stored per method in a map. + /// + /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + public class MethodMapTransactionAttributeSource : ITransactionAttributeSource + { + private IDictionary _methodMap; + private IDictionary _nameMap; + + #region Logging Definition + + private static readonly ILog LOG = LogManager.GetLogger(typeof (MethodMapTransactionAttributeSource)); + + #endregion + + /// + /// Creates a new instance of the + /// class. + /// + public MethodMapTransactionAttributeSource() + { + _methodMap = new Hashtable(); + _nameMap = new Hashtable(); + } + + /// + /// Set a name/attribute map, consisting of "FQCN.method, AssemblyName" method names + /// (e.g. "MyNameSpace.MyClass.MyMethod, MyAssembly") and ITransactionAttribute + /// instances (or Strings to be converted to instances). + /// + /// + ///

+ /// The key values of the supplied + /// must adhere to the following form:
+ /// FQCN.methodName, Assembly. + ///

+ /// + /// MyNameSpace.MyClass.MyMethod, MyAssembly + /// + ///
+ public IDictionary MethodMap + { + set + { + foreach (DictionaryEntry entry in value) + { + + string name = entry.Key as string; + ITransactionAttribute attribute = null; + //Check if we need to convert from a string to ITransactionAttribute + if (entry.Value is ITransactionAttribute) + { + attribute = entry.Value as ITransactionAttribute; + } + else + { + TransactionAttributeEditor editor = new TransactionAttributeEditor(); + editor.SetAsText(entry.Value.ToString()); + attribute = editor.Value; + } + AddTransactionalMethod( name, attribute ); + + } + + } + } + /// + /// Add an attribute for a transactional method. + /// + /// + /// Method names can end or start with "*" for matching multiple methods. + /// + /// The class and method name, separated by a dot. + /// The attribute to be associated with the method. + public void AddTransactionalMethod( string name, ITransactionAttribute attribute ) + { + AssertUtils.ArgumentNotNull(name, "name"); + int lastCommaIndex = name.LastIndexOf( "," ); + if (lastCommaIndex == -1) + { + throw new ArgumentException("'" + name + "'" + + " is not a valid method name, missing AssemblyName. Format is FQN.MethodName, AssemblyName."); + } + string fqnWithMethod = name.Substring(0, lastCommaIndex); + + int lastDotIndex = fqnWithMethod.LastIndexOf( "." ); + if ( lastDotIndex == -1 ) + { + throw new TransactionUsageException("'" + fqnWithMethod + "' is not a valid method name: format is FQN.methodName"); + } + string className = fqnWithMethod.Substring(0, lastDotIndex ); + string assemblyName = name.Substring(lastCommaIndex + 1); + string methodName = fqnWithMethod.Substring(lastDotIndex + 1 ); + string fqnClassName = className + ", " + assemblyName; + try + { + Type type = TypeResolutionUtils.ResolveType(fqnClassName); + AddTransactionalMethod( type, methodName, attribute ); + } catch ( TypeLoadException exception ) + { + throw new TransactionUsageException( "Type '" + fqnClassName + "' not found.", exception ); + } + } + + /// + /// Add an attribute for a transactional method. + /// + /// + /// Method names can end or start with "*" for matching multiple methods. + /// + /// The target interface or class. + /// The mapped method name. + /// + /// The attribute to be associated with the method. + /// + public void AddTransactionalMethod( + Type type, string mappedName, ITransactionAttribute transactionAttribute ) + { + // TODO address method overloading? At present this will + // simply match all methods that have the given name. + string name = type.Name + "." + mappedName; + MethodInfo[] methods = type.GetMethods(); + IList matchingMethods = new ArrayList(); + for ( int i = 0; i < methods.Length; i++ ) + { + if ( methods[i].Name.Equals( mappedName ) || IsMatch(methods[i].Name, mappedName )) + { + matchingMethods.Add( methods[i] ); + } + } + if ( matchingMethods.Count == 0 ) + { + throw new TransactionUsageException("Couldn't find method '" + mappedName + "' on Type [" + type.Name + "]"); + } + // register all matching methods + foreach ( MethodInfo currentMethod in matchingMethods ) + { + string regularMethodName = (string)_nameMap[currentMethod]; + if ( regularMethodName == null || ( !regularMethodName.Equals(name) && regularMethodName.Length <= name.Length)) + { + // No already registered method name, or more specific + // method name specification now -> (re-)register method. + if (LOG.IsDebugEnabled && regularMethodName != null) + { + LOG.Debug("Replacing attribute for transactional method [" + currentMethod + "]: current name '" + + name + "' is more specific than '" + regularMethodName + "'"); + } + _nameMap.Add( currentMethod, name ); + AddTransactionalMethod( currentMethod, transactionAttribute ); + } + else + { + if (LOG.IsDebugEnabled && regularMethodName != null) + { + LOG.Debug("Keeping attribute for transactional method [" + currentMethod + "]: current name '" + + name + "' is not more specific than '" + regularMethodName + "'"); + } + } + } + } + + /// + /// Add an attribute for a transactional method. + /// + /// The transactional method. + /// + /// The attribute to be associated with the method. + /// + public void AddTransactionalMethod( MethodInfo method, ITransactionAttribute transactionAttribute ) + { + _methodMap.Add( method, transactionAttribute ); + } + + /// + /// Does the supplied match the supplied ? + /// + /// + /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, + /// as well as direct equality. This behaviour can (of course) be overridden in + /// derived classes. + /// + /// The method name of the class. + /// The name in the descriptor. + /// True if the names match. + protected virtual bool IsMatch( string methodName, string mappedName ) + { + return PatternMatchUtils.SimpleMatch(mappedName, methodName); + } + + #region ITransactionAttributeSource Members + /// + /// Return the for this + /// method. + /// + /// The method to check. + /// + /// The target . May be null, in which case the declaring + /// class of the supplied must be used. + /// + /// + /// A or + /// null if the method is non-transactional. + /// + public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) + { + //Might have registered MethodInfo objects whose declaring type is the interface, so 'downcast' + //to the most specific method which is typically what is passed in as the first method argument. + foreach (DictionaryEntry dictionaryEntry in _methodMap) + { + MethodInfo currentMethod = (MethodInfo)dictionaryEntry.Key; + + MethodInfo specificMethod; + if (targetType == null) + { + specificMethod = currentMethod; + } + else + { + ComposedCriteria searchCriteria = new ComposedCriteria(); + searchCriteria.Add(new MethodNameMatchCriteria(currentMethod.Name)); + searchCriteria.Add(new MethodParametersCountCriteria(currentMethod.GetParameters().Length)); +#if NET_2_0 + searchCriteria.Add(new MethodGenericArgumentsCountCriteria( + currentMethod.GetGenericArguments().Length)); +#endif + searchCriteria.Add(new MethodParametersCriteria(ReflectionUtils.GetParameterTypes(currentMethod))); + + MemberInfo[] matchingMethods = targetType.FindMembers( + MemberTypes.Method, + BindingFlags.Instance | BindingFlags.Public, + new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), + searchCriteria); + + if (matchingMethods != null && matchingMethods.Length == 1) + { + specificMethod = matchingMethods[0] as MethodInfo; + } + else + { + specificMethod = currentMethod; + } + } + + if (method == specificMethod) + { + return (ITransactionAttribute)dictionaryEntry.Value; + } + } + return (ITransactionAttribute)_methodMap[method]; + } + #endregion + + + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/NameMatchTransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/NameMatchTransactionAttributeSource.cs index 4c1d57cf..edfe4ec3 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/NameMatchTransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/NameMatchTransactionAttributeSource.cs @@ -1,203 +1,202 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Reflection; -using Common.Logging; -using Spring.Util; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Simple implementation of the - /// that allows attributes to be matched by registered name. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: NameMatchTransactionAttributeSource.cs,v 1.9 2008/05/29 17:26:41 markpollack Exp $ - [Serializable] - public class NameMatchTransactionAttributeSource : ITransactionAttributeSource - { - /// - /// Logger available to subclasses, static for optimal serialization - /// - [NonSerialized()] - protected static readonly ILog log = LogManager.GetLogger(typeof(NameMatchTransactionAttributeSource)); - - /// - /// Keys are method names; values are ITransactionAttributes - /// - private IDictionary nameMap; - - /// - /// Creates a new instance of the - /// class. - /// - public NameMatchTransactionAttributeSource() - { - nameMap = new Hashtable(); - } - - /// - /// Set a name/attribute map, consisting of method names (e.g. "MyMethod") and - /// instances - /// (or Strings to be converted to ITransactionAttribute instances). - /// - public IDictionary NameMap - { - set - { - foreach (DictionaryEntry entry in value) - { - string name = entry.Key as string; - ITransactionAttribute attribute = null; - if (entry.Value is ITransactionAttribute) - { - attribute = entry.Value as ITransactionAttribute; - } - else - { - TransactionAttributeEditor editor = new TransactionAttributeEditor(); - editor.SetAsText(entry.Value.ToString()); - attribute = editor.Value; - } - AddTransactionMethod(name, attribute); - } - } - } - - /// - /// Parses the given properties into a name/attribute map. - /// - /// - /// Expects method names as keys and string attributes definitions as values, - /// parsable into - /// instances via - /// . - /// - /// The properties of the transaction. - public NameValueCollection NameProperties - { - set - { - SetProperties(value); - } - } - - /// - /// Does the supplied match the supplied ? - /// - /// - /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, - /// as well as direct equality. Can be overridden in subclasses. - /// - /// The method name of the class. - /// The name in the descriptor. - /// True if the names match. - protected virtual bool IsMatch( string methodName, string mappedName ) - { - return PatternMatchUtils.SimpleMatch(mappedName, methodName); - } - - /// - /// Add an attribute for a transactional method. - /// - /// - ///

- /// Method names can end with "*" for matching multiple methods. - ///

- ///
- /// The transactional method name. - /// - /// The attribute to be associated with the method. - /// - public void AddTransactionMethod( string methodName, ITransactionAttribute attribute ) - { - #region Instrumentation - if (log.IsDebugEnabled) - { - log.Debug("Adding transactional method [" + methodName + "] with attribute [" + attribute + "]"); - } - #endregion - nameMap.Add( methodName, attribute ); - } - - /// - /// Parses the given properties into a name/attribute map. - /// - /// - /// Expects method names as keys and string attributes definitions as values, - /// parsable into - /// instances via - /// . - /// - /// The properties of the transaction. - public void SetProperties( NameValueCollection transactionAttributes ) - { - TransactionAttributeEditor editor = new TransactionAttributeEditor(); - foreach ( string methodName in transactionAttributes.Keys ) - { - string value = transactionAttributes[methodName]; - editor.SetAsText(value); - AddTransactionMethod(methodName, editor.Value); - } - } - - #region ITransactionAttributeSource Members - /// - /// Return the for this - /// method. - /// - /// The method to check. - /// - /// The target . May be null, in which case the declaring - /// class of the supplied must be used. - /// - /// - /// A or - /// null if the method is non-transactional. - /// - public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) - { - string methodName = method.Name; - ITransactionAttribute attribute = (ITransactionAttribute) nameMap[methodName]; - if ( attribute != null ) - { - return attribute; - } - else - { - string bestNameMatch = null; - foreach ( string mappedName in nameMap.Keys ) - { - if ( ( IsMatch( methodName, mappedName ) ) && ( bestNameMatch == null || bestNameMatch.Length <= mappedName.Length ) ) - { - attribute = (ITransactionAttribute) nameMap[mappedName]; - bestNameMatch = mappedName; - } - } - } - return attribute; - } - #endregion - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Reflection; +using Common.Logging; +using Spring.Util; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Simple implementation of the + /// that allows attributes to be matched by registered name. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class NameMatchTransactionAttributeSource : ITransactionAttributeSource + { + /// + /// Logger available to subclasses, static for optimal serialization + /// + [NonSerialized()] + protected static readonly ILog log = LogManager.GetLogger(typeof(NameMatchTransactionAttributeSource)); + + /// + /// Keys are method names; values are ITransactionAttributes + /// + private IDictionary nameMap; + + /// + /// Creates a new instance of the + /// class. + /// + public NameMatchTransactionAttributeSource() + { + nameMap = new Hashtable(); + } + + /// + /// Set a name/attribute map, consisting of method names (e.g. "MyMethod") and + /// instances + /// (or Strings to be converted to ITransactionAttribute instances). + /// + public IDictionary NameMap + { + set + { + foreach (DictionaryEntry entry in value) + { + string name = entry.Key as string; + ITransactionAttribute attribute = null; + if (entry.Value is ITransactionAttribute) + { + attribute = entry.Value as ITransactionAttribute; + } + else + { + TransactionAttributeEditor editor = new TransactionAttributeEditor(); + editor.SetAsText(entry.Value.ToString()); + attribute = editor.Value; + } + AddTransactionMethod(name, attribute); + } + } + } + + /// + /// Parses the given properties into a name/attribute map. + /// + /// + /// Expects method names as keys and string attributes definitions as values, + /// parsable into + /// instances via + /// . + /// + /// The properties of the transaction. + public NameValueCollection NameProperties + { + set + { + SetProperties(value); + } + } + + /// + /// Does the supplied match the supplied ? + /// + /// + /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches, + /// as well as direct equality. Can be overridden in subclasses. + /// + /// The method name of the class. + /// The name in the descriptor. + /// True if the names match. + protected virtual bool IsMatch( string methodName, string mappedName ) + { + return PatternMatchUtils.SimpleMatch(mappedName, methodName); + } + + /// + /// Add an attribute for a transactional method. + /// + /// + ///

+ /// Method names can end with "*" for matching multiple methods. + ///

+ ///
+ /// The transactional method name. + /// + /// The attribute to be associated with the method. + /// + public void AddTransactionMethod( string methodName, ITransactionAttribute attribute ) + { + #region Instrumentation + if (log.IsDebugEnabled) + { + log.Debug("Adding transactional method [" + methodName + "] with attribute [" + attribute + "]"); + } + #endregion + nameMap.Add( methodName, attribute ); + } + + /// + /// Parses the given properties into a name/attribute map. + /// + /// + /// Expects method names as keys and string attributes definitions as values, + /// parsable into + /// instances via + /// . + /// + /// The properties of the transaction. + public void SetProperties( NameValueCollection transactionAttributes ) + { + TransactionAttributeEditor editor = new TransactionAttributeEditor(); + foreach ( string methodName in transactionAttributes.Keys ) + { + string value = transactionAttributes[methodName]; + editor.SetAsText(value); + AddTransactionMethod(methodName, editor.Value); + } + } + + #region ITransactionAttributeSource Members + /// + /// Return the for this + /// method. + /// + /// The method to check. + /// + /// The target . May be null, in which case the declaring + /// class of the supplied must be used. + /// + /// + /// A or + /// null if the method is non-transactional. + /// + public ITransactionAttribute ReturnTransactionAttribute(MethodInfo method, Type targetType) + { + string methodName = method.Name; + ITransactionAttribute attribute = (ITransactionAttribute) nameMap[methodName]; + if ( attribute != null ) + { + return attribute; + } + else + { + string bestNameMatch = null; + foreach ( string mappedName in nameMap.Keys ) + { + if ( ( IsMatch( methodName, mappedName ) ) && ( bestNameMatch == null || bestNameMatch.Length <= mappedName.Length ) ) + { + attribute = (ITransactionAttribute) nameMap[mappedName]; + bestNameMatch = mappedName; + } + } + } + return attribute; + } + #endregion + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/NoRollbackRuleAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/NoRollbackRuleAttribute.cs index 6a34075b..7b986a70 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/NoRollbackRuleAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/NoRollbackRuleAttribute.cs @@ -1,49 +1,48 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Tag class. Its class means it has the opposite behaviour to the - /// superclass. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: NoRollbackRuleAttribute.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - public class NoRollbackRuleAttribute : RollbackRuleAttribute - { - /// - /// Creates a new instance of the - /// class. - /// - public NoRollbackRuleAttribute( string exceptionType ) : base( exceptionType ){} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The class that will trigger a rollback. - /// - public NoRollbackRuleAttribute( Type exceptionType ) : base( exceptionType ){} - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Tag class. Its class means it has the opposite behaviour to the + /// superclass. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + public class NoRollbackRuleAttribute : RollbackRuleAttribute + { + /// + /// Creates a new instance of the + /// class. + /// + public NoRollbackRuleAttribute( string exceptionType ) : base( exceptionType ){} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The class that will trigger a rollback. + /// + public NoRollbackRuleAttribute( Type exceptionType ) : base( exceptionType ){} + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/RollbackRuleAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/RollbackRuleAttribute.cs index 7e86714b..15565bbb 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/RollbackRuleAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/RollbackRuleAttribute.cs @@ -1,202 +1,201 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Spring.Aop.Framework; -using Spring.Util; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Rule determining whether or not a given exception (and any subclasses) should - /// cause a rollback. - /// - /// - ///

- /// Multiple such rules can be applied to determine whether a transaction should commit - /// or rollback after an exception has been thrown. - ///

- ///
- /// Griffin Caprio (.NET) - /// $Id: RollbackRuleAttribute.cs,v 1.7 2008/03/31 20:09:59 markpollack Exp $ - [Serializable] - public class RollbackRuleAttribute : Attribute - { - private string _exceptionName; - - /// - /// Canonical instance representing default behavior for rolling back on - /// all s. - /// - public static RollbackRuleAttribute RollbackOnSystemExceptions - = new RollbackRuleAttribute(typeof (Exception).Name); - - /// - /// Creates a new instance of the - /// class - /// for the named . - /// - /// The exception name. - /// - ///

- /// As always, the should be the full - /// assembly qualified version. - ///

- ///
- public RollbackRuleAttribute( string exceptionName ) - { - AssertUtils.ArgumentHasText(exceptionName, "exceptionName"); - _exceptionName = exceptionName; - } - - /// - /// Creates a new instance of the - /// class - /// for the suplied . - /// - /// - ///

- /// The exception class must be or a subclass. - ///

- ///

- /// This is the preferred way to construct a - /// , - /// matching the exception class and subclasses. - ///

- ///
- /// - /// The class that will trigger a rollback. - /// - public RollbackRuleAttribute( Type exceptionType ) - { - AssertUtils.ArgumentNotNull(exceptionType, "exceptionType"); - if ( ! typeof(Exception).IsAssignableFrom( exceptionType ) ) - { - throw new AopConfigException("Cannot construct rollback rule from " + exceptionType + "; " + "It's not an Exception"); - } - _exceptionName = exceptionType.Name; - } - - /// - /// Returns the name of the exception. - /// - public string ExceptionName - { - get { return _exceptionName; } - } - - /// - /// Return the depth to the matching superclass execption . - /// - /// - /// A return value of 0 means that the matches. - /// - /// - /// The of exception to find. - /// - /// - /// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins. - /// - public int GetDepth( Type exceptionType ) - { - return getDepth( exceptionType, 0 ); - } - - /// - /// Return the depth to the matching superclass execption . - /// - /// - /// A return value of 0 means that the s - /// matches. - /// - /// - /// The exception object to find. - /// - /// - /// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins. - /// - public int GetDepth( object exception ) - { - return GetDepth( exception.GetType() ); - } - - /// - /// Returns a representation of this instance. - /// - /// - /// A containing the exception covered by this instance. - /// - public override string ToString() - { - return "RollbackRule with pattern '" + ExceptionName + "'"; - } - - /// - /// Override of . - /// - /// The hashcode of the exception name covered by this instance. - public override int GetHashCode() - { - return ExceptionName.GetHashCode(); - } - - /// - /// Override of . - /// - /// The object to compare. - /// True if the input object is equal to this instance. - public override bool Equals(object obj) - { - RollbackRuleAttribute rollbackRuleAttribute = obj as RollbackRuleAttribute; - if ( rollbackRuleAttribute == null ) - { - return false; - } - return Equals( rollbackRuleAttribute ); - } - - /// - /// Strongly typed Equals() implementation. - /// - /// - /// The to compare. - /// - /// - /// True if the input object is equal to the supplied . - /// - public bool Equals( RollbackRuleAttribute rollbackRuleAttribute ) - { - return ExceptionName.Equals(rollbackRuleAttribute.ExceptionName); - } - - private int getDepth( Type exceptionType, int depth ) - { - if ( ( exceptionType.Name.IndexOf( ExceptionName ) != -1 ) || ( exceptionType.FullName.IndexOf( ExceptionName ) != -1 ) ) - { - return depth; - } - if ( exceptionType == typeof(Exception)) - { - return -1; - } - return getDepth( exceptionType.BaseType, depth + 1 ); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Spring.Aop.Framework; +using Spring.Util; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Rule determining whether or not a given exception (and any subclasses) should + /// cause a rollback. + /// + /// + ///

+ /// Multiple such rules can be applied to determine whether a transaction should commit + /// or rollback after an exception has been thrown. + ///

+ ///
+ /// Griffin Caprio (.NET) + [Serializable] + public class RollbackRuleAttribute : Attribute + { + private string _exceptionName; + + /// + /// Canonical instance representing default behavior for rolling back on + /// all s. + /// + public static RollbackRuleAttribute RollbackOnSystemExceptions + = new RollbackRuleAttribute(typeof (Exception).Name); + + /// + /// Creates a new instance of the + /// class + /// for the named . + /// + /// The exception name. + /// + ///

+ /// As always, the should be the full + /// assembly qualified version. + ///

+ ///
+ public RollbackRuleAttribute( string exceptionName ) + { + AssertUtils.ArgumentHasText(exceptionName, "exceptionName"); + _exceptionName = exceptionName; + } + + /// + /// Creates a new instance of the + /// class + /// for the suplied . + /// + /// + ///

+ /// The exception class must be or a subclass. + ///

+ ///

+ /// This is the preferred way to construct a + /// , + /// matching the exception class and subclasses. + ///

+ ///
+ /// + /// The class that will trigger a rollback. + /// + public RollbackRuleAttribute( Type exceptionType ) + { + AssertUtils.ArgumentNotNull(exceptionType, "exceptionType"); + if ( ! typeof(Exception).IsAssignableFrom( exceptionType ) ) + { + throw new AopConfigException("Cannot construct rollback rule from " + exceptionType + "; " + "It's not an Exception"); + } + _exceptionName = exceptionType.Name; + } + + /// + /// Returns the name of the exception. + /// + public string ExceptionName + { + get { return _exceptionName; } + } + + /// + /// Return the depth to the matching superclass execption . + /// + /// + /// A return value of 0 means that the matches. + /// + /// + /// The of exception to find. + /// + /// + /// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins. + /// + public int GetDepth( Type exceptionType ) + { + return getDepth( exceptionType, 0 ); + } + + /// + /// Return the depth to the matching superclass execption . + /// + /// + /// A return value of 0 means that the s + /// matches. + /// + /// + /// The exception object to find. + /// + /// + /// Return -1 if there's no match. Otherwise, return depth. Lowest depth wins. + /// + public int GetDepth( object exception ) + { + return GetDepth( exception.GetType() ); + } + + /// + /// Returns a representation of this instance. + /// + /// + /// A containing the exception covered by this instance. + /// + public override string ToString() + { + return "RollbackRule with pattern '" + ExceptionName + "'"; + } + + /// + /// Override of . + /// + /// The hashcode of the exception name covered by this instance. + public override int GetHashCode() + { + return ExceptionName.GetHashCode(); + } + + /// + /// Override of . + /// + /// The object to compare. + /// True if the input object is equal to this instance. + public override bool Equals(object obj) + { + RollbackRuleAttribute rollbackRuleAttribute = obj as RollbackRuleAttribute; + if ( rollbackRuleAttribute == null ) + { + return false; + } + return Equals( rollbackRuleAttribute ); + } + + /// + /// Strongly typed Equals() implementation. + /// + /// + /// The to compare. + /// + /// + /// True if the input object is equal to the supplied . + /// + public bool Equals( RollbackRuleAttribute rollbackRuleAttribute ) + { + return ExceptionName.Equals(rollbackRuleAttribute.ExceptionName); + } + + private int getDepth( Type exceptionType, int depth ) + { + if ( ( exceptionType.Name.IndexOf( ExceptionName ) != -1 ) || ( exceptionType.FullName.IndexOf( ExceptionName ) != -1 ) ) + { + return depth; + } + if ( exceptionType == typeof(Exception)) + { + return -1; + } + return getDepth( exceptionType.BaseType, depth + 1 ); + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/RuleBasedTransactionAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/RuleBasedTransactionAttribute.cs index 9d362869..303e7926 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/RuleBasedTransactionAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/RuleBasedTransactionAttribute.cs @@ -1,159 +1,158 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Text; - -using Spring.Collections; - -namespace Spring.Transaction.Interceptor -{ - /// - /// implementation - /// that works out whether a given exception should cause transaction rollback by applying - /// a number of rollback rules, both positive and negative. - /// - /// - /// If no rules are relevant to the exception, it behaves like the - /// class - /// (rolling back on runtime exceptions).. - ///

- /// The - /// creates objects of this class. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: RuleBasedTransactionAttribute.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - public class RuleBasedTransactionAttribute : DefaultTransactionAttribute - { - private IList _rollbackRules; - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The desired transaction propagation behaviour. - /// - /// - /// The rollback rules list for this transaction attribute. - /// - public RuleBasedTransactionAttribute( - TransactionPropagation transactionPropagation, IList ruleList ) - : base(transactionPropagation) - { - _rollbackRules = ruleList; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - public RuleBasedTransactionAttribute( ) - { - _rollbackRules = new ArrayList(); - } - - /// - /// Sets the rollback rules list for this transaction attribute. - /// - public IList RollbackRules - { - set { _rollbackRules = value; } - } - - /// - /// Will a transaction be rolled back if the supplied - /// is thrown during the lifecycle of a transaction to which this attribute is applied? - /// - /// The offending . - /// True if the exception should cause a rollback, false otherwise. - public override bool RollbackOn(Exception exception) - { - RollbackRuleAttribute finalAttribute = null; - int deepest = Int32.MaxValue; - - if ( _rollbackRules != null ) - { - foreach ( RollbackRuleAttribute rule in _rollbackRules ) - { - int depth = rule.GetDepth( exception ); - if ( ( depth >= 0 ) && ( depth < deepest ) ) - { - deepest = depth; - finalAttribute = rule; - } - } - } - if ( null == finalAttribute ) - { - return base.RollbackOn( exception ); - } - return !( finalAttribute is NoRollbackRuleAttribute ); - } - - /// - /// Returns a representation of this instance. - /// - /// - /// A representation of this instance. - /// - public override string ToString() - { - StringBuilder result = new StringBuilder(); - result.Append(DefinitionDescription); - SortedSet rules = new SortedSet(); - foreach ( RollbackRuleAttribute rule in _rollbackRules ) - { - string sign = ( rule is NoRollbackRuleAttribute ) ? COMMIT_RULE_PREFIX : ROLLBACK_RULE_PREFIX; - rules.Add( sign + rule.ExceptionName ); - } - foreach ( string rule in rules ) - { - result.Append(','); - result.Append(rule); - } - return result.ToString( ); - } - /// - /// Adds a to this - /// attributes list of rollback rules. - /// - /// - /// The to add. - /// - public void AddRollbackRule( RollbackRuleAttribute rule ) - { - _rollbackRules.Add( rule ); - } - - /// - /// Clears the rollback rules for this attribute. - /// - public void ClearRollbackRules() - { - _rollbackRules.Clear(); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Text; + +using Spring.Collections; + +namespace Spring.Transaction.Interceptor +{ + /// + /// implementation + /// that works out whether a given exception should cause transaction rollback by applying + /// a number of rollback rules, both positive and negative. + /// + /// + /// If no rules are relevant to the exception, it behaves like the + /// class + /// (rolling back on runtime exceptions).. + ///

+ /// The + /// creates objects of this class. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + public class RuleBasedTransactionAttribute : DefaultTransactionAttribute + { + private IList _rollbackRules; + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The desired transaction propagation behaviour. + /// + /// + /// The rollback rules list for this transaction attribute. + /// + public RuleBasedTransactionAttribute( + TransactionPropagation transactionPropagation, IList ruleList ) + : base(transactionPropagation) + { + _rollbackRules = ruleList; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + public RuleBasedTransactionAttribute( ) + { + _rollbackRules = new ArrayList(); + } + + /// + /// Sets the rollback rules list for this transaction attribute. + /// + public IList RollbackRules + { + set { _rollbackRules = value; } + } + + /// + /// Will a transaction be rolled back if the supplied + /// is thrown during the lifecycle of a transaction to which this attribute is applied? + /// + /// The offending . + /// True if the exception should cause a rollback, false otherwise. + public override bool RollbackOn(Exception exception) + { + RollbackRuleAttribute finalAttribute = null; + int deepest = Int32.MaxValue; + + if ( _rollbackRules != null ) + { + foreach ( RollbackRuleAttribute rule in _rollbackRules ) + { + int depth = rule.GetDepth( exception ); + if ( ( depth >= 0 ) && ( depth < deepest ) ) + { + deepest = depth; + finalAttribute = rule; + } + } + } + if ( null == finalAttribute ) + { + return base.RollbackOn( exception ); + } + return !( finalAttribute is NoRollbackRuleAttribute ); + } + + /// + /// Returns a representation of this instance. + /// + /// + /// A representation of this instance. + /// + public override string ToString() + { + StringBuilder result = new StringBuilder(); + result.Append(DefinitionDescription); + SortedSet rules = new SortedSet(); + foreach ( RollbackRuleAttribute rule in _rollbackRules ) + { + string sign = ( rule is NoRollbackRuleAttribute ) ? COMMIT_RULE_PREFIX : ROLLBACK_RULE_PREFIX; + rules.Add( sign + rule.ExceptionName ); + } + foreach ( string rule in rules ) + { + result.Append(','); + result.Append(rule); + } + return result.ToString( ); + } + /// + /// Adds a to this + /// attributes list of rollback rules. + /// + /// + /// The to add. + /// + public void AddRollbackRule( RollbackRuleAttribute rule ) + { + _rollbackRules.Add( rule ); + } + + /// + /// Clears the rollback rules for this attribute. + /// + public void ClearRollbackRules() + { + _rollbackRules.Clear(); + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs index 661c6759..e0eab33d 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs @@ -1,496 +1,495 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections.Specialized; -using System.Reflection; -using Common.Logging; -using Spring.Objects.Factory; -using Spring.Threading; -using Spring.Util; -using IsolationLevel=System.Data.IsolationLevel; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Superclass for transaction aspects, such as the AOP Alliance-compatible - /// . - /// - /// - ///

- /// This enables the underlying Spring transaction infrastructure to be used - /// to easily implement an aspect for any aspect system. - ///

- ///

- /// Subclasses are responsible for calling methods in this class in the correct order. - ///

- ///

- /// Uses the Strategy design pattern. A - /// implementation will perform the actual transaction management - ///

- ///

- /// A transaction aspect is serializable if its - /// and - /// are serializable. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: TransactionAspectSupport.cs,v 1.15 2008/05/27 19:06:57 markpollack Exp $ - [Serializable] - public class TransactionAspectSupport : IInitializingObject - { - //TODO work on serialization support. - - #region TransactionInfo Class - /// - /// Opaque object used to hold transaction information. - /// - /// - ///

- /// Subclasses must pass it back to method on this class, but not see its internals. - ///

- ///
- internal protected class TransactionInfo - { - - private ITransactionAttribute _transactionAttribute; - private string _joinpointIdentification; - private ITransactionStatus _transactionStatus; - private TransactionInfo _oldTransactionInfo; - - /// - /// Creates a new instance of the - /// - /// class for the supplied . - /// - /// The transaction attributes to associate with any transaction. - /// The info for diagnostic display of joinpoint - public TransactionInfo( ITransactionAttribute transactionAttribute, string joinpointIdentification) - { - _transactionAttribute = transactionAttribute; - _joinpointIdentification = joinpointIdentification; - } - - /// - /// Does this instance currently have a transaction? - /// - /// True if this instance has a transaction. - public bool HasTransaction - { - get { return _transactionStatus != null; } - } - - /// - /// Gets and sets the for this object. - /// - public ITransactionStatus TransactionStatus - { - set { _transactionStatus = value; } - get { return _transactionStatus; } - } - - /// - /// Binds this - /// - /// instance to the thread local storage variable for the current thread and - /// backs up the existing - /// - /// object for the current thread. - /// - public void BindToThread() - { - // Expose current TransactionStatus, preserving any existing TransactionStatus - // for restoration after this transaction is complete. - TransactionInfo currentTransactionInfo = LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo; - _oldTransactionInfo = currentTransactionInfo; - LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, this); - } - - /// - /// Restores the previous - /// - /// object to the current thread. - /// - public void RestoreThreadLocalStatus() - { - // Use stack to restore old transaction TransactionInfo. - // Will be null if none was set. - LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, _oldTransactionInfo); - } - - /// - /// Gets the current - /// for this - /// - /// object. - /// - public ITransactionAttribute TransactionAttribute - { - get { return _transactionAttribute; } - } - - /// - /// Gets the joinpoint identification. - /// - /// The joinpoint identification. - public string JoinpointIdentification - { - get { return _joinpointIdentification; } - } - } - #endregion - - #region Logging Definition - - [NonSerialized] - protected ILog log = LogManager.GetLogger(typeof (TransactionAspectSupport)); - - #endregion - - - /// - /// The name in thread local storage where the TransactionInfo object is located - /// - public const string CURRENT_TRANSACTIONINFO_SLOTNAME = "TransactionAspectSupport.CurrentTransactionInfoSlotName"; - - /// - /// The currently referenced by - /// this aspect - /// - private IPlatformTransactionManager _transactionManager; - - /// - /// The currently - /// referenced by this aspect. - /// - private ITransactionAttributeSource _transactionAttributeSource; - - /// - /// Creates a new instance of the - /// class. - /// - public TransactionAspectSupport() {} - - /// - /// Gets and sets the for - /// this aspect. - /// - public IPlatformTransactionManager TransactionManager - { - get { return _transactionManager; } - set { _transactionManager = value; } - } - - /// - /// Gets and sets the - /// for - /// this aspect. - /// - public ITransactionAttributeSource TransactionAttributeSource - { - get { return _transactionAttributeSource; } - set { _transactionAttributeSource = value; } - } - - /// - /// Returns the - /// of the current method invocation. - /// - /// - /// Mainly intended for code that wants to set the current transaction - /// rollback-only but not throw an application exception. - /// - /// - /// If the transaction info cannot be found, because the method was invoked - /// outside of an AOP invocation context. - /// - public static ITransactionStatus CurrentTransactionStatus - { - get { return CurrentTransactionInfo.TransactionStatus; } - } - - /// - /// Subclasses can use this to return the current - /// . - /// - /// - /// Only subclasses that cannot handle all operations in one method - /// need to use this mechanism to get at the current - /// . - /// An around advice such as an AOP Alliance - /// can hold a reference to the - /// - /// throughout the aspect method. - /// A - /// will be returned even if no transaction was created. The - /// - /// property can be used to query this. - /// - /// - /// If no transaction has been created by an aspect. - /// - protected static TransactionInfo CurrentTransactionInfo - { - get - { - TransactionInfo currentTransactionInfo = - LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo; - if (currentTransactionInfo == null) - { - throw new NoTransactionException("No transaction aspect-managed ITransactionStatus in scope"); - } - return currentTransactionInfo; - } - } - /// - /// Set properties with method names as keys and transaction attribute - /// descriptors (parsed via ) as values: - /// e.g. key = "MyMethod", value = "PROPAGATION_REQUIRED,readOnly". - /// - /// - /// - /// Method names are always applied to the target class, no matter if defined in an - /// interface or the class itself. - /// - ///

- /// Internally, a - /// - /// will be created from the given properties. - ///

- ///
- public NameValueCollection TransactionAttributes - { - set - { - NameMatchTransactionAttributeSource attributeSource = new NameMatchTransactionAttributeSource(); - attributeSource.NameProperties = value; - _transactionAttributeSource = attributeSource; - } - } - - /// - /// Checks that the required properties are set. - /// - public void AfterPropertiesSet() - { - if ( null == _transactionManager) - { - throw new ArgumentException("IPlatformTransactionManager is required"); - } - if ( null == _transactionAttributeSource ) - { - throw new ArgumentException("Either 'TransactionAttributeSource' or 'TransactionAttribute' property is required: " + - "If there are no transactional methods, don't use a TransactionInterceptor " + - "or TransactionProxyFactoryObject." ); - } - } - - /// - /// Create a transaction if necessary - /// - /// Method about to execute - /// Type that the method is on - /// - /// A object, - /// whether or not a transaction was created. - ///

- /// The - /// - /// property on the - /// - /// class can be used to tell if there was a transaction created. - ///

- ///
- protected TransactionInfo CreateTransactionIfNecessary( MethodInfo method, Type targetType ) - { - // If the transaction attribute is null, the method is non-transactional. - ITransactionAttribute sourceAttr = _transactionAttributeSource.ReturnTransactionAttribute( method, targetType ); - - return CreateTransactionIfNecessary(sourceAttr, MethodIdentification(method)); - } - - /// - /// Creates the transaction if necessary. - /// - /// The source transaction attribute. - /// The joinpoint identification. - /// Transaction Info for declarative transaction management. - protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification) - { - ITransactionAttribute txAttr = sourceAttr; - - if (txAttr != null && txAttr.Name == null) - { - txAttr = new DelegatingTransactionAttributeWithName(txAttr, joinpointIdentification); - } - - TransactionInfo transactionInfo = new TransactionInfo(txAttr, joinpointIdentification); - if ( txAttr != null ) - { - // We need a transaction for this method - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Getting transaction for " + transactionInfo.JoinpointIdentification); - } - - #endregion - // The transaction manager will flag an error if an incompatible tx already exists - transactionInfo.TransactionStatus = _transactionManager.GetTransaction(txAttr); - } - else - { - // The TransactionInfo.HasTransaction property will return - // false. We created it only to preserve the integrity of - // the ThreadLocal stack maintained in this class. - if (log.IsDebugEnabled) - { - log.Debug("Don't need to create transaction for [" + joinpointIdentification + - "]: this method isn't transactional"); - } - } - - // We always bind the TransactionInfo to the thread, even if we didn't create - // a new transaction here. This guarantees that the TransactionInfo stack - // will be managed correctly even if no transaction was created by this aspect. - transactionInfo.BindToThread( ); - return transactionInfo; - } - - /// - /// Identifies the method by providing the qualfied method name. - /// - /// The method info. - /// qualified mehtod name. - protected string MethodIdentification(MethodInfo methodInfo) - { - return ObjectUtils.GetQualifiedMethodName(methodInfo); - } - - /// - /// Execute after the successful completion of call, but not after an exception was handled. - /// - /// - ///

- /// Do nothing if we didn't create a transaction. - ///

- ///
- /// - /// The - /// - /// about the current transaction. - /// - protected void CommitTransactionAfterReturning( TransactionInfo transactionInfo ) - { - if ( transactionInfo != null && transactionInfo.HasTransaction ) - { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Invoking commit for transaction on " + transactionInfo.JoinpointIdentification); - } - - #endregion - - _transactionManager.Commit( transactionInfo.TransactionStatus ); - } - } - - /// - /// Handle a exception, closing out the transaction. - /// - /// - ///

- /// We may commit or roll back, depending on our configuration. - ///

- ///
- /// - /// The - /// - /// about the current transaction. - /// - /// The encountered. - protected void CompleteTransactionAfterThrowing( - TransactionInfo transactionInfo, Exception exception ) - { - if ( transactionInfo != null && transactionInfo.HasTransaction ) - { - if (log.IsDebugEnabled) - { - log.Debug("Completing transaction for [" + transactionInfo.JoinpointIdentification + "] after exception: " + exception); - } - - if ( transactionInfo.TransactionAttribute.RollbackOn( exception )) - { - try - { - _transactionManager.Rollback( transactionInfo.TransactionStatus ); - } - catch (Exception e) - { - log.Error("Application exception overridden by rollback exception", e); - throw; - } - } - else - { - // We don't roll back on this exception. - // Will still roll back if TransactionStatus.RollbackOnly is true. - try - { - _transactionManager.Commit(transactionInfo.TransactionStatus); - } catch (Exception e) - { - log.Error("Application exception overriden by commit exception", e); - throw; - } - - } - } - } - /// - /// Resets the - /// - /// for this thread. - /// - /// - /// - /// Call this in all cases: exceptions or normal return. - /// - /// - /// - /// The - /// - /// about the current transaction. May be null. - /// - protected void CleanupTransactionInfo( TransactionInfo transactionInfo ) - { - if ( transactionInfo != null ) - { - transactionInfo.RestoreThreadLocalStatus( ); - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections.Specialized; +using System.Reflection; +using Common.Logging; +using Spring.Objects.Factory; +using Spring.Threading; +using Spring.Util; +using IsolationLevel=System.Data.IsolationLevel; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Superclass for transaction aspects, such as the AOP Alliance-compatible + /// . + /// + /// + ///

+ /// This enables the underlying Spring transaction infrastructure to be used + /// to easily implement an aspect for any aspect system. + ///

+ ///

+ /// Subclasses are responsible for calling methods in this class in the correct order. + ///

+ ///

+ /// Uses the Strategy design pattern. A + /// implementation will perform the actual transaction management + ///

+ ///

+ /// A transaction aspect is serializable if its + /// and + /// are serializable. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + [Serializable] + public class TransactionAspectSupport : IInitializingObject + { + //TODO work on serialization support. + + #region TransactionInfo Class + /// + /// Opaque object used to hold transaction information. + /// + /// + ///

+ /// Subclasses must pass it back to method on this class, but not see its internals. + ///

+ ///
+ internal protected class TransactionInfo + { + + private ITransactionAttribute _transactionAttribute; + private string _joinpointIdentification; + private ITransactionStatus _transactionStatus; + private TransactionInfo _oldTransactionInfo; + + /// + /// Creates a new instance of the + /// + /// class for the supplied . + /// + /// The transaction attributes to associate with any transaction. + /// The info for diagnostic display of joinpoint + public TransactionInfo( ITransactionAttribute transactionAttribute, string joinpointIdentification) + { + _transactionAttribute = transactionAttribute; + _joinpointIdentification = joinpointIdentification; + } + + /// + /// Does this instance currently have a transaction? + /// + /// True if this instance has a transaction. + public bool HasTransaction + { + get { return _transactionStatus != null; } + } + + /// + /// Gets and sets the for this object. + /// + public ITransactionStatus TransactionStatus + { + set { _transactionStatus = value; } + get { return _transactionStatus; } + } + + /// + /// Binds this + /// + /// instance to the thread local storage variable for the current thread and + /// backs up the existing + /// + /// object for the current thread. + /// + public void BindToThread() + { + // Expose current TransactionStatus, preserving any existing TransactionStatus + // for restoration after this transaction is complete. + TransactionInfo currentTransactionInfo = LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo; + _oldTransactionInfo = currentTransactionInfo; + LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, this); + } + + /// + /// Restores the previous + /// + /// object to the current thread. + /// + public void RestoreThreadLocalStatus() + { + // Use stack to restore old transaction TransactionInfo. + // Will be null if none was set. + LogicalThreadContext.SetData(CURRENT_TRANSACTIONINFO_SLOTNAME, _oldTransactionInfo); + } + + /// + /// Gets the current + /// for this + /// + /// object. + /// + public ITransactionAttribute TransactionAttribute + { + get { return _transactionAttribute; } + } + + /// + /// Gets the joinpoint identification. + /// + /// The joinpoint identification. + public string JoinpointIdentification + { + get { return _joinpointIdentification; } + } + } + #endregion + + #region Logging Definition + + [NonSerialized] + protected ILog log = LogManager.GetLogger(typeof (TransactionAspectSupport)); + + #endregion + + + /// + /// The name in thread local storage where the TransactionInfo object is located + /// + public const string CURRENT_TRANSACTIONINFO_SLOTNAME = "TransactionAspectSupport.CurrentTransactionInfoSlotName"; + + /// + /// The currently referenced by + /// this aspect + /// + private IPlatformTransactionManager _transactionManager; + + /// + /// The currently + /// referenced by this aspect. + /// + private ITransactionAttributeSource _transactionAttributeSource; + + /// + /// Creates a new instance of the + /// class. + /// + public TransactionAspectSupport() {} + + /// + /// Gets and sets the for + /// this aspect. + /// + public IPlatformTransactionManager TransactionManager + { + get { return _transactionManager; } + set { _transactionManager = value; } + } + + /// + /// Gets and sets the + /// for + /// this aspect. + /// + public ITransactionAttributeSource TransactionAttributeSource + { + get { return _transactionAttributeSource; } + set { _transactionAttributeSource = value; } + } + + /// + /// Returns the + /// of the current method invocation. + /// + /// + /// Mainly intended for code that wants to set the current transaction + /// rollback-only but not throw an application exception. + /// + /// + /// If the transaction info cannot be found, because the method was invoked + /// outside of an AOP invocation context. + /// + public static ITransactionStatus CurrentTransactionStatus + { + get { return CurrentTransactionInfo.TransactionStatus; } + } + + /// + /// Subclasses can use this to return the current + /// . + /// + /// + /// Only subclasses that cannot handle all operations in one method + /// need to use this mechanism to get at the current + /// . + /// An around advice such as an AOP Alliance + /// can hold a reference to the + /// + /// throughout the aspect method. + /// A + /// will be returned even if no transaction was created. The + /// + /// property can be used to query this. + /// + /// + /// If no transaction has been created by an aspect. + /// + protected static TransactionInfo CurrentTransactionInfo + { + get + { + TransactionInfo currentTransactionInfo = + LogicalThreadContext.GetData(CURRENT_TRANSACTIONINFO_SLOTNAME) as TransactionInfo; + if (currentTransactionInfo == null) + { + throw new NoTransactionException("No transaction aspect-managed ITransactionStatus in scope"); + } + return currentTransactionInfo; + } + } + /// + /// Set properties with method names as keys and transaction attribute + /// descriptors (parsed via ) as values: + /// e.g. key = "MyMethod", value = "PROPAGATION_REQUIRED,readOnly". + /// + /// + /// + /// Method names are always applied to the target class, no matter if defined in an + /// interface or the class itself. + /// + ///

+ /// Internally, a + /// + /// will be created from the given properties. + ///

+ ///
+ public NameValueCollection TransactionAttributes + { + set + { + NameMatchTransactionAttributeSource attributeSource = new NameMatchTransactionAttributeSource(); + attributeSource.NameProperties = value; + _transactionAttributeSource = attributeSource; + } + } + + /// + /// Checks that the required properties are set. + /// + public void AfterPropertiesSet() + { + if ( null == _transactionManager) + { + throw new ArgumentException("IPlatformTransactionManager is required"); + } + if ( null == _transactionAttributeSource ) + { + throw new ArgumentException("Either 'TransactionAttributeSource' or 'TransactionAttribute' property is required: " + + "If there are no transactional methods, don't use a TransactionInterceptor " + + "or TransactionProxyFactoryObject." ); + } + } + + /// + /// Create a transaction if necessary + /// + /// Method about to execute + /// Type that the method is on + /// + /// A object, + /// whether or not a transaction was created. + ///

+ /// The + /// + /// property on the + /// + /// class can be used to tell if there was a transaction created. + ///

+ ///
+ protected TransactionInfo CreateTransactionIfNecessary( MethodInfo method, Type targetType ) + { + // If the transaction attribute is null, the method is non-transactional. + ITransactionAttribute sourceAttr = _transactionAttributeSource.ReturnTransactionAttribute( method, targetType ); + + return CreateTransactionIfNecessary(sourceAttr, MethodIdentification(method)); + } + + /// + /// Creates the transaction if necessary. + /// + /// The source transaction attribute. + /// The joinpoint identification. + /// Transaction Info for declarative transaction management. + protected TransactionInfo CreateTransactionIfNecessary(ITransactionAttribute sourceAttr, string joinpointIdentification) + { + ITransactionAttribute txAttr = sourceAttr; + + if (txAttr != null && txAttr.Name == null) + { + txAttr = new DelegatingTransactionAttributeWithName(txAttr, joinpointIdentification); + } + + TransactionInfo transactionInfo = new TransactionInfo(txAttr, joinpointIdentification); + if ( txAttr != null ) + { + // We need a transaction for this method + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Getting transaction for " + transactionInfo.JoinpointIdentification); + } + + #endregion + // The transaction manager will flag an error if an incompatible tx already exists + transactionInfo.TransactionStatus = _transactionManager.GetTransaction(txAttr); + } + else + { + // The TransactionInfo.HasTransaction property will return + // false. We created it only to preserve the integrity of + // the ThreadLocal stack maintained in this class. + if (log.IsDebugEnabled) + { + log.Debug("Don't need to create transaction for [" + joinpointIdentification + + "]: this method isn't transactional"); + } + } + + // We always bind the TransactionInfo to the thread, even if we didn't create + // a new transaction here. This guarantees that the TransactionInfo stack + // will be managed correctly even if no transaction was created by this aspect. + transactionInfo.BindToThread( ); + return transactionInfo; + } + + /// + /// Identifies the method by providing the qualfied method name. + /// + /// The method info. + /// qualified mehtod name. + protected string MethodIdentification(MethodInfo methodInfo) + { + return ObjectUtils.GetQualifiedMethodName(methodInfo); + } + + /// + /// Execute after the successful completion of call, but not after an exception was handled. + /// + /// + ///

+ /// Do nothing if we didn't create a transaction. + ///

+ ///
+ /// + /// The + /// + /// about the current transaction. + /// + protected void CommitTransactionAfterReturning( TransactionInfo transactionInfo ) + { + if ( transactionInfo != null && transactionInfo.HasTransaction ) + { + #region Instrumentation + + if (log.IsDebugEnabled) + { + log.Debug("Invoking commit for transaction on " + transactionInfo.JoinpointIdentification); + } + + #endregion + + _transactionManager.Commit( transactionInfo.TransactionStatus ); + } + } + + /// + /// Handle a exception, closing out the transaction. + /// + /// + ///

+ /// We may commit or roll back, depending on our configuration. + ///

+ ///
+ /// + /// The + /// + /// about the current transaction. + /// + /// The encountered. + protected void CompleteTransactionAfterThrowing( + TransactionInfo transactionInfo, Exception exception ) + { + if ( transactionInfo != null && transactionInfo.HasTransaction ) + { + if (log.IsDebugEnabled) + { + log.Debug("Completing transaction for [" + transactionInfo.JoinpointIdentification + "] after exception: " + exception); + } + + if ( transactionInfo.TransactionAttribute.RollbackOn( exception )) + { + try + { + _transactionManager.Rollback( transactionInfo.TransactionStatus ); + } + catch (Exception e) + { + log.Error("Application exception overridden by rollback exception", e); + throw; + } + } + else + { + // We don't roll back on this exception. + // Will still roll back if TransactionStatus.RollbackOnly is true. + try + { + _transactionManager.Commit(transactionInfo.TransactionStatus); + } catch (Exception e) + { + log.Error("Application exception overriden by commit exception", e); + throw; + } + + } + } + } + /// + /// Resets the + /// + /// for this thread. + /// + /// + /// + /// Call this in all cases: exceptions or normal return. + /// + /// + /// + /// The + /// + /// about the current transaction. May be null. + /// + protected void CleanupTransactionInfo( TransactionInfo transactionInfo ) + { + if ( transactionInfo != null ) + { + transactionInfo.RestoreThreadLocalStatus( ); + } + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs index 0a461ce5..8422afe0 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs @@ -1,203 +1,202 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Data; -using Spring.Transaction.Support; - - -#endregion - -namespace Spring.Transaction.Interceptor -{ - /// - /// .NET Attribute for describing transactional behavior of methods in a class. - /// - /// This attribute type is generally directly comparable - /// to Spring's class and - /// in fact will - /// directly convert the data to a - /// so that Spring's transaction support code does not have to know about - /// attributes. If no rules are relevant to the exception it will be treaded - /// like DefaultTransactionAttribute, (rolling back on all exceptions). - /// - /// The default property values are TransactionPropagation.Required, IsolationLevel.ReadCommitted, - /// DefaultTransactionDefinition.TIMEOUT_DEFAULT (can be changed, by default is the default - /// value of the underlying transaction subsystem) - /// ReadOnly = false, and Type.EmtptyTypes specified for Rollbackfor and NoRollbackFor exception - /// types. - /// - /// - /// Mark Pollack (.NET) - /// $Id: TransactionAttribute.cs,v 1.8 2007/12/07 07:30:48 markpollack Exp $ - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, - Inherited = true)] - [Serializable] - public class TransactionAttribute : Attribute - { - #region Fields - private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; - private IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted; - private int _timeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; - private bool _readOnly = false; - private Type[] _rollbackTypes = Type.EmptyTypes; - private Type[] _noRollbackTypes = Type.EmptyTypes; -#if NET_2_0 - private System.Transactions.EnterpriseServicesInteropOption _esInteropOption = - System.Transactions.EnterpriseServicesInteropOption.Automatic; -#endif - - #endregion - - #region Constructor (s) - /// - /// Initializes a new instance of the class. - /// - public TransactionAttribute() - { - - } - - /// - /// Initializes a new instance of the class. - /// - /// The transaction propagation. - public TransactionAttribute(TransactionPropagation transactionPropagation) : this() - { - _transactionPropagation = transactionPropagation; - } - - /// - /// Initializes a new instance of the class. - /// - /// The transaction propagation. - /// The isolation level. - public TransactionAttribute(TransactionPropagation transactionPropagation, - IsolationLevel isolationLevel) : this(transactionPropagation) - { - _isolationLevel = isolationLevel; - } - - /// - /// Initializes a new instance of the class. - /// - /// The isolation level. - public TransactionAttribute(IsolationLevel isolationLevel) - { - _isolationLevel = isolationLevel; - } - - #endregion - - #region Properties - - /// - /// Gets the transaction propagation. - /// - /// Defaults to TransactionPropagation.Required - /// The transaction propagation. - public TransactionPropagation TransactionPropagation - { - get { return _transactionPropagation; } - } - - /// - /// Gets the isolation level. - /// - /// Defaults to IsolationLevel.Unspecified - /// The isolation level. - public IsolationLevel IsolationLevel - { - get { return _isolationLevel; } - } - - /// - /// Gets or sets the timeout. - /// - /// Defaults to the default timeout of the underlying transaction system. - /// The timeout. - public int Timeout - { - get { return _timeout; } - set { _timeout = value; } - } - - /// - /// Gets or sets a value indicating whether the transaction is readonly. - /// - /// Defaults to false - /// true if read-only; otherwise, false. - public bool ReadOnly - { - get { return _readOnly; } - set { _readOnly = value; } - } - - /// - /// Gets or sets the zero or more exception types which - /// indicating which exception types must cause a transaction - /// rollback. - /// - /// This is the preferred way to construct a rollback rule, - /// matching the exception class and subclasses. - /// The rollback types. - public Type[] RollbackFor - { - get { return _rollbackTypes; } - set { _rollbackTypes = value; } - } - - /// - /// Gets or sets zero or more exceptions types which - /// indicationg which exception type must not - /// cause a transaction rollback. - /// - /// This is the preferred way to construct a rollback rule, - /// matching the exception type. - /// The no rollback for. - public Type[] NoRollbackFor - { - get { return _noRollbackTypes; } - set { _noRollbackTypes = value; } - } - - -#if NET_2_0 - /// - /// Gets or sets the enterprise services interop option. - /// - /// The enterprise services interop option. - public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption - { - get { return _esInteropOption;} - set { _esInteropOption = value; } - } -#endif - - #endregion - - #region Methods - - #endregion - - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Data; +using Spring.Transaction.Support; + + +#endregion + +namespace Spring.Transaction.Interceptor +{ + /// + /// .NET Attribute for describing transactional behavior of methods in a class. + /// + /// This attribute type is generally directly comparable + /// to Spring's class and + /// in fact will + /// directly convert the data to a + /// so that Spring's transaction support code does not have to know about + /// attributes. If no rules are relevant to the exception it will be treaded + /// like DefaultTransactionAttribute, (rolling back on all exceptions). + /// + /// The default property values are TransactionPropagation.Required, IsolationLevel.ReadCommitted, + /// DefaultTransactionDefinition.TIMEOUT_DEFAULT (can be changed, by default is the default + /// value of the underlying transaction subsystem) + /// ReadOnly = false, and Type.EmtptyTypes specified for Rollbackfor and NoRollbackFor exception + /// types. + /// + /// + /// Mark Pollack (.NET) + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, + Inherited = true)] + [Serializable] + public class TransactionAttribute : Attribute + { + #region Fields + private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; + private IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted; + private int _timeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; + private bool _readOnly = false; + private Type[] _rollbackTypes = Type.EmptyTypes; + private Type[] _noRollbackTypes = Type.EmptyTypes; +#if NET_2_0 + private System.Transactions.EnterpriseServicesInteropOption _esInteropOption = + System.Transactions.EnterpriseServicesInteropOption.Automatic; +#endif + + #endregion + + #region Constructor (s) + /// + /// Initializes a new instance of the class. + /// + public TransactionAttribute() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The transaction propagation. + public TransactionAttribute(TransactionPropagation transactionPropagation) : this() + { + _transactionPropagation = transactionPropagation; + } + + /// + /// Initializes a new instance of the class. + /// + /// The transaction propagation. + /// The isolation level. + public TransactionAttribute(TransactionPropagation transactionPropagation, + IsolationLevel isolationLevel) : this(transactionPropagation) + { + _isolationLevel = isolationLevel; + } + + /// + /// Initializes a new instance of the class. + /// + /// The isolation level. + public TransactionAttribute(IsolationLevel isolationLevel) + { + _isolationLevel = isolationLevel; + } + + #endregion + + #region Properties + + /// + /// Gets the transaction propagation. + /// + /// Defaults to TransactionPropagation.Required + /// The transaction propagation. + public TransactionPropagation TransactionPropagation + { + get { return _transactionPropagation; } + } + + /// + /// Gets the isolation level. + /// + /// Defaults to IsolationLevel.Unspecified + /// The isolation level. + public IsolationLevel IsolationLevel + { + get { return _isolationLevel; } + } + + /// + /// Gets or sets the timeout. + /// + /// Defaults to the default timeout of the underlying transaction system. + /// The timeout. + public int Timeout + { + get { return _timeout; } + set { _timeout = value; } + } + + /// + /// Gets or sets a value indicating whether the transaction is readonly. + /// + /// Defaults to false + /// true if read-only; otherwise, false. + public bool ReadOnly + { + get { return _readOnly; } + set { _readOnly = value; } + } + + /// + /// Gets or sets the zero or more exception types which + /// indicating which exception types must cause a transaction + /// rollback. + /// + /// This is the preferred way to construct a rollback rule, + /// matching the exception class and subclasses. + /// The rollback types. + public Type[] RollbackFor + { + get { return _rollbackTypes; } + set { _rollbackTypes = value; } + } + + /// + /// Gets or sets zero or more exceptions types which + /// indicationg which exception type must not + /// cause a transaction rollback. + /// + /// This is the preferred way to construct a rollback rule, + /// matching the exception type. + /// The no rollback for. + public Type[] NoRollbackFor + { + get { return _noRollbackTypes; } + set { _noRollbackTypes = value; } + } + + +#if NET_2_0 + /// + /// Gets or sets the enterprise services interop option. + /// + /// The enterprise services interop option. + public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption + { + get { return _esInteropOption;} + set { _esInteropOption = value; } + } +#endif + + #endregion + + #region Methods + + #endregion + + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeConverter.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeConverter.cs index 8a91e2ed..86d9d9db 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeConverter.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeConverter.cs @@ -1,90 +1,89 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - - -using System; -using System.ComponentModel; -using System.Globalization; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Type converter for - /// objects. - /// - /// - /// Takes s of the form - ///

PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2

- ///

where only propagation code is required. For example:

- ///

PROPAGATION_MANDATORY,ISOLATION_DEFAULT

- ///

- /// The tokens can be in any order. Propagation and isolation codes - /// must use the names of the values in the - /// enumeration. Timeout values are in seconds. If no timeout is specified, the transaction - /// manager will apply a default timeout specific to the particular transaction manager. - ///

- ///

- /// A "+" before an exception name substring indicates that transactions should commit even - /// if this exception is thrown; a "-" that they should roll back. - ///

- ///
- /// Mark Pollack - /// $Id: TransactionAttributeConverter.cs,v 1.1 2007/12/29 00:28:53 markpollack Exp $ - public class TransactionAttributeConverter : TypeConverter - { - /// - /// Returns whether this converter can convert an object of the given type to an ITransactionAttribute, using the specified context. - /// - /// An that provides a format context. - /// A that represents the type you want to convert from. - /// - /// true if this converter can perform the conversion; otherwise, false. - /// - public override bool CanConvertFrom( - ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof (string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - /// Converts from string to ITransactionAttribute - /// - /// The context. - /// The culture. - /// The string value to convert - /// An ITransactionAttribute instance - public override object ConvertFrom( - ITypeDescriptorContext context, CultureInfo culture, object val) - { - if (val is string) - { - string value = val as string; - TransactionAttributeEditor editor = new TransactionAttributeEditor(); - editor.SetAsText(value); - return editor.Value; - } - return base.ConvertFrom(context, culture, val); - } - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + + +using System; +using System.ComponentModel; +using System.Globalization; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Type converter for + /// objects. + /// + /// + /// Takes s of the form + ///

PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2

+ ///

where only propagation code is required. For example:

+ ///

PROPAGATION_MANDATORY,ISOLATION_DEFAULT

+ ///

+ /// The tokens can be in any order. Propagation and isolation codes + /// must use the names of the values in the + /// enumeration. Timeout values are in seconds. If no timeout is specified, the transaction + /// manager will apply a default timeout specific to the particular transaction manager. + ///

+ ///

+ /// A "+" before an exception name substring indicates that transactions should commit even + /// if this exception is thrown; a "-" that they should roll back. + ///

+ ///
+ /// Mark Pollack + public class TransactionAttributeConverter : TypeConverter + { + /// + /// Returns whether this converter can convert an object of the given type to an ITransactionAttribute, using the specified context. + /// + /// An that provides a format context. + /// A that represents the type you want to convert from. + /// + /// true if this converter can perform the conversion; otherwise, false. + /// + public override bool CanConvertFrom( + ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof (string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + + /// + /// Converts from string to ITransactionAttribute + /// + /// The context. + /// The culture. + /// The string value to convert + /// An ITransactionAttribute instance + public override object ConvertFrom( + ITypeDescriptorContext context, CultureInfo culture, object val) + { + if (val is string) + { + string value = val as string; + TransactionAttributeEditor editor = new TransactionAttributeEditor(); + editor.SetAsText(value); + return editor.Value; + } + return base.ConvertFrom(context, culture, val); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeEditor.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeEditor.cs index c64647cb..7532b5a7 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeEditor.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeEditor.cs @@ -1,154 +1,153 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using Spring.Util; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Type converter for - /// objects. - /// - /// - /// Takes s of the form - ///

PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2

- ///

where only propagation code is required. For example:

- ///

PROPAGATION_MANDATORY,ISOLATION_DEFAULT

- ///

- /// The tokens can be in any order. Propagation and isolation codes - /// must use the names of the values in the - /// enumeration. Timeout values are in seconds. If no timeout is specified, the transaction - /// manager will apply a default timeout specific to the particular transaction manager. - ///

- ///

- /// A "+" before an exception name substring indicates that transactions should commit even - /// if this exception is thrown; a "-" that they should roll back. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: TransactionAttributeEditor.cs,v 1.7 2007/12/07 07:30:48 markpollack Exp $ - public class TransactionAttributeEditor - { - private RuleBasedTransactionAttribute _attribute; - - /// - /// Parses the input properties string into a valid - /// instance - /// - /// - /// The string defining the transactional properties. - /// - public void SetAsText( string transactionProperties ) - { - if (!StringUtils.HasText(transactionProperties)) - { - _attribute = null; - } - else - { - string[] tokens = StringUtils.CommaDelimitedListToStringArray( transactionProperties ); - RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute(); - for ( int i = 0; i < tokens.Length; i++ ) - { - string token = tokens[i].Trim(); - if ( token.StartsWith(DefaultTransactionAttribute.PROPAGATION_CONSTANT_PREFIX)) - { - attribute.PropagationBehavior = convertPropagationValue( token ); - } else if ( token.StartsWith(DefaultTransactionAttribute.ISOLATION_CONSTANT_PREFIX ) ) - { - attribute.TransactionIsolationLevel = convertIsolationValue( token ); - } else if ( token.StartsWith(DefaultTransactionAttribute.TIMEOUT_PREFIX ) ) - { - string value = token.Substring(DefaultTransactionAttribute.TIMEOUT_PREFIX.Length); - attribute.TransactionTimeout = Convert.ToInt32( value ); - } else if ( token.StartsWith( DefaultTransactionAttribute.READ_ONLY_MARKER ) ) - { - attribute.ReadOnly = true; - } else if ( token.StartsWith( DefaultTransactionAttribute.COMMIT_RULE_PREFIX ) ) - { - attribute.AddRollbackRule( new NoRollbackRuleAttribute(token.Substring( 1 ) ) ); - } else if ( token.StartsWith( DefaultTransactionAttribute.ROLLBACK_RULE_PREFIX ) ) - { - attribute.AddRollbackRule( new RollbackRuleAttribute( token.Substring( 1 ) ) ); - } else - { - throw new ArgumentException("Illegal transaction attribute token: [" + token + "]"); - } - } - _attribute = attribute; - } - } - - /// - /// Gets the - /// from this editor. - /// - public ITransactionAttribute Value - { - get { return _attribute; } - } - - private TransactionPropagation convertPropagationValue( string transactionPropagation ) - { - switch ( transactionPropagation.ToUpper() ) - { - case "PROPAGATION_REQUIRED": - return TransactionPropagation.Required; - case "PROPAGATION_SUPPORTS": - return TransactionPropagation.Supports; - case "PROPAGATION_MANDATORY": - return TransactionPropagation.Mandatory; - case "PROPAGATION_REQUIRES_NEW": - return TransactionPropagation.RequiresNew; - case "PROPAGATION_NOT_SUPPORTED": - return TransactionPropagation.NotSupported; - case "PROPAGATION_NEVER": - return TransactionPropagation.Never; - case "PROPAGATION_NESTED": - return TransactionPropagation.Nested; - default: - throw new ArgumentException("Illegal transaction propagation token: [" + transactionPropagation + "]"); - } - } - - private IsolationLevel convertIsolationValue( string isolationLevel ) - { - switch ( isolationLevel.ToUpper() ) - { - case "ISOLATION_DEFAULT": - return IsolationLevel.ReadCommitted; - case "ISOLATION_READUNCOMMITTED": - return IsolationLevel.ReadUncommitted; - case "ISOLATION_READCOMMITTED": - return IsolationLevel.ReadCommitted; - case "ISOLATION_REPEATABLEREAD": - return IsolationLevel.RepeatableRead; - case "ISOLATION_SERIALIZABLE": - return IsolationLevel.Serializable; - default: - return IsolationLevel.ReadCommitted; - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using Spring.Util; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Type converter for + /// objects. + /// + /// + /// Takes s of the form + ///

PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2

+ ///

where only propagation code is required. For example:

+ ///

PROPAGATION_MANDATORY,ISOLATION_DEFAULT

+ ///

+ /// The tokens can be in any order. Propagation and isolation codes + /// must use the names of the values in the + /// enumeration. Timeout values are in seconds. If no timeout is specified, the transaction + /// manager will apply a default timeout specific to the particular transaction manager. + ///

+ ///

+ /// A "+" before an exception name substring indicates that transactions should commit even + /// if this exception is thrown; a "-" that they should roll back. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + public class TransactionAttributeEditor + { + private RuleBasedTransactionAttribute _attribute; + + /// + /// Parses the input properties string into a valid + /// instance + /// + /// + /// The string defining the transactional properties. + /// + public void SetAsText( string transactionProperties ) + { + if (!StringUtils.HasText(transactionProperties)) + { + _attribute = null; + } + else + { + string[] tokens = StringUtils.CommaDelimitedListToStringArray( transactionProperties ); + RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute(); + for ( int i = 0; i < tokens.Length; i++ ) + { + string token = tokens[i].Trim(); + if ( token.StartsWith(DefaultTransactionAttribute.PROPAGATION_CONSTANT_PREFIX)) + { + attribute.PropagationBehavior = convertPropagationValue( token ); + } else if ( token.StartsWith(DefaultTransactionAttribute.ISOLATION_CONSTANT_PREFIX ) ) + { + attribute.TransactionIsolationLevel = convertIsolationValue( token ); + } else if ( token.StartsWith(DefaultTransactionAttribute.TIMEOUT_PREFIX ) ) + { + string value = token.Substring(DefaultTransactionAttribute.TIMEOUT_PREFIX.Length); + attribute.TransactionTimeout = Convert.ToInt32( value ); + } else if ( token.StartsWith( DefaultTransactionAttribute.READ_ONLY_MARKER ) ) + { + attribute.ReadOnly = true; + } else if ( token.StartsWith( DefaultTransactionAttribute.COMMIT_RULE_PREFIX ) ) + { + attribute.AddRollbackRule( new NoRollbackRuleAttribute(token.Substring( 1 ) ) ); + } else if ( token.StartsWith( DefaultTransactionAttribute.ROLLBACK_RULE_PREFIX ) ) + { + attribute.AddRollbackRule( new RollbackRuleAttribute( token.Substring( 1 ) ) ); + } else + { + throw new ArgumentException("Illegal transaction attribute token: [" + token + "]"); + } + } + _attribute = attribute; + } + } + + /// + /// Gets the + /// from this editor. + /// + public ITransactionAttribute Value + { + get { return _attribute; } + } + + private TransactionPropagation convertPropagationValue( string transactionPropagation ) + { + switch ( transactionPropagation.ToUpper() ) + { + case "PROPAGATION_REQUIRED": + return TransactionPropagation.Required; + case "PROPAGATION_SUPPORTS": + return TransactionPropagation.Supports; + case "PROPAGATION_MANDATORY": + return TransactionPropagation.Mandatory; + case "PROPAGATION_REQUIRES_NEW": + return TransactionPropagation.RequiresNew; + case "PROPAGATION_NOT_SUPPORTED": + return TransactionPropagation.NotSupported; + case "PROPAGATION_NEVER": + return TransactionPropagation.Never; + case "PROPAGATION_NESTED": + return TransactionPropagation.Nested; + default: + throw new ArgumentException("Illegal transaction propagation token: [" + transactionPropagation + "]"); + } + } + + private IsolationLevel convertIsolationValue( string isolationLevel ) + { + switch ( isolationLevel.ToUpper() ) + { + case "ISOLATION_DEFAULT": + return IsolationLevel.ReadCommitted; + case "ISOLATION_READUNCOMMITTED": + return IsolationLevel.ReadUncommitted; + case "ISOLATION_READCOMMITTED": + return IsolationLevel.ReadCommitted; + case "ISOLATION_REPEATABLEREAD": + return IsolationLevel.RepeatableRead; + case "ISOLATION_SERIALIZABLE": + return IsolationLevel.Serializable; + default: + return IsolationLevel.ReadCommitted; + } + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceAdvisor.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceAdvisor.cs index b1403cf8..5845c589 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceAdvisor.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceAdvisor.cs @@ -1,131 +1,130 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using Spring.Aop.Framework; -using Spring.Aop.Support; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Advisor driven by a , used to exclude - /// a from methods that - /// are non-transactional. - /// - /// - ///

- /// Because the AOP framework caches advice calculations, this is normally - /// faster than just letting the - /// run and find out itself that it has no work to do. - ///

- ///
- /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: TransactionAttributeSourceAdvisor.cs,v 1.11 2007/12/07 08:10:03 markpollack Exp $ - [Serializable] - public class TransactionAttributeSourceAdvisor : StaticMethodMatcherPointcutAdvisor - { - #region Fields - - private ITransactionAttributeSource _transactionAttributeSource; - - #endregion - - #region Constructor(s) - - /// - /// Initializes a new instance of the class. - /// - /// - ///

- /// This is an abstract class, and as such has no publicly - /// visible constructors. - ///

- ///
- public TransactionAttributeSourceAdvisor() - { - } - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The pre-configured transaction interceptor. - /// - public TransactionAttributeSourceAdvisor( TransactionInterceptor transactionInterceptor ) - : base( transactionInterceptor ) - { - SetTxAttributeSource(transactionInterceptor); - } - - #endregion - - #region Properties - - /// - /// Sets the transaction interceptor. - /// - /// The transaction interceptor. - public TransactionInterceptor TransactionInterceptor - { - set - { - //TODO refactor - Advice = value; - SetTxAttributeSource(value); - } - } - - #endregion - - #region Methods - - /// - /// Tests the input method to see if it's covered by the advisor. - /// - /// The method to match. - /// The to match against. - /// - /// True if the supplied is covered by the advisor. - /// - public override bool Matches(MethodInfo method, Type targetClass) - { - return (_transactionAttributeSource.ReturnTransactionAttribute(method, targetClass) != null); - } - - /// - /// Sets the tx attribute source. - /// - /// The transaction interceptor. - protected void SetTxAttributeSource(TransactionInterceptor transactionInterceptor) - { - if (transactionInterceptor.TransactionAttributeSource == null) - { - throw new AopConfigException("Cannot construct a TransactionAttributeSourceAdvisor using a " + - "TransactionInterceptor that has no TransactionAttributeSource configured."); - } - _transactionAttributeSource = transactionInterceptor.TransactionAttributeSource; - } - - #endregion - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using Spring.Aop.Framework; +using Spring.Aop.Support; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Advisor driven by a , used to exclude + /// a from methods that + /// are non-transactional. + /// + /// + ///

+ /// Because the AOP framework caches advice calculations, this is normally + /// faster than just letting the + /// run and find out itself that it has no work to do. + ///

+ ///
+ /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class TransactionAttributeSourceAdvisor : StaticMethodMatcherPointcutAdvisor + { + #region Fields + + private ITransactionAttributeSource _transactionAttributeSource; + + #endregion + + #region Constructor(s) + + /// + /// Initializes a new instance of the class. + /// + /// + ///

+ /// This is an abstract class, and as such has no publicly + /// visible constructors. + ///

+ ///
+ public TransactionAttributeSourceAdvisor() + { + } + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The pre-configured transaction interceptor. + /// + public TransactionAttributeSourceAdvisor( TransactionInterceptor transactionInterceptor ) + : base( transactionInterceptor ) + { + SetTxAttributeSource(transactionInterceptor); + } + + #endregion + + #region Properties + + /// + /// Sets the transaction interceptor. + /// + /// The transaction interceptor. + public TransactionInterceptor TransactionInterceptor + { + set + { + //TODO refactor + Advice = value; + SetTxAttributeSource(value); + } + } + + #endregion + + #region Methods + + /// + /// Tests the input method to see if it's covered by the advisor. + /// + /// The method to match. + /// The to match against. + /// + /// True if the supplied is covered by the advisor. + /// + public override bool Matches(MethodInfo method, Type targetClass) + { + return (_transactionAttributeSource.ReturnTransactionAttribute(method, targetClass) != null); + } + + /// + /// Sets the tx attribute source. + /// + /// The transaction interceptor. + protected void SetTxAttributeSource(TransactionInterceptor transactionInterceptor) + { + if (transactionInterceptor.TransactionAttributeSource == null) + { + throw new AopConfigException("Cannot construct a TransactionAttributeSourceAdvisor using a " + + "TransactionInterceptor that has no TransactionAttributeSource configured."); + } + _transactionAttributeSource = transactionInterceptor.TransactionAttributeSource; + } + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceEditor.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceEditor.cs index 18aef49b..20a65473 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceEditor.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttributeSourceEditor.cs @@ -1,149 +1,148 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using Spring.Util; - -namespace Spring.Transaction.Interceptor -{ - /// - /// Editor that can convert values into - /// instances. - /// - /// - /// The transaction attribute string must be parseable by the - /// in this package. - ///

- /// Strings must be specified in the following syntax:
- /// FQCN.methodName=<transaction attribute string> (sans <>). - ///

- /// - /// ExampleNamespace.ExampleClass.MyMethod=PROPAGATION_MANDATORY,ISOLATION_DEFAULT - /// - /// - /// The specified class must be the one where the methods are defined; in the case of - /// implementing an interface, the interface class name must be specified. - /// - ///

- /// This will register all overloaded methods for a given name. Does not support explicit - /// registration of certain overloaded methods. Supports wildcard style mappings (in - /// the form "xxx*"), e.g. "Notify*" for "Notify" and "NotifyAll". - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: TransactionAttributeSourceEditor.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - public class TransactionAttributeSourceEditor - { - #region PropertiesEditor Class - /// - /// Internal class to parse property values. - /// - protected internal class PropertiesEditor - { - private IDictionary _properties; - - /// - /// Creates a new instance of the - /// class. - /// - /// The property values to be parsed. - public PropertiesEditor( string properties ) - { - _properties = new Hashtable(); - parseProperties( properties ); - } - - /// - /// Indexer to return values based on index value. - /// - public string this[ string index ] - { - get { return (string) _properties[index]; } - } - - /// - /// Returns the collection of keys for properties. - /// - public ICollection Keys - { - get { return _properties.Keys; } - } - - private void parseProperties( string properties ) - { - string[] tokens = StringUtils.DelimitedListToStringArray( properties, "\n"); - foreach ( string token in tokens ) - { - string[] property = token.Split('='); - _properties.Add( property[0].Trim(), property[1].Trim()); - } - } - } - #endregion - - private ITransactionAttributeSource _attributeSource; - - /// - /// Creates a new instance of the - /// class. - /// - public TransactionAttributeSourceEditor() {} - - /// - /// Parses the input properties into a valid - /// - /// instance - /// - /// The properties string to be parsed. - public void SetAsText( string attributeSource ) - { - MethodMapTransactionAttributeSource source = new MethodMapTransactionAttributeSource(); - if ( attributeSource == null || attributeSource.Length == 0 ) - { - _attributeSource = null; - } else - { - PropertiesEditor editor = new PropertiesEditor(attributeSource); - TransactionAttributeEditor tae = new TransactionAttributeEditor(); - - foreach ( string name in editor.Keys ) - { - string value = editor[name]; - tae.SetAsText( value ); - ITransactionAttribute transactionAttribute = tae.Value; - source.AddTransactionalMethod( name, transactionAttribute ); - } - } - _attributeSource = source; - } - - /// - /// Gets the - /// from this instance. - /// - public ITransactionAttributeSource Value - { - get { return _attributeSource; } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using Spring.Util; + +namespace Spring.Transaction.Interceptor +{ + /// + /// Editor that can convert values into + /// instances. + /// + /// + /// The transaction attribute string must be parseable by the + /// in this package. + ///

+ /// Strings must be specified in the following syntax:
+ /// FQCN.methodName=<transaction attribute string> (sans <>). + ///

+ /// + /// ExampleNamespace.ExampleClass.MyMethod=PROPAGATION_MANDATORY,ISOLATION_DEFAULT + /// + /// + /// The specified class must be the one where the methods are defined; in the case of + /// implementing an interface, the interface class name must be specified. + /// + ///

+ /// This will register all overloaded methods for a given name. Does not support explicit + /// registration of certain overloaded methods. Supports wildcard style mappings (in + /// the form "xxx*"), e.g. "Notify*" for "Notify" and "NotifyAll". + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + public class TransactionAttributeSourceEditor + { + #region PropertiesEditor Class + /// + /// Internal class to parse property values. + /// + protected internal class PropertiesEditor + { + private IDictionary _properties; + + /// + /// Creates a new instance of the + /// class. + /// + /// The property values to be parsed. + public PropertiesEditor( string properties ) + { + _properties = new Hashtable(); + parseProperties( properties ); + } + + /// + /// Indexer to return values based on index value. + /// + public string this[ string index ] + { + get { return (string) _properties[index]; } + } + + /// + /// Returns the collection of keys for properties. + /// + public ICollection Keys + { + get { return _properties.Keys; } + } + + private void parseProperties( string properties ) + { + string[] tokens = StringUtils.DelimitedListToStringArray( properties, "\n"); + foreach ( string token in tokens ) + { + string[] property = token.Split('='); + _properties.Add( property[0].Trim(), property[1].Trim()); + } + } + } + #endregion + + private ITransactionAttributeSource _attributeSource; + + /// + /// Creates a new instance of the + /// class. + /// + public TransactionAttributeSourceEditor() {} + + /// + /// Parses the input properties into a valid + /// + /// instance + /// + /// The properties string to be parsed. + public void SetAsText( string attributeSource ) + { + MethodMapTransactionAttributeSource source = new MethodMapTransactionAttributeSource(); + if ( attributeSource == null || attributeSource.Length == 0 ) + { + _attributeSource = null; + } else + { + PropertiesEditor editor = new PropertiesEditor(attributeSource); + TransactionAttributeEditor tae = new TransactionAttributeEditor(); + + foreach ( string name in editor.Keys ) + { + string value = editor[name]; + tae.SetAsText( value ); + ITransactionAttribute transactionAttribute = tae.Value; + source.AddTransactionalMethod( name, transactionAttribute ); + } + } + _attributeSource = source; + } + + /// + /// Gets the + /// from this instance. + /// + public ITransactionAttributeSource Value + { + get { return _attributeSource; } + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionInterceptor.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionInterceptor.cs index 9e8731ab..458f5dbc 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionInterceptor.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionInterceptor.cs @@ -1,90 +1,89 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Reflection; -using AopAlliance.Intercept; - -namespace Spring.Transaction.Interceptor -{ - /// - /// An AOP Alliance providing - /// declarative transaction management using the common Spring.NET transaction infrastructure. - /// - /// - ///

- /// That class contains the necessary calls into Spring.NET's underlying - /// transaction API: subclasses such as this are responsible for calling - /// superclass methods such as - /// - /// in the correct order, in the event of normal invocation return or an exception. - ///

- ///

- /// s are thread-safe. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: TransactionInterceptor.cs,v 1.12 2007/09/07 04:46:53 markpollack Exp $ - [Serializable] - public class TransactionInterceptor : TransactionAspectSupport, IMethodInterceptor - { - /// - /// AOP Alliance invoke call that handles all transaction plumbing. - /// - /// - /// The method that is to execute in the context of a transaction. - /// - /// The return value from the method invocation. - public object Invoke(IMethodInvocation invocation) - { - // Work out the target class: may be null. - // The TransactionAttributeSource should be passed the target class - // as well as the method, which may be from an interface. - Type targetType = ( invocation.This != null ) ? invocation.This.GetType() : null; - - // If the transaction attribute is null, the method is non-transactional. - TransactionInfo txnInfo = CreateTransactionIfNecessary( invocation.Method, targetType ); - object returnValue = null; - - try - { - // This is an around advice. - // Invoke the next interceptor in the chain. - // This will normally result in a target object being invoked. - returnValue = invocation.Proceed(); - } - catch ( Exception ex ) - { - // target invocation exception - CompleteTransactionAfterThrowing( txnInfo, ex ); - throw; - } - finally - { - CleanupTransactionInfo( txnInfo ); - } - CommitTransactionAfterReturning( txnInfo ); - return returnValue; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Reflection; +using AopAlliance.Intercept; + +namespace Spring.Transaction.Interceptor +{ + /// + /// An AOP Alliance providing + /// declarative transaction management using the common Spring.NET transaction infrastructure. + /// + /// + ///

+ /// That class contains the necessary calls into Spring.NET's underlying + /// transaction API: subclasses such as this are responsible for calling + /// superclass methods such as + /// + /// in the correct order, in the event of normal invocation return or an exception. + ///

+ ///

+ /// s are thread-safe. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + [Serializable] + public class TransactionInterceptor : TransactionAspectSupport, IMethodInterceptor + { + /// + /// AOP Alliance invoke call that handles all transaction plumbing. + /// + /// + /// The method that is to execute in the context of a transaction. + /// + /// The return value from the method invocation. + public object Invoke(IMethodInvocation invocation) + { + // Work out the target class: may be null. + // The TransactionAttributeSource should be passed the target class + // as well as the method, which may be from an interface. + Type targetType = ( invocation.This != null ) ? invocation.This.GetType() : null; + + // If the transaction attribute is null, the method is non-transactional. + TransactionInfo txnInfo = CreateTransactionIfNecessary( invocation.Method, targetType ); + object returnValue = null; + + try + { + // This is an around advice. + // Invoke the next interceptor in the chain. + // This will normally result in a target object being invoked. + returnValue = invocation.Proceed(); + } + catch ( Exception ex ) + { + // target invocation exception + CompleteTransactionAfterThrowing( txnInfo, ex ); + throw; + } + finally + { + CleanupTransactionInfo( txnInfo ); + } + CommitTransactionAfterReturning( txnInfo ); + return returnValue; + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionProxyFactoryObject.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionProxyFactoryObject.cs index 0b05b2aa..199ec428 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionProxyFactoryObject.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionProxyFactoryObject.cs @@ -1,353 +1,352 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections.Specialized; - -using Spring.Aop; -using Spring.Aop.Framework; -using Spring.Aop.Framework.Adapter; -using Spring.Aop.Framework.DynamicProxy; -using Spring.Aop.Support; -using Spring.Aop.Target; -using Spring.Core.TypeResolution; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Transaction.Interceptor -{ - /// - /// Proxy factory object for simplified declarative transaction handling. - /// - /// - ///

- /// Alternative to the standard AOP - /// with a . - ///

- ///

- /// This class is intended to cover the typical case of declarative - /// transaction demarcation: namely, wrapping a (singleton) target object with a - /// transactional proxy, proxying all the interfaces that the target implements. - ///

- ///

- /// Internally, a - /// instance is used, but the user of this class does not have to care. Optionally, an - /// can be specified to cause conditional invocation of - /// the underlying . - ///

- ///

- /// The - /// - /// and - /// - /// properties can be set to add additional interceptors to the mix. - ///

- ///
- /// Juergen Hoeller - /// Dmitriy Kopylenko - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: TransactionProxyFactoryObject.cs,v 1.7 2007/08/01 17:56:16 markpollack Exp $ - public class TransactionProxyFactoryObject : ProxyConfig, IFactoryObject, IInitializingObject - { - private TransactionInterceptor _transactionInterceptor; - private object _target; - private Type[] _proxyInterfaces; - private TruePointcut _pointcut; - private object[] _preInterceptors; - private object[] _postInterceptors; - private IAdvisorAdapterRegistry _advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance; - private object _proxy; - - /// - /// Creates a new instance of the - /// class. - /// - public TransactionProxyFactoryObject() - { - _transactionInterceptor = new TransactionInterceptor(); - } - - /// - /// Set the transaction manager for this factory. - /// - /// - /// It is this instance that will perform actual transaction management: this class is - /// just a way of invoking it. - /// - public IPlatformTransactionManager PlatformTransactionManager - { - set { _transactionInterceptor.TransactionManager = value; } - } - - /// - /// Set the target object, i.e. the object to be wrapped with a transactional proxy. - /// - /// - ///

- /// The target may be any object, in which case a - /// will - /// be created. If it is a , no wrapper - /// is created: this enables the use of a pooling - /// or prototype . - ///

- ///
- public object Target - { - set { _target = value; } - } - - /// - /// Specify the set of interfaces being proxied. - /// - /// - ///

- /// If left null (the default), the AOP infrastructure works - /// out which interfaces need proxying by analyzing the target, - /// proxying all of the interfaces that the target object implements. - ///

- ///
- public string[] ProxyInterfaces - { - set { _proxyInterfaces = TypeResolutionUtils.ResolveInterfaceArray( value ); } - } - - /// - /// Set properties with method names as keys and transaction attribute - /// descriptors as values. - /// - /// - ///

- /// The various transaction attribute descriptors are parsed via - /// an instance of the - /// class. - ///

- /// - /// Method names are always applied to the target class, no matter if defined in an - /// interface or the class itself. - /// - ///

- /// Internally, a - /// - /// will be created from the given properties. - ///

- ///
- /// - ///

- /// An example string (method name and transaction attributes) might be: - ///

- ///

- /// key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly". - ///

- ///
- public NameValueCollection TransactionAttributes - { - set { _transactionInterceptor.TransactionAttributes = value; } - } - - /// - /// Set the transaction attribute source which is used to find transaction - /// attributes. - /// - /// - ///

- /// If specifying a property value, an - /// appropriate - /// implementation will create a - /// - /// from the value. - ///

- ///
- public ITransactionAttributeSource TransactionAttributeSource - { - set { _transactionInterceptor.TransactionAttributeSource = value; } - } - - /// - /// Set a pointcut, i.e an object that can cause conditional invocation - /// of the - /// depending on method and attributes passed. - /// - /// - /// - /// Additional interceptors are always invoked. - /// - /// - public TruePointcut TruePointcut - { - set { _pointcut = value; } - } - - /// - /// Set additional interceptors (or advisors) to be applied before the - /// implicit transaction interceptor. - /// - public object[] PreInterceptors - { - set { _preInterceptors = value; } - } - - /// - /// Set additional interceptors (or advisors) to be applied after the - /// implicit transaction interceptor. - /// - /// - ///

- /// Note that this is just necessary if you rely on those interceptors in general. - ///

- ///
- public object[] PostInterceptors - { - set { _postInterceptors = value; } - } - - /// - /// Specify the to use. - /// - /// The default instance is the global AdvisorAdapterRegistry. - public IAdvisorAdapterRegistry AdvisorAdapterRegistry - { - set { _advisorAdapterRegistry = value; } - } - - #region IFactoryObject Members - /// - /// Returns the object for this proxy factory. - /// - public Type ObjectType - { - get - { - if ( _proxy != null ) - { - return _proxy.GetType(); - } - else if ( _target != null && _target is ITargetSource ) - { - return _target.GetType(); - } - else - { - return null; - } - } - } - /// - /// Returns the object wrapped by this proxy factory. - /// - /// The target object proxy. - public object GetObject() - { - return _proxy; - } - - /// - /// Is this object a singleton? Always returns true in this implementation. - /// - public bool IsSingleton - { - get - { - return true; - } - } - #endregion - - #region IInitializingObject Members - /// - /// Method run after all the properties have been set for this object. - /// Responsible for actual proxy creation. - /// - public void AfterPropertiesSet() - { - _transactionInterceptor.AfterPropertiesSet(); - - if ( _target == null ) - { - throw new ArgumentException("'target' is required."); - } - ProxyFactory proxyFactory = new ProxyFactory(); - - if ( _preInterceptors != null ) - { - for ( int i = 0; i < _preInterceptors.Length; i++ ) - { - proxyFactory.AddAdvisor(_advisorAdapterRegistry.Wrap(_preInterceptors[i])); - } - } - if ( _pointcut != null ) - { - IAdvisor advice = new DefaultPointcutAdvisor(_pointcut, _transactionInterceptor); - proxyFactory.AddAdvisor(advice); - } - else - { - proxyFactory.AddAdvisor( new TransactionAttributeSourceAdvisor( _transactionInterceptor ) ); - } - if ( _postInterceptors != null ) - { - for ( int i = 0; i < _postInterceptors.Length; i++ ) - { - proxyFactory.AddAdvisor(_advisorAdapterRegistry.Wrap(_postInterceptors[i])); - } - } - proxyFactory.CopyFrom(this); - proxyFactory.TargetSource = createTargetSource(_target); - if ( _proxyInterfaces != null ) - { - proxyFactory.Interfaces = _proxyInterfaces; - } - else if ( !ProxyTargetType ) - { - if ( _target is ITargetSource ) - { - throw new AopConfigException("Either 'ProxyInterfaces' or 'ProxyTargetType' is required " + - "when using an ITargetSource as 'target'"); - } - proxyFactory.Interfaces = AopUtils.GetAllInterfaces(_target); - } - _proxy = proxyFactory.GetProxy(); - } - #endregion - - /// - /// Set the target or . - /// - /// - /// The target. If this is an implementation of the - /// interface, it is used as our ; otherwise it is - /// wrapped in a . - /// - /// An for this object. - protected ITargetSource createTargetSource( object target ) - { - if ( target is ITargetSource ) - { - return (ITargetSource) target; - } else - { - return new SingletonTargetSource( target ); - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections.Specialized; + +using Spring.Aop; +using Spring.Aop.Framework; +using Spring.Aop.Framework.Adapter; +using Spring.Aop.Framework.DynamicProxy; +using Spring.Aop.Support; +using Spring.Aop.Target; +using Spring.Core.TypeResolution; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Transaction.Interceptor +{ + /// + /// Proxy factory object for simplified declarative transaction handling. + /// + /// + ///

+ /// Alternative to the standard AOP + /// with a . + ///

+ ///

+ /// This class is intended to cover the typical case of declarative + /// transaction demarcation: namely, wrapping a (singleton) target object with a + /// transactional proxy, proxying all the interfaces that the target implements. + ///

+ ///

+ /// Internally, a + /// instance is used, but the user of this class does not have to care. Optionally, an + /// can be specified to cause conditional invocation of + /// the underlying . + ///

+ ///

+ /// The + /// + /// and + /// + /// properties can be set to add additional interceptors to the mix. + ///

+ ///
+ /// Juergen Hoeller + /// Dmitriy Kopylenko + /// Rod Johnson + /// Griffin Caprio (.NET) + public class TransactionProxyFactoryObject : ProxyConfig, IFactoryObject, IInitializingObject + { + private TransactionInterceptor _transactionInterceptor; + private object _target; + private Type[] _proxyInterfaces; + private TruePointcut _pointcut; + private object[] _preInterceptors; + private object[] _postInterceptors; + private IAdvisorAdapterRegistry _advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance; + private object _proxy; + + /// + /// Creates a new instance of the + /// class. + /// + public TransactionProxyFactoryObject() + { + _transactionInterceptor = new TransactionInterceptor(); + } + + /// + /// Set the transaction manager for this factory. + /// + /// + /// It is this instance that will perform actual transaction management: this class is + /// just a way of invoking it. + /// + public IPlatformTransactionManager PlatformTransactionManager + { + set { _transactionInterceptor.TransactionManager = value; } + } + + /// + /// Set the target object, i.e. the object to be wrapped with a transactional proxy. + /// + /// + ///

+ /// The target may be any object, in which case a + /// will + /// be created. If it is a , no wrapper + /// is created: this enables the use of a pooling + /// or prototype . + ///

+ ///
+ public object Target + { + set { _target = value; } + } + + /// + /// Specify the set of interfaces being proxied. + /// + /// + ///

+ /// If left null (the default), the AOP infrastructure works + /// out which interfaces need proxying by analyzing the target, + /// proxying all of the interfaces that the target object implements. + ///

+ ///
+ public string[] ProxyInterfaces + { + set { _proxyInterfaces = TypeResolutionUtils.ResolveInterfaceArray( value ); } + } + + /// + /// Set properties with method names as keys and transaction attribute + /// descriptors as values. + /// + /// + ///

+ /// The various transaction attribute descriptors are parsed via + /// an instance of the + /// class. + ///

+ /// + /// Method names are always applied to the target class, no matter if defined in an + /// interface or the class itself. + /// + ///

+ /// Internally, a + /// + /// will be created from the given properties. + ///

+ ///
+ /// + ///

+ /// An example string (method name and transaction attributes) might be: + ///

+ ///

+ /// key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly". + ///

+ ///
+ public NameValueCollection TransactionAttributes + { + set { _transactionInterceptor.TransactionAttributes = value; } + } + + /// + /// Set the transaction attribute source which is used to find transaction + /// attributes. + /// + /// + ///

+ /// If specifying a property value, an + /// appropriate + /// implementation will create a + /// + /// from the value. + ///

+ ///
+ public ITransactionAttributeSource TransactionAttributeSource + { + set { _transactionInterceptor.TransactionAttributeSource = value; } + } + + /// + /// Set a pointcut, i.e an object that can cause conditional invocation + /// of the + /// depending on method and attributes passed. + /// + /// + /// + /// Additional interceptors are always invoked. + /// + /// + public TruePointcut TruePointcut + { + set { _pointcut = value; } + } + + /// + /// Set additional interceptors (or advisors) to be applied before the + /// implicit transaction interceptor. + /// + public object[] PreInterceptors + { + set { _preInterceptors = value; } + } + + /// + /// Set additional interceptors (or advisors) to be applied after the + /// implicit transaction interceptor. + /// + /// + ///

+ /// Note that this is just necessary if you rely on those interceptors in general. + ///

+ ///
+ public object[] PostInterceptors + { + set { _postInterceptors = value; } + } + + /// + /// Specify the to use. + /// + /// The default instance is the global AdvisorAdapterRegistry. + public IAdvisorAdapterRegistry AdvisorAdapterRegistry + { + set { _advisorAdapterRegistry = value; } + } + + #region IFactoryObject Members + /// + /// Returns the object for this proxy factory. + /// + public Type ObjectType + { + get + { + if ( _proxy != null ) + { + return _proxy.GetType(); + } + else if ( _target != null && _target is ITargetSource ) + { + return _target.GetType(); + } + else + { + return null; + } + } + } + /// + /// Returns the object wrapped by this proxy factory. + /// + /// The target object proxy. + public object GetObject() + { + return _proxy; + } + + /// + /// Is this object a singleton? Always returns true in this implementation. + /// + public bool IsSingleton + { + get + { + return true; + } + } + #endregion + + #region IInitializingObject Members + /// + /// Method run after all the properties have been set for this object. + /// Responsible for actual proxy creation. + /// + public void AfterPropertiesSet() + { + _transactionInterceptor.AfterPropertiesSet(); + + if ( _target == null ) + { + throw new ArgumentException("'target' is required."); + } + ProxyFactory proxyFactory = new ProxyFactory(); + + if ( _preInterceptors != null ) + { + for ( int i = 0; i < _preInterceptors.Length; i++ ) + { + proxyFactory.AddAdvisor(_advisorAdapterRegistry.Wrap(_preInterceptors[i])); + } + } + if ( _pointcut != null ) + { + IAdvisor advice = new DefaultPointcutAdvisor(_pointcut, _transactionInterceptor); + proxyFactory.AddAdvisor(advice); + } + else + { + proxyFactory.AddAdvisor( new TransactionAttributeSourceAdvisor( _transactionInterceptor ) ); + } + if ( _postInterceptors != null ) + { + for ( int i = 0; i < _postInterceptors.Length; i++ ) + { + proxyFactory.AddAdvisor(_advisorAdapterRegistry.Wrap(_postInterceptors[i])); + } + } + proxyFactory.CopyFrom(this); + proxyFactory.TargetSource = createTargetSource(_target); + if ( _proxyInterfaces != null ) + { + proxyFactory.Interfaces = _proxyInterfaces; + } + else if ( !ProxyTargetType ) + { + if ( _target is ITargetSource ) + { + throw new AopConfigException("Either 'ProxyInterfaces' or 'ProxyTargetType' is required " + + "when using an ITargetSource as 'target'"); + } + proxyFactory.Interfaces = AopUtils.GetAllInterfaces(_target); + } + _proxy = proxyFactory.GetProxy(); + } + #endregion + + /// + /// Set the target or . + /// + /// + /// The target. If this is an implementation of the + /// interface, it is used as our ; otherwise it is + /// wrapped in a . + /// + /// An for this object. + protected ITargetSource createTargetSource( object target ) + { + if ( target is ITargetSource ) + { + return (ITargetSource) target; + } else + { + return new SingletonTargetSource( target ); + } + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/InvalidIsolationLevelException.cs b/src/Spring/Spring.Data/Transaction/InvalidIsolationLevelException.cs index 5b2547dd..8791f8e9 100644 --- a/src/Spring/Spring.Data/Transaction/InvalidIsolationLevelException.cs +++ b/src/Spring/Spring.Data/Transaction/InvalidIsolationLevelException.cs @@ -1,81 +1,80 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - - /// - /// Exception that gets thrown when an invalid isolation level is specified, - /// i.e. an isolation level that the transaction manager implementation - /// doesn't support. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: InvalidIsolationLevelException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class InvalidIsolationLevelException : TransactionUsageException - { - /// - /// Creates a new instance of the - /// class. - /// - public InvalidIsolationLevelException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public InvalidIsolationLevelException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public InvalidIsolationLevelException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected InvalidIsolationLevelException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + + /// + /// Exception that gets thrown when an invalid isolation level is specified, + /// i.e. an isolation level that the transaction manager implementation + /// doesn't support. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class InvalidIsolationLevelException : TransactionUsageException + { + /// + /// Creates a new instance of the + /// class. + /// + public InvalidIsolationLevelException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public InvalidIsolationLevelException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public InvalidIsolationLevelException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected InvalidIsolationLevelException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/InvalidTimeoutException.cs b/src/Spring/Spring.Data/Transaction/InvalidTimeoutException.cs index f4f2c31e..2f499f98 100644 --- a/src/Spring/Spring.Data/Transaction/InvalidTimeoutException.cs +++ b/src/Spring/Spring.Data/Transaction/InvalidTimeoutException.cs @@ -1,130 +1,129 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception that gets thrown when an invalid timeout is specified, - /// for example when the transaction manager implementation doesn't support timeouts. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: InvalidTimeoutException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class InvalidTimeoutException : TransactionUsageException, ISerializable - { - /// - /// Invalid timeout value. - /// - private int _timeout = -1; - - /// - /// Returns the invalid timeout for this exception. - /// - public int Timeout - { - get - { - return _timeout; - } - } - - /// - /// Creates a new instance of the - /// class - /// with the specified message and timeout value. - /// - /// - /// A message about the exception. - /// - /// The (possibly invalid) timeout value. - public InvalidTimeoutException(string message, int timeout):base(message) - { - _timeout = timeout; - } - - /// - /// Creates a new instance of the - /// class. - /// - public InvalidTimeoutException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public InvalidTimeoutException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public InvalidTimeoutException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected InvalidTimeoutException( - SerializationInfo info, StreamingContext context ) : base( info, context ) - { - _timeout = info.GetInt32( "timeout" ); - } - - /// - /// Override of - /// to allow for private serialization. - /// - /// - /// The - /// that holds the serialized object data about the exception. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue( "timeout", _timeout ); - base.GetObjectData( info, context ); - } - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception that gets thrown when an invalid timeout is specified, + /// for example when the transaction manager implementation doesn't support timeouts. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class InvalidTimeoutException : TransactionUsageException, ISerializable + { + /// + /// Invalid timeout value. + /// + private int _timeout = -1; + + /// + /// Returns the invalid timeout for this exception. + /// + public int Timeout + { + get + { + return _timeout; + } + } + + /// + /// Creates a new instance of the + /// class + /// with the specified message and timeout value. + /// + /// + /// A message about the exception. + /// + /// The (possibly invalid) timeout value. + public InvalidTimeoutException(string message, int timeout):base(message) + { + _timeout = timeout; + } + + /// + /// Creates a new instance of the + /// class. + /// + public InvalidTimeoutException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public InvalidTimeoutException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public InvalidTimeoutException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected InvalidTimeoutException( + SerializationInfo info, StreamingContext context ) : base( info, context ) + { + _timeout = info.GetInt32( "timeout" ); + } + + /// + /// Override of + /// to allow for private serialization. + /// + /// + /// The + /// that holds the serialized object data about the exception. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue( "timeout", _timeout ); + base.GetObjectData( info, context ); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/NestedTransactionNotSupportedException.cs b/src/Spring/Spring.Data/Transaction/NestedTransactionNotSupportedException.cs index fadda7d6..9bc5c2d1 100644 --- a/src/Spring/Spring.Data/Transaction/NestedTransactionNotSupportedException.cs +++ b/src/Spring/Spring.Data/Transaction/NestedTransactionNotSupportedException.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception thrown when attempting to work with a nested transaction - /// but nested transactions are not supported by the underlying backend. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: NestedTransactionNotSupportedException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class NestedTransactionNotSupportedException : CannotCreateTransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public NestedTransactionNotSupportedException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public NestedTransactionNotSupportedException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NestedTransactionNotSupportedException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NestedTransactionNotSupportedException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception thrown when attempting to work with a nested transaction + /// but nested transactions are not supported by the underlying backend. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class NestedTransactionNotSupportedException : CannotCreateTransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public NestedTransactionNotSupportedException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public NestedTransactionNotSupportedException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NestedTransactionNotSupportedException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NestedTransactionNotSupportedException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/NoTransactionException.cs b/src/Spring/Spring.Data/Transaction/NoTransactionException.cs index 863010d6..9b3443ee 100644 --- a/src/Spring/Spring.Data/Transaction/NoTransactionException.cs +++ b/src/Spring/Spring.Data/Transaction/NoTransactionException.cs @@ -1,80 +1,79 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception thrown when an operation is attempted that relies on an existing - /// transaction (such as setting rollback status) and there is no existing transaction. - /// This represents an illegal usage of the transaction API. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: NoTransactionException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class NoTransactionException : TransactionUsageException - { - /// - /// Creates a new instance of the - /// class. - /// - public NoTransactionException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public NoTransactionException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public NoTransactionException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected NoTransactionException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception thrown when an operation is attempted that relies on an existing + /// transaction (such as setting rollback status) and there is no existing transaction. + /// This represents an illegal usage of the transaction API. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class NoTransactionException : TransactionUsageException + { + /// + /// Creates a new instance of the + /// class. + /// + public NoTransactionException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public NoTransactionException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public NoTransactionException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected NoTransactionException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Support/AbstractPlatformTransactionManager.cs b/src/Spring/Spring.Data/Transaction/Support/AbstractPlatformTransactionManager.cs index d286696a..7acfc1a2 100644 --- a/src/Spring/Spring.Data/Transaction/Support/AbstractPlatformTransactionManager.cs +++ b/src/Spring/Spring.Data/Transaction/Support/AbstractPlatformTransactionManager.cs @@ -1,1179 +1,1179 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Data; -using Common.Logging; - -namespace Spring.Transaction.Support -{ - /// - /// Abstract base class that allows for easy implementation of concrete platform transaction managers. - /// - /// - ///

Provides the following workflow handling: - ///

    - ///
  • Determines if there is an existing transaction
  • - ///
  • Applies the appropriate propagation behavior
  • - ///
  • Suspends and resumes transactions if necessary
  • - ///
  • Checks the rollback-only flag on commit
  • - ///
  • Applies the appropriate modification on rollback (actual rollback or setting rollback-only)
  • - ///
  • Triggers registered synchronization callbacks (if transaction synchronization is active)
  • - ///
- ///

- ///

- /// Transaction synchronization is a generic mechanism for registering - /// callbacks that get invoked at transaction completion time. The same mechanism - /// can also be used for custom synchronization efforts. - ///

- ///

- /// The state of this class is serializable. It's up to subclasses if - /// they wish to make their state to be serializable. - /// They should implement if they need - /// to restore any transient state. - ///

- ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// Griffin Caprio (.NET) - [Serializable] - public abstract class AbstractPlatformTransactionManager : IPlatformTransactionManager - { - #region Private SuspendedResourcesHolder Helper class - - private class SuspendedResourcesHolder - { - private IList _suspendedSynchronizations; - private object _suspendedResources; - private string _name; - private bool _readOnly; - private IsolationLevel _isolationLevel; - private bool _wasActive; - - - public SuspendedResourcesHolder(object suspendedResources) - { - _suspendedResources = suspendedResources; - } - - public SuspendedResourcesHolder(IList suspendedSynchronizations, object suspendedResources, - string name, bool readOnly, IsolationLevel isolationLevel, bool wasActive) - { - _suspendedSynchronizations = suspendedSynchronizations; - _suspendedResources = suspendedResources; - _name = name; - _readOnly = readOnly; - _isolationLevel = isolationLevel; - _wasActive = wasActive; - } - - public IList SuspendedSynchronizations - { - get { return _suspendedSynchronizations; } - } - - public object SuspendedResources - { - get { return _suspendedResources; } - } - - - public string Name - { - get { return _name; } - } - - public bool ReadOnly - { - get { return _readOnly; } - } - - public IsolationLevel IsolationLevel - { - get { return _isolationLevel; } - } - - public bool WasActive - { - get { return _wasActive; } - } - } - - #endregion - - #region Private Variables - - private TransactionSynchronizationState _transactionSyncState = TransactionSynchronizationState.Always; - private bool _nestedTransactionsAllowed; - private bool _rollbackOnCommitFailure; - private bool _failEarlyOnGlobalRollbackOnly; - private int _defaultTimeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; - - #region Logging Definition - - [NonSerialized()] protected ILog log = LogManager.GetLogger(typeof (AbstractPlatformTransactionManager)); - - #endregion - - #endregion - - #region Public Properties - - /// - /// Sets and gets when this transaction manager should activate the thread-bound - /// transaction synchronization support. Default is "always". - /// - /// - ///

- /// Note that transaction synchronization isn't supported for - /// multiple concurrent transactions by different transaction managers. - /// Only one transaction manager is allowed to activate it at any time. - ///

- /// - ///
- public TransactionSynchronizationState TransactionSynchronization - { - set { _transactionSyncState = value; } - get { return _transactionSyncState; } - } - - /// - /// Sets and gets whether nested transactions are allowed. Default is false. - /// - /// - ///

- /// Typically initialized with an appropriate default by the - /// concrete transaction manager subclass. - ///

- ///
- public bool NestedTransactionsAllowed - { - get { return _nestedTransactionsAllowed; } - set { _nestedTransactionsAllowed = value; } - } - - /// - /// Sets and gets a flag that determines whether or not the - /// - /// method must be invoked if a call to the - /// - /// method fails. Default is false. - /// - /// - /// Typically not necessary and thus to be avoided as it can override the - /// commit exception with a subsequent rollback exception. - /// - public bool RollbackOnCommitFailure - { - get { return _rollbackOnCommitFailure; } - set { _rollbackOnCommitFailure = value; } - } - - - /// - /// Gets or sets a value indicating whether to fail early in case of the transaction being - /// globally marked as rollback-only. - /// - /// - /// Default is "false", only causing an UnexpectedRollbackException at the - /// outermost transaction boundary. Switch this flag on to cause an - /// UnexpectedRollbackException as early as the global rollback-only marker - /// has been first detected, even from within an inner transaction boundary. - /// - /// - /// true if fail early on global rollback; otherwise, false. - /// - public bool FailEarlyOnGlobalRollbackOnly - { - get { return _failEarlyOnGlobalRollbackOnly; } - set { _failEarlyOnGlobalRollbackOnly = value; } - } - - /// - /// Gets or sets the default timeout that this transaction manager should apply if there - /// is no timeout specified at the transaction level, in seconds. - /// - /// Returns DefaultTransactionDefinition.TIMEOUT_DEFAULT to indicate the - /// underlying transaction infrastructure's default timeout. - /// The default timeout. - public int DefaultTimeout - { - get - { - return _defaultTimeout; - } - set - { - if (_defaultTimeout < DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - throw new InvalidTimeoutException("Invalid default timeout", _defaultTimeout); - } - _defaultTimeout = value; - } - } - - #endregion - - #region Abstract Methods - - /// - /// Return the current transaction object. - /// - /// The current transaction object. - /// - /// If transaction support is not available. - /// - /// - /// In the case of lookup or system errors. - /// - protected abstract object DoGetTransaction(); - - /// - /// Check if the given transaction object indicates an existing transaction - /// (that is, a transaction which has already started). - /// - /// - /// The result will be evaluated according to the specified propagation - /// behavior for the new transaction. An existing transaction might get - /// suspended (in case of PROPAGATION_REQUIRES_NEW), or the new transaction - /// might participate in the existing one (in case of PROPAGATION_REQUIRED). - /// Default implementation returns false, assuming that detection of or - /// participating in existing transactions is generally not supported. - /// Subclasses are of course encouraged to provide such support. - /// - /// Transaction object returned by - /// . - /// - /// True if there is an existing transaction. - /// - /// In the case of system errors. - /// - protected virtual bool IsExistingTransaction(object transaction) - { - return false; - } - - /// - /// Begin a new transaction with the given transaction definition. - /// - /// - /// Does not have to care about applying the propagation behavior, - /// as this has already been handled by this abstract manager. - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// instance, describing - /// propagation behavior, isolation level, timeout etc. - /// - /// - /// In the case of creation or system errors. - /// - protected abstract void DoBegin(object transaction, ITransactionDefinition definition); - - /// - /// Suspend the resources of the current transaction. - /// - /// - /// Transaction synchronization will already have been suspended. - /// - /// Default implementation throws a TransactionSuspensionNotSupportedException, - /// assuming that transaction suspension is generally not supported. - /// - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// An object that holds suspended resources (will be kept unexamined for passing it into - /// .) - /// - /// - /// If suspending is not supported by the transaction manager implementation. - /// - /// - /// in case of system errors. - /// - protected virtual object DoSuspend(object transaction) - { - throw new TransactionSuspensionNotSupportedException( - "Transaction manager [" + GetType().Name + "] does not support transaction suspension"); - } - - /// - /// Resume the resources of the current transaction. - /// - /// Transaction synchronization will be resumed afterwards. - /// - /// Default implementation throws a TransactionSuspensionNotSupportedException, - /// assuming that transaction suspension is generally not supported. - /// - /// - /// - /// Transaction object returned by - /// . - /// - /// - /// The object that holds suspended resources as returned by - /// . - /// - /// - /// If suspending is not supported by the transaction manager implementation. - /// - /// - /// In the case of system errors. - /// - protected virtual void DoResume(object transaction, object suspendedResources) - { - throw new TransactionSuspensionNotSupportedException( - "Transaction manager [" + GetType().Name + "] does not support transaction suspension"); - } - - /// - /// Perform an actual commit on the given transaction. - /// - /// The status representation of the transaction. - /// - ///

- /// An implementation does not need to check the rollback-only flag. - ///

- ///
- /// - /// In the case of system errors. - /// - protected abstract void DoCommit(DefaultTransactionStatus status); - - /// - /// Perform an actual rollback on the given transaction. - /// - /// The status representation of the transaction. - /// - /// An implementation does not need to check the new transaction flag. - /// - /// - /// In the case of system errors. - /// - protected abstract void DoRollback(DefaultTransactionStatus status); - - /// - /// Set the given transaction rollback-only. Only called on rollback - /// if the current transaction takes part in an existing one. - /// - /// Default implementation throws an IllegalTransactionStateException, - /// assuming that participating in existing transactions is generally not - /// supported. Subclasses are of course encouraged to provide such support. - /// - /// The status representation of the transaction. - /// - /// In the case of system errors. - /// - protected virtual void DoSetRollbackOnly(DefaultTransactionStatus status) - { - throw new IllegalTransactionStateException( - "Participating in existing transactions is not supported - when 'IsExistingTransaction' " + - "returns true, appropriate 'DoSetRollbackOnly' behavior must be provided"); - } - - /// - /// Return whether to use a savepoint for a nested transaction. Default is true, - /// which causes delegation to - /// for holding a savepoint. - /// - /// - /// - ///

- /// Subclasses can override this to return false, causing a further - /// invocation of - /// - /// despite an already existing transaction. - ///

- ///
- protected virtual bool UseSavepointForNestedTransaction() - { - return true; - } - - /// - /// Cleanup resources after transaction completion. - /// - /// - /// Transaction object returned by - /// . - /// - /// - ///

- /// Called after - /// and - /// - /// execution on any outcome. - ///

- ///

- /// Should not throw any exceptions but just issue warnings on errors. - ///

- ///

- /// Default implementation does nothing. - ///

- ///
- protected virtual void DoCleanupAfterCompletion(object transaction) - { - } - - #endregion - - #region IPlatformTransactionManager Members - - /// - /// Return a currently active transaction or create a new one. - /// - /// - ///

- /// This implementation handles propagation behavior. - ///

- ///

- /// Delegates to - /// , - /// , - /// and - /// . - ///

- ///

- /// Note that parameters like isolation level or timeout will only be applied - /// to new transactions, and thus be ignored when participating in active ones. - /// Furthermore, they aren't supported by every transaction manager: - /// a proper implementation should throw an exception when custom values - /// that it doesn't support are specified. - ///

- ///
- /// - /// instance (can be null for - /// defaults), describing propagation behavior, isolation level, timeout etc. - /// - /// - /// In case of lookup, creation, or system errors. - /// - /// - /// representing the new or current transaction. - /// - public ITransactionStatus GetTransaction(ITransactionDefinition definition) - { - object transaction = DoGetTransaction(); - bool debugEnabled = log.IsDebugEnabled; - bool newSynchronization; - - if (debugEnabled) - { - log.Debug("Using transaction object [" + transaction + "]"); - } - - if (definition == null) - { - definition = new DefaultTransactionDefinition(); - } - if (IsExistingTransaction(transaction)) - { - // Existing transaction found -> check propagation behavior to find out how to behave. - return HandleExistingTransaction(definition, transaction, debugEnabled); - } - - // Check definition settings for new transaction. - if (definition.TransactionTimeout < DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - throw new InvalidTimeoutException("Invalid transaction timeout", definition.TransactionTimeout); - } - - // No existing transaction found -> check propagation behavior to find out how to proceed. - if (definition.PropagationBehavior == TransactionPropagation.Mandatory) - { - throw new IllegalTransactionStateException( - "Transaction propagation 'mandatory' but no existing transaction found"); - } - else if (definition.PropagationBehavior == TransactionPropagation.Required || - definition.PropagationBehavior == TransactionPropagation.RequiresNew || - definition.PropagationBehavior == TransactionPropagation.Nested) - { - object suspendedResources = Suspend(null); - if (debugEnabled) - { - log.Debug("Creating new transaction with name [" + definition.Name + "]:" + definition); - } - try - { - DoBegin(transaction, definition); - } catch (TransactionException) - { - Resume(null, suspendedResources); - throw; - } - newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never); - return NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, - suspendedResources); - } - else - { - // Create "empty" transaction: no actual transaction, but potentially synchronization. - newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always); - return NewTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null); - - } - - } - - private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction, bool debugEnabled) - { - //bool newSynchronization; - if (definition.PropagationBehavior == TransactionPropagation.Never) - { - throw new IllegalTransactionStateException( - "Transaction propagation 'never' but existing transaction found."); - } - if (definition.PropagationBehavior == TransactionPropagation.NotSupported) - { - if (debugEnabled) - { - log.Debug("Suspending current transaction"); - } - object suspendedResources = Suspend(transaction); - bool newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always); - return - NewTransactionStatus(definition, null, false, newSynchronization, debugEnabled, - suspendedResources); - } - - if (definition.PropagationBehavior == TransactionPropagation.RequiresNew) - { - if (debugEnabled) - { - log.Debug("Suspending current transaction, creating new transaction with name [" + - definition.Name + "]:" + definition); - } - object suspendedResources = Suspend(transaction); - try - { - DoBegin(transaction, definition); - } - catch (TransactionException beginEx) - { - try - { - Resume(transaction, suspendedResources); - } - catch (TransactionException resumeEx) - { - log.Error( - "Inner transaction begin exception overridden by outer transaction resume exception"); - log.Error("Begin Transaction Exception", beginEx); - log.Error("Resume Transaction Exception", resumeEx); - throw; - } - throw; - } - bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never); - return - NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); - } - if (definition.PropagationBehavior == TransactionPropagation.Nested) - { - if (!NestedTransactionsAllowed) - { - throw new NestedTransactionNotSupportedException( - "Transaction manager does not allow nested transactions by default - " + - "specify 'NestedTransactionsAllowed' property with value 'true'"); - } - if (debugEnabled) - { - log.Debug("Creating nested transaction with name [" + definition.Name + "]:" + definition); - } - - if (UseSavepointForNestedTransaction()) - { - DefaultTransactionStatus status = - NewTransactionStatus(definition, transaction, false, false, debugEnabled, null); - status.CreateAndHoldSavepoint(DateTime.Now.ToLongTimeString()); - return status; - } - else - { - DoBegin(transaction, definition); - bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never); - return NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null); - - } - } - // Assumably PROPAGATION_SUPPORTS. - if (debugEnabled) { - log.Debug("Participating in existing transaction"); - } - bool newSynch = (_transactionSyncState != TransactionSynchronizationState.Never); - return NewTransactionStatus(definition, transaction, false, newSynch, debugEnabled, null); - - } - - /// - /// This implementation of commit handles participating in existing transactions - /// and programmatic rollback requests. - /// - /// - /// - /// - /// ITransactionStatus object returned by the - /// () method. - /// - /// - /// In case of commit or system errors. - /// - public void Commit(ITransactionStatus transactionStatus) - { - if (transactionStatus.Completed) - { - throw new IllegalTransactionStateException( - "Transaction is already completed - do not call commit or rollback more than once per transaction"); - } - - DefaultTransactionStatus defaultStatus = (DefaultTransactionStatus) transactionStatus; - if (defaultStatus.LocalRollbackOnly) - { - if (defaultStatus.Debug) - { - log.Debug("Transaction code has requested rollback"); - } - ProcessRollback(defaultStatus); - return; - } - if ( !ShouldCommitOnGlobalRollbackOnly && defaultStatus.GlobalRollbackOnly) - { - if (defaultStatus.Debug) - { - log.Debug("Global transaction is marked as rollback-only but transactional code requested commit"); - } - ProcessRollback(defaultStatus); - // Throw UnexpectedRollbackException only at outermost transaction boundary - // or if explicitly asked to. - if (defaultStatus.IsNewTransaction || FailEarlyOnGlobalRollbackOnly) - { - throw new UnexpectedRollbackException( - "Transaction rolled back because it has been marked as rollback-only"); - } - return; - } - ProcessCommit(defaultStatus); - - } - - protected virtual bool ShouldCommitOnGlobalRollbackOnly - { - get { return false; } - } - - private void ProcessCommit(DefaultTransactionStatus status) - { - try - { - bool beforeCompletionInvoked = false; - try - { - TriggerBeforeCommit(status); - TriggerBeforeCompletion(status); - beforeCompletionInvoked = true; - bool globalRollbackOnly = false; - if (status.IsNewTransaction || FailEarlyOnGlobalRollbackOnly) - { - globalRollbackOnly = status.GlobalRollbackOnly; - } - if (status.HasSavepoint) - { - status.ReleaseHeldSavepoint(); - } - else if (status.IsNewTransaction) - { - DoCommit(status); - } - // Throw UnexpectedRollbackException if we have a global rollback-only - // marker but still didn't get a corresponding exception from commit. - if (globalRollbackOnly) - { - throw new UnexpectedRollbackException( - "Transaction silently rolled back because it has been marked as rollback-only"); - } - } - catch (UnexpectedRollbackException) - { - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback); - throw; - } - catch (TransactionException ex) - { - if (RollbackOnCommitFailure) - { - DoRollbackOnCommitException(status, ex); - } - else - { - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown); - } - throw; - } - catch (Exception ex) - { - if (!beforeCompletionInvoked) - { - TriggerBeforeCompletion(status); - } - DoRollbackOnCommitException(status, ex); - throw; - } - // Trigger AfterCommit callbacks, with an exception thrown there - // propagated to callers but the transaction still considered as commited. - try - { - TriggerAfterCommit(status); - } - finally - { - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Committed); - } - } - finally - { - CleanupAfterCompletion(status); - } - } - - private void TriggerAfterCommit(DefaultTransactionStatus status) - { - if (status.NewSynchronization) - { - if (status.Debug) - { - log.Debug("Trigger AfterCommit Synchronization"); - } - IList synchronizations = TransactionSynchronizationManager.Synchronizations; - foreach (ITransactionSynchronization currentTxnSynchronization in synchronizations) - { - try - { - currentTxnSynchronization.AfterCommit(); - } - catch (Exception e) - { - log.Error("TransactionSynchronization.AfterCommit thew exception", e); - } - } - } - } - - /// - /// Roll back the given transaction, with regard to its status. - /// - /// - ///

- /// This implementation handles participating in existing transactions. - ///

- ///

- /// Delegates to - /// , - /// and - /// . - ///

- ///

- /// If the transaction wasn't a new one, just set it rollback-only - /// to take part in the surrounding transaction properly. - ///

- ///
- /// - /// ITransactionStatusObject returned by the - /// () method. - /// - /// - /// In case of system errors. - /// - public void Rollback(ITransactionStatus transactionStatus) - { - if (transactionStatus.Completed) - { - throw new IllegalTransactionStateException( - "Transaction is already completed - do not call commit or rollback more than once per transaction"); - } - DefaultTransactionStatus defaultStatus = (DefaultTransactionStatus) transactionStatus; - ProcessRollback(defaultStatus); - } - - private void ProcessRollback(DefaultTransactionStatus status) - { - try - { - try - { - TriggerBeforeCompletion(status); - if (status.HasSavepoint) - { - if (status.Debug) - { - log.Debug("Rolling back transaction to savepoint."); - } - status.RollbackToHeldSavepoint(); - } - else if (status.IsNewTransaction) - { - if (status.Debug) - { - log.Debug("Initiating transaction rollback"); - } - DoRollback(status); - } - else if (status.HasTransaction()) - { - if (status.LocalRollbackOnly) - { - if(status.Debug) - { - log.Debug("Participating transaction failed - marking existing transaction as rollback-only"); - } - } - DoSetRollbackOnly(status); - } - else - { - log.Debug("Should roll back transaction but cannot - no transaction available."); - } - } - catch (Exception) - { - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown); - throw; - } - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback); - } - finally - { - CleanupAfterCompletion(status); - } - } - - #endregion - - #region Protected Method - - private DefaultTransactionStatus NewTransactionStatus(ITransactionDefinition definition, - object transaction, bool newTransaction, - bool newSynchronization, bool debug, - object suspendedResources) - { - bool actualNewSynchronization = newSynchronization && - !TransactionSynchronizationManager.SynchronizationActive; - if (actualNewSynchronization) - { - TransactionSynchronizationManager.ActualTransactionActive = (transaction != null); - TransactionSynchronizationManager.CurrentTransactionIsolationLevel = - definition.TransactionIsolationLevel; - TransactionSynchronizationManager.CurrentTransactionReadOnly = definition.ReadOnly; - TransactionSynchronizationManager.CurrentTransactionName = definition.Name; - TransactionSynchronizationManager.InitSynchronization(); - } - return - new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.ReadOnly, debug, - suspendedResources); - } - - /// - /// Determines the timeout to use for the given definition. Will fall back to this manager's default - /// timeout if the transaction definition doesn't specify a non-default value. - /// - /// The transaction definition. - /// the actual timeout to use. - protected int DetermineTimeout(ITransactionDefinition definition) - { - if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { - return definition.TransactionTimeout; - } - return _defaultTimeout; - } - - #endregion - - #region Private Methods - - - - - - /// - /// Suspend the given transaction. Suspends transaction synchronization first, - /// then delegates to the doSuspend template method. - /// - /// the current transaction object - /// an object that holds suspended resources - private object Suspend(object transaction) - { - if (TransactionSynchronizationManager.SynchronizationActive) - { - IList suspendedSynchronizations = DoSuspendSynchronization(); - - try - { - object suspendedResources = null; - if (transaction != null) - { - suspendedResources = DoSuspend(transaction); - } - - string name = TransactionSynchronizationManager.CurrentTransactionName; - TransactionSynchronizationManager.CurrentTransactionName = null; - bool readOnly = TransactionSynchronizationManager.CurrentTransactionReadOnly; - TransactionSynchronizationManager.CurrentTransactionReadOnly = false; - IsolationLevel isolationLevel = TransactionSynchronizationManager.CurrentTransactionIsolationLevel; - TransactionSynchronizationManager.CurrentTransactionIsolationLevel = IsolationLevel.Unspecified; - bool wasActive = TransactionSynchronizationManager.ActualTransactionActive; - TransactionSynchronizationManager.ActualTransactionActive = false; - - - return new SuspendedResourcesHolder(suspendedSynchronizations, suspendedResources, - name, readOnly, isolationLevel, wasActive); - - } catch (TransactionException) - { - // DoSuspend failed - original transaction is still active - DoResumeSynchronization(suspendedSynchronizations); - throw; - } - } - else if (transaction != null) - { - // Transaction active but no synchronization active. - object suspendedResources = DoSuspend(transaction); - return new SuspendedResourcesHolder(suspendedResources); - } - else - { - // Neither transaction nor synchronization active. - return null; - } - - } - - private IList DoSuspendSynchronization() - { - IList suspendedSynchronizations = TransactionSynchronizationManager.Synchronizations; - foreach (ITransactionSynchronization currentTxnSynchronization in suspendedSynchronizations) - { - currentTxnSynchronization.Suspend(); - } - TransactionSynchronizationManager.ClearSynchronization(); - return suspendedSynchronizations; - } - - private void DoResumeSynchronization(IList suspendedSynchronizations) - { - TransactionSynchronizationManager.InitSynchronization(); - foreach (ITransactionSynchronization currentTxnSynchronization in suspendedSynchronizations) - { - currentTxnSynchronization.Resume(); - TransactionSynchronizationManager.RegisterSynchronization(currentTxnSynchronization); - } - } - - /// - /// Resume the given transaction. Delegates to the doResume template method - /// first, then resuming transaction synchronization. - /// - /// the current transaction object - /// the object that holds suspended resources, as returned by suspend - private void Resume(object transaction, object suspendedResources) - { - SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; - if (resourcesHolder != null) - { - object suspendedResourcesObject = resourcesHolder.SuspendedResources; - if (suspendedResourcesObject != null) - { - DoResume(transaction, suspendedResourcesObject); - } - IList suspendedSynchronizations = resourcesHolder.SuspendedSynchronizations; - if (suspendedSynchronizations != null) - { - TransactionSynchronizationManager.ActualTransactionActive = resourcesHolder.WasActive; - TransactionSynchronizationManager.CurrentTransactionIsolationLevel = resourcesHolder.IsolationLevel; - TransactionSynchronizationManager.CurrentTransactionReadOnly = resourcesHolder.ReadOnly; - TransactionSynchronizationManager.CurrentTransactionName = resourcesHolder.Name; - DoResumeSynchronization(suspendedSynchronizations); - } - - } - } - - - - /// - /// Invoke doRollback, handling rollback exceptions properly. - /// - /// object representing the transaction - /// the thrown application exception or error - /// - /// in case of a rollback error - /// - private void DoRollbackOnCommitException(DefaultTransactionStatus status, Exception exception) - { - try - { - if (status.IsNewTransaction) - { - if (status.Debug) - { - log.Debug("Initiating transaction rollback on commit exception."); - } - DoRollback(status); - } - else if (status.HasTransaction()) - { - if (status.Debug) - { - log.Debug("Marking existing transaction as rollback-only after commit exception", exception); - } - DoSetRollbackOnly(status); - } - } - catch (Exception) - { - //TODO investigate rollback behavior... - log.Error("Commit exception overridden by rollback exception", exception); - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown); - throw; - } - TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback); - } - - /// - /// Trigger beforeCommit callback. - /// - /// object representing the transaction - private void TriggerBeforeCommit(DefaultTransactionStatus status) - { - if (status.NewSynchronization) - { - IList synchronizations = TransactionSynchronizationManager.Synchronizations; - foreach (ITransactionSynchronization currentTxnSynchronization in synchronizations) - { - currentTxnSynchronization.BeforeCommit(status.ReadOnly); - } - } - } - - /// - /// Trigger beforeCompletion callback. - /// - /// object representing the transaction - private void TriggerBeforeCompletion(DefaultTransactionStatus status) - { - if (status.NewSynchronization) - { - if (status.Debug) - { - log.Debug("Trigger BeforeCompletion Synchronization"); - } - IList synchronizations = TransactionSynchronizationManager.Synchronizations; - foreach (ITransactionSynchronization synchronization in synchronizations) - { - try - { - synchronization.BeforeCompletion(); - } - catch (Exception e) - { - log.Error("TransactionSynchronization.BeforeCompletion threw exception", e); - } - } - } - } - - /// - /// Trigger afterCompletion callback, handling exceptions properly. - /// - /// object representing the transaction - /// - /// Completion status according to - /// - private void TriggerAfterCompletion(DefaultTransactionStatus status, TransactionSynchronizationStatus completionStatus) - { - if (status.NewSynchronization) - { - IList synchronizations = TransactionSynchronizationManager.Synchronizations; - if (!status.HasTransaction() || status.IsNewTransaction) - { - if (status.Debug) - { - log.Debug("Triggering afterCompletion synchronization"); - } - InvokeAfterCompletion(synchronizations, completionStatus); - } - else - { - //TODO investigate parallel of JTA/System.Txs - log.Info("Transaction controlled outside of spring tx manager."); - } - } - } - - private void InvokeAfterCompletion(IList synchronizations, TransactionSynchronizationStatus status) - { - foreach (ITransactionSynchronization synchronization in synchronizations) - { - try - { - synchronization.AfterCompletion(status); - } catch (Exception e) - { - log.Error("TransactionSynchronization.AfterCompletion threw exception", e); - } - } - } - - /// - /// Clean up after completion, clearing synchronization if necessary, - /// and invoking doCleanupAfterCompletion. - /// - /// object representing the transaction - private void CleanupAfterCompletion(DefaultTransactionStatus status) - { - status.Completed = true; - if (status.NewSynchronization) - { - TransactionSynchronizationManager.Clear(); - } - if (status.IsNewTransaction) - { - DoCleanupAfterCompletion(status.Transaction); - } - if (status.SuspendedResources != null) - { - if (status.Debug) - { - log.Debug("Resuming suspended transaction"); - } - Resume(status.Transaction, status.SuspendedResources); - } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Data; +using Common.Logging; + +namespace Spring.Transaction.Support +{ + /// + /// Abstract base class that allows for easy implementation of concrete platform transaction managers. + /// + /// + ///

Provides the following workflow handling: + ///

    + ///
  • Determines if there is an existing transaction
  • + ///
  • Applies the appropriate propagation behavior
  • + ///
  • Suspends and resumes transactions if necessary
  • + ///
  • Checks the rollback-only flag on commit
  • + ///
  • Applies the appropriate modification on rollback (actual rollback or setting rollback-only)
  • + ///
  • Triggers registered synchronization callbacks (if transaction synchronization is active)
  • + ///
+ ///

+ ///

+ /// Transaction synchronization is a generic mechanism for registering + /// callbacks that get invoked at transaction completion time. The same mechanism + /// can also be used for custom synchronization efforts. + ///

+ ///

+ /// The state of this class is serializable. It's up to subclasses if + /// they wish to make their state to be serializable. + /// They should implement if they need + /// to restore any transient state. + ///

+ ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + /// Griffin Caprio (.NET) + [Serializable] + public abstract class AbstractPlatformTransactionManager : IPlatformTransactionManager + { + #region Private SuspendedResourcesHolder Helper class + + private class SuspendedResourcesHolder + { + private IList _suspendedSynchronizations; + private object _suspendedResources; + private string _name; + private bool _readOnly; + private IsolationLevel _isolationLevel; + private bool _wasActive; + + + public SuspendedResourcesHolder(object suspendedResources) + { + _suspendedResources = suspendedResources; + } + + public SuspendedResourcesHolder(IList suspendedSynchronizations, object suspendedResources, + string name, bool readOnly, IsolationLevel isolationLevel, bool wasActive) + { + _suspendedSynchronizations = suspendedSynchronizations; + _suspendedResources = suspendedResources; + _name = name; + _readOnly = readOnly; + _isolationLevel = isolationLevel; + _wasActive = wasActive; + } + + public IList SuspendedSynchronizations + { + get { return _suspendedSynchronizations; } + } + + public object SuspendedResources + { + get { return _suspendedResources; } + } + + + public string Name + { + get { return _name; } + } + + public bool ReadOnly + { + get { return _readOnly; } + } + + public IsolationLevel IsolationLevel + { + get { return _isolationLevel; } + } + + public bool WasActive + { + get { return _wasActive; } + } + } + + #endregion + + #region Private Variables + + private TransactionSynchronizationState _transactionSyncState = TransactionSynchronizationState.Always; + private bool _nestedTransactionsAllowed; + private bool _rollbackOnCommitFailure; + private bool _failEarlyOnGlobalRollbackOnly; + private int _defaultTimeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; + + #region Logging Definition + + [NonSerialized()] protected ILog log = LogManager.GetLogger(typeof (AbstractPlatformTransactionManager)); + + #endregion + + #endregion + + #region Public Properties + + /// + /// Sets and gets when this transaction manager should activate the thread-bound + /// transaction synchronization support. Default is "always". + /// + /// + ///

+ /// Note that transaction synchronization isn't supported for + /// multiple concurrent transactions by different transaction managers. + /// Only one transaction manager is allowed to activate it at any time. + ///

+ /// + ///
+ public TransactionSynchronizationState TransactionSynchronization + { + set { _transactionSyncState = value; } + get { return _transactionSyncState; } + } + + /// + /// Sets and gets whether nested transactions are allowed. Default is false. + /// + /// + ///

+ /// Typically initialized with an appropriate default by the + /// concrete transaction manager subclass. + ///

+ ///
+ public bool NestedTransactionsAllowed + { + get { return _nestedTransactionsAllowed; } + set { _nestedTransactionsAllowed = value; } + } + + /// + /// Sets and gets a flag that determines whether or not the + /// + /// method must be invoked if a call to the + /// + /// method fails. Default is false. + /// + /// + /// Typically not necessary and thus to be avoided as it can override the + /// commit exception with a subsequent rollback exception. + /// + public bool RollbackOnCommitFailure + { + get { return _rollbackOnCommitFailure; } + set { _rollbackOnCommitFailure = value; } + } + + + /// + /// Gets or sets a value indicating whether to fail early in case of the transaction being + /// globally marked as rollback-only. + /// + /// + /// Default is "false", only causing an UnexpectedRollbackException at the + /// outermost transaction boundary. Switch this flag on to cause an + /// UnexpectedRollbackException as early as the global rollback-only marker + /// has been first detected, even from within an inner transaction boundary. + /// + /// + /// true if fail early on global rollback; otherwise, false. + /// + public bool FailEarlyOnGlobalRollbackOnly + { + get { return _failEarlyOnGlobalRollbackOnly; } + set { _failEarlyOnGlobalRollbackOnly = value; } + } + + /// + /// Gets or sets the default timeout that this transaction manager should apply if there + /// is no timeout specified at the transaction level, in seconds. + /// + /// Returns DefaultTransactionDefinition.TIMEOUT_DEFAULT to indicate the + /// underlying transaction infrastructure's default timeout. + /// The default timeout. + public int DefaultTimeout + { + get + { + return _defaultTimeout; + } + set + { + if (_defaultTimeout < DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + throw new InvalidTimeoutException("Invalid default timeout", _defaultTimeout); + } + _defaultTimeout = value; + } + } + + #endregion + + #region Abstract Methods + + /// + /// Return the current transaction object. + /// + /// The current transaction object. + /// + /// If transaction support is not available. + /// + /// + /// In the case of lookup or system errors. + /// + protected abstract object DoGetTransaction(); + + /// + /// Check if the given transaction object indicates an existing transaction + /// (that is, a transaction which has already started). + /// + /// + /// The result will be evaluated according to the specified propagation + /// behavior for the new transaction. An existing transaction might get + /// suspended (in case of PROPAGATION_REQUIRES_NEW), or the new transaction + /// might participate in the existing one (in case of PROPAGATION_REQUIRED). + /// Default implementation returns false, assuming that detection of or + /// participating in existing transactions is generally not supported. + /// Subclasses are of course encouraged to provide such support. + /// + /// Transaction object returned by + /// . + /// + /// True if there is an existing transaction. + /// + /// In the case of system errors. + /// + protected virtual bool IsExistingTransaction(object transaction) + { + return false; + } + + /// + /// Begin a new transaction with the given transaction definition. + /// + /// + /// Does not have to care about applying the propagation behavior, + /// as this has already been handled by this abstract manager. + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// instance, describing + /// propagation behavior, isolation level, timeout etc. + /// + /// + /// In the case of creation or system errors. + /// + protected abstract void DoBegin(object transaction, ITransactionDefinition definition); + + /// + /// Suspend the resources of the current transaction. + /// + /// + /// Transaction synchronization will already have been suspended. + /// + /// Default implementation throws a TransactionSuspensionNotSupportedException, + /// assuming that transaction suspension is generally not supported. + /// + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// An object that holds suspended resources (will be kept unexamined for passing it into + /// .) + /// + /// + /// If suspending is not supported by the transaction manager implementation. + /// + /// + /// in case of system errors. + /// + protected virtual object DoSuspend(object transaction) + { + throw new TransactionSuspensionNotSupportedException( + "Transaction manager [" + GetType().Name + "] does not support transaction suspension"); + } + + /// + /// Resume the resources of the current transaction. + /// + /// Transaction synchronization will be resumed afterwards. + /// + /// Default implementation throws a TransactionSuspensionNotSupportedException, + /// assuming that transaction suspension is generally not supported. + /// + /// + /// + /// Transaction object returned by + /// . + /// + /// + /// The object that holds suspended resources as returned by + /// . + /// + /// + /// If suspending is not supported by the transaction manager implementation. + /// + /// + /// In the case of system errors. + /// + protected virtual void DoResume(object transaction, object suspendedResources) + { + throw new TransactionSuspensionNotSupportedException( + "Transaction manager [" + GetType().Name + "] does not support transaction suspension"); + } + + /// + /// Perform an actual commit on the given transaction. + /// + /// The status representation of the transaction. + /// + ///

+ /// An implementation does not need to check the rollback-only flag. + ///

+ ///
+ /// + /// In the case of system errors. + /// + protected abstract void DoCommit(DefaultTransactionStatus status); + + /// + /// Perform an actual rollback on the given transaction. + /// + /// The status representation of the transaction. + /// + /// An implementation does not need to check the new transaction flag. + /// + /// + /// In the case of system errors. + /// + protected abstract void DoRollback(DefaultTransactionStatus status); + + /// + /// Set the given transaction rollback-only. Only called on rollback + /// if the current transaction takes part in an existing one. + /// + /// Default implementation throws an IllegalTransactionStateException, + /// assuming that participating in existing transactions is generally not + /// supported. Subclasses are of course encouraged to provide such support. + /// + /// The status representation of the transaction. + /// + /// In the case of system errors. + /// + protected virtual void DoSetRollbackOnly(DefaultTransactionStatus status) + { + throw new IllegalTransactionStateException( + "Participating in existing transactions is not supported - when 'IsExistingTransaction' " + + "returns true, appropriate 'DoSetRollbackOnly' behavior must be provided"); + } + + /// + /// Return whether to use a savepoint for a nested transaction. Default is true, + /// which causes delegation to + /// for holding a savepoint. + /// + /// + /// + ///

+ /// Subclasses can override this to return false, causing a further + /// invocation of + /// + /// despite an already existing transaction. + ///

+ ///
+ protected virtual bool UseSavepointForNestedTransaction() + { + return true; + } + + /// + /// Cleanup resources after transaction completion. + /// + /// + /// Transaction object returned by + /// . + /// + /// + ///

+ /// Called after + /// and + /// + /// execution on any outcome. + ///

+ ///

+ /// Should not throw any exceptions but just issue warnings on errors. + ///

+ ///

+ /// Default implementation does nothing. + ///

+ ///
+ protected virtual void DoCleanupAfterCompletion(object transaction) + { + } + + #endregion + + #region IPlatformTransactionManager Members + + /// + /// Return a currently active transaction or create a new one. + /// + /// + ///

+ /// This implementation handles propagation behavior. + ///

+ ///

+ /// Delegates to + /// , + /// , + /// and + /// . + ///

+ ///

+ /// Note that parameters like isolation level or timeout will only be applied + /// to new transactions, and thus be ignored when participating in active ones. + /// Furthermore, they aren't supported by every transaction manager: + /// a proper implementation should throw an exception when custom values + /// that it doesn't support are specified. + ///

+ ///
+ /// + /// instance (can be null for + /// defaults), describing propagation behavior, isolation level, timeout etc. + /// + /// + /// In case of lookup, creation, or system errors. + /// + /// + /// representing the new or current transaction. + /// + public ITransactionStatus GetTransaction(ITransactionDefinition definition) + { + object transaction = DoGetTransaction(); + bool debugEnabled = log.IsDebugEnabled; + bool newSynchronization; + + if (debugEnabled) + { + log.Debug("Using transaction object [" + transaction + "]"); + } + + if (definition == null) + { + definition = new DefaultTransactionDefinition(); + } + if (IsExistingTransaction(transaction)) + { + // Existing transaction found -> check propagation behavior to find out how to behave. + return HandleExistingTransaction(definition, transaction, debugEnabled); + } + + // Check definition settings for new transaction. + if (definition.TransactionTimeout < DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + throw new InvalidTimeoutException("Invalid transaction timeout", definition.TransactionTimeout); + } + + // No existing transaction found -> check propagation behavior to find out how to proceed. + if (definition.PropagationBehavior == TransactionPropagation.Mandatory) + { + throw new IllegalTransactionStateException( + "Transaction propagation 'mandatory' but no existing transaction found"); + } + else if (definition.PropagationBehavior == TransactionPropagation.Required || + definition.PropagationBehavior == TransactionPropagation.RequiresNew || + definition.PropagationBehavior == TransactionPropagation.Nested) + { + object suspendedResources = Suspend(null); + if (debugEnabled) + { + log.Debug("Creating new transaction with name [" + definition.Name + "]:" + definition); + } + try + { + DoBegin(transaction, definition); + } catch (TransactionException) + { + Resume(null, suspendedResources); + throw; + } + newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never); + return NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, + suspendedResources); + } + else + { + // Create "empty" transaction: no actual transaction, but potentially synchronization. + newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always); + return NewTransactionStatus(definition, null, false, newSynchronization, debugEnabled, null); + + } + + } + + private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction, bool debugEnabled) + { + //bool newSynchronization; + if (definition.PropagationBehavior == TransactionPropagation.Never) + { + throw new IllegalTransactionStateException( + "Transaction propagation 'never' but existing transaction found."); + } + if (definition.PropagationBehavior == TransactionPropagation.NotSupported) + { + if (debugEnabled) + { + log.Debug("Suspending current transaction"); + } + object suspendedResources = Suspend(transaction); + bool newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always); + return + NewTransactionStatus(definition, null, false, newSynchronization, debugEnabled, + suspendedResources); + } + + if (definition.PropagationBehavior == TransactionPropagation.RequiresNew) + { + if (debugEnabled) + { + log.Debug("Suspending current transaction, creating new transaction with name [" + + definition.Name + "]:" + definition); + } + object suspendedResources = Suspend(transaction); + try + { + DoBegin(transaction, definition); + } + catch (TransactionException beginEx) + { + try + { + Resume(transaction, suspendedResources); + } + catch (TransactionException resumeEx) + { + log.Error( + "Inner transaction begin exception overridden by outer transaction resume exception"); + log.Error("Begin Transaction Exception", beginEx); + log.Error("Resume Transaction Exception", resumeEx); + throw; + } + throw; + } + bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never); + return + NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); + } + if (definition.PropagationBehavior == TransactionPropagation.Nested) + { + if (!NestedTransactionsAllowed) + { + throw new NestedTransactionNotSupportedException( + "Transaction manager does not allow nested transactions by default - " + + "specify 'NestedTransactionsAllowed' property with value 'true'"); + } + if (debugEnabled) + { + log.Debug("Creating nested transaction with name [" + definition.Name + "]:" + definition); + } + + if (UseSavepointForNestedTransaction()) + { + DefaultTransactionStatus status = + NewTransactionStatus(definition, transaction, false, false, debugEnabled, null); + status.CreateAndHoldSavepoint(DateTime.Now.ToLongTimeString()); + return status; + } + else + { + DoBegin(transaction, definition); + bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never); + return NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null); + + } + } + // Assumably PROPAGATION_SUPPORTS. + if (debugEnabled) { + log.Debug("Participating in existing transaction"); + } + bool newSynch = (_transactionSyncState != TransactionSynchronizationState.Never); + return NewTransactionStatus(definition, transaction, false, newSynch, debugEnabled, null); + + } + + /// + /// This implementation of commit handles participating in existing transactions + /// and programmatic rollback requests. + /// + /// + /// + /// + /// ITransactionStatus object returned by the + /// () method. + /// + /// + /// In case of commit or system errors. + /// + public void Commit(ITransactionStatus transactionStatus) + { + if (transactionStatus.Completed) + { + throw new IllegalTransactionStateException( + "Transaction is already completed - do not call commit or rollback more than once per transaction"); + } + + DefaultTransactionStatus defaultStatus = (DefaultTransactionStatus) transactionStatus; + if (defaultStatus.LocalRollbackOnly) + { + if (defaultStatus.Debug) + { + log.Debug("Transaction code has requested rollback"); + } + ProcessRollback(defaultStatus); + return; + } + if ( !ShouldCommitOnGlobalRollbackOnly && defaultStatus.GlobalRollbackOnly) + { + if (defaultStatus.Debug) + { + log.Debug("Global transaction is marked as rollback-only but transactional code requested commit"); + } + ProcessRollback(defaultStatus); + // Throw UnexpectedRollbackException only at outermost transaction boundary + // or if explicitly asked to. + if (defaultStatus.IsNewTransaction || FailEarlyOnGlobalRollbackOnly) + { + throw new UnexpectedRollbackException( + "Transaction rolled back because it has been marked as rollback-only"); + } + return; + } + ProcessCommit(defaultStatus); + + } + + protected virtual bool ShouldCommitOnGlobalRollbackOnly + { + get { return false; } + } + + private void ProcessCommit(DefaultTransactionStatus status) + { + try + { + bool beforeCompletionInvoked = false; + try + { + TriggerBeforeCommit(status); + TriggerBeforeCompletion(status); + beforeCompletionInvoked = true; + bool globalRollbackOnly = false; + if (status.IsNewTransaction || FailEarlyOnGlobalRollbackOnly) + { + globalRollbackOnly = status.GlobalRollbackOnly; + } + if (status.HasSavepoint) + { + status.ReleaseHeldSavepoint(); + } + else if (status.IsNewTransaction) + { + DoCommit(status); + } + // Throw UnexpectedRollbackException if we have a global rollback-only + // marker but still didn't get a corresponding exception from commit. + if (globalRollbackOnly) + { + throw new UnexpectedRollbackException( + "Transaction silently rolled back because it has been marked as rollback-only"); + } + } + catch (UnexpectedRollbackException) + { + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback); + throw; + } + catch (TransactionException ex) + { + if (RollbackOnCommitFailure) + { + DoRollbackOnCommitException(status, ex); + } + else + { + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown); + } + throw; + } + catch (Exception ex) + { + if (!beforeCompletionInvoked) + { + TriggerBeforeCompletion(status); + } + DoRollbackOnCommitException(status, ex); + throw; + } + // Trigger AfterCommit callbacks, with an exception thrown there + // propagated to callers but the transaction still considered as commited. + try + { + TriggerAfterCommit(status); + } + finally + { + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Committed); + } + } + finally + { + CleanupAfterCompletion(status); + } + } + + private void TriggerAfterCommit(DefaultTransactionStatus status) + { + if (status.NewSynchronization) + { + if (status.Debug) + { + log.Debug("Trigger AfterCommit Synchronization"); + } + IList synchronizations = TransactionSynchronizationManager.Synchronizations; + foreach (ITransactionSynchronization currentTxnSynchronization in synchronizations) + { + try + { + currentTxnSynchronization.AfterCommit(); + } + catch (Exception e) + { + log.Error("TransactionSynchronization.AfterCommit thew exception", e); + } + } + } + } + + /// + /// Roll back the given transaction, with regard to its status. + /// + /// + ///

+ /// This implementation handles participating in existing transactions. + ///

+ ///

+ /// Delegates to + /// , + /// and + /// . + ///

+ ///

+ /// If the transaction wasn't a new one, just set it rollback-only + /// to take part in the surrounding transaction properly. + ///

+ ///
+ /// + /// ITransactionStatusObject returned by the + /// () method. + /// + /// + /// In case of system errors. + /// + public void Rollback(ITransactionStatus transactionStatus) + { + if (transactionStatus.Completed) + { + throw new IllegalTransactionStateException( + "Transaction is already completed - do not call commit or rollback more than once per transaction"); + } + DefaultTransactionStatus defaultStatus = (DefaultTransactionStatus) transactionStatus; + ProcessRollback(defaultStatus); + } + + private void ProcessRollback(DefaultTransactionStatus status) + { + try + { + try + { + TriggerBeforeCompletion(status); + if (status.HasSavepoint) + { + if (status.Debug) + { + log.Debug("Rolling back transaction to savepoint."); + } + status.RollbackToHeldSavepoint(); + } + else if (status.IsNewTransaction) + { + if (status.Debug) + { + log.Debug("Initiating transaction rollback"); + } + DoRollback(status); + } + else if (status.HasTransaction()) + { + if (status.LocalRollbackOnly) + { + if(status.Debug) + { + log.Debug("Participating transaction failed - marking existing transaction as rollback-only"); + } + } + DoSetRollbackOnly(status); + } + else + { + log.Debug("Should roll back transaction but cannot - no transaction available."); + } + } + catch (Exception) + { + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown); + throw; + } + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback); + } + finally + { + CleanupAfterCompletion(status); + } + } + + #endregion + + #region Protected Method + + private DefaultTransactionStatus NewTransactionStatus(ITransactionDefinition definition, + object transaction, bool newTransaction, + bool newSynchronization, bool debug, + object suspendedResources) + { + bool actualNewSynchronization = newSynchronization && + !TransactionSynchronizationManager.SynchronizationActive; + if (actualNewSynchronization) + { + TransactionSynchronizationManager.ActualTransactionActive = (transaction != null); + TransactionSynchronizationManager.CurrentTransactionIsolationLevel = + definition.TransactionIsolationLevel; + TransactionSynchronizationManager.CurrentTransactionReadOnly = definition.ReadOnly; + TransactionSynchronizationManager.CurrentTransactionName = definition.Name; + TransactionSynchronizationManager.InitSynchronization(); + } + return + new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.ReadOnly, debug, + suspendedResources); + } + + /// + /// Determines the timeout to use for the given definition. Will fall back to this manager's default + /// timeout if the transaction definition doesn't specify a non-default value. + /// + /// The transaction definition. + /// the actual timeout to use. + protected int DetermineTimeout(ITransactionDefinition definition) + { + if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) + { + return definition.TransactionTimeout; + } + return _defaultTimeout; + } + + #endregion + + #region Private Methods + + + + + + /// + /// Suspend the given transaction. Suspends transaction synchronization first, + /// then delegates to the doSuspend template method. + /// + /// the current transaction object + /// an object that holds suspended resources + private object Suspend(object transaction) + { + if (TransactionSynchronizationManager.SynchronizationActive) + { + IList suspendedSynchronizations = DoSuspendSynchronization(); + + try + { + object suspendedResources = null; + if (transaction != null) + { + suspendedResources = DoSuspend(transaction); + } + + string name = TransactionSynchronizationManager.CurrentTransactionName; + TransactionSynchronizationManager.CurrentTransactionName = null; + bool readOnly = TransactionSynchronizationManager.CurrentTransactionReadOnly; + TransactionSynchronizationManager.CurrentTransactionReadOnly = false; + IsolationLevel isolationLevel = TransactionSynchronizationManager.CurrentTransactionIsolationLevel; + TransactionSynchronizationManager.CurrentTransactionIsolationLevel = IsolationLevel.Unspecified; + bool wasActive = TransactionSynchronizationManager.ActualTransactionActive; + TransactionSynchronizationManager.ActualTransactionActive = false; + + + return new SuspendedResourcesHolder(suspendedSynchronizations, suspendedResources, + name, readOnly, isolationLevel, wasActive); + + } catch (TransactionException) + { + // DoSuspend failed - original transaction is still active + DoResumeSynchronization(suspendedSynchronizations); + throw; + } + } + else if (transaction != null) + { + // Transaction active but no synchronization active. + object suspendedResources = DoSuspend(transaction); + return new SuspendedResourcesHolder(suspendedResources); + } + else + { + // Neither transaction nor synchronization active. + return null; + } + + } + + private IList DoSuspendSynchronization() + { + IList suspendedSynchronizations = TransactionSynchronizationManager.Synchronizations; + foreach (ITransactionSynchronization currentTxnSynchronization in suspendedSynchronizations) + { + currentTxnSynchronization.Suspend(); + } + TransactionSynchronizationManager.ClearSynchronization(); + return suspendedSynchronizations; + } + + private void DoResumeSynchronization(IList suspendedSynchronizations) + { + TransactionSynchronizationManager.InitSynchronization(); + foreach (ITransactionSynchronization currentTxnSynchronization in suspendedSynchronizations) + { + currentTxnSynchronization.Resume(); + TransactionSynchronizationManager.RegisterSynchronization(currentTxnSynchronization); + } + } + + /// + /// Resume the given transaction. Delegates to the doResume template method + /// first, then resuming transaction synchronization. + /// + /// the current transaction object + /// the object that holds suspended resources, as returned by suspend + private void Resume(object transaction, object suspendedResources) + { + SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources; + if (resourcesHolder != null) + { + object suspendedResourcesObject = resourcesHolder.SuspendedResources; + if (suspendedResourcesObject != null) + { + DoResume(transaction, suspendedResourcesObject); + } + IList suspendedSynchronizations = resourcesHolder.SuspendedSynchronizations; + if (suspendedSynchronizations != null) + { + TransactionSynchronizationManager.ActualTransactionActive = resourcesHolder.WasActive; + TransactionSynchronizationManager.CurrentTransactionIsolationLevel = resourcesHolder.IsolationLevel; + TransactionSynchronizationManager.CurrentTransactionReadOnly = resourcesHolder.ReadOnly; + TransactionSynchronizationManager.CurrentTransactionName = resourcesHolder.Name; + DoResumeSynchronization(suspendedSynchronizations); + } + + } + } + + + + /// + /// Invoke doRollback, handling rollback exceptions properly. + /// + /// object representing the transaction + /// the thrown application exception or error + /// + /// in case of a rollback error + /// + private void DoRollbackOnCommitException(DefaultTransactionStatus status, Exception exception) + { + try + { + if (status.IsNewTransaction) + { + if (status.Debug) + { + log.Debug("Initiating transaction rollback on commit exception."); + } + DoRollback(status); + } + else if (status.HasTransaction()) + { + if (status.Debug) + { + log.Debug("Marking existing transaction as rollback-only after commit exception", exception); + } + DoSetRollbackOnly(status); + } + } + catch (Exception) + { + //TODO investigate rollback behavior... + log.Error("Commit exception overridden by rollback exception", exception); + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown); + throw; + } + TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback); + } + + /// + /// Trigger beforeCommit callback. + /// + /// object representing the transaction + private void TriggerBeforeCommit(DefaultTransactionStatus status) + { + if (status.NewSynchronization) + { + IList synchronizations = TransactionSynchronizationManager.Synchronizations; + foreach (ITransactionSynchronization currentTxnSynchronization in synchronizations) + { + currentTxnSynchronization.BeforeCommit(status.ReadOnly); + } + } + } + + /// + /// Trigger beforeCompletion callback. + /// + /// object representing the transaction + private void TriggerBeforeCompletion(DefaultTransactionStatus status) + { + if (status.NewSynchronization) + { + if (status.Debug) + { + log.Debug("Trigger BeforeCompletion Synchronization"); + } + IList synchronizations = TransactionSynchronizationManager.Synchronizations; + foreach (ITransactionSynchronization synchronization in synchronizations) + { + try + { + synchronization.BeforeCompletion(); + } + catch (Exception e) + { + log.Error("TransactionSynchronization.BeforeCompletion threw exception", e); + } + } + } + } + + /// + /// Trigger afterCompletion callback, handling exceptions properly. + /// + /// object representing the transaction + /// + /// Completion status according to + /// + private void TriggerAfterCompletion(DefaultTransactionStatus status, TransactionSynchronizationStatus completionStatus) + { + if (status.NewSynchronization) + { + IList synchronizations = TransactionSynchronizationManager.Synchronizations; + if (!status.HasTransaction() || status.IsNewTransaction) + { + if (status.Debug) + { + log.Debug("Triggering afterCompletion synchronization"); + } + InvokeAfterCompletion(synchronizations, completionStatus); + } + else + { + //TODO investigate parallel of JTA/System.Txs + log.Info("Transaction controlled outside of spring tx manager."); + } + } + } + + private void InvokeAfterCompletion(IList synchronizations, TransactionSynchronizationStatus status) + { + foreach (ITransactionSynchronization synchronization in synchronizations) + { + try + { + synchronization.AfterCompletion(status); + } catch (Exception e) + { + log.Error("TransactionSynchronization.AfterCompletion threw exception", e); + } + } + } + + /// + /// Clean up after completion, clearing synchronization if necessary, + /// and invoking doCleanupAfterCompletion. + /// + /// object representing the transaction + private void CleanupAfterCompletion(DefaultTransactionStatus status) + { + status.Completed = true; + if (status.NewSynchronization) + { + TransactionSynchronizationManager.Clear(); + } + if (status.IsNewTransaction) + { + DoCleanupAfterCompletion(status.Transaction); + } + if (status.SuspendedResources != null) + { + if (status.Debug) + { + log.Debug("Resuming suspended transaction"); + } + Resume(status.Transaction, status.SuspendedResources); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs b/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs index 52dd0725..acb0d1fc 100644 --- a/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs +++ b/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs @@ -1,289 +1,288 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Data; -using System.Text; - -namespace Spring.Transaction.Support -{ - /// - /// Default implementation of the - /// interface, offering object-style configuration and sensible default values. - /// - /// - ///

- /// Base class for both and - /// . - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: DefaultTransactionDefinition.cs,v 1.15 2007/12/07 08:10:03 markpollack Exp $ - [Serializable] - public class DefaultTransactionDefinition : ITransactionDefinition - { - /// - /// Prefix for Propagation settings. - /// - public static readonly string PROPAGATION_CONSTANT_PREFIX = "PROPAGATION"; - - /// - /// Prefix for IsolationLevel settings. - /// - public static readonly string ISOLATION_CONSTANT_PREFIX = "ISOLATION"; - - /// - /// Prefix for transaction timeout values in description strings. - /// - public static readonly string TIMEOUT_PREFIX = "timeout_"; - - /// - /// Marker for read-only transactions in description strings. - /// - public static readonly string READ_ONLY_MARKER = "readOnly"; - - /// - /// The default transaction timeout. - /// - public const int TIMEOUT_DEFAULT = -1; - - //TODO Refactoring to sync with Spring 2.0 for nt/enums for various default values. - - private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; - private IsolationLevel _transactionIsolationLevel = IsolationLevel.ReadCommitted; - private int _timeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; - private bool _readOnly = false; - private string _name = null; -#if NET_2_0 - private System.Transactions.EnterpriseServicesInteropOption _esInteropOption; - -#endif - - /// - /// Creates a new instance of the - /// class. - /// - public DefaultTransactionDefinition() {} - - /// - /// Creates a new instance of the - /// class - /// with the supplied - /// behaviour. - /// - /// - /// The desired behavior. - /// - public DefaultTransactionDefinition( TransactionPropagation transactionPropagation ) - { - _transactionPropagation = transactionPropagation; - } - - #region ITransactionDefinition Members - - // TODO change method name to same as type returned (TransactionPropagation) - - - - /// - /// Gets / Sets the propagation - /// behavior. - /// - public TransactionPropagation PropagationBehavior - { - get { return _transactionPropagation; } - set { _transactionPropagation = value; } - } - - - // TODO change method name to same as type returned (TransactionPropagation) - - - /// - /// Return the isolation level of type . - /// - /// - ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// Note that a transaction manager that does not support custom isolation levels - /// will throw an exception when given any other level than - /// . - ///

- ///
- public IsolationLevel TransactionIsolationLevel - { - get { return _transactionIsolationLevel; } - set { _transactionIsolationLevel = value; } - } - - /// - /// Return the transaction timeout. - /// - /// - ///

- /// Must return a number of seconds, or -1. - /// Only makes sense in combination with - /// and - /// . - /// Note that a transaction manager that does not support timeouts will - /// throw an exception when given any other timeout than -1. - ///

- ///
- public int TransactionTimeout - { - get { return _timeout; } - set - { - if ( value < DefaultTransactionDefinition.TIMEOUT_DEFAULT ) - { - throw new ArgumentException( "Timeout must be a positive integer or DefaultTransactionDefinition.TIMEOUT_DEFAULT" ); - } - _timeout = value; - } - } - - /// - /// Get whether to optimize as read-only transaction. - /// - /// - ///

- /// This just serves as hint for the actual transaction subsystem, - /// it will not necessarily cause failure of write accesses. - ///

- ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// A transaction manager that cannot interpret the read-only hint - /// will not throw an exception when given ReadOnly=true. - ///

- ///
- public bool ReadOnly - { - get { return _readOnly; } - set { _readOnly = value; } - } - - /// - /// Return the name of this transaction. Can be null. - /// - /// - /// - /// This will be used as a transaction name to be shown in a - /// transaction monitor, if applicable. In the case of Spring - /// declarative transactions, the exposed name will be the fully - /// qualified type name + "." method name + assembly (by default). - /// - public string Name - { - get { return _name; } - set { _name = value;} - } - -#if NET_2_0 - /// - /// Gets the enterprise services interop option. - /// - /// The enterprise services interop option. - public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption - { - get { return _esInteropOption; } - set { _esInteropOption = value; } - } -#endif - - #endregion - - /// - /// An override of the default method. - /// - /// The to compare to. - /// True if the objects are equal. - public override bool Equals(object obj) - { - return ( obj is ITransactionDefinition ) && ToString().Equals( obj.ToString() ); - } - - /// - /// An override of the default method that returns the - /// hashcode of the - /// - /// property. - /// - /// - /// The hashcode of the - /// - /// property. - /// - public override int GetHashCode() - { - return ToString().GetHashCode(); - } - - /// - /// An override of the default method that returns a string - /// representation of the - /// - /// property. - /// - /// - /// A string representation of the - /// - /// property. - /// - public override string ToString() - { - return DefinitionDescription; - } - - /// - /// Returns a representation of the - /// - /// property. - /// - protected string DefinitionDescription - { - get - { - StringBuilder builder = new StringBuilder(); - builder.Append( PROPAGATION_CONSTANT_PREFIX +"_" + PropagationBehavior ); - builder.Append( "," ); - builder.Append( ISOLATION_CONSTANT_PREFIX + "_" +TransactionIsolationLevel ); - if ( TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT ) - { - builder.Append( ",timeout_" + _timeout ); - } - if ( ReadOnly ) - { - builder.Append( ",readOnly" ); - } - return builder.ToString(); - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Data; +using System.Text; + +namespace Spring.Transaction.Support +{ + /// + /// Default implementation of the + /// interface, offering object-style configuration and sensible default values. + /// + /// + ///

+ /// Base class for both and + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + [Serializable] + public class DefaultTransactionDefinition : ITransactionDefinition + { + /// + /// Prefix for Propagation settings. + /// + public static readonly string PROPAGATION_CONSTANT_PREFIX = "PROPAGATION"; + + /// + /// Prefix for IsolationLevel settings. + /// + public static readonly string ISOLATION_CONSTANT_PREFIX = "ISOLATION"; + + /// + /// Prefix for transaction timeout values in description strings. + /// + public static readonly string TIMEOUT_PREFIX = "timeout_"; + + /// + /// Marker for read-only transactions in description strings. + /// + public static readonly string READ_ONLY_MARKER = "readOnly"; + + /// + /// The default transaction timeout. + /// + public const int TIMEOUT_DEFAULT = -1; + + //TODO Refactoring to sync with Spring 2.0 for nt/enums for various default values. + + private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; + private IsolationLevel _transactionIsolationLevel = IsolationLevel.ReadCommitted; + private int _timeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; + private bool _readOnly = false; + private string _name = null; +#if NET_2_0 + private System.Transactions.EnterpriseServicesInteropOption _esInteropOption; + +#endif + + /// + /// Creates a new instance of the + /// class. + /// + public DefaultTransactionDefinition() {} + + /// + /// Creates a new instance of the + /// class + /// with the supplied + /// behaviour. + /// + /// + /// The desired behavior. + /// + public DefaultTransactionDefinition( TransactionPropagation transactionPropagation ) + { + _transactionPropagation = transactionPropagation; + } + + #region ITransactionDefinition Members + + // TODO change method name to same as type returned (TransactionPropagation) + + + + /// + /// Gets / Sets the propagation + /// behavior. + /// + public TransactionPropagation PropagationBehavior + { + get { return _transactionPropagation; } + set { _transactionPropagation = value; } + } + + + // TODO change method name to same as type returned (TransactionPropagation) + + + /// + /// Return the isolation level of type . + /// + /// + ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// Note that a transaction manager that does not support custom isolation levels + /// will throw an exception when given any other level than + /// . + ///

+ ///
+ public IsolationLevel TransactionIsolationLevel + { + get { return _transactionIsolationLevel; } + set { _transactionIsolationLevel = value; } + } + + /// + /// Return the transaction timeout. + /// + /// + ///

+ /// Must return a number of seconds, or -1. + /// Only makes sense in combination with + /// and + /// . + /// Note that a transaction manager that does not support timeouts will + /// throw an exception when given any other timeout than -1. + ///

+ ///
+ public int TransactionTimeout + { + get { return _timeout; } + set + { + if ( value < DefaultTransactionDefinition.TIMEOUT_DEFAULT ) + { + throw new ArgumentException( "Timeout must be a positive integer or DefaultTransactionDefinition.TIMEOUT_DEFAULT" ); + } + _timeout = value; + } + } + + /// + /// Get whether to optimize as read-only transaction. + /// + /// + ///

+ /// This just serves as hint for the actual transaction subsystem, + /// it will not necessarily cause failure of write accesses. + ///

+ ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// A transaction manager that cannot interpret the read-only hint + /// will not throw an exception when given ReadOnly=true. + ///

+ ///
+ public bool ReadOnly + { + get { return _readOnly; } + set { _readOnly = value; } + } + + /// + /// Return the name of this transaction. Can be null. + /// + /// + /// + /// This will be used as a transaction name to be shown in a + /// transaction monitor, if applicable. In the case of Spring + /// declarative transactions, the exposed name will be the fully + /// qualified type name + "." method name + assembly (by default). + /// + public string Name + { + get { return _name; } + set { _name = value;} + } + +#if NET_2_0 + /// + /// Gets the enterprise services interop option. + /// + /// The enterprise services interop option. + public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption + { + get { return _esInteropOption; } + set { _esInteropOption = value; } + } +#endif + + #endregion + + /// + /// An override of the default method. + /// + /// The to compare to. + /// True if the objects are equal. + public override bool Equals(object obj) + { + return ( obj is ITransactionDefinition ) && ToString().Equals( obj.ToString() ); + } + + /// + /// An override of the default method that returns the + /// hashcode of the + /// + /// property. + /// + /// + /// The hashcode of the + /// + /// property. + /// + public override int GetHashCode() + { + return ToString().GetHashCode(); + } + + /// + /// An override of the default method that returns a string + /// representation of the + /// + /// property. + /// + /// + /// A string representation of the + /// + /// property. + /// + public override string ToString() + { + return DefinitionDescription; + } + + /// + /// Returns a representation of the + /// + /// property. + /// + protected string DefinitionDescription + { + get + { + StringBuilder builder = new StringBuilder(); + builder.Append( PROPAGATION_CONSTANT_PREFIX +"_" + PropagationBehavior ); + builder.Append( "," ); + builder.Append( ISOLATION_CONSTANT_PREFIX + "_" +TransactionIsolationLevel ); + if ( TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT ) + { + builder.Append( ",timeout_" + _timeout ); + } + if ( ReadOnly ) + { + builder.Append( ",readOnly" ); + } + return builder.ToString(); + } + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionStatus.cs b/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionStatus.cs index 3f176273..da8b2fb1 100644 --- a/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionStatus.cs +++ b/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionStatus.cs @@ -1,328 +1,327 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - - -namespace Spring.Transaction.Support -{ - /// - /// Default implementation of the interface, - /// used by . - /// - /// - ///

- /// Holds all status information that - /// - /// needs internally, including a generic transaction object determined by - /// the concrete transaction manager implementation. - ///

- ///

- /// Supports delegating savepoint-related methods to a transaction object - /// that implements the interface. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: DefaultTransactionStatus.cs,v 1.14 2007/12/06 06:23:33 markpollack Exp $ - public class DefaultTransactionStatus : ITransactionStatus - { - private object _transaction; - private bool _newTransaction; - private bool _newSynchronization; - private bool _readOnly; - private readonly bool _debug; - private object _suspendedResources; - - private string _savepoint; - private bool _rollbackOnly; - private bool _completed = false; - - /// - /// Creates a new instance of the - /// class. - /// - /// The underlying transaction object that can hold state for the internal - /// transaction implementation. - /// True if the transaction is new, else false if participating in an existing transaction. - /// True if a new transaction synchronization has been opened for the given - /// . - /// True if the transaction is read only. - /// if set to true, enable debug log in tx managers. - /// The suspended resources for the given . - public DefaultTransactionStatus( object transaction, - bool newTransaction, - bool newSynchronization, - bool readOnly, - bool debug, - object suspendedResources) - { - _transaction = transaction; - _newTransaction = newTransaction; - _newSynchronization = newSynchronization; - _readOnly = readOnly; - _debug = debug; - _suspendedResources = suspendedResources; - } - - #region Properties - - /// - /// Gets a value indicating whether the progress of this transaction is debugged. - /// This is used by AbstractPlatformTransactionManager as an optimization, to prevent repeated - /// calls to log.IsDebug. Not really intended for client code. - /// true if debug; otherwise, false. - public bool Debug - { - get { return _debug; } - } - - /// - /// Returns the underlying transaction object. - /// - public object Transaction - { - get { return _transaction; } - } - - /// - /// Gets or sets a value indicating whether the Transaction is completed, that is commited or rolled back. - /// - /// true if completed; otherwise, false. - public bool Completed - { - get { return _completed; } - set { _completed = value; } - } - - /// - /// Returns true if the underlying transaction is read only. - /// - public bool ReadOnly - { - get { return _readOnly; } - } - - /// - /// Flag indicating if a new transaction synchronization has been opened - /// for this transaction. - /// - public bool NewSynchronization - { - get { return _newSynchronization; } - } - - /// - /// Returns suspended resources for this transaction. - /// - public object SuspendedResources - { - get { return _suspendedResources; } - } - - /// - /// Gets and sets the savepoint for the current transaction, if any. - /// - public string Savepoint - { - get { return _savepoint; } - set { _savepoint = value; } - } - - /// - /// Returns a flag indicating if the transaction has a savepoint. - /// - public bool HasSavepoint - { - get { return ( _savepoint != null ); } - } - - /// - /// Determines whether there is an actual transaction active. - /// - /// - /// true if there is an actual transaction active; otherwise, false. - /// - public bool HasTransaction() - { - return Transaction != null; - } - - /// - /// Return the underlying transaction as a - /// , if possible. - /// - /// - /// If the underlying transaction does not support savepoints. - /// - protected ISavepointManager SavepointManager - { - get - { - if ( ! IsTransactionSavepointManager ) - { - throw new NestedTransactionNotSupportedException( - "Transaction object [" + Transaction + "] does not support savepoints."); - } - return ( ISavepointManager) Transaction; - } - } - /// - /// Return true if the underlying transaction implements the - /// interface. - /// - public bool IsTransactionSavepointManager - { - get { return ( Transaction is ISavepointManager ); } - } - #endregion - - #region ITransactionStatus Members - /// - /// Returns true if the transaction is new, else false if participating - /// in an existing transaction. - /// - public bool IsNewTransaction - { - get - { - return ( HasTransaction() && _newTransaction ); - } - } - - /// - /// Determine the rollbackOnly flag via checking both this - /// - /// and the transaction object, provided that the latter implements the - /// interface. - /// - /// The property can only be set to true. - public bool RollbackOnly - { - get { - return ( LocalRollbackOnly || GlobalRollbackOnly); - } - - set { if (value) {_rollbackOnly = value;} } - } - #endregion - - - /// - /// Determine the rollback-only flag via checking this TransactionStatus. Will only - /// return true if the application set the property RollbackOnly to true on this - /// TransactionStatus object. - /// - /// true if [local rollback only]; otherwise, false. - public bool LocalRollbackOnly - { - get - { - return _rollbackOnly; - } - } - - public bool GlobalRollbackOnly - { - get - { - return ((_transaction is ISmartTransactionObject) && - ((ISmartTransactionObject) _transaction).RollbackOnly); - } - } - #region ISavepointManager Members - /// - /// This implementation delegates to the underlying transaction object - /// (if it implements the interface) - /// to create a savepoint. - /// - /// - /// If the underlying transaction does not support savepoints. - /// - public void CreateSavepoint( string savepoint ) - { - SavepointManager.CreateSavepoint( savepoint ); - } - - /// - /// This implementation delegates to the underlying transaction object - /// (if it implements the interface) - /// to rollback to the supplied . - /// - /// The savepoint to rollback to. - public void RollbackToSavepoint( string savepoint ) - { - SavepointManager.RollbackToSavepoint( savepoint ); - } - - /// - /// This implementation delegates to the underlying transaction object - /// (if it implements the interface) - /// to release the supplied . - /// - /// The savepoint to release. - public void ReleaseSavepoint( string savepoint) - { - SavepointManager.ReleaseSavepoint( savepoint ); - } - - #endregion - /// - /// Create a savepoint and hold it for the transaction. - /// - /// - /// If the underlying transaction does not support savepoints. - /// - public void CreateAndHoldSavepoint( string savepoint ) - { - SavepointManager.CreateSavepoint( savepoint ); - Savepoint = savepoint; - } - - /// - /// Roll back to the savepoint that is held for the transaction. - /// - /// - /// If no save point has been created. - /// - public void RollbackToHeldSavepoint() - { - if ( ! HasSavepoint ) - { - throw new TransactionUsageException( "No savepoint associated with current transaction" ); - } - SavepointManager.RollbackToSavepoint( Savepoint ); - } - - /// - /// Release the savepoint that is held for the transaction. - /// - /// - /// If no save point has been created. - /// - public void ReleaseHeldSavepoint() - { - if ( ! HasSavepoint ) - { - throw new TransactionUsageException( "No savepoint associated with current transaction" ); - } - SavepointManager.ReleaseSavepoint( Savepoint ); - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + + +namespace Spring.Transaction.Support +{ + /// + /// Default implementation of the interface, + /// used by . + /// + /// + ///

+ /// Holds all status information that + /// + /// needs internally, including a generic transaction object determined by + /// the concrete transaction manager implementation. + ///

+ ///

+ /// Supports delegating savepoint-related methods to a transaction object + /// that implements the interface. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public class DefaultTransactionStatus : ITransactionStatus + { + private object _transaction; + private bool _newTransaction; + private bool _newSynchronization; + private bool _readOnly; + private readonly bool _debug; + private object _suspendedResources; + + private string _savepoint; + private bool _rollbackOnly; + private bool _completed = false; + + /// + /// Creates a new instance of the + /// class. + /// + /// The underlying transaction object that can hold state for the internal + /// transaction implementation. + /// True if the transaction is new, else false if participating in an existing transaction. + /// True if a new transaction synchronization has been opened for the given + /// . + /// True if the transaction is read only. + /// if set to true, enable debug log in tx managers. + /// The suspended resources for the given . + public DefaultTransactionStatus( object transaction, + bool newTransaction, + bool newSynchronization, + bool readOnly, + bool debug, + object suspendedResources) + { + _transaction = transaction; + _newTransaction = newTransaction; + _newSynchronization = newSynchronization; + _readOnly = readOnly; + _debug = debug; + _suspendedResources = suspendedResources; + } + + #region Properties + + /// + /// Gets a value indicating whether the progress of this transaction is debugged. + /// This is used by AbstractPlatformTransactionManager as an optimization, to prevent repeated + /// calls to log.IsDebug. Not really intended for client code. + /// true if debug; otherwise, false. + public bool Debug + { + get { return _debug; } + } + + /// + /// Returns the underlying transaction object. + /// + public object Transaction + { + get { return _transaction; } + } + + /// + /// Gets or sets a value indicating whether the Transaction is completed, that is commited or rolled back. + /// + /// true if completed; otherwise, false. + public bool Completed + { + get { return _completed; } + set { _completed = value; } + } + + /// + /// Returns true if the underlying transaction is read only. + /// + public bool ReadOnly + { + get { return _readOnly; } + } + + /// + /// Flag indicating if a new transaction synchronization has been opened + /// for this transaction. + /// + public bool NewSynchronization + { + get { return _newSynchronization; } + } + + /// + /// Returns suspended resources for this transaction. + /// + public object SuspendedResources + { + get { return _suspendedResources; } + } + + /// + /// Gets and sets the savepoint for the current transaction, if any. + /// + public string Savepoint + { + get { return _savepoint; } + set { _savepoint = value; } + } + + /// + /// Returns a flag indicating if the transaction has a savepoint. + /// + public bool HasSavepoint + { + get { return ( _savepoint != null ); } + } + + /// + /// Determines whether there is an actual transaction active. + /// + /// + /// true if there is an actual transaction active; otherwise, false. + /// + public bool HasTransaction() + { + return Transaction != null; + } + + /// + /// Return the underlying transaction as a + /// , if possible. + /// + /// + /// If the underlying transaction does not support savepoints. + /// + protected ISavepointManager SavepointManager + { + get + { + if ( ! IsTransactionSavepointManager ) + { + throw new NestedTransactionNotSupportedException( + "Transaction object [" + Transaction + "] does not support savepoints."); + } + return ( ISavepointManager) Transaction; + } + } + /// + /// Return true if the underlying transaction implements the + /// interface. + /// + public bool IsTransactionSavepointManager + { + get { return ( Transaction is ISavepointManager ); } + } + #endregion + + #region ITransactionStatus Members + /// + /// Returns true if the transaction is new, else false if participating + /// in an existing transaction. + /// + public bool IsNewTransaction + { + get + { + return ( HasTransaction() && _newTransaction ); + } + } + + /// + /// Determine the rollbackOnly flag via checking both this + /// + /// and the transaction object, provided that the latter implements the + /// interface. + /// + /// The property can only be set to true. + public bool RollbackOnly + { + get { + return ( LocalRollbackOnly || GlobalRollbackOnly); + } + + set { if (value) {_rollbackOnly = value;} } + } + #endregion + + + /// + /// Determine the rollback-only flag via checking this TransactionStatus. Will only + /// return true if the application set the property RollbackOnly to true on this + /// TransactionStatus object. + /// + /// true if [local rollback only]; otherwise, false. + public bool LocalRollbackOnly + { + get + { + return _rollbackOnly; + } + } + + public bool GlobalRollbackOnly + { + get + { + return ((_transaction is ISmartTransactionObject) && + ((ISmartTransactionObject) _transaction).RollbackOnly); + } + } + #region ISavepointManager Members + /// + /// This implementation delegates to the underlying transaction object + /// (if it implements the interface) + /// to create a savepoint. + /// + /// + /// If the underlying transaction does not support savepoints. + /// + public void CreateSavepoint( string savepoint ) + { + SavepointManager.CreateSavepoint( savepoint ); + } + + /// + /// This implementation delegates to the underlying transaction object + /// (if it implements the interface) + /// to rollback to the supplied . + /// + /// The savepoint to rollback to. + public void RollbackToSavepoint( string savepoint ) + { + SavepointManager.RollbackToSavepoint( savepoint ); + } + + /// + /// This implementation delegates to the underlying transaction object + /// (if it implements the interface) + /// to release the supplied . + /// + /// The savepoint to release. + public void ReleaseSavepoint( string savepoint) + { + SavepointManager.ReleaseSavepoint( savepoint ); + } + + #endregion + /// + /// Create a savepoint and hold it for the transaction. + /// + /// + /// If the underlying transaction does not support savepoints. + /// + public void CreateAndHoldSavepoint( string savepoint ) + { + SavepointManager.CreateSavepoint( savepoint ); + Savepoint = savepoint; + } + + /// + /// Roll back to the savepoint that is held for the transaction. + /// + /// + /// If no save point has been created. + /// + public void RollbackToHeldSavepoint() + { + if ( ! HasSavepoint ) + { + throw new TransactionUsageException( "No savepoint associated with current transaction" ); + } + SavepointManager.RollbackToSavepoint( Savepoint ); + } + + /// + /// Release the savepoint that is held for the transaction. + /// + /// + /// If no save point has been created. + /// + public void ReleaseHeldSavepoint() + { + if ( ! HasSavepoint ) + { + throw new TransactionUsageException( "No savepoint associated with current transaction" ); + } + SavepointManager.ReleaseSavepoint( Savepoint ); + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/ISmartTransactionObject.cs b/src/Spring/Spring.Data/Transaction/Support/ISmartTransactionObject.cs index 34b1b659..393f67d8 100644 --- a/src/Spring/Spring.Data/Transaction/Support/ISmartTransactionObject.cs +++ b/src/Spring/Spring.Data/Transaction/Support/ISmartTransactionObject.cs @@ -1,51 +1,50 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Support -{ - /// - /// Interface to be implemented by transaction objects that are able to - /// return an internal rollback-only marker, typically from a another - /// transaction that has participated and marked it as rollback-only. - /// - /// - ///

- /// Autodetected by , - /// to always return a current rollbackOnly flag even if not resulting from the current - /// . - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: ISmartTransactionObject.cs,v 1.6 2007/08/29 03:42:20 markpollack Exp $ - public interface ISmartTransactionObject - { - /// - /// Return whether the transaction is internally marked as rollback-only. - /// - /// True of the transaction is marked as rollback-only. - bool RollbackOnly - { - get; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Support +{ + /// + /// Interface to be implemented by transaction objects that are able to + /// return an internal rollback-only marker, typically from a another + /// transaction that has participated and marked it as rollback-only. + /// + /// + ///

+ /// Autodetected by , + /// to always return a current rollbackOnly flag even if not resulting from the current + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + public interface ISmartTransactionObject + { + /// + /// Return whether the transaction is internally marked as rollback-only. + /// + /// True of the transaction is marked as rollback-only. + bool RollbackOnly + { + get; + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/ITransactionCallback.cs b/src/Spring/Spring.Data/Transaction/Support/ITransactionCallback.cs index 1e889632..710cedef 100644 --- a/src/Spring/Spring.Data/Transaction/Support/ITransactionCallback.cs +++ b/src/Spring/Spring.Data/Transaction/Support/ITransactionCallback.cs @@ -1,50 +1,49 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - - -namespace Spring.Transaction.Support -{ - /// - /// Callback interface for transactional code. - /// - /// - ///

To be used with 's Execute - /// methods. - ///

- ///

- /// Typically used to gather various calls to transaction-unaware low-level - /// services into a higher-level method implementation with transaction - /// demarcation. - ///

- ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// $Id: ITransactionCallback.cs,v 1.4 2007/08/01 23:32:39 markpollack Exp $ - public interface ITransactionCallback - { - /// - /// Gets called by TransactionTemplate.Execute within a - /// transaction context. - /// - /// The associated transaction status. - /// A result object or null. - object DoInTransaction(ITransactionStatus status); - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + + +namespace Spring.Transaction.Support +{ + /// + /// Callback interface for transactional code. + /// + /// + ///

To be used with 's Execute + /// methods. + ///

+ ///

+ /// Typically used to gather various calls to transaction-unaware low-level + /// services into a higher-level method implementation with transaction + /// demarcation. + ///

+ ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + public interface ITransactionCallback + { + /// + /// Gets called by TransactionTemplate.Execute within a + /// transaction context. + /// + /// The associated transaction status. + /// A result object or null. + object DoInTransaction(ITransactionStatus status); + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/ITransactionOperations.cs b/src/Spring/Spring.Data/Transaction/Support/ITransactionOperations.cs index a606c762..dc3bcffc 100644 --- a/src/Spring/Spring.Data/Transaction/Support/ITransactionOperations.cs +++ b/src/Spring/Spring.Data/Transaction/Support/ITransactionOperations.cs @@ -1,65 +1,64 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Transaction.Support -{ - /// - /// Interface specifying basic transaction exectuion operations. - /// - /// - /// Implemented by . Not often used directly, - /// but a useful option to enhance testability, as it can easily be mocked or stubbed. - /// - /// Juergen Hoeller - /// Mark Pollac (.NET) - /// $Id: ITransactionOperations.cs,v 1.1 2007/08/01 18:53:14 markpollack Exp $ - public interface ITransactionOperations - { - /// - /// Executes the the action specified by the given delegate callback within a transaction. - /// - /// Allows for returning a result object created within the transaction, that is, - /// a domain object or a collection of domain objects. An exception thrown by the callback - /// is treated as a fatal exception that enforces a rollback. Such an exception gets - /// propagated to the caller of the template. - /// - /// The delegate that specifies the transactional action. - /// A result object returned by the callback, or null if one - /// - /// In case of initialization or system errors. - /// - object Execute(TransactionDelegate transactionMethod); - - /// - /// Executes the action specified by the given callback object within a transaction. - /// - /// Allows for returning a result object created within the transaction, that is, - /// a domain object or a collection of domain objects. An exception thrown by the callback - /// is treated as a fatal exception that enforces a rollback. Such an exception gets - /// propagated to the caller of the template. - /// - /// The callback object that specifies the transactional action. - /// A result object returned by the callback, or null if one - /// - /// In case of initialization or system errors. - /// - object Execute(ITransactionCallback action); - } +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Transaction.Support +{ + /// + /// Interface specifying basic transaction exectuion operations. + /// + /// + /// Implemented by . Not often used directly, + /// but a useful option to enhance testability, as it can easily be mocked or stubbed. + /// + /// Juergen Hoeller + /// Mark Pollac (.NET) + public interface ITransactionOperations + { + /// + /// Executes the the action specified by the given delegate callback within a transaction. + /// + /// Allows for returning a result object created within the transaction, that is, + /// a domain object or a collection of domain objects. An exception thrown by the callback + /// is treated as a fatal exception that enforces a rollback. Such an exception gets + /// propagated to the caller of the template. + /// + /// The delegate that specifies the transactional action. + /// A result object returned by the callback, or null if one + /// + /// In case of initialization or system errors. + /// + object Execute(TransactionDelegate transactionMethod); + + /// + /// Executes the action specified by the given callback object within a transaction. + /// + /// Allows for returning a result object created within the transaction, that is, + /// a domain object or a collection of domain objects. An exception thrown by the callback + /// is treated as a fatal exception that enforces a rollback. Such an exception gets + /// propagated to the caller of the template. + /// + /// The callback object that specifies the transactional action. + /// A result object returned by the callback, or null if one + /// + /// In case of initialization or system errors. + /// + object Execute(ITransactionCallback action); + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Support/ITransactionSynchronization.cs b/src/Spring/Spring.Data/Transaction/Support/ITransactionSynchronization.cs index 94f11b8b..147e928d 100644 --- a/src/Spring/Spring.Data/Transaction/Support/ITransactionSynchronization.cs +++ b/src/Spring/Spring.Data/Transaction/Support/ITransactionSynchronization.cs @@ -1,130 +1,129 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Support -{ - /// - /// Interface for transaction synchronization callbacks. - /// - /// - /// Supported by . - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: ITransactionSynchronization.cs,v 1.7 2006/11/24 05:57:46 markpollack Exp $ - public interface ITransactionSynchronization - { - /// - /// Suspend this synchronization. - /// - /// - ///

- /// Supposed to unbind resources from - /// - /// if managing any. - ///

- ///
- void Suspend(); - - /// - /// Resume this synchronization. - /// - /// - ///

- /// Supposed to rebind resources from - /// - /// if managing any. - ///

- ///
- void Resume(); - - /// - /// Invoked before transaction commit (before - /// ) - /// Can e.g. flush transactional O/R Mapping sessions to the database - /// - /// - /// - /// This callback does not mean that the transaction will actually be - /// commited. A rollback decision can still occur after this method - /// has been called. This callback is rather meant to perform work - /// that's only relevant if a commit still has a chance - /// to happen, such as flushing SQL statements to the database. - /// - /// - /// Note that exceptions will get propagated to the commit caller and cause a - /// rollback of the transaction. - /// - /// (note: do not throw TransactionException subclasses here!) - /// - /// - /// - /// If the transaction is defined as a read-only transaction. - /// - void BeforeCommit( bool readOnly ); - - /// - /// Invoked after transaction commit. - /// - /// Can e.g. commit further operations that are supposed to follow on - /// a successful commit of the main transaction. - /// Throws exception in case of errors; will be propagated to the caller. - /// Note: To not throw TransactionExeption sbuclasses here! - /// - /// - void AfterCommit(); - - /// - /// Invoked before transaction commit/rollback (after - /// , - /// even if - /// - /// threw an exception). - /// - /// - ///

- /// Can e.g. perform resource cleanup. - ///

- ///

- /// Note that exceptions will get propagated to the commit caller - /// and cause a rollback of the transaction. - ///

- ///
- void BeforeCompletion(); - - /// - /// Invoked after transaction commit/rollback. - /// - /// - /// Status according to - /// - /// - /// Can e.g. perform resource cleanup, in this case after transaction completion. - ///

- /// Note that exceptions will get propagated to the commit or rollback - /// caller, although they will not influence the outcome of the transaction. - ///

- ///
- void AfterCompletion( TransactionSynchronizationStatus status ); - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Support +{ + /// + /// Interface for transaction synchronization callbacks. + /// + /// + /// Supported by . + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public interface ITransactionSynchronization + { + /// + /// Suspend this synchronization. + /// + /// + ///

+ /// Supposed to unbind resources from + /// + /// if managing any. + ///

+ ///
+ void Suspend(); + + /// + /// Resume this synchronization. + /// + /// + ///

+ /// Supposed to rebind resources from + /// + /// if managing any. + ///

+ ///
+ void Resume(); + + /// + /// Invoked before transaction commit (before + /// ) + /// Can e.g. flush transactional O/R Mapping sessions to the database + /// + /// + /// + /// This callback does not mean that the transaction will actually be + /// commited. A rollback decision can still occur after this method + /// has been called. This callback is rather meant to perform work + /// that's only relevant if a commit still has a chance + /// to happen, such as flushing SQL statements to the database. + /// + /// + /// Note that exceptions will get propagated to the commit caller and cause a + /// rollback of the transaction. + /// + /// (note: do not throw TransactionException subclasses here!) + /// + /// + /// + /// If the transaction is defined as a read-only transaction. + /// + void BeforeCommit( bool readOnly ); + + /// + /// Invoked after transaction commit. + /// + /// Can e.g. commit further operations that are supposed to follow on + /// a successful commit of the main transaction. + /// Throws exception in case of errors; will be propagated to the caller. + /// Note: To not throw TransactionExeption sbuclasses here! + /// + /// + void AfterCommit(); + + /// + /// Invoked before transaction commit/rollback (after + /// , + /// even if + /// + /// threw an exception). + /// + /// + ///

+ /// Can e.g. perform resource cleanup. + ///

+ ///

+ /// Note that exceptions will get propagated to the commit caller + /// and cause a rollback of the transaction. + ///

+ ///
+ void BeforeCompletion(); + + /// + /// Invoked after transaction commit/rollback. + /// + /// + /// Status according to + /// + /// + /// Can e.g. perform resource cleanup, in this case after transaction completion. + ///

+ /// Note that exceptions will get propagated to the commit or rollback + /// caller, although they will not influence the outcome of the transaction. + ///

+ ///
+ void AfterCompletion( TransactionSynchronizationStatus status ); + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/ResourceHolderSupport.cs b/src/Spring/Spring.Data/Transaction/Support/ResourceHolderSupport.cs index 0a4bf827..26a5f76d 100644 --- a/src/Spring/Spring.Data/Transaction/Support/ResourceHolderSupport.cs +++ b/src/Spring/Spring.Data/Transaction/Support/ResourceHolderSupport.cs @@ -1,199 +1,198 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Support -{ - /// - /// Convenient base class for resource holders. - /// - /// - ///

- /// Features rollback-only support transactions. Can expire after a certain number of - /// seconds or milliseconds, to determine transactional timeouts. - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: ResourceHolderSupport.cs,v 1.9 2007/01/30 20:12:29 markpollack Exp $ - public abstract class ResourceHolderSupport - { - private bool synchronizedWithTransaction = false; - private bool rollbackOnly = false; - private DateTime deadline; - private int referenceCount = 0; - - /// - /// Mark the resource as synchronized with a transaction. - /// - public bool SynchronizedWithTransaction - { - get { return synchronizedWithTransaction; } - set { synchronizedWithTransaction = value; } - } - - /// - /// Get or set whether the resource is synchronized with a transaction. - /// - /// true if synchronized; otherwise, false. - public bool RollbackOnly - { - get { return rollbackOnly; } - set { rollbackOnly = value;} - } - - /// - /// Return the expiration deadline of this object. - /// - public DateTime Deadline - { - get { return deadline; } - } - - /// - /// Return whether this object has an associated timeout. - /// - public bool HasTimeout - { - get { return ( deadline != DateTime.MinValue ); } - } - - /// - /// Return the time to live for this object in seconds. - /// - /// - ///

- /// Rounds up eagerly, e.g. '9.00001' to '10'. - ///

- ///
- /// - /// If no deadline has been set. - /// - public int TimeToLiveInSeconds - { - get - { - int secs = (int)Math.Ceiling( TimeToLiveInMilliseconds / 1000 ); - checkTransactionTimeout(secs <= 0); - return secs; - } - } - - /// - /// Return the time to live for this object in milliseconds. - /// - /// - /// If no deadline has been set. - /// - public double TimeToLiveInMilliseconds - { - get - { - if ( deadline == DateTime.MinValue ) - { - throw new ArgumentException( "No deadline specified for this resource holder."); - } - TimeSpan duration = deadline - DateTime.Now; - checkTransactionTimeout(duration.TotalMilliseconds <= 0); - if (duration.TotalMilliseconds > 0) - { - return duration.TotalMilliseconds; - } - else - { - return 0; - } - } - } - - /// - /// Sets the timeout for this object in milliseconds. - /// - /// Number of milliseconds until expiration. - public long TimeoutInMillis - { - set - { - deadline = DateTime.Now.AddMilliseconds(value); - } - } - - /// - /// Sets the timeout for this object in seconds. - /// - /// Number of seconds until expiration. - public int TimeoutInSeconds - { - set - { - TimeoutInMillis = value * 1000; - } - } - - private void checkTransactionTimeout(bool deadlineReached) - { - if (deadlineReached) - { - RollbackOnly = true; - throw new TransactionTimedOutException("Transaction timed out: deadline was " + Deadline); - } - } - - - /// - /// Clear the transaction state of this resource holder. - /// - public virtual void Clear() - { - synchronizedWithTransaction = false; - rollbackOnly = false; - deadline = DateTime.MinValue; - } - - /// - /// Increase the reference count by one because the holder has been requested. - /// - public void Requested() - { - referenceCount++; - } - - /// - /// Decrease the reference count by one because the holder has been released. - /// - public void Released() - { - referenceCount--; - } - - /// - /// Return wheterh there are still open references to this holder - /// - public bool IsOpen - { - get - { - return (referenceCount > 0); - } - } - - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Support +{ + /// + /// Convenient base class for resource holders. + /// + /// + ///

+ /// Features rollback-only support transactions. Can expire after a certain number of + /// seconds or milliseconds, to determine transactional timeouts. + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + public abstract class ResourceHolderSupport + { + private bool synchronizedWithTransaction = false; + private bool rollbackOnly = false; + private DateTime deadline; + private int referenceCount = 0; + + /// + /// Mark the resource as synchronized with a transaction. + /// + public bool SynchronizedWithTransaction + { + get { return synchronizedWithTransaction; } + set { synchronizedWithTransaction = value; } + } + + /// + /// Get or set whether the resource is synchronized with a transaction. + /// + /// true if synchronized; otherwise, false. + public bool RollbackOnly + { + get { return rollbackOnly; } + set { rollbackOnly = value;} + } + + /// + /// Return the expiration deadline of this object. + /// + public DateTime Deadline + { + get { return deadline; } + } + + /// + /// Return whether this object has an associated timeout. + /// + public bool HasTimeout + { + get { return ( deadline != DateTime.MinValue ); } + } + + /// + /// Return the time to live for this object in seconds. + /// + /// + ///

+ /// Rounds up eagerly, e.g. '9.00001' to '10'. + ///

+ ///
+ /// + /// If no deadline has been set. + /// + public int TimeToLiveInSeconds + { + get + { + int secs = (int)Math.Ceiling( TimeToLiveInMilliseconds / 1000 ); + checkTransactionTimeout(secs <= 0); + return secs; + } + } + + /// + /// Return the time to live for this object in milliseconds. + /// + /// + /// If no deadline has been set. + /// + public double TimeToLiveInMilliseconds + { + get + { + if ( deadline == DateTime.MinValue ) + { + throw new ArgumentException( "No deadline specified for this resource holder."); + } + TimeSpan duration = deadline - DateTime.Now; + checkTransactionTimeout(duration.TotalMilliseconds <= 0); + if (duration.TotalMilliseconds > 0) + { + return duration.TotalMilliseconds; + } + else + { + return 0; + } + } + } + + /// + /// Sets the timeout for this object in milliseconds. + /// + /// Number of milliseconds until expiration. + public long TimeoutInMillis + { + set + { + deadline = DateTime.Now.AddMilliseconds(value); + } + } + + /// + /// Sets the timeout for this object in seconds. + /// + /// Number of seconds until expiration. + public int TimeoutInSeconds + { + set + { + TimeoutInMillis = value * 1000; + } + } + + private void checkTransactionTimeout(bool deadlineReached) + { + if (deadlineReached) + { + RollbackOnly = true; + throw new TransactionTimedOutException("Transaction timed out: deadline was " + Deadline); + } + } + + + /// + /// Clear the transaction state of this resource holder. + /// + public virtual void Clear() + { + synchronizedWithTransaction = false; + rollbackOnly = false; + deadline = DateTime.MinValue; + } + + /// + /// Increase the reference count by one because the holder has been requested. + /// + public void Requested() + { + referenceCount++; + } + + /// + /// Decrease the reference count by one because the holder has been released. + /// + public void Released() + { + referenceCount--; + } + + /// + /// Return wheterh there are still open references to this holder + /// + public bool IsOpen + { + get + { + return (referenceCount > 0); + } + } + + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionCallbackWithoutResult.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionCallbackWithoutResult.cs index 3c3304cc..804cf6ff 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionCallbackWithoutResult.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionCallbackWithoutResult.cs @@ -1,75 +1,74 @@ -#region License - -/* - * Copyright © 2002-2005 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Transaction.Support -{ - /// - /// Simple convenience class for TransactionCallback implementation. - /// Allows for implementing a DoInTransaction version without result, - /// i.e. without the need for a return statement. - /// - /// Mark Pollack (.NET) - /// $Id: TransactionCallbackWithoutResult.cs,v 1.3 2006/06/21 14:07:30 markpollack Exp $ - public abstract class TransactionCallbackWithoutResult : ITransactionCallback - { - #region Methods - - /// - /// Gets called by TransactionTemplate.execute within a transactional context - /// when no return value is required. - /// - /// The status. - /// - /// Does not need to care about transactions itself, although it can retrieve - /// and influence the status of the current transaction via the given status - /// object, e.g. setting rollback-only. - /// A RuntimeException thrown by the callback is treated as application - /// exception that enforces a rollback. An exception gets propagated to the - /// caller of the template. - /// - public abstract void DoInTransactionWithoutResult(ITransactionStatus status); - - #endregion - - #region ITransactionCallback Members - - /// - /// Gets called by TransactionTemplate.Execute within a - /// transaction context. - /// - /// The associated transaction status. - /// a result object or null - public object DoInTransaction(ITransactionStatus status) - { - DoInTransactionWithoutResult(status); - return null; - } - - - - #endregion - } -} +#region License + +/* + * Copyright © 2002-2005 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Transaction.Support +{ + /// + /// Simple convenience class for TransactionCallback implementation. + /// Allows for implementing a DoInTransaction version without result, + /// i.e. without the need for a return statement. + /// + /// Mark Pollack (.NET) + public abstract class TransactionCallbackWithoutResult : ITransactionCallback + { + #region Methods + + /// + /// Gets called by TransactionTemplate.execute within a transactional context + /// when no return value is required. + /// + /// The status. + /// + /// Does not need to care about transactions itself, although it can retrieve + /// and influence the status of the current transaction via the given status + /// object, e.g. setting rollback-only. + /// A RuntimeException thrown by the callback is treated as application + /// exception that enforces a rollback. An exception gets propagated to the + /// caller of the template. + /// + public abstract void DoInTransactionWithoutResult(ITransactionStatus status); + + #endregion + + #region ITransactionCallback Members + + /// + /// Gets called by TransactionTemplate.Execute within a + /// transaction context. + /// + /// The associated transaction status. + /// a result object or null + public object DoInTransaction(ITransactionStatus status) + { + DoInTransactionWithoutResult(status); + return null; + } + + + + #endregion + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionDelegate.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionDelegate.cs index 964ee795..78c6327f 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionDelegate.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionDelegate.cs @@ -1,42 +1,42 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Transaction.Support -{ - - /// - /// Callback delegate for performing actions within a transactional context. - /// - /// - ///

To be used with 's Execute - /// methods. - ///

- ///

- /// Typically used to gather various calls to transaction-unaware low-level - /// services into a higher-level method implementation with transaction - /// demarcation. - ///

- ///
- /// The status of the transaction, can be used to - /// trigger a rollback the current transaction by settings its - /// RollbackOnly property to true. - /// A result object or null. - public delegate object TransactionDelegate(ITransactionStatus status); -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Transaction.Support +{ + + /// + /// Callback delegate for performing actions within a transactional context. + /// + /// + ///

To be used with 's Execute + /// methods. + ///

+ ///

+ /// Typically used to gather various calls to transaction-unaware low-level + /// services into a higher-level method implementation with transaction + /// demarcation. + ///

+ ///
+ /// The status of the transaction, can be used to + /// trigger a rollback the current transaction by settings its + /// RollbackOnly property to true. + /// A result object or null. + public delegate object TransactionDelegate(ITransactionStatus status); +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationAdapter.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationAdapter.cs index 590994d2..f6b01aca 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationAdapter.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationAdapter.cs @@ -1,146 +1,145 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Support -{ - /// - /// Adapter for the - /// interface. - /// - /// - /// Contains empty implementations of all interface methods, for easy overriding of - /// single methods. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: TransactionSynchronizationAdapter.cs,v 1.7 2006/12/06 00:02:25 markpollack Exp $ - public abstract class TransactionSynchronizationAdapter : ITransactionSynchronization, IComparable - { - - - #region ITransactionSynchronization Members - /// - /// Suspend this synchronization. - /// - /// - ///

- /// Supposed to unbind resources from - /// - /// if managing any. - ///

- ///
- public virtual void Suspend() {} - - /// - /// Resume this synchronization. - /// - /// - ///

- /// Supposed to unbind resources from - /// - /// if managing any. - ///

- ///
- public virtual void Resume() {} - - /// - /// Invoked before transaction commit (before - /// ) - /// - /// - /// If the transaction is defined as a read-only transaction. - /// - /// - ///

- /// Can flush transactional sessions to the database. - ///

- ///

- /// Note that exceptions will get propagated to the commit caller and - /// cause a rollback of the transaction. - ///

- ///
- public virtual void BeforeCommit( bool readOnly ) {} - - - /// - /// Invoked after transaction commit. - /// - /// Can e.g. commit further operations that are supposed to follow on - /// a successful commit of the main transaction. - /// Throws exception in case of errors; will be propagated to the caller. - /// Note: To not throw TransactionExeption sbuclasses here! - /// - public virtual void AfterCommit() - { - } - - /// - /// Invoked before transaction commit/rollback (after - /// , - /// even if - /// - /// threw an exception). - /// - /// - ///

- /// Can e.g. perform resource cleanup. - ///

- ///

- /// Note that exceptions will get propagated to the commit caller - /// and cause a rollback of the transaction. - ///

- ///
- public virtual void BeforeCompletion() {} - - /// - /// Invoked after transaction commit/rollback. - /// - /// - /// Status according to - /// - /// - /// Can e.g. perform resource cleanup, in this case after transaction completion. - ///

- /// Note that exceptions will get propagated to the commit or rollback - /// caller, although they will not influence the outcome of the transaction. - ///

- ///
- public virtual void AfterCompletion( TransactionSynchronizationStatus status ) {} - #endregion - - /// - ///Compares the current instance with another object of the same type. - /// - /// - /// - ///A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than obj. Zero This instance is equal to obj. Greater than zero This instance is greater than obj. - /// - /// - ///An object to compare with this instance. - ///obj is not the same type as this instance. 2 - public virtual int CompareTo(object obj) - { - return Int32.MinValue; - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Support +{ + /// + /// Adapter for the + /// interface. + /// + /// + /// Contains empty implementations of all interface methods, for easy overriding of + /// single methods. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public abstract class TransactionSynchronizationAdapter : ITransactionSynchronization, IComparable + { + + + #region ITransactionSynchronization Members + /// + /// Suspend this synchronization. + /// + /// + ///

+ /// Supposed to unbind resources from + /// + /// if managing any. + ///

+ ///
+ public virtual void Suspend() {} + + /// + /// Resume this synchronization. + /// + /// + ///

+ /// Supposed to unbind resources from + /// + /// if managing any. + ///

+ ///
+ public virtual void Resume() {} + + /// + /// Invoked before transaction commit (before + /// ) + /// + /// + /// If the transaction is defined as a read-only transaction. + /// + /// + ///

+ /// Can flush transactional sessions to the database. + ///

+ ///

+ /// Note that exceptions will get propagated to the commit caller and + /// cause a rollback of the transaction. + ///

+ ///
+ public virtual void BeforeCommit( bool readOnly ) {} + + + /// + /// Invoked after transaction commit. + /// + /// Can e.g. commit further operations that are supposed to follow on + /// a successful commit of the main transaction. + /// Throws exception in case of errors; will be propagated to the caller. + /// Note: To not throw TransactionExeption sbuclasses here! + /// + public virtual void AfterCommit() + { + } + + /// + /// Invoked before transaction commit/rollback (after + /// , + /// even if + /// + /// threw an exception). + /// + /// + ///

+ /// Can e.g. perform resource cleanup. + ///

+ ///

+ /// Note that exceptions will get propagated to the commit caller + /// and cause a rollback of the transaction. + ///

+ ///
+ public virtual void BeforeCompletion() {} + + /// + /// Invoked after transaction commit/rollback. + /// + /// + /// Status according to + /// + /// + /// Can e.g. perform resource cleanup, in this case after transaction completion. + ///

+ /// Note that exceptions will get propagated to the commit or rollback + /// caller, although they will not influence the outcome of the transaction. + ///

+ ///
+ public virtual void AfterCompletion( TransactionSynchronizationStatus status ) {} + #endregion + + /// + ///Compares the current instance with another object of the same type. + /// + /// + /// + ///A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than obj. Zero This instance is equal to obj. Greater than zero This instance is greater than obj. + /// + /// + ///An object to compare with this instance. + ///obj is not the same type as this instance. 2 + public virtual int CompareTo(object obj) + { + return Int32.MinValue; + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationManager.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationManager.cs index 65ad218b..c2c48230 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationManager.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationManager.cs @@ -1,491 +1,490 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Collections; -using System.Data; -using System.Globalization; -using System.Threading; -using Spring.Core; -using Spring.Threading; -using Spring.Util; - -namespace Spring.Transaction.Support -{ - /// - /// Internal class that manages resources and transaction synchronizations per thread. - /// - /// - /// Supports one resource per key without overwriting, i.e. a resource needs to - /// be removed before a new one can be set for the same key. - /// Supports a list of transaction synchronizations if synchronization is active. - ///

- /// Resource management code should check for thread-bound resources via GetResource(). - /// It is normally not supposed - /// to bind resources to threads, as this is the responsiblity of transaction managers. - /// A further option is to lazily bind on first use if transaction synchronization - /// is active, for performing transactions that span an arbitrary number of resources. - ///

- ///

- /// Transaction synchronization must be activated and deactivated by a transaction - /// manager via - /// InitSynchronization - /// and - /// ClearSynchronization. - /// This is automatically supported by - /// . - ///

- ///

- /// Resource management code should only register synchronizations when this - /// manager is active, and perform resource cleanup immediately else. - /// If transaction synchronization isn't active, there is either no current - /// transaction, or the transaction manager doesn't support synchronizations. - ///

- /// Note that this class uses following naming convention for the - /// named 'data slots' for storage of thread local data, 'Spring.Transaction:Name' - /// where Name is either - ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - /// $Id: TransactionSynchronizationManager.cs,v 1.19 2008/02/17 13:17:13 markpollack Exp $ - public sealed class TransactionSynchronizationManager - { - #region Logging - - private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof (TransactionSynchronizationManager)); - - #endregion - - #region Fields - private static readonly string syncsDataSlotName = "Spring.Transactions:syncList"; - - private static readonly string resourcesDataSlotName = "Spring.Transactions:resources"; - - private static readonly string currentTxReadOnlyDataSlotName = "Spring.Transactions:currentTxReadOnly"; - - private static readonly string currentTxNameDataSlotName = "Spring.Transactions:currentTxName"; - - private static readonly string currentTxIsolationLevelDataSlotName = "Spring.Transactions:currentTxIsolationLevel"; - - private static readonly string actualTxActiveDataSlotName = "Spring.Transactions:actualTxActive"; - - private static IComparer syncComparer = new OrderComparator(); - - #endregion - - #region Management of transaction-associated resource handles - /// - /// Return all resources that are bound to the current thread. - /// - /// Main for debugging purposes. Resource manager should always - /// invoke HasResource for a specific resource key that they are interested in. - /// - /// IDictionary with resource keys and resource objects or empty - /// dictionary if none is bound. - public static IDictionary ResourceDictionary - { - get - { - IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; - if (resources != null) - { - //TODO add readonly wrapper in Spring.Collections. - return resources; - } - else - { - return new Hashtable(); - } - } - } - - /// - /// Check if there is a resource for the given key bound to the current thread. - /// - /// key to check - /// if there is a value bound to the current thread - public static bool HasResource(Object key) - { - AssertUtils.ArgumentNotNull(key, "Key must not be null"); - return ResourceDictionary.Contains(key); - } - - /// - /// Retrieve a resource for the given key that is bound to the current thread. - /// - /// key to check - /// a value bound to the current thread, or null if none. - public static object GetResource(Object key) - { - AssertUtils.ArgumentNotNull(key, "Key must not be null"); - IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; - if (resources == null) - { - return null; - } - //Check for contains since indexer returning null behavior changes in 2.0 - if (!resources.Contains(key)) - { - return null; - } - object val = resources[key]; - - if (val != null && LOG.IsDebugEnabled) - { - LOG.Debug("Retrieved value [" + Describe(val) + "] for key [" + Describe(key) + "] bound to thread [" + - SystemUtils.ThreadId + "]"); - } - return val; - } - - /// - /// Bind the given resource for teh given key to the current thread - /// - /// key to bind the value to - /// value to bind - public static void BindResource(Object key, Object value) - { - AssertUtils.ArgumentNotNull(key, "Key value for thread local storage of transactional resources must not be null"); - AssertUtils.ArgumentNotNull(value, "Transactional resource to bind to thread local storage must not be null" ); - - IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; - //Set thread local resource storage if not found - if (resources == null) - { - resources = new Hashtable(); - LogicalThreadContext.SetData(resourcesDataSlotName, resources); - } - if (resources.Contains(key)) - { - throw new InvalidOperationException("Already value [" + resources[key] + "] for key [" + key + - "] bound to thread [" + SystemUtils.ThreadId + "]"); - } - resources.Add(key, value); - if (LOG.IsDebugEnabled) - { - LOG.Debug("Bound value [" + Describe(value) + "] for key [" + Describe(key) + "] to thread [" + - SystemUtils.ThreadId + "]"); - } - } - - - /// - /// Unbind a resource for the given key from the current thread - /// - /// key to check - /// the previously bound value - /// if there is no value bound to the thread - public static object UnbindResource(Object key) - { - AssertUtils.ArgumentNotNull(key, "Key must not be null"); - - IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; - if (resources == null || !resources.Contains(key)) - { - throw new InvalidOperationException("No value for key [" + key + "] bound to thread [" + - SystemUtils.ThreadId + "]"); - } - Object val = resources[key]; - resources.Remove(key); - if (resources.Count == 0) - { - LogicalThreadContext.FreeNamedDataSlot(resourcesDataSlotName); - } - if (LOG.IsDebugEnabled) - { - LOG.Debug("Removed value [" + Describe(val) + "] for key [" + Describe(key) + "] from thread [" + - SystemUtils.ThreadId + "]"); - } - return val; - } - - #endregion - - /// - /// Activate transaction synchronization for the current thread. - /// - /// - /// Called by transaction manager at the beginning of a transaction. - /// - /// - /// If synchronization is already active. - /// - public static void InitSynchronization() - { - if ( SynchronizationActive ) - { - throw new InvalidOperationException( "Cannot activate transaction synchronization - already active" ); - } - if (LOG.IsDebugEnabled) - { - LOG.Debug("Initializing transaction synchronization"); - } - ArrayList syncs = new ArrayList(); - LogicalThreadContext.SetData(syncsDataSlotName, syncs); - } - - /// - /// Deactivate transaction synchronization for the current thread. - /// - /// - /// Called by transaction manager on transaction cleanup. - /// - /// - /// If synchronization is not active. - /// - public static void ClearSynchronization() - { - if ( !SynchronizationActive ) - { - throw new InvalidOperationException( "Cannot deactivate transaction synchronization - not active" ); - } - if (LOG.IsDebugEnabled) - { - LOG.Debug("Clearing transaction synchronization"); - } - LogicalThreadContext.FreeNamedDataSlot(syncsDataSlotName); - } - - /// - /// Clears the entire transaction synchronization state for the current thread, registered - /// synchronizations as well as the various transaction characteristics. - /// - public static void Clear() - { - ClearSynchronization(); - CurrentTransactionName = null; - CurrentTransactionReadOnly = false; - CurrentTransactionIsolationLevel = IsolationLevel.Unspecified; - ActualTransactionActive = false; - } - - /// - /// Register a new transaction synchronization for the current thread. - /// - /// - /// Typically called by resource management code. - /// - /// - /// If synchronization is not active. - /// - public static void RegisterSynchronization( ITransactionSynchronization synchronization ) - { - AssertUtils.ArgumentNotNull(synchronization, "TransactionSynchronization must not be null"); - if ( !SynchronizationActive ) - { - throw new InvalidOperationException( "Transaction synchronization is not active" ); - } - ArrayList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as ArrayList; - if (syncs != null) - { - object root = syncs.SyncRoot; - lock (root) - { - syncs.Add(synchronization); - } - } - } - - private static string Describe(object obj) - { - return obj == null ? "" : obj + "@" + obj.GetHashCode().ToString("X"); - } - - #region Properties - - /// - /// Return an unmodifiable list of all registered synchronizations - /// for the current thread. - /// - /// - /// A list of - /// instances. - /// - /// - /// If synchronization is not active. - /// - public static IList Synchronizations - { - get - { - if ( ! SynchronizationActive ) - { - throw new InvalidOperationException( "Transaction synchronization is not active" ); - } - ArrayList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as ArrayList; - if (syncs != null) - { - // Sort lazily here, not in registerSynchronization. - object root = syncs.SyncRoot; - lock (root) - { - syncs.Sort(syncComparer); - } - // Return unmodifiable snapshot, to avoid exceptions - // while iterating and invoking synchronization callbacks that in turn - // might register further synchronizations. - return ArrayList.ReadOnly(syncs); - } - else - { - return ArrayList.ReadOnly(new ArrayList()); - } - } - } - - /// - /// Return if transaction synchronization is active for the current thread. - /// - /// - /// Can be called before - /// InitSynchronization - /// to avoid unnecessary instance creation. - /// - public static bool SynchronizationActive - { - get - { - IList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as IList; - return syncs != null; - } - } - - /// - /// Gets or sets a value indicating whether the - /// current transaction is read only. - /// - /// - /// Called by transaction manager on transaction begin and on cleanup. - /// Return whether the current transaction is marked as read-only. - /// To be called by resource management code when preparing a newly - /// created resource (for example, a Hibernate Session). - ///

Note that transaction synchronizations receive the read-only flag - /// as argument for the beforeCommit callback, to be able - /// to suppress change detection on commit. The present method is meant - /// to be used for earlier read-only checks, for example to set the - /// flush mode of a Hibernate Session to FlushMode.Never upfront. - ///

- ///
- /// - /// true if current transaction read only; otherwise, false. - /// - public static bool CurrentTransactionReadOnly - { - get - { - return LogicalThreadContext.GetData(currentTxReadOnlyDataSlotName) != null; - } - set - { - if (value) - { - LogicalThreadContext.SetData(currentTxReadOnlyDataSlotName, true); - } - else - { - LogicalThreadContext.FreeNamedDataSlot(currentTxReadOnlyDataSlotName); - } - - } - } - - /// - /// Gets or sets the name of the current transaction, if any. - /// - /// Called by the transaction manager on transaction begin and on cleanup. - /// To be called by resource management code for optimizations per use case, for - /// example to optimize fetch strategies for specific named transactions. - /// The name of the current transactio or null if none set. - public static string CurrentTransactionName - { - get - { - return LogicalThreadContext.GetData(currentTxNameDataSlotName) as string; - } - set - { - LogicalThreadContext.SetData(currentTxNameDataSlotName, value); - } - } - - /// - /// Gets or sets a value indicating whether there currently is an actual transaction - /// active. - /// - /// This indicates wheter the current thread is associated with an actual - /// transaction rather than just with active transaction synchronization. - /// Called by the transaction manager on transaction begin and on cleanup. - /// To be called by resource management code that wants to discriminate between - /// active transaction synchronization (with or without backing resource transaction; - /// also on PROPAGATION_SUPPORTS) and an actual transaction being active; on - /// PROPAGATION_REQUIRES, PROPAGATION_REQUIRES_NEW, etC) - /// - /// true if [actual transaction active]; otherwise, false. - /// - public static bool ActualTransactionActive - { - get - { - return LogicalThreadContext.GetData(actualTxActiveDataSlotName) != null; - } - set - { - if (value) - { - LogicalThreadContext.SetData(actualTxActiveDataSlotName, value); - } - else - { - LogicalThreadContext.FreeNamedDataSlot(actualTxActiveDataSlotName); - } - } - } - - - /// - /// Gets or sets the current transaction isolation level, if any. - /// - /// Called by the transaction manager on transaction begin and on cleanup. - /// The current transaction isolation level. If no current transaction is - /// active, retrun IsolationLevel.Unspecified - public static IsolationLevel CurrentTransactionIsolationLevel - { - get - { - object data = - LogicalThreadContext.GetData(currentTxIsolationLevelDataSlotName); - if (data != null) - { - return (IsolationLevel) data; - } - else - { - return IsolationLevel.Unspecified; - } - } - set - { - LogicalThreadContext.SetData(currentTxIsolationLevelDataSlotName, value); - } - } - #endregion - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Collections; +using System.Data; +using System.Globalization; +using System.Threading; +using Spring.Core; +using Spring.Threading; +using Spring.Util; + +namespace Spring.Transaction.Support +{ + /// + /// Internal class that manages resources and transaction synchronizations per thread. + /// + /// + /// Supports one resource per key without overwriting, i.e. a resource needs to + /// be removed before a new one can be set for the same key. + /// Supports a list of transaction synchronizations if synchronization is active. + ///

+ /// Resource management code should check for thread-bound resources via GetResource(). + /// It is normally not supposed + /// to bind resources to threads, as this is the responsiblity of transaction managers. + /// A further option is to lazily bind on first use if transaction synchronization + /// is active, for performing transactions that span an arbitrary number of resources. + ///

+ ///

+ /// Transaction synchronization must be activated and deactivated by a transaction + /// manager via + /// InitSynchronization + /// and + /// ClearSynchronization. + /// This is automatically supported by + /// . + ///

+ ///

+ /// Resource management code should only register synchronizations when this + /// manager is active, and perform resource cleanup immediately else. + /// If transaction synchronization isn't active, there is either no current + /// transaction, or the transaction manager doesn't support synchronizations. + ///

+ /// Note that this class uses following naming convention for the + /// named 'data slots' for storage of thread local data, 'Spring.Transaction:Name' + /// where Name is either + ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + public sealed class TransactionSynchronizationManager + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof (TransactionSynchronizationManager)); + + #endregion + + #region Fields + private static readonly string syncsDataSlotName = "Spring.Transactions:syncList"; + + private static readonly string resourcesDataSlotName = "Spring.Transactions:resources"; + + private static readonly string currentTxReadOnlyDataSlotName = "Spring.Transactions:currentTxReadOnly"; + + private static readonly string currentTxNameDataSlotName = "Spring.Transactions:currentTxName"; + + private static readonly string currentTxIsolationLevelDataSlotName = "Spring.Transactions:currentTxIsolationLevel"; + + private static readonly string actualTxActiveDataSlotName = "Spring.Transactions:actualTxActive"; + + private static IComparer syncComparer = new OrderComparator(); + + #endregion + + #region Management of transaction-associated resource handles + /// + /// Return all resources that are bound to the current thread. + /// + /// Main for debugging purposes. Resource manager should always + /// invoke HasResource for a specific resource key that they are interested in. + /// + /// IDictionary with resource keys and resource objects or empty + /// dictionary if none is bound. + public static IDictionary ResourceDictionary + { + get + { + IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; + if (resources != null) + { + //TODO add readonly wrapper in Spring.Collections. + return resources; + } + else + { + return new Hashtable(); + } + } + } + + /// + /// Check if there is a resource for the given key bound to the current thread. + /// + /// key to check + /// if there is a value bound to the current thread + public static bool HasResource(Object key) + { + AssertUtils.ArgumentNotNull(key, "Key must not be null"); + return ResourceDictionary.Contains(key); + } + + /// + /// Retrieve a resource for the given key that is bound to the current thread. + /// + /// key to check + /// a value bound to the current thread, or null if none. + public static object GetResource(Object key) + { + AssertUtils.ArgumentNotNull(key, "Key must not be null"); + IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; + if (resources == null) + { + return null; + } + //Check for contains since indexer returning null behavior changes in 2.0 + if (!resources.Contains(key)) + { + return null; + } + object val = resources[key]; + + if (val != null && LOG.IsDebugEnabled) + { + LOG.Debug("Retrieved value [" + Describe(val) + "] for key [" + Describe(key) + "] bound to thread [" + + SystemUtils.ThreadId + "]"); + } + return val; + } + + /// + /// Bind the given resource for teh given key to the current thread + /// + /// key to bind the value to + /// value to bind + public static void BindResource(Object key, Object value) + { + AssertUtils.ArgumentNotNull(key, "Key value for thread local storage of transactional resources must not be null"); + AssertUtils.ArgumentNotNull(value, "Transactional resource to bind to thread local storage must not be null" ); + + IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; + //Set thread local resource storage if not found + if (resources == null) + { + resources = new Hashtable(); + LogicalThreadContext.SetData(resourcesDataSlotName, resources); + } + if (resources.Contains(key)) + { + throw new InvalidOperationException("Already value [" + resources[key] + "] for key [" + key + + "] bound to thread [" + SystemUtils.ThreadId + "]"); + } + resources.Add(key, value); + if (LOG.IsDebugEnabled) + { + LOG.Debug("Bound value [" + Describe(value) + "] for key [" + Describe(key) + "] to thread [" + + SystemUtils.ThreadId + "]"); + } + } + + + /// + /// Unbind a resource for the given key from the current thread + /// + /// key to check + /// the previously bound value + /// if there is no value bound to the thread + public static object UnbindResource(Object key) + { + AssertUtils.ArgumentNotNull(key, "Key must not be null"); + + IDictionary resources = LogicalThreadContext.GetData(resourcesDataSlotName) as IDictionary; + if (resources == null || !resources.Contains(key)) + { + throw new InvalidOperationException("No value for key [" + key + "] bound to thread [" + + SystemUtils.ThreadId + "]"); + } + Object val = resources[key]; + resources.Remove(key); + if (resources.Count == 0) + { + LogicalThreadContext.FreeNamedDataSlot(resourcesDataSlotName); + } + if (LOG.IsDebugEnabled) + { + LOG.Debug("Removed value [" + Describe(val) + "] for key [" + Describe(key) + "] from thread [" + + SystemUtils.ThreadId + "]"); + } + return val; + } + + #endregion + + /// + /// Activate transaction synchronization for the current thread. + /// + /// + /// Called by transaction manager at the beginning of a transaction. + /// + /// + /// If synchronization is already active. + /// + public static void InitSynchronization() + { + if ( SynchronizationActive ) + { + throw new InvalidOperationException( "Cannot activate transaction synchronization - already active" ); + } + if (LOG.IsDebugEnabled) + { + LOG.Debug("Initializing transaction synchronization"); + } + ArrayList syncs = new ArrayList(); + LogicalThreadContext.SetData(syncsDataSlotName, syncs); + } + + /// + /// Deactivate transaction synchronization for the current thread. + /// + /// + /// Called by transaction manager on transaction cleanup. + /// + /// + /// If synchronization is not active. + /// + public static void ClearSynchronization() + { + if ( !SynchronizationActive ) + { + throw new InvalidOperationException( "Cannot deactivate transaction synchronization - not active" ); + } + if (LOG.IsDebugEnabled) + { + LOG.Debug("Clearing transaction synchronization"); + } + LogicalThreadContext.FreeNamedDataSlot(syncsDataSlotName); + } + + /// + /// Clears the entire transaction synchronization state for the current thread, registered + /// synchronizations as well as the various transaction characteristics. + /// + public static void Clear() + { + ClearSynchronization(); + CurrentTransactionName = null; + CurrentTransactionReadOnly = false; + CurrentTransactionIsolationLevel = IsolationLevel.Unspecified; + ActualTransactionActive = false; + } + + /// + /// Register a new transaction synchronization for the current thread. + /// + /// + /// Typically called by resource management code. + /// + /// + /// If synchronization is not active. + /// + public static void RegisterSynchronization( ITransactionSynchronization synchronization ) + { + AssertUtils.ArgumentNotNull(synchronization, "TransactionSynchronization must not be null"); + if ( !SynchronizationActive ) + { + throw new InvalidOperationException( "Transaction synchronization is not active" ); + } + ArrayList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as ArrayList; + if (syncs != null) + { + object root = syncs.SyncRoot; + lock (root) + { + syncs.Add(synchronization); + } + } + } + + private static string Describe(object obj) + { + return obj == null ? "" : obj + "@" + obj.GetHashCode().ToString("X"); + } + + #region Properties + + /// + /// Return an unmodifiable list of all registered synchronizations + /// for the current thread. + /// + /// + /// A list of + /// instances. + /// + /// + /// If synchronization is not active. + /// + public static IList Synchronizations + { + get + { + if ( ! SynchronizationActive ) + { + throw new InvalidOperationException( "Transaction synchronization is not active" ); + } + ArrayList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as ArrayList; + if (syncs != null) + { + // Sort lazily here, not in registerSynchronization. + object root = syncs.SyncRoot; + lock (root) + { + syncs.Sort(syncComparer); + } + // Return unmodifiable snapshot, to avoid exceptions + // while iterating and invoking synchronization callbacks that in turn + // might register further synchronizations. + return ArrayList.ReadOnly(syncs); + } + else + { + return ArrayList.ReadOnly(new ArrayList()); + } + } + } + + /// + /// Return if transaction synchronization is active for the current thread. + /// + /// + /// Can be called before + /// InitSynchronization + /// to avoid unnecessary instance creation. + /// + public static bool SynchronizationActive + { + get + { + IList syncs = LogicalThreadContext.GetData(syncsDataSlotName) as IList; + return syncs != null; + } + } + + /// + /// Gets or sets a value indicating whether the + /// current transaction is read only. + /// + /// + /// Called by transaction manager on transaction begin and on cleanup. + /// Return whether the current transaction is marked as read-only. + /// To be called by resource management code when preparing a newly + /// created resource (for example, a Hibernate Session). + ///

Note that transaction synchronizations receive the read-only flag + /// as argument for the beforeCommit callback, to be able + /// to suppress change detection on commit. The present method is meant + /// to be used for earlier read-only checks, for example to set the + /// flush mode of a Hibernate Session to FlushMode.Never upfront. + ///

+ ///
+ /// + /// true if current transaction read only; otherwise, false. + /// + public static bool CurrentTransactionReadOnly + { + get + { + return LogicalThreadContext.GetData(currentTxReadOnlyDataSlotName) != null; + } + set + { + if (value) + { + LogicalThreadContext.SetData(currentTxReadOnlyDataSlotName, true); + } + else + { + LogicalThreadContext.FreeNamedDataSlot(currentTxReadOnlyDataSlotName); + } + + } + } + + /// + /// Gets or sets the name of the current transaction, if any. + /// + /// Called by the transaction manager on transaction begin and on cleanup. + /// To be called by resource management code for optimizations per use case, for + /// example to optimize fetch strategies for specific named transactions. + /// The name of the current transactio or null if none set. + public static string CurrentTransactionName + { + get + { + return LogicalThreadContext.GetData(currentTxNameDataSlotName) as string; + } + set + { + LogicalThreadContext.SetData(currentTxNameDataSlotName, value); + } + } + + /// + /// Gets or sets a value indicating whether there currently is an actual transaction + /// active. + /// + /// This indicates wheter the current thread is associated with an actual + /// transaction rather than just with active transaction synchronization. + /// Called by the transaction manager on transaction begin and on cleanup. + /// To be called by resource management code that wants to discriminate between + /// active transaction synchronization (with or without backing resource transaction; + /// also on PROPAGATION_SUPPORTS) and an actual transaction being active; on + /// PROPAGATION_REQUIRES, PROPAGATION_REQUIRES_NEW, etC) + /// + /// true if [actual transaction active]; otherwise, false. + /// + public static bool ActualTransactionActive + { + get + { + return LogicalThreadContext.GetData(actualTxActiveDataSlotName) != null; + } + set + { + if (value) + { + LogicalThreadContext.SetData(actualTxActiveDataSlotName, value); + } + else + { + LogicalThreadContext.FreeNamedDataSlot(actualTxActiveDataSlotName); + } + } + } + + + /// + /// Gets or sets the current transaction isolation level, if any. + /// + /// Called by the transaction manager on transaction begin and on cleanup. + /// The current transaction isolation level. If no current transaction is + /// active, retrun IsolationLevel.Unspecified + public static IsolationLevel CurrentTransactionIsolationLevel + { + get + { + object data = + LogicalThreadContext.GetData(currentTxIsolationLevelDataSlotName); + if (data != null) + { + return (IsolationLevel) data; + } + else + { + return IsolationLevel.Unspecified; + } + } + set + { + LogicalThreadContext.SetData(currentTxIsolationLevelDataSlotName, value); + } + } + #endregion + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationState.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationState.cs index 29cc83ae..3d3c6115 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationState.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationState.cs @@ -1,50 +1,49 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Support -{ - /// - /// Enumeration containing the state of transaction synchronization. - /// - /// Griffin Caprio (.NET) - /// $Id: TransactionSynchronizationState.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - public enum TransactionSynchronizationState - { - /// - /// Always activate transaction synchronization, even for "empty" transactions - /// that result from . - /// - /// with no existing backend transaction. - Always, - /// - /// Activate transaction synchronization only for actual transactions, - /// i.e. not for empty ones that result from . - /// - /// with no - /// existing backend transaction. - OnActualTransaction, - /// - /// Never active transaction synchronization. - /// - Never - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Support +{ + /// + /// Enumeration containing the state of transaction synchronization. + /// + /// Griffin Caprio (.NET) + public enum TransactionSynchronizationState + { + /// + /// Always activate transaction synchronization, even for "empty" transactions + /// that result from . + /// + /// with no existing backend transaction. + Always, + /// + /// Activate transaction synchronization only for actual transactions, + /// i.e. not for empty ones that result from . + /// + /// with no + /// existing backend transaction. + OnActualTransaction, + /// + /// Never active transaction synchronization. + /// + Never + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationStatus.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationStatus.cs index 7a0e3570..f1645f88 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationStatus.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionSynchronizationStatus.cs @@ -1,45 +1,44 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; - -namespace Spring.Transaction.Support -{ - /// - /// Enumeration of status values when synchronizing transactions. - /// - /// Griffin Caprio - /// $Id: TransactionSynchronizationStatus.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - public enum TransactionSynchronizationStatus - { - /// - /// Completion status in case of proper commit. - /// - Committed, - /// - /// Completion status in case of proper rollback. - /// - Rolledback, - /// - /// Completion status in case of heuristic mixed completion or system error. - /// - Unknown, - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; + +namespace Spring.Transaction.Support +{ + /// + /// Enumeration of status values when synchronizing transactions. + /// + /// Griffin Caprio + public enum TransactionSynchronizationStatus + { + /// + /// Completion status in case of proper commit. + /// + Committed, + /// + /// Completion status in case of proper rollback. + /// + Rolledback, + /// + /// Completion status in case of heuristic mixed completion or system error. + /// + Unknown, + } +} diff --git a/src/Spring/Spring.Data/Transaction/Support/TransactionTemplate.cs b/src/Spring/Spring.Data/Transaction/Support/TransactionTemplate.cs index b5971b87..fe1dfac6 100644 --- a/src/Spring/Spring.Data/Transaction/Support/TransactionTemplate.cs +++ b/src/Spring/Spring.Data/Transaction/Support/TransactionTemplate.cs @@ -1,218 +1,217 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using Common.Logging; -using Spring.Objects.Factory; - -namespace Spring.Transaction.Support -{ - /// - /// Helper class that simplifies programmatic transaction demarcation and - /// transaction exception handling. - /// - /// - ///

- /// The central methods are - /// - /// and - /// supporting transactional code wrapped in the delegate instance. It handles the - /// transaction lifecycle and possible exceptions such that neither the delegate - /// implementation nor the calling code needs to explicitly handle transactions. - ///

- ///

- /// Can be used within a service implementation via direct instantiation with - /// a transaction manager reference, or get prepared in an application context - /// and given to services as object reference. - ///

- /// - /// The transaction manager should always be configured as an object in the application - /// context, in the first case given to the service directly, in the second case to the - /// prepared template. - /// - ///

- /// Supports setting the propagation behavior and the isolation level by name, - /// for convenient configuration in context definitions. - ///

- ///
- /// Juergen Hoeller - /// Mark Pollack (.NET) - /// Griffin Caprio (.NET) - /// $Id: TransactionTemplate.cs,v 1.13 2007/08/01 18:53:14 markpollack Exp $ - public class TransactionTemplate : DefaultTransactionDefinition, ITransactionOperations, IInitializingObject - { - private IPlatformTransactionManager _platformTransactionManager; - - #region Logging Definition - - protected readonly ILog log = LogManager.GetLogger(typeof(TransactionTemplate)); - - #endregion - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Mainly targeted at configuration by an object factory. - ///

- /// - /// The - /// - /// property must be set before any calls to the - /// - /// or - /// method. - /// - ///
- /// - public TransactionTemplate() {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - ///

- /// Mainly targeted at configuration by an object factory. - ///

- ///
- /// - /// The transaction management strategy to be used. - /// - public TransactionTemplate( IPlatformTransactionManager platformTransactionManager ) - { - _platformTransactionManager = platformTransactionManager; - } - - /// - /// Gets and sets the to - /// be used. - /// - public IPlatformTransactionManager PlatformTransactionManager - { - get { return _platformTransactionManager; } - set { _platformTransactionManager = value; } - } - - #region IInitializingObject Members - /// - /// Ensures that the - /// - /// has been set. - /// - public void AfterPropertiesSet() - { - if ( _platformTransactionManager == null ) - { - throw new ArgumentException( "IPlatformTransactionManager instance is required." ); - } - } - #endregion - - - /// - /// Executes the the action specified by the given delegate callback within a transaction. - /// - /// The delegate that specifies the transactional action. - /// - /// A result object returned by the callback, or null if one - /// - /// Allows for returning a result object created within the transaction, that is, - /// a domain object or a collection of domain objects. An exception thrown by the callback - /// is treated as a fatal exception that enforces a rollback. Such an exception gets - /// propagated to the caller of the template. - /// - /// - /// In case of initialization or system errors. - /// - public object Execute( TransactionDelegate transactionMethod ) - { - ITransactionStatus status = _platformTransactionManager.GetTransaction( this ); - object result; - try - { - result = transactionMethod( status ); - } - catch ( Exception ex ) - { - rollbackOnException( status, ex ); - throw; - } - _platformTransactionManager.Commit( status ); - return result; - } - - - /// - /// Executes the action specified by the given callback object within a transaction. - /// - /// The callback object that specifies the transactional action. - /// - /// A result object returned by the callback, or null if one - /// - /// Allows for returning a result object created within the transaction, that is, - /// a domain object or a collection of domain objects. An exception thrown by the callback - /// is treated as a fatal exception that enforces a rollback. Such an exception gets - /// propagated to the caller of the template. - /// - /// - /// In case of initialization or system errors. - /// - public object Execute(ITransactionCallback action) - { - ITransactionStatus status = _platformTransactionManager.GetTransaction( this ); - object result; - try - { - result = action.DoInTransaction(status); - } - catch ( Exception ex ) - { - rollbackOnException( status, ex ); - throw; - } - _platformTransactionManager.Commit( status ); - return result; - } - - /// - /// Perform a rollback, handling rollback exceptions properly. - /// - /// The object representing the transaction. - /// The thrown application exception or error. - private void rollbackOnException( ITransactionStatus status, Exception exception ) - { - if (log.IsDebugEnabled) - { - log.Debug("Initiating transaction rollback on application exception", exception); - } - try - { - _platformTransactionManager.Rollback( status ); - } - catch ( Exception ex ) - { - log.Error("Application exception overridden by rollback exception", ex); - throw; - } - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using Common.Logging; +using Spring.Objects.Factory; + +namespace Spring.Transaction.Support +{ + /// + /// Helper class that simplifies programmatic transaction demarcation and + /// transaction exception handling. + /// + /// + ///

+ /// The central methods are + /// + /// and + /// supporting transactional code wrapped in the delegate instance. It handles the + /// transaction lifecycle and possible exceptions such that neither the delegate + /// implementation nor the calling code needs to explicitly handle transactions. + ///

+ ///

+ /// Can be used within a service implementation via direct instantiation with + /// a transaction manager reference, or get prepared in an application context + /// and given to services as object reference. + ///

+ /// + /// The transaction manager should always be configured as an object in the application + /// context, in the first case given to the service directly, in the second case to the + /// prepared template. + /// + ///

+ /// Supports setting the propagation behavior and the isolation level by name, + /// for convenient configuration in context definitions. + ///

+ ///
+ /// Juergen Hoeller + /// Mark Pollack (.NET) + /// Griffin Caprio (.NET) + public class TransactionTemplate : DefaultTransactionDefinition, ITransactionOperations, IInitializingObject + { + private IPlatformTransactionManager _platformTransactionManager; + + #region Logging Definition + + protected readonly ILog log = LogManager.GetLogger(typeof(TransactionTemplate)); + + #endregion + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Mainly targeted at configuration by an object factory. + ///

+ /// + /// The + /// + /// property must be set before any calls to the + /// + /// or + /// method. + /// + ///
+ /// + public TransactionTemplate() {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + ///

+ /// Mainly targeted at configuration by an object factory. + ///

+ ///
+ /// + /// The transaction management strategy to be used. + /// + public TransactionTemplate( IPlatformTransactionManager platformTransactionManager ) + { + _platformTransactionManager = platformTransactionManager; + } + + /// + /// Gets and sets the to + /// be used. + /// + public IPlatformTransactionManager PlatformTransactionManager + { + get { return _platformTransactionManager; } + set { _platformTransactionManager = value; } + } + + #region IInitializingObject Members + /// + /// Ensures that the + /// + /// has been set. + /// + public void AfterPropertiesSet() + { + if ( _platformTransactionManager == null ) + { + throw new ArgumentException( "IPlatformTransactionManager instance is required." ); + } + } + #endregion + + + /// + /// Executes the the action specified by the given delegate callback within a transaction. + /// + /// The delegate that specifies the transactional action. + /// + /// A result object returned by the callback, or null if one + /// + /// Allows for returning a result object created within the transaction, that is, + /// a domain object or a collection of domain objects. An exception thrown by the callback + /// is treated as a fatal exception that enforces a rollback. Such an exception gets + /// propagated to the caller of the template. + /// + /// + /// In case of initialization or system errors. + /// + public object Execute( TransactionDelegate transactionMethod ) + { + ITransactionStatus status = _platformTransactionManager.GetTransaction( this ); + object result; + try + { + result = transactionMethod( status ); + } + catch ( Exception ex ) + { + rollbackOnException( status, ex ); + throw; + } + _platformTransactionManager.Commit( status ); + return result; + } + + + /// + /// Executes the action specified by the given callback object within a transaction. + /// + /// The callback object that specifies the transactional action. + /// + /// A result object returned by the callback, or null if one + /// + /// Allows for returning a result object created within the transaction, that is, + /// a domain object or a collection of domain objects. An exception thrown by the callback + /// is treated as a fatal exception that enforces a rollback. Such an exception gets + /// propagated to the caller of the template. + /// + /// + /// In case of initialization or system errors. + /// + public object Execute(ITransactionCallback action) + { + ITransactionStatus status = _platformTransactionManager.GetTransaction( this ); + object result; + try + { + result = action.DoInTransaction(status); + } + catch ( Exception ex ) + { + rollbackOnException( status, ex ); + throw; + } + _platformTransactionManager.Commit( status ); + return result; + } + + /// + /// Perform a rollback, handling rollback exceptions properly. + /// + /// The object representing the transaction. + /// The thrown application exception or error. + private void rollbackOnException( ITransactionStatus status, Exception exception ) + { + if (log.IsDebugEnabled) + { + log.Debug("Initiating transaction rollback on application exception", exception); + } + try + { + _platformTransactionManager.Rollback( status ); + } + catch ( Exception ex ) + { + log.Error("Application exception overridden by rollback exception", ex); + throw; + } + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/TransactionException.cs b/src/Spring/Spring.Data/Transaction/TransactionException.cs index 9db40a8f..44e7a68b 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionException.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionException.cs @@ -1,84 +1,83 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Base class for all transaction exceptions. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: TransactionException.cs,v 1.7 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public abstract class TransactionException : ApplicationException - { - /// - /// Creates a new instance of the TransactionException class. - /// - protected TransactionException() - { - } - - /// - /// Creates a new instance of the TransactionException class, with the specified message. - /// - /// - /// A message about the exception. - /// - protected TransactionException (string message) : base(message) - { - } - - /// - /// Creates a new instance of the TransactionException class with the specified message - /// and root cause. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - protected TransactionException (string message, Exception rootCause) - : base(message, rootCause) - { - } - - /// - /// Creates a new instance of the TransactionException class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TransactionException ( - SerializationInfo info, StreamingContext context) - : base (info, context) - { - } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Base class for all transaction exceptions. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public abstract class TransactionException : ApplicationException + { + /// + /// Creates a new instance of the TransactionException class. + /// + protected TransactionException() + { + } + + /// + /// Creates a new instance of the TransactionException class, with the specified message. + /// + /// + /// A message about the exception. + /// + protected TransactionException (string message) : base(message) + { + } + + /// + /// Creates a new instance of the TransactionException class with the specified message + /// and root cause. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + protected TransactionException (string message, Exception rootCause) + : base(message, rootCause) + { + } + + /// + /// Creates a new instance of the TransactionException class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransactionException ( + SerializationInfo info, StreamingContext context) + : base (info, context) + { + } + } +} diff --git a/src/Spring/Spring.Data/Transaction/TransactionOutcomeState.cs b/src/Spring/Spring.Data/Transaction/TransactionOutcomeState.cs index d25bcafc..08dde703 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionOutcomeState.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionOutcomeState.cs @@ -1,37 +1,36 @@ -#region License - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Transaction -{ - /// - /// Represents a transaction's current state. - /// - /// Griffin Caprio (.NET) - /// $Id: TransactionOutcomeState.cs,v 1.4 2006/05/18 21:37:51 markpollack Exp $ - public enum TransactionOutcomeState - { - /// - /// The transaction state is unknown. - /// - Unknown, - /// - /// The transaction has been committed. - /// - Committed, - /// - /// The transaction has been rolled back. - /// - Rolledback, - /// - /// The transaction is in an unknown, mixed state. - /// - Mixed - } -} +#region License + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Transaction +{ + /// + /// Represents a transaction's current state. + /// + /// Griffin Caprio (.NET) + public enum TransactionOutcomeState + { + /// + /// The transaction state is unknown. + /// + Unknown, + /// + /// The transaction has been committed. + /// + Committed, + /// + /// The transaction has been rolled back. + /// + Rolledback, + /// + /// The transaction is in an unknown, mixed state. + /// + Mixed + } +} diff --git a/src/Spring/Spring.Data/Transaction/TransactionPropagation.cs b/src/Spring/Spring.Data/Transaction/TransactionPropagation.cs index bcb3fe6b..4b20cd48 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionPropagation.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionPropagation.cs @@ -1,103 +1,102 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -namespace Spring.Transaction -{ - /// - /// Enumeration describing Spring.NET's - /// transaction propagation settings. - /// - /// Griffin Caprio (.NET) - /// $Id: TransactionPropagation.cs,v 1.7 2007/05/29 20:00:33 markpollack Exp $ - public enum TransactionPropagation - { - /// - /// Support a current transaction, create a new one if none exists. - /// - /// - ///

- /// Analogous to System.EnterpriseServices.TransactionOption value of the same name. - /// This is typically the default setting of a transaction definition. - ///

- ///
- Required, - - /// - /// Support a current transaction, execute non-transactionally if none exists. - /// - /// - ///

- /// Analogous to System.EnterpriseServices.TransactionOption.Supported. - ///

- ///
- Supports, - - /// - /// Support a current transaction, throw an exception if none exists. - /// - /// - ///

- /// No corresponding System.EnterpriseServices.TransactionOption value. - ///

- ///
- Mandatory, - - /// - /// Create a new transaction, suspending the current transaction if one exists. - /// - /// - ///

- /// Analogous to System.EnterpriseServices.TransactionOption value of the same name. - ///

- ///
- RequiresNew, - - /// - /// Execute non-transactionally, suspending the current transaction if one exists. - /// - /// - ///

- /// Analogous to System.EnterpriseServices.TransactionOption value of the same name. - ///

- ///
- NotSupported, - - /// - /// Execute non-transactionally, throw an exception if a transaction exists. - /// - /// - ///

- /// Analogous to System.EnterpriseServices.TransactionOption.Disabled. - ///

- ///
- Never, - - /// - /// Execute within a nested transaction if a current transaction exists, else - /// behave like . - /// - /// - ///

- /// There is no analogous feature in TransactionOption. - ///

- ///
- Nested - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +namespace Spring.Transaction +{ + /// + /// Enumeration describing Spring.NET's + /// transaction propagation settings. + /// + /// Griffin Caprio (.NET) + public enum TransactionPropagation + { + /// + /// Support a current transaction, create a new one if none exists. + /// + /// + ///

+ /// Analogous to System.EnterpriseServices.TransactionOption value of the same name. + /// This is typically the default setting of a transaction definition. + ///

+ ///
+ Required, + + /// + /// Support a current transaction, execute non-transactionally if none exists. + /// + /// + ///

+ /// Analogous to System.EnterpriseServices.TransactionOption.Supported. + ///

+ ///
+ Supports, + + /// + /// Support a current transaction, throw an exception if none exists. + /// + /// + ///

+ /// No corresponding System.EnterpriseServices.TransactionOption value. + ///

+ ///
+ Mandatory, + + /// + /// Create a new transaction, suspending the current transaction if one exists. + /// + /// + ///

+ /// Analogous to System.EnterpriseServices.TransactionOption value of the same name. + ///

+ ///
+ RequiresNew, + + /// + /// Execute non-transactionally, suspending the current transaction if one exists. + /// + /// + ///

+ /// Analogous to System.EnterpriseServices.TransactionOption value of the same name. + ///

+ ///
+ NotSupported, + + /// + /// Execute non-transactionally, throw an exception if a transaction exists. + /// + /// + ///

+ /// Analogous to System.EnterpriseServices.TransactionOption.Disabled. + ///

+ ///
+ Never, + + /// + /// Execute within a nested transaction if a current transaction exists, else + /// behave like . + /// + /// + ///

+ /// There is no analogous feature in TransactionOption. + ///

+ ///
+ Nested + } +} diff --git a/src/Spring/Spring.Data/Transaction/TransactionSuspensionNotSupportedException.cs b/src/Spring/Spring.Data/Transaction/TransactionSuspensionNotSupportedException.cs index 33a6ca98..f8d1957a 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionSuspensionNotSupportedException.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionSuspensionNotSupportedException.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception thrown when attempting to suspend an existing transaction - /// but transaction suspension is not supported by the underlying backend. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: TransactionSuspensionNotSupportedException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class TransactionSuspensionNotSupportedException : CannotCreateTransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public TransactionSuspensionNotSupportedException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public TransactionSuspensionNotSupportedException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public TransactionSuspensionNotSupportedException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TransactionSuspensionNotSupportedException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception thrown when attempting to suspend an existing transaction + /// but transaction suspension is not supported by the underlying backend. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class TransactionSuspensionNotSupportedException : CannotCreateTransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public TransactionSuspensionNotSupportedException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TransactionSuspensionNotSupportedException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public TransactionSuspensionNotSupportedException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransactionSuspensionNotSupportedException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/TransactionSystemException.cs b/src/Spring/Spring.Data/Transaction/TransactionSystemException.cs index 31642283..3c41d948 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionSystemException.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionSystemException.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception thrown when a general transaction system error is encountered, - /// for instance on commit or rollback. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: TransactionSystemException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class TransactionSystemException : TransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public TransactionSystemException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public TransactionSystemException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public TransactionSystemException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TransactionSystemException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception thrown when a general transaction system error is encountered, + /// for instance on commit or rollback. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class TransactionSystemException : TransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public TransactionSystemException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TransactionSystemException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public TransactionSystemException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransactionSystemException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/TransactionTimedOutException.cs b/src/Spring/Spring.Data/Transaction/TransactionTimedOutException.cs index 65d3603f..ffc8be45 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionTimedOutException.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionTimedOutException.cs @@ -1,56 +1,56 @@ -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Exception to be thrown when a transaction has timed out. - /// - [Serializable] - public class TransactionTimedOutException : TransactionException - { - /// - /// Create a new instance - /// - public TransactionTimedOutException() : base() - { - - } - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public TransactionTimedOutException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public TransactionTimedOutException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TransactionTimedOutException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } -} +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Exception to be thrown when a transaction has timed out. + /// + [Serializable] + public class TransactionTimedOutException : TransactionException + { + /// + /// Create a new instance + /// + public TransactionTimedOutException() : base() + { + + } + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TransactionTimedOutException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public TransactionTimedOutException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransactionTimedOutException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } +} diff --git a/src/Spring/Spring.Data/Transaction/TransactionUsageException.cs b/src/Spring/Spring.Data/Transaction/TransactionUsageException.cs index faf62557..38f60904 100644 --- a/src/Spring/Spring.Data/Transaction/TransactionUsageException.cs +++ b/src/Spring/Spring.Data/Transaction/TransactionUsageException.cs @@ -1,79 +1,78 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Superclass for exceptions caused by inappropriate usage of - /// a Spring.NET transaction API. - /// - /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// $Id: TransactionUsageException.cs,v 1.6 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class TransactionUsageException : TransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public TransactionUsageException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public TransactionUsageException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public TransactionUsageException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected TransactionUsageException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Superclass for exceptions caused by inappropriate usage of + /// a Spring.NET transaction API. + /// + /// Juergen Hoeller + /// Griffin Caprio (.NET) + [Serializable] + public class TransactionUsageException : TransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public TransactionUsageException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public TransactionUsageException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public TransactionUsageException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected TransactionUsageException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/UnexpectedRollbackException.cs b/src/Spring/Spring.Data/Transaction/UnexpectedRollbackException.cs index 7de89163..ea424995 100644 --- a/src/Spring/Spring.Data/Transaction/UnexpectedRollbackException.cs +++ b/src/Spring/Spring.Data/Transaction/UnexpectedRollbackException.cs @@ -1,78 +1,77 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -using System; -using System.Runtime.Serialization; - -namespace Spring.Transaction -{ - /// - /// Thrown when an attempt to commit a transaction resulted in an unexpected rollback. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - /// $Id: UnexpectedRollbackException.cs,v 1.5 2006/05/18 21:37:51 markpollack Exp $ - [Serializable] - public class UnexpectedRollbackException : TransactionException - { - /// - /// Creates a new instance of the - /// class. - /// - public UnexpectedRollbackException( ) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - public UnexpectedRollbackException( String message ) : base(message) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// A message about the exception. - /// - /// - /// The root exception that is being wrapped. - /// - public UnexpectedRollbackException(string message, Exception rootCause) - : base(message, rootCause) {} - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The - /// that holds the serialized object data about the exception being thrown. - /// - /// - /// The - /// that contains contextual information about the source or destination. - /// - protected UnexpectedRollbackException( - SerializationInfo info, StreamingContext context ) : base( info, context ) {} - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +using System; +using System.Runtime.Serialization; + +namespace Spring.Transaction +{ + /// + /// Thrown when an attempt to commit a transaction resulted in an unexpected rollback. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + [Serializable] + public class UnexpectedRollbackException : TransactionException + { + /// + /// Creates a new instance of the + /// class. + /// + public UnexpectedRollbackException( ) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + public UnexpectedRollbackException( String message ) : base(message) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// A message about the exception. + /// + /// + /// The root exception that is being wrapped. + /// + public UnexpectedRollbackException(string message, Exception rootCause) + : base(message, rootCause) {} + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The + /// that holds the serialized object data about the exception being thrown. + /// + /// + /// The + /// that contains contextual information about the source or destination. + /// + protected UnexpectedRollbackException( + SerializationInfo info, StreamingContext context ) : base( info, context ) {} + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs b/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs index db4b0c36..ca4ffef9 100644 --- a/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs +++ b/src/Spring/Spring.Services/EnterpriseServices/EnterpriseServicesExporter.cs @@ -1,318 +1,317 @@ -#region License - -/* - * Copyright 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -#region Imports - -using System; -using System.Collections; -using System.EnterpriseServices; -using System.IO; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Objects.Factory; -using Spring.Util; - -#endregion - -namespace Spring.EnterpriseServices -{ - /// - /// Exports specified components as ServicedComponents. - /// - /// - ///

- /// This class will create ServicedComponent wrapper for each of the - /// specified components and register them with the Component Services. - ///

- ///
- /// Aleksandar Seovic - /// $Id: EnterpriseServicesExporter.cs,v 1.6 2007/05/16 10:03:24 oakinger Exp $ - public class EnterpriseServicesExporter : IInitializingObject, IObjectFactoryAware - { - #region Fields - - private IObjectFactory objectFactory; - - private IList components = new ArrayList(); - private string applicationName; - private string applicationId; - private ActivationOption activationMode = ActivationOption.Library; - private string description; - private ApplicationAccessControlAttribute accessControl; - private ApplicationQueuingAttribute applicationQueuing; - private IList roles; - - private string assemblyName; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates new enterprise services exporter. - /// - public EnterpriseServicesExporter() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets list of components to export. - /// - public IList Components - { - get { return components; } - set { components = value; } - } - - /// - /// Gets or sets COM+ application name. - /// - public string ApplicationName - { - get { return applicationName; } - set { applicationName = value; } - } - - /// - /// Gets or sets application identifier (GUID). Defaults to generated GUID if not specified. - /// - public string ApplicationId - { - get { return applicationId; } - set { applicationId = value; } - } - - /// - /// Gets or sets application activation mode, which can be either Server or Library (default). - /// - public ActivationOption ActivationMode - { - get { return activationMode; } - set { activationMode = value; } - } - - /// - /// Gets or sets application description. - /// - public string Description - { - get { return description; } - set { description = value; } - } - - /// - /// Gets or sets access control attribute. - /// - public ApplicationAccessControlAttribute AccessControl - { - get { return accessControl; } - set { accessControl = value; } - } - - /// - /// Gets or sets application queuing attribute. - /// - public ApplicationQueuingAttribute ApplicationQueuing - { - get { return applicationQueuing; } - set { applicationQueuing = value; } - } - - /// - /// Gets or sets application roles. - /// - public IList Roles - { - get { return roles; } - set { roles = value; } - } - - /// - /// Gets or sets name of the generated assembly that will contain serviced components. - /// - public string Assembly - { - get { return assemblyName; } - set { assemblyName = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Called by Spring container after object is configured in order to initialize it. - /// - public void AfterPropertiesSet() - { - if (roles != null && roles.Count > 0) - { - RefreshRoles(); - } - Export(); - } - - #endregion - - #region IObjectFactoryAware Members - - /// - /// Sets object factory instance. - /// - public IObjectFactory ObjectFactory - { - set { objectFactory = value; } - } - - #endregion - - #region Public Methods - - /// - /// Creates ServicedComponent wrappers for the specified components and registers - /// them with COM+ Component Services. - /// - public virtual void Export() - { - AssemblyName an = new AssemblyName(); - an.Name = assemblyName; - an.Version = new Version("1.0.0.0"); - an.KeyPair = new StrongNameKeyPair(GetKeyPair()); - AssemblyBuilder proxyAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave); - ModuleBuilder module = proxyAssembly.DefineDynamicModule(assemblyName, assemblyName + ".dll", true); - ApplyAssemblyAttributes(proxyAssembly); - - foreach (ServicedComponentExporter definition in components) - { - definition.CreateWrapperType(module, objectFactory); - } - - proxyAssembly.Save(assemblyName + ".dll"); - - RegistrationConfig config = new RegistrationConfig(); - config.Application = applicationName; - config.AssemblyFile = AppDomain.CurrentDomain.DynamicDirectory + assemblyName + ".dll"; - config.InstallationFlags = InstallationFlags.FindOrCreateTargetApplication; - - RegistrationHelper regHelper = new RegistrationHelper(); - regHelper.InstallAssemblyFromConfig(ref config); - } - - #endregion - - #region Private Methods - - /// - /// Reads key pair from embedded resource. - /// - /// Key pair as a byte array. - private byte[] GetKeyPair() - { - using (Stream keys = GetType().Assembly.GetManifestResourceStream("Spring.EnterpriseServices.EnterpriseServices.keys")) - { - byte[] bytes = new byte[keys.Length]; - keys.Read(bytes, 0, (int) keys.Length); - return bytes; - } - } - - /// - /// Applies custom attributes to generated assembly. - /// - /// Dynamic assembly to apply attributes to. - private void ApplyAssemblyAttributes(AssemblyBuilder assembly) - { - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationNameAttribute), applicationName)); - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationActivationAttribute), activationMode)); - if (applicationId != null) - { - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationIDAttribute), applicationId)); - } - if (description != null) - { - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(DescriptionAttribute), description)); - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(AssemblyDescriptionAttribute), description)); - } - if (accessControl != null) - { - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(accessControl)); - } - if (applicationQueuing != null) - { - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(applicationQueuing)); - } - if (roles != null) - { - foreach (SecurityRoleAttribute role in roles) - { - assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(SecurityRoleAttribute), - new object[] {role.Role}, role)); - } - } - } - - /// - /// Replaces roles expressed using string with appropriate SecurityRoleAttribute instance. - /// - private void RefreshRoles() - { - for (int i = 0; i < roles.Count; i++) - { - object role = roles[i]; - if (role is string) - { - roles[i] = ParseRole((string) role); - } - } - } - - /// - /// Parses string representation of SecurityRoleAttribute. - /// - /// Role definition string. - /// Configured SecurityRoleAttribute instance. - private SecurityRoleAttribute ParseRole(string roleString) - { - string[] parts = roleString.Split(':'); - SecurityRoleAttribute role = new SecurityRoleAttribute(parts[0].Trim()); - if (parts.Length > 1) - { - role.Description = parts[1].Trim(); - } - if (parts.Length > 2) - { - role.SetEveryoneAccess = bool.Parse(parts[2].Trim()); - } - - return role; - } - - #endregion - } -} - +#region License + +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +#region Imports + +using System; +using System.Collections; +using System.EnterpriseServices; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Objects.Factory; +using Spring.Util; + +#endregion + +namespace Spring.EnterpriseServices +{ + /// + /// Exports specified components as ServicedComponents. + /// + /// + ///

+ /// This class will create ServicedComponent wrapper for each of the + /// specified components and register them with the Component Services. + ///

+ ///
+ /// Aleksandar Seovic + public class EnterpriseServicesExporter : IInitializingObject, IObjectFactoryAware + { + #region Fields + + private IObjectFactory objectFactory; + + private IList components = new ArrayList(); + private string applicationName; + private string applicationId; + private ActivationOption activationMode = ActivationOption.Library; + private string description; + private ApplicationAccessControlAttribute accessControl; + private ApplicationQueuingAttribute applicationQueuing; + private IList roles; + + private string assemblyName; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates new enterprise services exporter. + /// + public EnterpriseServicesExporter() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets list of components to export. + /// + public IList Components + { + get { return components; } + set { components = value; } + } + + /// + /// Gets or sets COM+ application name. + /// + public string ApplicationName + { + get { return applicationName; } + set { applicationName = value; } + } + + /// + /// Gets or sets application identifier (GUID). Defaults to generated GUID if not specified. + /// + public string ApplicationId + { + get { return applicationId; } + set { applicationId = value; } + } + + /// + /// Gets or sets application activation mode, which can be either Server or Library (default). + /// + public ActivationOption ActivationMode + { + get { return activationMode; } + set { activationMode = value; } + } + + /// + /// Gets or sets application description. + /// + public string Description + { + get { return description; } + set { description = value; } + } + + /// + /// Gets or sets access control attribute. + /// + public ApplicationAccessControlAttribute AccessControl + { + get { return accessControl; } + set { accessControl = value; } + } + + /// + /// Gets or sets application queuing attribute. + /// + public ApplicationQueuingAttribute ApplicationQueuing + { + get { return applicationQueuing; } + set { applicationQueuing = value; } + } + + /// + /// Gets or sets application roles. + /// + public IList Roles + { + get { return roles; } + set { roles = value; } + } + + /// + /// Gets or sets name of the generated assembly that will contain serviced components. + /// + public string Assembly + { + get { return assemblyName; } + set { assemblyName = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Called by Spring container after object is configured in order to initialize it. + /// + public void AfterPropertiesSet() + { + if (roles != null && roles.Count > 0) + { + RefreshRoles(); + } + Export(); + } + + #endregion + + #region IObjectFactoryAware Members + + /// + /// Sets object factory instance. + /// + public IObjectFactory ObjectFactory + { + set { objectFactory = value; } + } + + #endregion + + #region Public Methods + + /// + /// Creates ServicedComponent wrappers for the specified components and registers + /// them with COM+ Component Services. + /// + public virtual void Export() + { + AssemblyName an = new AssemblyName(); + an.Name = assemblyName; + an.Version = new Version("1.0.0.0"); + an.KeyPair = new StrongNameKeyPair(GetKeyPair()); + AssemblyBuilder proxyAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave); + ModuleBuilder module = proxyAssembly.DefineDynamicModule(assemblyName, assemblyName + ".dll", true); + ApplyAssemblyAttributes(proxyAssembly); + + foreach (ServicedComponentExporter definition in components) + { + definition.CreateWrapperType(module, objectFactory); + } + + proxyAssembly.Save(assemblyName + ".dll"); + + RegistrationConfig config = new RegistrationConfig(); + config.Application = applicationName; + config.AssemblyFile = AppDomain.CurrentDomain.DynamicDirectory + assemblyName + ".dll"; + config.InstallationFlags = InstallationFlags.FindOrCreateTargetApplication; + + RegistrationHelper regHelper = new RegistrationHelper(); + regHelper.InstallAssemblyFromConfig(ref config); + } + + #endregion + + #region Private Methods + + /// + /// Reads key pair from embedded resource. + /// + /// Key pair as a byte array. + private byte[] GetKeyPair() + { + using (Stream keys = GetType().Assembly.GetManifestResourceStream("Spring.EnterpriseServices.EnterpriseServices.keys")) + { + byte[] bytes = new byte[keys.Length]; + keys.Read(bytes, 0, (int) keys.Length); + return bytes; + } + } + + /// + /// Applies custom attributes to generated assembly. + /// + /// Dynamic assembly to apply attributes to. + private void ApplyAssemblyAttributes(AssemblyBuilder assembly) + { + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationNameAttribute), applicationName)); + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationActivationAttribute), activationMode)); + if (applicationId != null) + { + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(ApplicationIDAttribute), applicationId)); + } + if (description != null) + { + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(DescriptionAttribute), description)); + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(AssemblyDescriptionAttribute), description)); + } + if (accessControl != null) + { + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(accessControl)); + } + if (applicationQueuing != null) + { + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(applicationQueuing)); + } + if (roles != null) + { + foreach (SecurityRoleAttribute role in roles) + { + assembly.SetCustomAttribute(ReflectionUtils.CreateCustomAttribute(typeof(SecurityRoleAttribute), + new object[] {role.Role}, role)); + } + } + } + + /// + /// Replaces roles expressed using string with appropriate SecurityRoleAttribute instance. + /// + private void RefreshRoles() + { + for (int i = 0; i < roles.Count; i++) + { + object role = roles[i]; + if (role is string) + { + roles[i] = ParseRole((string) role); + } + } + } + + /// + /// Parses string representation of SecurityRoleAttribute. + /// + /// Role definition string. + /// Configured SecurityRoleAttribute instance. + private SecurityRoleAttribute ParseRole(string roleString) + { + string[] parts = roleString.Split(':'); + SecurityRoleAttribute role = new SecurityRoleAttribute(parts[0].Trim()); + if (parts.Length > 1) + { + role.Description = parts[1].Trim(); + } + if (parts.Length > 2) + { + role.SetEveryoneAccess = bool.Parse(parts[2].Trim()); + } + + return role; + } + + #endregion + } +} + #endif // (!NET_1_0) \ No newline at end of file diff --git a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs index cce34421..4cbe1b64 100644 --- a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs +++ b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentExporter.cs @@ -1,225 +1,224 @@ -#region License - -/* - * Copyright 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -#region Imports - -using System; -using System.Collections; -using System.EnterpriseServices; -using System.Reflection.Emit; - -using Spring.Core.TypeResolution; -using Spring.Objects.Factory; -using Spring.Proxy; -using Spring.Util; - -#endregion - -namespace Spring.EnterpriseServices -{ - /// - /// Encapsulates information necessary to create ServicedComponent - /// wrapper around target class. - /// - /// - ///

- /// Instances of this class should be used as elements in the Components - /// list of the class, which will - /// register them with COM+ Services. - ///

- ///
- /// Aleksandar Seovic - /// $Id: ServicedComponentExporter.cs,v 1.9 2007/07/31 18:18:19 bbaia Exp $ - public class ServicedComponentExporter : IInitializingObject, IObjectNameAware - { - #region Fields - - private string _objectName; - private string _targetName; - private string[] _interfaces; - private IList _typeAttributes = new ArrayList(); - private IDictionary _memberAttributes = new Hashtable(); - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public ServicedComponentExporter() - {} - - #endregion - - #region Properties - - /// - /// Gets or sets name of the target object that should be exposed as a serviced component. - /// - public string TargetName - { - get { return _targetName; } - set { _targetName = value; } - } - - /// - /// Gets or sets the list of interfaces whose methods should be exported. - /// - /// - /// The default value of this property is all the interfaces - /// implemented or inherited by the target type. - /// - /// The interfaces to export. - public string[] Interfaces - { - get { return _interfaces; } - set { _interfaces = value; } - } - - /// - /// Gets or sets a list of custom attributes - /// that should be applied to a proxy class. - /// - public IList TypeAttributes - { - get { return _typeAttributes; } - set { _typeAttributes = value; } - } - - /// - /// Gets or sets a dictionary of custom attributes - /// that should be applied to proxy members. - /// - /// - /// Map key is an expression that members can be matched against. Value is a list - /// of attributes that should be applied to each member that matches expression. - /// - public IDictionary MemberAttributes - { - get { return _memberAttributes; } - set { _memberAttributes = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Validate configuration. - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - } - - #endregion - - #region IObjectNameAware Members - - /// - /// Set the name of the object in the object factory - /// that created this object. - /// - public string ObjectName - { - set { _objectName = value; } - } - - #endregion - - #region Methods - - private void ValidateConfiguration() - { - if (TargetName == null) - { - throw new ArgumentException("The TargetName property is required."); - } - } - - /// - /// Creates ServicedComponent wrapper around target class. - /// - /// Dynamic module builder to use - /// Object factory to get target from. - internal Type CreateWrapperType(ModuleBuilder module, IObjectFactory objectFactory) - { - // create wrapper using appropriate proxy builder - IProxyTypeBuilder proxyBuilder = new ServicedComponentProxyTypeBuilder(module); - proxyBuilder.Name = _objectName; - proxyBuilder.TargetType = objectFactory.GetType(TargetName); - if (_interfaces != null && _interfaces.Length > 0) - { - proxyBuilder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(_interfaces); - } - proxyBuilder.TypeAttributes = TypeAttributes; - proxyBuilder.MemberAttributes = MemberAttributes; - - Type componentType = proxyBuilder.BuildProxyType(); - - // create and register client-side proxy factory for component - - return componentType; - } - - #endregion - - #region ServicedComponentProxyTypeBuilder inner class definition - - private sealed class ServicedComponentProxyTypeBuilder : CompositionProxyTypeBuilder - { - #region Fields - - private ModuleBuilder module; - - #endregion - - #region Constructor(s) / Destructor - - public ServicedComponentProxyTypeBuilder(ModuleBuilder module) - { - this.module = module; - - BaseType = typeof(ServicedComponent); - } - - #endregion - - #region Protected Methods - - protected override TypeBuilder CreateTypeBuilder(string name, Type baseType) - { - return module.DefineType(name, - System.Reflection.TypeAttributes.BeforeFieldInit | System.Reflection.TypeAttributes.Public, - baseType); - } - - #endregion - } - - #endregion - } -} - -#endif // (!NET_1_0) +#region License + +/* + * Copyright 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +#region Imports + +using System; +using System.Collections; +using System.EnterpriseServices; +using System.Reflection.Emit; + +using Spring.Core.TypeResolution; +using Spring.Objects.Factory; +using Spring.Proxy; +using Spring.Util; + +#endregion + +namespace Spring.EnterpriseServices +{ + /// + /// Encapsulates information necessary to create ServicedComponent + /// wrapper around target class. + /// + /// + ///

+ /// Instances of this class should be used as elements in the Components + /// list of the class, which will + /// register them with COM+ Services. + ///

+ ///
+ /// Aleksandar Seovic + public class ServicedComponentExporter : IInitializingObject, IObjectNameAware + { + #region Fields + + private string _objectName; + private string _targetName; + private string[] _interfaces; + private IList _typeAttributes = new ArrayList(); + private IDictionary _memberAttributes = new Hashtable(); + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public ServicedComponentExporter() + {} + + #endregion + + #region Properties + + /// + /// Gets or sets name of the target object that should be exposed as a serviced component. + /// + public string TargetName + { + get { return _targetName; } + set { _targetName = value; } + } + + /// + /// Gets or sets the list of interfaces whose methods should be exported. + /// + /// + /// The default value of this property is all the interfaces + /// implemented or inherited by the target type. + /// + /// The interfaces to export. + public string[] Interfaces + { + get { return _interfaces; } + set { _interfaces = value; } + } + + /// + /// Gets or sets a list of custom attributes + /// that should be applied to a proxy class. + /// + public IList TypeAttributes + { + get { return _typeAttributes; } + set { _typeAttributes = value; } + } + + /// + /// Gets or sets a dictionary of custom attributes + /// that should be applied to proxy members. + /// + /// + /// Map key is an expression that members can be matched against. Value is a list + /// of attributes that should be applied to each member that matches expression. + /// + public IDictionary MemberAttributes + { + get { return _memberAttributes; } + set { _memberAttributes = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Validate configuration. + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + } + + #endregion + + #region IObjectNameAware Members + + /// + /// Set the name of the object in the object factory + /// that created this object. + /// + public string ObjectName + { + set { _objectName = value; } + } + + #endregion + + #region Methods + + private void ValidateConfiguration() + { + if (TargetName == null) + { + throw new ArgumentException("The TargetName property is required."); + } + } + + /// + /// Creates ServicedComponent wrapper around target class. + /// + /// Dynamic module builder to use + /// Object factory to get target from. + internal Type CreateWrapperType(ModuleBuilder module, IObjectFactory objectFactory) + { + // create wrapper using appropriate proxy builder + IProxyTypeBuilder proxyBuilder = new ServicedComponentProxyTypeBuilder(module); + proxyBuilder.Name = _objectName; + proxyBuilder.TargetType = objectFactory.GetType(TargetName); + if (_interfaces != null && _interfaces.Length > 0) + { + proxyBuilder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(_interfaces); + } + proxyBuilder.TypeAttributes = TypeAttributes; + proxyBuilder.MemberAttributes = MemberAttributes; + + Type componentType = proxyBuilder.BuildProxyType(); + + // create and register client-side proxy factory for component + + return componentType; + } + + #endregion + + #region ServicedComponentProxyTypeBuilder inner class definition + + private sealed class ServicedComponentProxyTypeBuilder : CompositionProxyTypeBuilder + { + #region Fields + + private ModuleBuilder module; + + #endregion + + #region Constructor(s) / Destructor + + public ServicedComponentProxyTypeBuilder(ModuleBuilder module) + { + this.module = module; + + BaseType = typeof(ServicedComponent); + } + + #endregion + + #region Protected Methods + + protected override TypeBuilder CreateTypeBuilder(string name, Type baseType) + { + return module.DefineType(name, + System.Reflection.TypeAttributes.BeforeFieldInit | System.Reflection.TypeAttributes.Public, + baseType); + } + + #endregion + } + + #endregion + } +} + +#endif // (!NET_1_0) diff --git a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentFactory.cs b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentFactory.cs index aa476b19..d1b86904 100644 --- a/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentFactory.cs +++ b/src/Spring/Spring.Services/EnterpriseServices/ServicedComponentFactory.cs @@ -1,183 +1,182 @@ -#region License - -/* - * Copyright 2002-2006 the original author or authors. - * - * 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. - */ - -#endregion - -#if (!NET_1_0) - -#region Imports - -using System; - -using Spring.Util; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.EnterpriseServices -{ - /// - /// Factory Object that instantiates and configures ServicedComponent. - /// - /// - ///

- /// This factory object should be used to instantiate and configure - /// serviced components created by . - ///

- ///
- /// Aleksandar Seovic - /// $Id: ServicedComponentFactory.cs,v 1.7 2007/05/16 10:03:25 oakinger Exp $ - public class ServicedComponentFactory : IConfigurableFactoryObject, IInitializingObject - { - #region Fields - - private string name; - private string server; - - private bool isSingleton; - private IObjectDefinition productTemplate; - - private Type componentType; - private object singletonInstance; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates new instance of serviced component factory. - /// - public ServicedComponentFactory() - { - this.isSingleton = false; - } - - #endregion - - #region Properties - - /// - /// Gets or sets component name, as registered with COM+ Services. - /// - public string Name - { - get { return name; } - set { name = value; } - } - - /// - /// Gets or sets name of the remote server that COM+ component is registered with. - /// - public string Server - { - get { return server; } - set { server = value; } - } - - #endregion - - #region IConfigurableFactoryObject Members - - /// - /// Returns configured instance of the serviced component. - /// - /// Configured instance of the serviced component. - public object GetObject() - { - if (IsSingleton) - { - if (singletonInstance == null) - { - singletonInstance = CreateInstance(); - } - return singletonInstance; - } - else - { - return CreateInstance(); - } - } - - /// - /// Returns type of serviced component. - /// - public Type ObjectType - { - get { return componentType; } - } - - /// - /// Gets or sets whether serviced component should be treated as singleton. Default is false. - /// - public bool IsSingleton - { - get { return isSingleton; } - set { isSingleton = value; } - } - - /// - /// Gets or sets the template object definition - /// that should be used to configure proxy instance. - /// - public IObjectDefinition ProductTemplate - { - get { return productTemplate; } - set { productTemplate = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Initializes factory object. - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - componentType = Type.GetTypeFromProgID(Name, Server); - } - - #endregion - - #region Private Methods - - private void ValidateConfiguration() - { - if (Name == null) - { - throw new ArgumentException("The Name property is required."); - } - } - - /// - /// Creates new instance of serviced component. - /// - /// New instance of serviced component. - private object CreateInstance() - { - return Activator.CreateInstance(componentType); - } - - #endregion - } -} - -#endif // (!NET_1_0) +#region License + +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + */ + +#endregion + +#if (!NET_1_0) + +#region Imports + +using System; + +using Spring.Util; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.EnterpriseServices +{ + /// + /// Factory Object that instantiates and configures ServicedComponent. + /// + /// + ///

+ /// This factory object should be used to instantiate and configure + /// serviced components created by . + ///

+ ///
+ /// Aleksandar Seovic + public class ServicedComponentFactory : IConfigurableFactoryObject, IInitializingObject + { + #region Fields + + private string name; + private string server; + + private bool isSingleton; + private IObjectDefinition productTemplate; + + private Type componentType; + private object singletonInstance; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates new instance of serviced component factory. + /// + public ServicedComponentFactory() + { + this.isSingleton = false; + } + + #endregion + + #region Properties + + /// + /// Gets or sets component name, as registered with COM+ Services. + /// + public string Name + { + get { return name; } + set { name = value; } + } + + /// + /// Gets or sets name of the remote server that COM+ component is registered with. + /// + public string Server + { + get { return server; } + set { server = value; } + } + + #endregion + + #region IConfigurableFactoryObject Members + + /// + /// Returns configured instance of the serviced component. + /// + /// Configured instance of the serviced component. + public object GetObject() + { + if (IsSingleton) + { + if (singletonInstance == null) + { + singletonInstance = CreateInstance(); + } + return singletonInstance; + } + else + { + return CreateInstance(); + } + } + + /// + /// Returns type of serviced component. + /// + public Type ObjectType + { + get { return componentType; } + } + + /// + /// Gets or sets whether serviced component should be treated as singleton. Default is false. + /// + public bool IsSingleton + { + get { return isSingleton; } + set { isSingleton = value; } + } + + /// + /// Gets or sets the template object definition + /// that should be used to configure proxy instance. + /// + public IObjectDefinition ProductTemplate + { + get { return productTemplate; } + set { productTemplate = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Initializes factory object. + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + componentType = Type.GetTypeFromProgID(Name, Server); + } + + #endregion + + #region Private Methods + + private void ValidateConfiguration() + { + if (Name == null) + { + throw new ArgumentException("The Name property is required."); + } + } + + /// + /// Creates new instance of serviced component. + /// + /// New instance of serviced component. + private object CreateInstance() + { + return Activator.CreateInstance(componentType); + } + + #endregion + } +} + +#endif // (!NET_1_0) diff --git a/src/Spring/Spring.Services/Remoting/CaoExporter.cs b/src/Spring/Spring.Services/Remoting/CaoExporter.cs index 8852124b..75b0782c 100644 --- a/src/Spring/Spring.Services/Remoting/CaoExporter.cs +++ b/src/Spring/Spring.Services/Remoting/CaoExporter.cs @@ -1,294 +1,293 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Remoting; - -using Spring.Context; -using Spring.Core; -using Spring.Objects; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Support; -using Spring.Remoting.Support; -using Spring.Util; - -#endregion - -namespace Spring.Remoting -{ - /// - /// Registers an object type on the server - /// as a Client Activated Object (CAO). - /// - /// Aleksandar Seovic - /// Mark Pollack - /// Bruno Baia - /// $Id: CaoExporter.cs,v 1.12 2007/11/07 19:03:09 bbaia Exp $ - public class CaoExporter : ConfigurableLifetime, IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable - { - #region Logging - - private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(CaoExporter)); - - #endregion - - #region Fields - - private string targetName; - private string[] interfaces; - - private IApplicationContext applicationContext; - private AbstractObjectFactory objectFactory; - - private CaoRemoteFactory remoteFactory; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the class. - /// - public CaoExporter() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets the name of the target object definition. - /// - public string TargetName - { - get { return targetName; } - set { targetName = value; } - } - - /// - /// Gets or sets the list of interfaces whose methods should be exported. - /// - /// - /// The default value of this property is all the interfaces - /// implemented or inherited by the target type. - /// - /// The interfaces to export. - public string[] Interfaces - { - get { return interfaces; } - set { interfaces = value; } - } - - #endregion - - #region IApplicationContextAware Members - - /// - /// Gets or sets the that this - /// object runs in. - /// - public IApplicationContext ApplicationContext - { - get { return applicationContext; } - set { applicationContext = value; } - } - - #endregion - - #region IObjectFactoryAware Members - - /// - /// Sets object factory to use. - /// - public IObjectFactory ObjectFactory - { - set { objectFactory = (AbstractObjectFactory) value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Publish the object - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - Export(); - } - - #endregion - - #region IDisposable Members - - /// - /// Disconnect the remote object from the registered remoting channels. - /// - public void Dispose() - { - RemotingServices.Disconnect(remoteFactory); - } - - #endregion - - #region Private Methods - - private void ValidateConfiguration() - { - if (TargetName == null) - { - throw new ArgumentException("The TargetName property is required."); - } - } - - private void Export() - { - remoteFactory = new CaoRemoteFactory(this, targetName, interfaces, objectFactory); - - RemotingServices.Marshal(remoteFactory, targetName); - - #region Instrumentation - - if (LOG.IsDebugEnabled) - { - LOG.Debug(String.Format("Target '{0}' registered.", targetName)); - } - - #endregion - } - - #endregion - - #region BaseCao inner class definition - - /// - /// This class extends to allow CAOs - /// to be disconnect from the client. - /// - public abstract class BaseCao : BaseRemoteObject, IDisposable - { - #region IDisposable Members - - void IDisposable.Dispose() - { - RemotingServices.Disconnect(this); - } - - #endregion - } - - #endregion - - #region CaoRemoteFactory inner class definition - - private sealed class CaoRemoteFactory : MarshalByRefObject, ICaoRemoteFactory - { - #region Fields - - private AbstractObjectFactory objectFactory; - private string targetName; - private RemoteObjectFactory remoteObjectFactory; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Create a new instance of the RemoteFactory. - /// - public CaoRemoteFactory(ILifetime lifetime, string targetName, - string[] interfaces, AbstractObjectFactory objectFactory) - { - this.targetName = targetName; - this.objectFactory = objectFactory; - - this.remoteObjectFactory = new RemoteObjectFactory(); - this.remoteObjectFactory.BaseType = typeof(BaseCao); - this.remoteObjectFactory.Interfaces = interfaces; - this.remoteObjectFactory.Infinite = lifetime.Infinite; - this.remoteObjectFactory.InitialLeaseTime = lifetime.InitialLeaseTime; - this.remoteObjectFactory.RenewOnCallTime = lifetime.RenewOnCallTime; - this.remoteObjectFactory.SponsorshipTimeout = lifetime.SponsorshipTimeout; - } - - #endregion - - #region Membres de ICaoRemoteFactory - - /// - /// Returns the CAO proxy. - /// - /// The remote object. - public object GetObject() - { - remoteObjectFactory.Target = objectFactory.GetObject(targetName); - - return remoteObjectFactory.GetObject(); - } - - /// - /// Returns the CAO proxy using the - /// argument list to call the constructor. - /// - /// - /// The matching of arguments to call the constructor is done - /// by type. The alternative ways, by index and by constructor - /// name are not supported. - /// - /// Constructor - /// arguments used to create the object. - /// The remote object. - public object GetObject(object[] constructorArguments) - { - RootObjectDefinition mergedObjectDefinition = objectFactory.GetMergedObjectDefinition(targetName, false); - - if (typeof(IFactoryObject).IsAssignableFrom(mergedObjectDefinition.ObjectType)) - { - throw new NotSupportedException( - "Client activated objects with constructor arguments is not supported with IFactoryObject implementations."); - } - - remoteObjectFactory.Target = objectFactory.GetObject(targetName, constructorArguments); - - return remoteObjectFactory.GetObject(); - } - - #endregion - - #region Overrided Methods - - /// - /// Set infinite lifetime. - /// - public override object InitializeLifetimeService() - { - return null; - } - - #endregion - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Remoting; + +using Spring.Context; +using Spring.Core; +using Spring.Objects; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Support; +using Spring.Remoting.Support; +using Spring.Util; + +#endregion + +namespace Spring.Remoting +{ + /// + /// Registers an object type on the server + /// as a Client Activated Object (CAO). + /// + /// Aleksandar Seovic + /// Mark Pollack + /// Bruno Baia + public class CaoExporter : ConfigurableLifetime, IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(CaoExporter)); + + #endregion + + #region Fields + + private string targetName; + private string[] interfaces; + + private IApplicationContext applicationContext; + private AbstractObjectFactory objectFactory; + + private CaoRemoteFactory remoteFactory; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the class. + /// + public CaoExporter() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the name of the target object definition. + /// + public string TargetName + { + get { return targetName; } + set { targetName = value; } + } + + /// + /// Gets or sets the list of interfaces whose methods should be exported. + /// + /// + /// The default value of this property is all the interfaces + /// implemented or inherited by the target type. + /// + /// The interfaces to export. + public string[] Interfaces + { + get { return interfaces; } + set { interfaces = value; } + } + + #endregion + + #region IApplicationContextAware Members + + /// + /// Gets or sets the that this + /// object runs in. + /// + public IApplicationContext ApplicationContext + { + get { return applicationContext; } + set { applicationContext = value; } + } + + #endregion + + #region IObjectFactoryAware Members + + /// + /// Sets object factory to use. + /// + public IObjectFactory ObjectFactory + { + set { objectFactory = (AbstractObjectFactory) value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Publish the object + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + Export(); + } + + #endregion + + #region IDisposable Members + + /// + /// Disconnect the remote object from the registered remoting channels. + /// + public void Dispose() + { + RemotingServices.Disconnect(remoteFactory); + } + + #endregion + + #region Private Methods + + private void ValidateConfiguration() + { + if (TargetName == null) + { + throw new ArgumentException("The TargetName property is required."); + } + } + + private void Export() + { + remoteFactory = new CaoRemoteFactory(this, targetName, interfaces, objectFactory); + + RemotingServices.Marshal(remoteFactory, targetName); + + #region Instrumentation + + if (LOG.IsDebugEnabled) + { + LOG.Debug(String.Format("Target '{0}' registered.", targetName)); + } + + #endregion + } + + #endregion + + #region BaseCao inner class definition + + /// + /// This class extends to allow CAOs + /// to be disconnect from the client. + /// + public abstract class BaseCao : BaseRemoteObject, IDisposable + { + #region IDisposable Members + + void IDisposable.Dispose() + { + RemotingServices.Disconnect(this); + } + + #endregion + } + + #endregion + + #region CaoRemoteFactory inner class definition + + private sealed class CaoRemoteFactory : MarshalByRefObject, ICaoRemoteFactory + { + #region Fields + + private AbstractObjectFactory objectFactory; + private string targetName; + private RemoteObjectFactory remoteObjectFactory; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Create a new instance of the RemoteFactory. + /// + public CaoRemoteFactory(ILifetime lifetime, string targetName, + string[] interfaces, AbstractObjectFactory objectFactory) + { + this.targetName = targetName; + this.objectFactory = objectFactory; + + this.remoteObjectFactory = new RemoteObjectFactory(); + this.remoteObjectFactory.BaseType = typeof(BaseCao); + this.remoteObjectFactory.Interfaces = interfaces; + this.remoteObjectFactory.Infinite = lifetime.Infinite; + this.remoteObjectFactory.InitialLeaseTime = lifetime.InitialLeaseTime; + this.remoteObjectFactory.RenewOnCallTime = lifetime.RenewOnCallTime; + this.remoteObjectFactory.SponsorshipTimeout = lifetime.SponsorshipTimeout; + } + + #endregion + + #region Membres de ICaoRemoteFactory + + /// + /// Returns the CAO proxy. + /// + /// The remote object. + public object GetObject() + { + remoteObjectFactory.Target = objectFactory.GetObject(targetName); + + return remoteObjectFactory.GetObject(); + } + + /// + /// Returns the CAO proxy using the + /// argument list to call the constructor. + /// + /// + /// The matching of arguments to call the constructor is done + /// by type. The alternative ways, by index and by constructor + /// name are not supported. + /// + /// Constructor + /// arguments used to create the object. + /// The remote object. + public object GetObject(object[] constructorArguments) + { + RootObjectDefinition mergedObjectDefinition = objectFactory.GetMergedObjectDefinition(targetName, false); + + if (typeof(IFactoryObject).IsAssignableFrom(mergedObjectDefinition.ObjectType)) + { + throw new NotSupportedException( + "Client activated objects with constructor arguments is not supported with IFactoryObject implementations."); + } + + remoteObjectFactory.Target = objectFactory.GetObject(targetName, constructorArguments); + + return remoteObjectFactory.GetObject(); + } + + #endregion + + #region Overrided Methods + + /// + /// Set infinite lifetime. + /// + public override object InitializeLifetimeService() + { + return null; + } + + #endregion + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/CaoFactoryObject.cs b/src/Spring/Spring.Services/Remoting/CaoFactoryObject.cs index 37f9bb86..122c1904 100644 --- a/src/Spring/Spring.Services/Remoting/CaoFactoryObject.cs +++ b/src/Spring/Spring.Services/Remoting/CaoFactoryObject.cs @@ -1,151 +1,150 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Objects.Factory; -using Spring.Remoting.Support; - -#endregion - -namespace Spring.Remoting -{ - /// - /// Factory for creating a reference to a - /// client activated object (CAO). - /// - /// Aleksandar Seovic - /// Mark Pollack - /// Bruno Baia - /// $Id: CaoFactoryObject.cs,v 1.4 2006/09/13 20:20:14 bbaia Exp $ - public class CaoFactoryObject : IFactoryObject, IInitializingObject - { - #region Fields - - private string remoteTargetName; - private string serviceUrl; - private object[] constructorArguments; - - #endregion - - #region Properties - - /// - /// The remote target name to activate. - /// - public string RemoteTargetName - { - get { return remoteTargetName; } - set { remoteTargetName = value; } - } - - /// - /// The Uri of the remote type. - /// - public string ServiceUrl - { - get { return serviceUrl; } - set { serviceUrl = value; } - } - - /// - /// Argument list used to call the CAO constructor. - /// - public object[] ConstructorArguments - { - get { return constructorArguments; } - set { constructorArguments = value; } - } - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the class. - /// - public CaoFactoryObject() - { - } - - #endregion - - #region IInitializingObject Members - - /// - /// Callback method called once all factory properties have been set. - /// - /// if an error occured - public void AfterPropertiesSet() - { - if (RemoteTargetName == null) - { - throw new ArgumentException("The RemoteTargetName property is required."); - } - - if (ServiceUrl == null) - { - throw new ArgumentException("The ServiceUrl property is required."); - } - } - - #endregion - - #region IFactoryObject Members - - /// - /// Always return false. - /// - public bool IsSingleton - { - get { return false; } - } - - /// - /// The type of object to be created. - /// - public Type ObjectType - { - get { return typeof(MarshalByRefObject); } - } - - /// - /// Return the CAO proxy. - /// - /// the CAO proxy - public object GetObject() - { - ICaoRemoteFactory remoteFactory = (ICaoRemoteFactory) Activator.GetObject(typeof(ICaoRemoteFactory), serviceUrl.TrimEnd('/') + '/' + remoteTargetName); - - if (constructorArguments != null) - { - return remoteFactory.GetObject(constructorArguments); - } - else - { - return remoteFactory.GetObject(); - } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Objects.Factory; +using Spring.Remoting.Support; + +#endregion + +namespace Spring.Remoting +{ + /// + /// Factory for creating a reference to a + /// client activated object (CAO). + /// + /// Aleksandar Seovic + /// Mark Pollack + /// Bruno Baia + public class CaoFactoryObject : IFactoryObject, IInitializingObject + { + #region Fields + + private string remoteTargetName; + private string serviceUrl; + private object[] constructorArguments; + + #endregion + + #region Properties + + /// + /// The remote target name to activate. + /// + public string RemoteTargetName + { + get { return remoteTargetName; } + set { remoteTargetName = value; } + } + + /// + /// The Uri of the remote type. + /// + public string ServiceUrl + { + get { return serviceUrl; } + set { serviceUrl = value; } + } + + /// + /// Argument list used to call the CAO constructor. + /// + public object[] ConstructorArguments + { + get { return constructorArguments; } + set { constructorArguments = value; } + } + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the class. + /// + public CaoFactoryObject() + { + } + + #endregion + + #region IInitializingObject Members + + /// + /// Callback method called once all factory properties have been set. + /// + /// if an error occured + public void AfterPropertiesSet() + { + if (RemoteTargetName == null) + { + throw new ArgumentException("The RemoteTargetName property is required."); + } + + if (ServiceUrl == null) + { + throw new ArgumentException("The ServiceUrl property is required."); + } + } + + #endregion + + #region IFactoryObject Members + + /// + /// Always return false. + /// + public bool IsSingleton + { + get { return false; } + } + + /// + /// The type of object to be created. + /// + public Type ObjectType + { + get { return typeof(MarshalByRefObject); } + } + + /// + /// Return the CAO proxy. + /// + /// the CAO proxy + public object GetObject() + { + ICaoRemoteFactory remoteFactory = (ICaoRemoteFactory) Activator.GetObject(typeof(ICaoRemoteFactory), serviceUrl.TrimEnd('/') + '/' + remoteTargetName); + + if (constructorArguments != null) + { + return remoteFactory.GetObject(constructorArguments); + } + else + { + return remoteFactory.GetObject(); + } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/Config/RemotingNamespaceParser.cs b/src/Spring/Spring.Services/Remoting/Config/RemotingNamespaceParser.cs index 89e6f129..3c0c12d5 100644 --- a/src/Spring/Spring.Services/Remoting/Config/RemotingNamespaceParser.cs +++ b/src/Spring/Spring.Services/Remoting/Config/RemotingNamespaceParser.cs @@ -1,491 +1,490 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System.Xml; - -using Spring.Context.Support; -using Spring.Core.TypeResolution; -using Spring.Objects; -using Spring.Objects.Factory.Support; -using Spring.Objects.Factory.Config; -using Spring.Objects.Factory.Xml; -using Spring.Util; - -#endregion - -namespace Spring.Remoting.Config -{ - /// - /// Implementation of the custom configuration parser for remoting definitions. - /// - /// Bruno Baia - /// $Id: RemotingNamespaceParser.cs,v 1.3 2007/10/08 14:57:34 bbaia Exp $ - [ - NamespaceParser( - Namespace = "http://www.springframework.net/remoting", - SchemaLocationAssemblyHint = typeof(RemotingNamespaceParser), - SchemaLocation = "/Spring.Remoting.Config/spring-remoting-1.1.xsd") - ] - public sealed class RemotingNamespaceParser : ObjectsNamespaceParser - { - private const string RemotingTypePrefix = "remoting: "; - - static RemotingNamespaceParser() - { - TypeRegistry.RegisterType( - RemotingTypePrefix + RemotingConfigurerConstants.RemotingConfigurerElement, - typeof(RemotingConfigurer)); - TypeRegistry.RegisterType( - RemotingTypePrefix + SaoFactoryObjectConstants.SaoFactoryObjectElement, - typeof(SaoFactoryObject)); - TypeRegistry.RegisterType( - RemotingTypePrefix + CaoFactoryObjectConstants.CaoFactoryObjectElement, - typeof(CaoFactoryObject)); - TypeRegistry.RegisterType( - RemotingTypePrefix + RemoteObjectFactoryConstants.RemoteObjectFactoryElement, - typeof(RemoteObjectFactory)); - TypeRegistry.RegisterType( - RemotingTypePrefix + SaoExporterConstants.SaoExporterElement, - typeof(SaoExporter)); - TypeRegistry.RegisterType( - RemotingTypePrefix + CaoExporterConstants.CaoExporterElement, - typeof(CaoExporter)); - } - - /// - /// Initializes a new instance of the class. - /// - public RemotingNamespaceParser() - {} - - - /// - /// Parse the specified element and register any resulting - /// IObjectDefinitions with the IObjectDefinitionRegistry that is - /// embedded in the supplied ParserContext. - /// - /// The element to be parsed into one or more IObjectDefinitions - /// The object encapsulating the current state of the parsing - /// process. - /// - /// The primary IObjectDefinition (can be null as explained above) - /// - /// - /// Implementations should return the primary IObjectDefinition - /// that results from the parse phase if they wish to used nested - /// inside (for example) a <property> tag. - /// Implementations may return null if they will not - /// be used in a nested scenario. - /// - /// - public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) - { - string name = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); - IConfigurableObjectDefinition remotingDefinition = ParseRemotingDefinition(element, name, parserContext); - if (!StringUtils.HasText(name)) - { - name = ObjectDefinitionReaderUtils.GenerateObjectName(remotingDefinition, parserContext.Registry); - } - parserContext.Registry.RegisterObjectDefinition(name, remotingDefinition); - - return null; - } - - - - /// - /// Parses remoting definitions. - /// - /// Validator XML element. - /// The name of the object definition. - /// The parser context. - /// A remoting object definition. - private IConfigurableObjectDefinition ParseRemotingDefinition( - XmlElement element, string name, ParserContext parserContext) - { - switch (element.LocalName) - { - case RemotingConfigurerConstants.RemotingConfigurerElement: - return ParseRemotingConfigurer(element, name, parserContext); - case SaoFactoryObjectConstants.SaoFactoryObjectElement: - return ParseSaoFactoryObject(element, name, parserContext); - case CaoFactoryObjectConstants.CaoFactoryObjectElement: - return ParseCaoFactoryObject(element, name, parserContext); - case RemoteObjectFactoryConstants.RemoteObjectFactoryElement: - return ParseRemoteObjectFactory(element, name, parserContext); - case SaoExporterConstants.SaoExporterElement: - return ParseSaoExporter(element, name, parserContext); - case CaoExporterConstants.CaoExporterElement: - return ParseCaoExporter(element, name, parserContext); - } - - return null; - } - - /// - /// Parses the RemotingConfigurer definition. - /// - /// The element to parse. - /// The name of the object definition. - /// The parser context. - /// RemotingConfigurer object definition. - private IConfigurableObjectDefinition ParseRemotingConfigurer( - XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string filename = element.GetAttribute(RemotingConfigurerConstants.FilenameAttribute); - string useConfigFile = element.GetAttribute(RemotingConfigurerConstants.UseConfigFileAttribute); - string ensureSecurity = element.GetAttribute(RemotingConfigurerConstants.EnsureSecurityAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(filename)) - { - properties.Add("Filename", filename); - } - if (StringUtils.HasText(useConfigFile)) - { - properties.Add("UseConfigFile", useConfigFile); - } - if (StringUtils.HasText(ensureSecurity)) - { - properties.Add("EnsureSecurity", ensureSecurity); - } - - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - return cod; - } - - /// - /// Parses the SaoFactoryObject definition. - /// - /// The element to parse. - /// The name of the object definition. - /// The parser context. - /// SaoFactoryObject object definition. - private IConfigurableObjectDefinition ParseSaoFactoryObject( - XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string serviceInterface = element.GetAttribute(SaoFactoryObjectConstants.ServiceInterfaceAttribute); - string serviceUrl = element.GetAttribute(SaoFactoryObjectConstants.ServiceUrlAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(serviceInterface)) - { - properties.Add("ServiceInterface", serviceInterface); - } - if (StringUtils.HasText(serviceUrl)) - { - properties.Add("ServiceUrl", serviceUrl); - } - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - return cod; - } - - /// - /// Parses the CaoFactoryObject definition. - /// - /// The element to parse. - /// The name of the object definition. - /// The parser context. - /// CaoFactoryObject object definition. - private IConfigurableObjectDefinition ParseCaoFactoryObject( - XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string remoteTargetName = element.GetAttribute(CaoFactoryObjectConstants.RemoteTargetNameAttribute); - string serviceUrl = element.GetAttribute(CaoFactoryObjectConstants.ServiceUrlAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(remoteTargetName)) - { - properties.Add("RemoteTargetName", remoteTargetName); - } - if (StringUtils.HasText(serviceUrl)) - { - properties.Add("ServiceUrl", serviceUrl); - } - - foreach (XmlElement child in element.ChildNodes) - { - switch (child.LocalName) - { - case CaoFactoryObjectConstants.ConstructorArgumentsElement: - properties.Add("ConstructorArguments", base.GetList(child, name, parserContext.ParserHelper)); - break; - } - } - - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - - return cod; - } - - /// - /// Parses the RemoteObjectFactory definition. - /// - /// The element to parse. - /// The name of the object definition. - /// The parser context. - /// RemoteObjectFactory object definition. - private IConfigurableObjectDefinition ParseRemoteObjectFactory( - XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string targetName = element.GetAttribute(RemoteObjectFactoryConstants.TargetNameAttribute); - string infinite = element.GetAttribute(RemoteObjectFactoryConstants.InfiniteAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(targetName)) - { - properties.Add("Target", targetName); - } - if (StringUtils.HasText(infinite)) - { - properties.Add("Infinite", infinite); - } - - foreach (XmlElement child in element.ChildNodes) - { - switch (child.LocalName) - { - case LifeTimeConstants.LifeTimeElement: - ParseLifeTime(properties, child, parserContext); - break; - case InterfacesConstants.InterfacesElement: - properties.Add("Interfaces", base.GetList(child, name, parserContext.ParserHelper)); - break; - } - } - - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - - return cod; - } - - /// - /// Parses the SaoExporter definition. - /// - /// The element to parse. - /// The name of the object definition. - /// The parser context. - /// SaoExporter object definition. - private IConfigurableObjectDefinition ParseSaoExporter( - XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string targetName = element.GetAttribute(SaoExporterConstants.TargetNameAttribute); - string applicationName = element.GetAttribute(SaoExporterConstants.ApplicationNameAttribute); - string serviceName = element.GetAttribute(SaoExporterConstants.ServiceNameAttribute); - string infinite = element.GetAttribute(SaoExporterConstants.InfiniteAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(targetName)) - { - properties.Add("TargetName", targetName); - } - if (StringUtils.HasText(applicationName)) - { - properties.Add("ApplicationName", applicationName); - } - if (StringUtils.HasText(serviceName)) - { - properties.Add("ServiceName", serviceName); - } - if (StringUtils.HasText(infinite)) - { - properties.Add("Infinite", infinite); - } - - foreach (XmlElement child in element.ChildNodes) - { - switch (child.LocalName) - { - case LifeTimeConstants.LifeTimeElement: - ParseLifeTime(properties, child, parserContext); - break; - case InterfacesConstants.InterfacesElement: - properties.Add("Interfaces", base.GetList(child, name, parserContext.ParserHelper)); - break; - } - } - - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - return cod; - } - - /// - /// Parses the CaoExporter definition. - /// - /// The element to parse. - /// The name of the object definition. - /// The parser context. - /// CaoExporter object definition. - private IConfigurableObjectDefinition ParseCaoExporter( - XmlElement element, string name, ParserContext parserContext) - { - string typeName = GetTypeName(element); - string targetName = element.GetAttribute(CaoExporterConstants.TargetNameAttribute); - string infinite = element.GetAttribute(CaoExporterConstants.InfiniteAttribute); - - MutablePropertyValues properties = new MutablePropertyValues(); - if (StringUtils.HasText(targetName)) - { - properties.Add("TargetName", targetName); - } - if (StringUtils.HasText(infinite)) - { - properties.Add("Infinite", infinite); - } - - foreach (XmlElement child in element.ChildNodes) - { - switch (child.LocalName) - { - case LifeTimeConstants.LifeTimeElement: - ParseLifeTime(properties, child, parserContext); - break; - case InterfacesConstants.InterfacesElement: - properties.Add("Interfaces", base.GetList(child, name, parserContext.ParserHelper)); - break; - } - } - - IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( - typeName, null, parserContext.ReaderContext.Reader.Domain); - cod.PropertyValues = properties; - - return cod; - } - - /// - /// Parses the LifeTime definition. - /// - private void ParseLifeTime(MutablePropertyValues properties, XmlElement child, ParserContext parserContext) - { - string initialLeaseTime = child.GetAttribute(LifeTimeConstants.InitialLeaseTimeAttribute); - string renewOnCallTime = child.GetAttribute(LifeTimeConstants.RenewOnCallTimeAttribute); - string sponsorshipTimeout = child.GetAttribute(LifeTimeConstants.SponsorshipTimeoutAttribute); - - if (StringUtils.HasText(initialLeaseTime)) - { - properties.Add("InitialLeaseTime", initialLeaseTime); - } - if (StringUtils.HasText(renewOnCallTime)) - { - properties.Add("RenewOnCallTime", renewOnCallTime); - } - if (StringUtils.HasText(sponsorshipTimeout)) - { - properties.Add("SponsorshipTimeout", sponsorshipTimeout); - } - } - - /// - /// Gets the name of the object type for the specified element. - /// - /// The element. - /// The name of the object type. - private string GetTypeName(XmlElement element) - { - string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); - if (StringUtils.IsNullOrEmpty(typeName)) - { - return RemotingTypePrefix + element.LocalName; - } - return typeName; - } - - #region Element & Attribute Name Constants - - private class RemotingConfigurerConstants - { - public const string RemotingConfigurerElement = "configurer"; - public const string FilenameAttribute = "filename"; - public const string UseConfigFileAttribute = "useConfigFile"; - public const string EnsureSecurityAttribute = "ensureSecurity"; - } - - private class SaoFactoryObjectConstants - { - public const string SaoFactoryObjectElement = "saoFactory"; - public const string ServiceInterfaceAttribute = "serviceInterface"; - public const string ServiceUrlAttribute = "serviceUrl"; - } - - private class CaoFactoryObjectConstants - { - public const string CaoFactoryObjectElement = "caoFactory"; - public const string ConstructorArgumentsElement = "constructor-args"; - public const string RemoteTargetNameAttribute = "remoteTargetName"; - public const string ServiceUrlAttribute = "serviceUrl"; - } - - private class LifeTimeConstants - { - public const string LifeTimeElement = "lifeTime"; - public const string InitialLeaseTimeAttribute = "initialLeaseTime"; - public const string RenewOnCallTimeAttribute = "renewOnCallTime"; - public const string SponsorshipTimeoutAttribute = "sponsorshipTimeout"; - } - - private class InterfacesConstants - { - public const string InterfacesElement = "interfaces"; - } - - private class RemoteObjectFactoryConstants - { - public const string RemoteObjectFactoryElement = "remoteObjectFactory"; - public const string TargetNameAttribute = "targetName"; - public const string InfiniteAttribute = "infinite"; - } - - private class SaoExporterConstants - { - public const string SaoExporterElement = "saoExporter"; - public const string TargetNameAttribute = "targetName"; - public const string ApplicationNameAttribute = "applicationName"; - public const string ServiceNameAttribute = "serviceName"; - public const string InfiniteAttribute = "infinite"; - } - - private class CaoExporterConstants - { - public const string CaoExporterElement = "caoExporter"; - public const string TargetNameAttribute = "targetName"; - public const string InfiniteAttribute = "infinite"; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System.Xml; + +using Spring.Context.Support; +using Spring.Core.TypeResolution; +using Spring.Objects; +using Spring.Objects.Factory.Support; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Xml; +using Spring.Util; + +#endregion + +namespace Spring.Remoting.Config +{ + /// + /// Implementation of the custom configuration parser for remoting definitions. + /// + /// Bruno Baia + [ + NamespaceParser( + Namespace = "http://www.springframework.net/remoting", + SchemaLocationAssemblyHint = typeof(RemotingNamespaceParser), + SchemaLocation = "/Spring.Remoting.Config/spring-remoting-1.1.xsd") + ] + public sealed class RemotingNamespaceParser : ObjectsNamespaceParser + { + private const string RemotingTypePrefix = "remoting: "; + + static RemotingNamespaceParser() + { + TypeRegistry.RegisterType( + RemotingTypePrefix + RemotingConfigurerConstants.RemotingConfigurerElement, + typeof(RemotingConfigurer)); + TypeRegistry.RegisterType( + RemotingTypePrefix + SaoFactoryObjectConstants.SaoFactoryObjectElement, + typeof(SaoFactoryObject)); + TypeRegistry.RegisterType( + RemotingTypePrefix + CaoFactoryObjectConstants.CaoFactoryObjectElement, + typeof(CaoFactoryObject)); + TypeRegistry.RegisterType( + RemotingTypePrefix + RemoteObjectFactoryConstants.RemoteObjectFactoryElement, + typeof(RemoteObjectFactory)); + TypeRegistry.RegisterType( + RemotingTypePrefix + SaoExporterConstants.SaoExporterElement, + typeof(SaoExporter)); + TypeRegistry.RegisterType( + RemotingTypePrefix + CaoExporterConstants.CaoExporterElement, + typeof(CaoExporter)); + } + + /// + /// Initializes a new instance of the class. + /// + public RemotingNamespaceParser() + {} + + + /// + /// Parse the specified element and register any resulting + /// IObjectDefinitions with the IObjectDefinitionRegistry that is + /// embedded in the supplied ParserContext. + /// + /// The element to be parsed into one or more IObjectDefinitions + /// The object encapsulating the current state of the parsing + /// process. + /// + /// The primary IObjectDefinition (can be null as explained above) + /// + /// + /// Implementations should return the primary IObjectDefinition + /// that results from the parse phase if they wish to used nested + /// inside (for example) a <property> tag. + /// Implementations may return null if they will not + /// be used in a nested scenario. + /// + /// + public override IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext) + { + string name = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); + IConfigurableObjectDefinition remotingDefinition = ParseRemotingDefinition(element, name, parserContext); + if (!StringUtils.HasText(name)) + { + name = ObjectDefinitionReaderUtils.GenerateObjectName(remotingDefinition, parserContext.Registry); + } + parserContext.Registry.RegisterObjectDefinition(name, remotingDefinition); + + return null; + } + + + + /// + /// Parses remoting definitions. + /// + /// Validator XML element. + /// The name of the object definition. + /// The parser context. + /// A remoting object definition. + private IConfigurableObjectDefinition ParseRemotingDefinition( + XmlElement element, string name, ParserContext parserContext) + { + switch (element.LocalName) + { + case RemotingConfigurerConstants.RemotingConfigurerElement: + return ParseRemotingConfigurer(element, name, parserContext); + case SaoFactoryObjectConstants.SaoFactoryObjectElement: + return ParseSaoFactoryObject(element, name, parserContext); + case CaoFactoryObjectConstants.CaoFactoryObjectElement: + return ParseCaoFactoryObject(element, name, parserContext); + case RemoteObjectFactoryConstants.RemoteObjectFactoryElement: + return ParseRemoteObjectFactory(element, name, parserContext); + case SaoExporterConstants.SaoExporterElement: + return ParseSaoExporter(element, name, parserContext); + case CaoExporterConstants.CaoExporterElement: + return ParseCaoExporter(element, name, parserContext); + } + + return null; + } + + /// + /// Parses the RemotingConfigurer definition. + /// + /// The element to parse. + /// The name of the object definition. + /// The parser context. + /// RemotingConfigurer object definition. + private IConfigurableObjectDefinition ParseRemotingConfigurer( + XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string filename = element.GetAttribute(RemotingConfigurerConstants.FilenameAttribute); + string useConfigFile = element.GetAttribute(RemotingConfigurerConstants.UseConfigFileAttribute); + string ensureSecurity = element.GetAttribute(RemotingConfigurerConstants.EnsureSecurityAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(filename)) + { + properties.Add("Filename", filename); + } + if (StringUtils.HasText(useConfigFile)) + { + properties.Add("UseConfigFile", useConfigFile); + } + if (StringUtils.HasText(ensureSecurity)) + { + properties.Add("EnsureSecurity", ensureSecurity); + } + + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + return cod; + } + + /// + /// Parses the SaoFactoryObject definition. + /// + /// The element to parse. + /// The name of the object definition. + /// The parser context. + /// SaoFactoryObject object definition. + private IConfigurableObjectDefinition ParseSaoFactoryObject( + XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string serviceInterface = element.GetAttribute(SaoFactoryObjectConstants.ServiceInterfaceAttribute); + string serviceUrl = element.GetAttribute(SaoFactoryObjectConstants.ServiceUrlAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(serviceInterface)) + { + properties.Add("ServiceInterface", serviceInterface); + } + if (StringUtils.HasText(serviceUrl)) + { + properties.Add("ServiceUrl", serviceUrl); + } + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + return cod; + } + + /// + /// Parses the CaoFactoryObject definition. + /// + /// The element to parse. + /// The name of the object definition. + /// The parser context. + /// CaoFactoryObject object definition. + private IConfigurableObjectDefinition ParseCaoFactoryObject( + XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string remoteTargetName = element.GetAttribute(CaoFactoryObjectConstants.RemoteTargetNameAttribute); + string serviceUrl = element.GetAttribute(CaoFactoryObjectConstants.ServiceUrlAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(remoteTargetName)) + { + properties.Add("RemoteTargetName", remoteTargetName); + } + if (StringUtils.HasText(serviceUrl)) + { + properties.Add("ServiceUrl", serviceUrl); + } + + foreach (XmlElement child in element.ChildNodes) + { + switch (child.LocalName) + { + case CaoFactoryObjectConstants.ConstructorArgumentsElement: + properties.Add("ConstructorArguments", base.GetList(child, name, parserContext.ParserHelper)); + break; + } + } + + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + + return cod; + } + + /// + /// Parses the RemoteObjectFactory definition. + /// + /// The element to parse. + /// The name of the object definition. + /// The parser context. + /// RemoteObjectFactory object definition. + private IConfigurableObjectDefinition ParseRemoteObjectFactory( + XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string targetName = element.GetAttribute(RemoteObjectFactoryConstants.TargetNameAttribute); + string infinite = element.GetAttribute(RemoteObjectFactoryConstants.InfiniteAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(targetName)) + { + properties.Add("Target", targetName); + } + if (StringUtils.HasText(infinite)) + { + properties.Add("Infinite", infinite); + } + + foreach (XmlElement child in element.ChildNodes) + { + switch (child.LocalName) + { + case LifeTimeConstants.LifeTimeElement: + ParseLifeTime(properties, child, parserContext); + break; + case InterfacesConstants.InterfacesElement: + properties.Add("Interfaces", base.GetList(child, name, parserContext.ParserHelper)); + break; + } + } + + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + + return cod; + } + + /// + /// Parses the SaoExporter definition. + /// + /// The element to parse. + /// The name of the object definition. + /// The parser context. + /// SaoExporter object definition. + private IConfigurableObjectDefinition ParseSaoExporter( + XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string targetName = element.GetAttribute(SaoExporterConstants.TargetNameAttribute); + string applicationName = element.GetAttribute(SaoExporterConstants.ApplicationNameAttribute); + string serviceName = element.GetAttribute(SaoExporterConstants.ServiceNameAttribute); + string infinite = element.GetAttribute(SaoExporterConstants.InfiniteAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(targetName)) + { + properties.Add("TargetName", targetName); + } + if (StringUtils.HasText(applicationName)) + { + properties.Add("ApplicationName", applicationName); + } + if (StringUtils.HasText(serviceName)) + { + properties.Add("ServiceName", serviceName); + } + if (StringUtils.HasText(infinite)) + { + properties.Add("Infinite", infinite); + } + + foreach (XmlElement child in element.ChildNodes) + { + switch (child.LocalName) + { + case LifeTimeConstants.LifeTimeElement: + ParseLifeTime(properties, child, parserContext); + break; + case InterfacesConstants.InterfacesElement: + properties.Add("Interfaces", base.GetList(child, name, parserContext.ParserHelper)); + break; + } + } + + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + return cod; + } + + /// + /// Parses the CaoExporter definition. + /// + /// The element to parse. + /// The name of the object definition. + /// The parser context. + /// CaoExporter object definition. + private IConfigurableObjectDefinition ParseCaoExporter( + XmlElement element, string name, ParserContext parserContext) + { + string typeName = GetTypeName(element); + string targetName = element.GetAttribute(CaoExporterConstants.TargetNameAttribute); + string infinite = element.GetAttribute(CaoExporterConstants.InfiniteAttribute); + + MutablePropertyValues properties = new MutablePropertyValues(); + if (StringUtils.HasText(targetName)) + { + properties.Add("TargetName", targetName); + } + if (StringUtils.HasText(infinite)) + { + properties.Add("Infinite", infinite); + } + + foreach (XmlElement child in element.ChildNodes) + { + switch (child.LocalName) + { + case LifeTimeConstants.LifeTimeElement: + ParseLifeTime(properties, child, parserContext); + break; + case InterfacesConstants.InterfacesElement: + properties.Add("Interfaces", base.GetList(child, name, parserContext.ParserHelper)); + break; + } + } + + IConfigurableObjectDefinition cod = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition( + typeName, null, parserContext.ReaderContext.Reader.Domain); + cod.PropertyValues = properties; + + return cod; + } + + /// + /// Parses the LifeTime definition. + /// + private void ParseLifeTime(MutablePropertyValues properties, XmlElement child, ParserContext parserContext) + { + string initialLeaseTime = child.GetAttribute(LifeTimeConstants.InitialLeaseTimeAttribute); + string renewOnCallTime = child.GetAttribute(LifeTimeConstants.RenewOnCallTimeAttribute); + string sponsorshipTimeout = child.GetAttribute(LifeTimeConstants.SponsorshipTimeoutAttribute); + + if (StringUtils.HasText(initialLeaseTime)) + { + properties.Add("InitialLeaseTime", initialLeaseTime); + } + if (StringUtils.HasText(renewOnCallTime)) + { + properties.Add("RenewOnCallTime", renewOnCallTime); + } + if (StringUtils.HasText(sponsorshipTimeout)) + { + properties.Add("SponsorshipTimeout", sponsorshipTimeout); + } + } + + /// + /// Gets the name of the object type for the specified element. + /// + /// The element. + /// The name of the object type. + private string GetTypeName(XmlElement element) + { + string typeName = element.GetAttribute(ObjectDefinitionConstants.TypeAttribute); + if (StringUtils.IsNullOrEmpty(typeName)) + { + return RemotingTypePrefix + element.LocalName; + } + return typeName; + } + + #region Element & Attribute Name Constants + + private class RemotingConfigurerConstants + { + public const string RemotingConfigurerElement = "configurer"; + public const string FilenameAttribute = "filename"; + public const string UseConfigFileAttribute = "useConfigFile"; + public const string EnsureSecurityAttribute = "ensureSecurity"; + } + + private class SaoFactoryObjectConstants + { + public const string SaoFactoryObjectElement = "saoFactory"; + public const string ServiceInterfaceAttribute = "serviceInterface"; + public const string ServiceUrlAttribute = "serviceUrl"; + } + + private class CaoFactoryObjectConstants + { + public const string CaoFactoryObjectElement = "caoFactory"; + public const string ConstructorArgumentsElement = "constructor-args"; + public const string RemoteTargetNameAttribute = "remoteTargetName"; + public const string ServiceUrlAttribute = "serviceUrl"; + } + + private class LifeTimeConstants + { + public const string LifeTimeElement = "lifeTime"; + public const string InitialLeaseTimeAttribute = "initialLeaseTime"; + public const string RenewOnCallTimeAttribute = "renewOnCallTime"; + public const string SponsorshipTimeoutAttribute = "sponsorshipTimeout"; + } + + private class InterfacesConstants + { + public const string InterfacesElement = "interfaces"; + } + + private class RemoteObjectFactoryConstants + { + public const string RemoteObjectFactoryElement = "remoteObjectFactory"; + public const string TargetNameAttribute = "targetName"; + public const string InfiniteAttribute = "infinite"; + } + + private class SaoExporterConstants + { + public const string SaoExporterElement = "saoExporter"; + public const string TargetNameAttribute = "targetName"; + public const string ApplicationNameAttribute = "applicationName"; + public const string ServiceNameAttribute = "serviceName"; + public const string InfiniteAttribute = "infinite"; + } + + private class CaoExporterConstants + { + public const string CaoExporterElement = "caoExporter"; + public const string TargetNameAttribute = "targetName"; + public const string InfiniteAttribute = "infinite"; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/RemoteObjectFactory.cs b/src/Spring/Spring.Services/Remoting/RemoteObjectFactory.cs index dd8050d4..077be905 100644 --- a/src/Spring/Spring.Services/Remoting/RemoteObjectFactory.cs +++ b/src/Spring/Spring.Services/Remoting/RemoteObjectFactory.cs @@ -1,184 +1,183 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Proxy; -using Spring.Objects.Factory; -using Spring.Remoting.Support; -using Spring.Util; -using Spring.Core.TypeResolution; - -#endregion - -namespace Spring.Remoting -{ - /// - /// Factory for creating MarshalByRefObject wrapper around target class. - /// - /// Bruno Baia - /// $Id: RemoteObjectFactory.cs,v 1.8 2007/07/31 18:18:19 bbaia Exp $ - public class RemoteObjectFactory : ConfigurableLifetime, IInitializingObject, IFactoryObject - { - #region Fields - - private object target; - private Type baseType = typeof(BaseRemoteObject); - private string[] interfaces; - - private ConstructorInfo proxyConstructor; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the MarshalByRefObjectFactory. - /// - public RemoteObjectFactory() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets the target object. - /// - public object Target - { - get { return target; } - set { target = value; } - } - - /// - /// Gets or sets the class or subclass - /// that the proxy must inherit from. - /// - public Type BaseType - { - get { return baseType; } - set { baseType = value; } - } - - /// - /// Gets or sets the list of interfaces to wrap. - /// - /// - /// The default value of this property is all the interfaces - /// implemented or inherited by the target type. - /// - /// The interfaces to export. - public string[] Interfaces - { - get { return interfaces; } - set { interfaces = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Initializes factory object. - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - GenerateProxy(); - } - - #endregion - - #region IFactoryObject Members - - /// - /// Returns type of the remotable target proxy. - /// - public Type ObjectType - { - get - { - return (proxyConstructor != null) ? proxyConstructor.DeclaringType : target.GetType(); - } - } - - /// - /// Creates new instance of the remotable target proxy. - /// - /// New instance of the remotable target proxy. - public object GetObject() - { - if (proxyConstructor == null) - GenerateProxy(); - - return proxyConstructor.Invoke(new object[1]{ target }); - } - - /// - /// Always returns false. - /// - public bool IsSingleton - { - get - { - return false; - } - } - - #endregion - - #region Private Methods - - private void ValidateConfiguration() - { - if (Target == null) - { - throw new ArgumentException("The Target property is required."); - } - if (!typeof(BaseRemoteObject).IsAssignableFrom(BaseType)) - { - throw new ArgumentException("The type BaseRemoteObject cannot be assigned from BaseType."); - } - } - - private void GenerateProxy() - { - IProxyTypeBuilder builder = new RemoteObjectProxyTypeBuilder(this); - builder.TargetType = target.GetType(); - builder.BaseType = baseType; - if (interfaces != null && interfaces.Length > 0) - { - builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(interfaces); - } - - Type remotableObjectType = builder.BuildProxyType(); - - proxyConstructor = remotableObjectType.GetConstructor(new Type[1] { builder.TargetType }); - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Proxy; +using Spring.Objects.Factory; +using Spring.Remoting.Support; +using Spring.Util; +using Spring.Core.TypeResolution; + +#endregion + +namespace Spring.Remoting +{ + /// + /// Factory for creating MarshalByRefObject wrapper around target class. + /// + /// Bruno Baia + public class RemoteObjectFactory : ConfigurableLifetime, IInitializingObject, IFactoryObject + { + #region Fields + + private object target; + private Type baseType = typeof(BaseRemoteObject); + private string[] interfaces; + + private ConstructorInfo proxyConstructor; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the MarshalByRefObjectFactory. + /// + public RemoteObjectFactory() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the target object. + /// + public object Target + { + get { return target; } + set { target = value; } + } + + /// + /// Gets or sets the class or subclass + /// that the proxy must inherit from. + /// + public Type BaseType + { + get { return baseType; } + set { baseType = value; } + } + + /// + /// Gets or sets the list of interfaces to wrap. + /// + /// + /// The default value of this property is all the interfaces + /// implemented or inherited by the target type. + /// + /// The interfaces to export. + public string[] Interfaces + { + get { return interfaces; } + set { interfaces = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Initializes factory object. + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + GenerateProxy(); + } + + #endregion + + #region IFactoryObject Members + + /// + /// Returns type of the remotable target proxy. + /// + public Type ObjectType + { + get + { + return (proxyConstructor != null) ? proxyConstructor.DeclaringType : target.GetType(); + } + } + + /// + /// Creates new instance of the remotable target proxy. + /// + /// New instance of the remotable target proxy. + public object GetObject() + { + if (proxyConstructor == null) + GenerateProxy(); + + return proxyConstructor.Invoke(new object[1]{ target }); + } + + /// + /// Always returns false. + /// + public bool IsSingleton + { + get + { + return false; + } + } + + #endregion + + #region Private Methods + + private void ValidateConfiguration() + { + if (Target == null) + { + throw new ArgumentException("The Target property is required."); + } + if (!typeof(BaseRemoteObject).IsAssignableFrom(BaseType)) + { + throw new ArgumentException("The type BaseRemoteObject cannot be assigned from BaseType."); + } + } + + private void GenerateProxy() + { + IProxyTypeBuilder builder = new RemoteObjectProxyTypeBuilder(this); + builder.TargetType = target.GetType(); + builder.BaseType = baseType; + if (interfaces != null && interfaces.Length > 0) + { + builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(interfaces); + } + + Type remotableObjectType = builder.BuildProxyType(); + + proxyConstructor = remotableObjectType.GetConstructor(new Type[1] { builder.TargetType }); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/RemotingConfigurer.cs b/src/Spring/Spring.Services/Remoting/RemotingConfigurer.cs index f1d4e019..f81e12ab 100644 --- a/src/Spring/Spring.Services/Remoting/RemotingConfigurer.cs +++ b/src/Spring/Spring.Services/Remoting/RemotingConfigurer.cs @@ -1,170 +1,169 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Remoting; - -using Common.Logging; -using Spring.Core; -using Spring.Core.IO; -using Spring.Objects.Factory.Config; - -#endregion - -namespace Spring.Remoting -{ - /// - /// Convenience class to configure remoting infrastructure from the IoC container. - /// - /// Bruno Baia - /// $Id: RemotingConfigurer.cs,v 1.7 2007/10/08 14:57:34 bbaia Exp $ - public class RemotingConfigurer : IObjectFactoryPostProcessor, IOrdered - { - #region Fields - - private static readonly ILog log = LogManager.GetLogger(typeof(RemotingConfigurer)); - - private int _order = Int32.MinValue; - - private IResource _filename; - private bool _useConfigFile = true; - private bool _ensureSecurity = false; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Initializes a new instance of the class. - /// - public RemotingConfigurer() - {} - - #endregion - - #region Properties - - /// - /// Gets or sets the name of the remoting configuration file. - /// - /// - /// If filename is or not set, - /// current AppDomain's configuration file will be used. - /// - public IResource Filename - { - get { return _filename; } - set { _filename = value; } - } - - /// - /// Indicates whether a configuration file is used. - /// Default value is . - /// - /// - /// If , default remoting configuration will be used. - /// - public bool UseConfigFile - { - get { return _useConfigFile; } - set { _useConfigFile = value; } - } - - /// - /// Gets or sets if security is enabled. - /// - /// - /// This property is only available since .NET Framework 2.0. - /// - public bool EnsureSecurity - { - get { return _ensureSecurity; } - set - { -#if NET_2_0 - _ensureSecurity = value; -#else - throw new NotSupportedException( - "The EnsureSecurity property is supported only on .Net Framework 2.0."); -#endif - } - } - - #endregion - - #region IObjectFactoryPostProcessor Members - - /// - /// Modify the application context's internal object factory after its - /// standard initialization. - /// - /// - /// The object factory used by the application context. - /// - /// - public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory) - { - string filename = null; - if (UseConfigFile) - { - filename = (Filename == null) - ? AppDomain.CurrentDomain.SetupInformation.ConfigurationFile - : Filename.File.FullName; - } -#if NET_2_0 - RemotingConfiguration.Configure(filename, EnsureSecurity); -#else - RemotingConfiguration.Configure(filename); -#endif - #region Instrumentation - - if (log.IsDebugEnabled) - { - if (filename == null) - { - log.Debug("Default remoting infrastructure loaded."); - } - else - { - log.Debug(String.Format("Remoting infrastructure configured using file '{0}'.", filename)); - } - } - - #endregion - } - - #endregion - - #region IOrdered Members - - /// - /// Return the order value of this object, - /// where a higher value means greater in terms of sorting. - /// - public int Order - { - get { return _order; } - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Remoting; + +using Common.Logging; +using Spring.Core; +using Spring.Core.IO; +using Spring.Objects.Factory.Config; + +#endregion + +namespace Spring.Remoting +{ + /// + /// Convenience class to configure remoting infrastructure from the IoC container. + /// + /// Bruno Baia + public class RemotingConfigurer : IObjectFactoryPostProcessor, IOrdered + { + #region Fields + + private static readonly ILog log = LogManager.GetLogger(typeof(RemotingConfigurer)); + + private int _order = Int32.MinValue; + + private IResource _filename; + private bool _useConfigFile = true; + private bool _ensureSecurity = false; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Initializes a new instance of the class. + /// + public RemotingConfigurer() + {} + + #endregion + + #region Properties + + /// + /// Gets or sets the name of the remoting configuration file. + /// + /// + /// If filename is or not set, + /// current AppDomain's configuration file will be used. + /// + public IResource Filename + { + get { return _filename; } + set { _filename = value; } + } + + /// + /// Indicates whether a configuration file is used. + /// Default value is . + /// + /// + /// If , default remoting configuration will be used. + /// + public bool UseConfigFile + { + get { return _useConfigFile; } + set { _useConfigFile = value; } + } + + /// + /// Gets or sets if security is enabled. + /// + /// + /// This property is only available since .NET Framework 2.0. + /// + public bool EnsureSecurity + { + get { return _ensureSecurity; } + set + { +#if NET_2_0 + _ensureSecurity = value; +#else + throw new NotSupportedException( + "The EnsureSecurity property is supported only on .Net Framework 2.0."); +#endif + } + } + + #endregion + + #region IObjectFactoryPostProcessor Members + + /// + /// Modify the application context's internal object factory after its + /// standard initialization. + /// + /// + /// The object factory used by the application context. + /// + /// + public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory) + { + string filename = null; + if (UseConfigFile) + { + filename = (Filename == null) + ? AppDomain.CurrentDomain.SetupInformation.ConfigurationFile + : Filename.File.FullName; + } +#if NET_2_0 + RemotingConfiguration.Configure(filename, EnsureSecurity); +#else + RemotingConfiguration.Configure(filename); +#endif + #region Instrumentation + + if (log.IsDebugEnabled) + { + if (filename == null) + { + log.Debug("Default remoting infrastructure loaded."); + } + else + { + log.Debug(String.Format("Remoting infrastructure configured using file '{0}'.", filename)); + } + } + + #endregion + } + + #endregion + + #region IOrdered Members + + /// + /// Return the order value of this object, + /// where a higher value means greater in terms of sorting. + /// + public int Order + { + get { return _order; } + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/SaoExporter.cs b/src/Spring/Spring.Services/Remoting/SaoExporter.cs index 2b1f853d..8f92e631 100644 --- a/src/Spring/Spring.Services/Remoting/SaoExporter.cs +++ b/src/Spring/Spring.Services/Remoting/SaoExporter.cs @@ -1,341 +1,340 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.Remoting; - -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Proxy; -using Spring.Context; -using Spring.Context.Support; -using Spring.Objects; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Support; -using Spring.Remoting.Support; -using Spring.Util; - -#endregion - -namespace Spring.Remoting -{ - /// - /// Publishes an instance of an object under - /// a given url as a Server Activated Object (SAO). - /// - /// - /// Object can be exported either as SingleCall or Singleton. - /// - /// Aleksandar Seovic - /// Mark Pollack - /// Bruno Baia - /// $Id: SaoExporter.cs,v 1.18 2007/07/31 18:18:19 bbaia Exp $ - public class SaoExporter : ConfigurableLifetime, IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable - { - #region Logging - - private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(SaoExporter)); - - #endregion - - #region Fields - - private string targetName; - private string applicationName; - private string serviceName; - private string[] interfaces; - - private IApplicationContext applicationContext; - private IObjectFactory objectFactory; - - private MarshalByRefObject remoteObject; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the class. - /// - public SaoExporter() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets the name of the target object definition. - /// - public string TargetName - { - get { return targetName; } - set { targetName = value; } - } - - /// - /// Gets or sets the name of the remote application. - /// - public string ApplicationName - { - get { return applicationName; } - set { applicationName = value; } - } - - /// - /// Gets or sets the name of the exported remote service. - /// - /// The name that will be used in the URI to refer to this service. - /// This will be of the form, tcp://host:port/ServiceName or - /// tcp://host:port/ApplicationName/ServiceName - /// - /// - public string ServiceName - { - get { return serviceName; } - set { serviceName = value; } - } - - /// - /// Gets or sets the list of interfaces whose methods should be exported. - /// - /// - /// The default value of this property is all the interfaces - /// implemented or inherited by the target type. - /// - /// The interfaces to export. - public string[] Interfaces - { - get { return interfaces; } - set { interfaces = value; } - } - - #endregion - - #region IApplicationContextAware Members - - /// - /// Gets or sets the that this - /// object runs in. - /// - public IApplicationContext ApplicationContext - { - get { return applicationContext; } - set { applicationContext = value; } - } - - #endregion - - #region IObjectFactoryAware Members - - /// - /// Sets object factory to use. - /// - public IObjectFactory ObjectFactory - { - set { objectFactory = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Publish the object - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - Export(); - } - - #endregion - - #region IDisposable Members - - /// - /// Disconnect the remote object from the registered remoting channels. - /// - public void Dispose() - { - RemotingServices.Disconnect(remoteObject); - } - - #endregion - - #region Private Methods - - private void ValidateConfiguration() - { - if (TargetName == null) - { - throw new ArgumentException("The TargetName property is required."); - } - - if (ServiceName == null) - { - throw new ArgumentException("The ServiceName property is required."); - } - } - - private void Export() - { - IProxyTypeBuilder builder = new SaoRemoteObjectProxyTypeBuilder(applicationContext.Name, targetName, this); - builder.TargetType = this.objectFactory.GetType(targetName); - if (interfaces != null && interfaces.Length > 0) - { - builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(interfaces); - } - - ConstructorInfo proxyConstructor = - builder.BuildProxyType().GetConstructor(Type.EmptyTypes); - - string objectUri = (applicationName != null ? applicationName + "/" + serviceName : serviceName); - - remoteObject = (MarshalByRefObject) proxyConstructor.Invoke(ObjectUtils.EmptyObjects); - - RemotingServices.Marshal(remoteObject, objectUri); - - #region Instrumentation - - if (LOG.IsDebugEnabled) - { - LOG.Debug(String.Format("Target '{0}' exported as '{1}'.", targetName, objectUri)); - } - - #endregion - } - - #endregion - - #region SaoRemoteObjectProxyTypeBuilder inner class definition - - /// - /// Builds a proxy type based on to wrap a target object - /// that is intended to be remotable. - /// - /// - /// The wrapped target object is retrieved by name from the IoC container. - /// - private sealed class SaoRemoteObjectProxyTypeBuilder : RemoteObjectProxyTypeBuilder - { - #region Fields - - private static readonly MethodInfo TimeSpan_FromTicks = - typeof(TimeSpan).GetMethod("FromTicks", BindingFlags.Public | BindingFlags.Static); - - private static readonly MethodInfo ContextRegistry_GetContext = - typeof(ContextRegistry).GetMethod("GetContext", new Type[1] { typeof(string) }); - - private static readonly MethodInfo IObjectFactory_GetObject = - typeof(IObjectFactory).GetMethod("GetObject", new Type[1] { typeof(string) }); - - private string contextName; - private string targetObjectName; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The name of the target object definition. - /// - /// - /// The name of the application context that this object runs in. - /// - /// - /// The lifetime properties to be applied to the target object. - /// - public SaoRemoteObjectProxyTypeBuilder(string contextName, string targetObjectName, ILifetime lifetime) - : base(lifetime) - { - this.contextName = contextName; - this.targetObjectName = targetObjectName; - - Name = "SaoRemoteObjectProxy"; - BaseType = typeof(BaseRemoteObject); - } - - #endregion - - #region IProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the target instance on which calls should be delegated to. - /// - /// The IL generator to use. - public override void PushTarget(ILGenerator il) - { - il.Emit(OpCodes.Ldstr, this.contextName); - il.Emit(OpCodes.Call, ContextRegistry_GetContext); - il.Emit(OpCodes.Ldstr, this.targetObjectName); - il.Emit(OpCodes.Callvirt, IObjectFactory_GetObject); - } - - #endregion - - #region Protected Methods - - /// - /// Implements constructors for the proxy class. - /// - /// - /// The to use. - /// - protected override void ImplementConstructors(TypeBuilder builder) - { - MethodAttributes attributes = MethodAttributes.Public | - MethodAttributes.HideBySig | MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - ConstructorBuilder cb = builder.DefineConstructor(attributes, - CallingConventions.Standard, Type.EmptyTypes); - - ILGenerator il = cb.GetILGenerator(); - GenerateRemoteObjectLifetimeInitialization(il); - il.Emit(OpCodes.Ret); - } - - /// - /// Deaclares a field that holds the target object instance. - /// - /// - /// The builder to use for code generation. - /// - protected override void DeclareTargetInstanceField(TypeBuilder builder) - { - } - - #endregion - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Remoting; + +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Proxy; +using Spring.Context; +using Spring.Context.Support; +using Spring.Objects; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Support; +using Spring.Remoting.Support; +using Spring.Util; + +#endregion + +namespace Spring.Remoting +{ + /// + /// Publishes an instance of an object under + /// a given url as a Server Activated Object (SAO). + /// + /// + /// Object can be exported either as SingleCall or Singleton. + /// + /// Aleksandar Seovic + /// Mark Pollack + /// Bruno Baia + public class SaoExporter : ConfigurableLifetime, IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(SaoExporter)); + + #endregion + + #region Fields + + private string targetName; + private string applicationName; + private string serviceName; + private string[] interfaces; + + private IApplicationContext applicationContext; + private IObjectFactory objectFactory; + + private MarshalByRefObject remoteObject; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the class. + /// + public SaoExporter() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the name of the target object definition. + /// + public string TargetName + { + get { return targetName; } + set { targetName = value; } + } + + /// + /// Gets or sets the name of the remote application. + /// + public string ApplicationName + { + get { return applicationName; } + set { applicationName = value; } + } + + /// + /// Gets or sets the name of the exported remote service. + /// + /// The name that will be used in the URI to refer to this service. + /// This will be of the form, tcp://host:port/ServiceName or + /// tcp://host:port/ApplicationName/ServiceName + /// + /// + public string ServiceName + { + get { return serviceName; } + set { serviceName = value; } + } + + /// + /// Gets or sets the list of interfaces whose methods should be exported. + /// + /// + /// The default value of this property is all the interfaces + /// implemented or inherited by the target type. + /// + /// The interfaces to export. + public string[] Interfaces + { + get { return interfaces; } + set { interfaces = value; } + } + + #endregion + + #region IApplicationContextAware Members + + /// + /// Gets or sets the that this + /// object runs in. + /// + public IApplicationContext ApplicationContext + { + get { return applicationContext; } + set { applicationContext = value; } + } + + #endregion + + #region IObjectFactoryAware Members + + /// + /// Sets object factory to use. + /// + public IObjectFactory ObjectFactory + { + set { objectFactory = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Publish the object + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + Export(); + } + + #endregion + + #region IDisposable Members + + /// + /// Disconnect the remote object from the registered remoting channels. + /// + public void Dispose() + { + RemotingServices.Disconnect(remoteObject); + } + + #endregion + + #region Private Methods + + private void ValidateConfiguration() + { + if (TargetName == null) + { + throw new ArgumentException("The TargetName property is required."); + } + + if (ServiceName == null) + { + throw new ArgumentException("The ServiceName property is required."); + } + } + + private void Export() + { + IProxyTypeBuilder builder = new SaoRemoteObjectProxyTypeBuilder(applicationContext.Name, targetName, this); + builder.TargetType = this.objectFactory.GetType(targetName); + if (interfaces != null && interfaces.Length > 0) + { + builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(interfaces); + } + + ConstructorInfo proxyConstructor = + builder.BuildProxyType().GetConstructor(Type.EmptyTypes); + + string objectUri = (applicationName != null ? applicationName + "/" + serviceName : serviceName); + + remoteObject = (MarshalByRefObject) proxyConstructor.Invoke(ObjectUtils.EmptyObjects); + + RemotingServices.Marshal(remoteObject, objectUri); + + #region Instrumentation + + if (LOG.IsDebugEnabled) + { + LOG.Debug(String.Format("Target '{0}' exported as '{1}'.", targetName, objectUri)); + } + + #endregion + } + + #endregion + + #region SaoRemoteObjectProxyTypeBuilder inner class definition + + /// + /// Builds a proxy type based on to wrap a target object + /// that is intended to be remotable. + /// + /// + /// The wrapped target object is retrieved by name from the IoC container. + /// + private sealed class SaoRemoteObjectProxyTypeBuilder : RemoteObjectProxyTypeBuilder + { + #region Fields + + private static readonly MethodInfo TimeSpan_FromTicks = + typeof(TimeSpan).GetMethod("FromTicks", BindingFlags.Public | BindingFlags.Static); + + private static readonly MethodInfo ContextRegistry_GetContext = + typeof(ContextRegistry).GetMethod("GetContext", new Type[1] { typeof(string) }); + + private static readonly MethodInfo IObjectFactory_GetObject = + typeof(IObjectFactory).GetMethod("GetObject", new Type[1] { typeof(string) }); + + private string contextName; + private string targetObjectName; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The name of the target object definition. + /// + /// + /// The name of the application context that this object runs in. + /// + /// + /// The lifetime properties to be applied to the target object. + /// + public SaoRemoteObjectProxyTypeBuilder(string contextName, string targetObjectName, ILifetime lifetime) + : base(lifetime) + { + this.contextName = contextName; + this.targetObjectName = targetObjectName; + + Name = "SaoRemoteObjectProxy"; + BaseType = typeof(BaseRemoteObject); + } + + #endregion + + #region IProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the target instance on which calls should be delegated to. + /// + /// The IL generator to use. + public override void PushTarget(ILGenerator il) + { + il.Emit(OpCodes.Ldstr, this.contextName); + il.Emit(OpCodes.Call, ContextRegistry_GetContext); + il.Emit(OpCodes.Ldstr, this.targetObjectName); + il.Emit(OpCodes.Callvirt, IObjectFactory_GetObject); + } + + #endregion + + #region Protected Methods + + /// + /// Implements constructors for the proxy class. + /// + /// + /// The to use. + /// + protected override void ImplementConstructors(TypeBuilder builder) + { + MethodAttributes attributes = MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName; + ConstructorBuilder cb = builder.DefineConstructor(attributes, + CallingConventions.Standard, Type.EmptyTypes); + + ILGenerator il = cb.GetILGenerator(); + GenerateRemoteObjectLifetimeInitialization(il); + il.Emit(OpCodes.Ret); + } + + /// + /// Deaclares a field that holds the target object instance. + /// + /// + /// The builder to use for code generation. + /// + protected override void DeclareTargetInstanceField(TypeBuilder builder) + { + } + + #endregion + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/SaoFactoryObject.cs b/src/Spring/Spring.Services/Remoting/SaoFactoryObject.cs index 7b102bd7..52fd5b2a 100644 --- a/src/Spring/Spring.Services/Remoting/SaoFactoryObject.cs +++ b/src/Spring/Spring.Services/Remoting/SaoFactoryObject.cs @@ -1,141 +1,140 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.Remoting -{ - /// - /// Factory for creating a reference to a - /// remote server activated object (SAO). - /// - /// - /// This is useful alternative to adminstrative type registration on - /// the client when you would like the client to have only - /// a reference to the interface that an SAO implements and not the - /// actual SAO implentation. - /// - /// Aleksandar Seovic - /// Mark Pollack - /// Bruno Baia - /// $Id: SaoFactoryObject.cs,v 1.7 2006/05/17 17:45:39 bbaia Exp $ - public class SaoFactoryObject : IFactoryObject, IInitializingObject - { - #region Fields - - private Type serviceInterface; - private string serviceUrl; - - #endregion - - #region Properties - - /// - /// The remote service interface. - /// - public Type ServiceInterface - { - get { return serviceInterface; } - set { serviceInterface = value; } - } - - /// - /// The URI of the well known object - /// - public string ServiceUrl - { - get { return serviceUrl; } - set { serviceUrl = value; } - } - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the SaoFactoryObject class. - /// - public SaoFactoryObject() - { - } - - #endregion - - #region IInitializingObject Members - - /// - /// Callback method called once all factory properties have been set. - /// - /// if an error occured - public void AfterPropertiesSet() - { - if (ServiceUrl == null) - { - throw new ArgumentException("The ServiceUrl property is required."); - } - - if (ServiceInterface == null) - { - throw new ArgumentException("The ServiceInterface property is required."); - } - - if (!ServiceInterface.IsInterface) - { - throw new ArgumentException("ServiceInterface must be an interface"); - } - } - - #endregion - - #region IFactoryObject Members - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - public bool IsSingleton - { - get { return false; } - } - - /// - /// The type of object to be created. - /// - public Type ObjectType - { - get { return serviceInterface; } - } - - /// - /// Return the SAO proxy. - /// - /// the SAO proxy - public object GetObject() - { - return Activator.GetObject(serviceInterface, serviceUrl); - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.Remoting +{ + /// + /// Factory for creating a reference to a + /// remote server activated object (SAO). + /// + /// + /// This is useful alternative to adminstrative type registration on + /// the client when you would like the client to have only + /// a reference to the interface that an SAO implements and not the + /// actual SAO implentation. + /// + /// Aleksandar Seovic + /// Mark Pollack + /// Bruno Baia + public class SaoFactoryObject : IFactoryObject, IInitializingObject + { + #region Fields + + private Type serviceInterface; + private string serviceUrl; + + #endregion + + #region Properties + + /// + /// The remote service interface. + /// + public Type ServiceInterface + { + get { return serviceInterface; } + set { serviceInterface = value; } + } + + /// + /// The URI of the well known object + /// + public string ServiceUrl + { + get { return serviceUrl; } + set { serviceUrl = value; } + } + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the SaoFactoryObject class. + /// + public SaoFactoryObject() + { + } + + #endregion + + #region IInitializingObject Members + + /// + /// Callback method called once all factory properties have been set. + /// + /// if an error occured + public void AfterPropertiesSet() + { + if (ServiceUrl == null) + { + throw new ArgumentException("The ServiceUrl property is required."); + } + + if (ServiceInterface == null) + { + throw new ArgumentException("The ServiceInterface property is required."); + } + + if (!ServiceInterface.IsInterface) + { + throw new ArgumentException("ServiceInterface must be an interface"); + } + } + + #endregion + + #region IFactoryObject Members + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + public bool IsSingleton + { + get { return false; } + } + + /// + /// The type of object to be created. + /// + public Type ObjectType + { + get { return serviceInterface; } + } + + /// + /// Return the SAO proxy. + /// + /// the SAO proxy + public object GetObject() + { + return Activator.GetObject(serviceInterface, serviceUrl); + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/Support/BaseRemoteObject.cs b/src/Spring/Spring.Services/Remoting/Support/BaseRemoteObject.cs index f12b5141..e25acf62 100644 --- a/src/Spring/Spring.Services/Remoting/Support/BaseRemoteObject.cs +++ b/src/Spring/Spring.Services/Remoting/Support/BaseRemoteObject.cs @@ -1,164 +1,163 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Runtime.Remoting.Lifetime; - -#endregion - -namespace Spring.Remoting.Support -{ - /// - /// This class extends to allow users - /// to define object lifecycle details by simply setting its properties. - /// - /// - ///

- /// Remoting exporters uses this class as a base proxy class - /// in order to support lifecycle configuration when exporting - /// a remote object. - ///

- ///
- /// Aleksandar Seovic - /// $Id: BaseRemoteObject.cs,v 1.1 2006/09/13 20:20:16 bbaia Exp $ - public abstract class BaseRemoteObject : MarshalByRefObject - { - #region Fields - - private bool isInfinite = false; - private TimeSpan initialLeaseTime = TimeSpan.Zero; - private TimeSpan renewOnCallTime = TimeSpan.Zero; - private TimeSpan sponsorshipTimeout = TimeSpan.Zero; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Initializes a new instance of the class. - /// - public BaseRemoteObject() - {} - - #endregion - - #region Properties - - /// - /// Gets or sets a value indicating whether this instance has infinite lifetime. - /// - /// - /// if this instance has infinite lifetime; - /// otherwise, . - /// - public bool IsInfinite - { - get { return isInfinite; } - set { isInfinite = value; } - } - - /// - /// Gets or sets the initial lease time. - /// - /// The initial lease time. - public TimeSpan InitialLeaseTime - { - get { return initialLeaseTime; } - set { initialLeaseTime = value; } - } - - /// - /// Gets or sets the amount of time lease should be - /// extended for on each call to this object. - /// - /// The amount of time lease should be - /// extended for on each call to this object. - public TimeSpan RenewOnCallTime - { - get { return renewOnCallTime; } - set { renewOnCallTime = value; } - } - - /// - /// Gets or sets the amount of time lease manager will for this object's - /// sponsors to respond. - /// - /// The amount of time lease manager will for this object's - /// sponsors to respond. - public TimeSpan SponsorshipTimeout - { - get { return sponsorshipTimeout; } - set { sponsorshipTimeout = value; } - } - - #endregion - - #region Methods - - /// - /// Obtains a lifetime service object to control the lifetime policy for this instance. - /// - /// - ///

- /// This method uses property values to configure for this object. - ///

- ///

- /// It is very much inspired by Ingo Rammer's example in Chapter 6 of "Advanced .NET Remoting", - /// but is modified slightly to make it more "Spring-friendly". Basically, the main difference is that - /// instead of pulling lease configuration from the .NET config file, this implementation relies - /// on Spring DI to get appropriate values injected, which makes it much more flexible. - ///

- ///
- /// - /// An object of type used to control the - /// lifetime policy for this instance. This is the current lifetime service object for - /// this instance if one exists; otherwise, a new lifetime service object initialized to the value - /// of the property. - /// - /// The immediate caller does not have infrastructure permission. - public override object InitializeLifetimeService() - { - if (this.isInfinite) - { - return null; - } - - ILease lease = (ILease) base.InitializeLifetimeService(); - if (this.initialLeaseTime != TimeSpan.Zero) - { - lease.InitialLeaseTime = this.initialLeaseTime; - } - if (this.renewOnCallTime != TimeSpan.Zero) - { - lease.RenewOnCallTime = this.renewOnCallTime; - } - if (this.sponsorshipTimeout != TimeSpan.Zero) - { - lease.SponsorshipTimeout = this.sponsorshipTimeout; - } - - return lease; - } - - #endregion - } +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Runtime.Remoting.Lifetime; + +#endregion + +namespace Spring.Remoting.Support +{ + /// + /// This class extends to allow users + /// to define object lifecycle details by simply setting its properties. + /// + /// + ///

+ /// Remoting exporters uses this class as a base proxy class + /// in order to support lifecycle configuration when exporting + /// a remote object. + ///

+ ///
+ /// Aleksandar Seovic + public abstract class BaseRemoteObject : MarshalByRefObject + { + #region Fields + + private bool isInfinite = false; + private TimeSpan initialLeaseTime = TimeSpan.Zero; + private TimeSpan renewOnCallTime = TimeSpan.Zero; + private TimeSpan sponsorshipTimeout = TimeSpan.Zero; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Initializes a new instance of the class. + /// + public BaseRemoteObject() + {} + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether this instance has infinite lifetime. + /// + /// + /// if this instance has infinite lifetime; + /// otherwise, . + /// + public bool IsInfinite + { + get { return isInfinite; } + set { isInfinite = value; } + } + + /// + /// Gets or sets the initial lease time. + /// + /// The initial lease time. + public TimeSpan InitialLeaseTime + { + get { return initialLeaseTime; } + set { initialLeaseTime = value; } + } + + /// + /// Gets or sets the amount of time lease should be + /// extended for on each call to this object. + /// + /// The amount of time lease should be + /// extended for on each call to this object. + public TimeSpan RenewOnCallTime + { + get { return renewOnCallTime; } + set { renewOnCallTime = value; } + } + + /// + /// Gets or sets the amount of time lease manager will for this object's + /// sponsors to respond. + /// + /// The amount of time lease manager will for this object's + /// sponsors to respond. + public TimeSpan SponsorshipTimeout + { + get { return sponsorshipTimeout; } + set { sponsorshipTimeout = value; } + } + + #endregion + + #region Methods + + /// + /// Obtains a lifetime service object to control the lifetime policy for this instance. + /// + /// + ///

+ /// This method uses property values to configure for this object. + ///

+ ///

+ /// It is very much inspired by Ingo Rammer's example in Chapter 6 of "Advanced .NET Remoting", + /// but is modified slightly to make it more "Spring-friendly". Basically, the main difference is that + /// instead of pulling lease configuration from the .NET config file, this implementation relies + /// on Spring DI to get appropriate values injected, which makes it much more flexible. + ///

+ ///
+ /// + /// An object of type used to control the + /// lifetime policy for this instance. This is the current lifetime service object for + /// this instance if one exists; otherwise, a new lifetime service object initialized to the value + /// of the property. + /// + /// The immediate caller does not have infrastructure permission. + public override object InitializeLifetimeService() + { + if (this.isInfinite) + { + return null; + } + + ILease lease = (ILease) base.InitializeLifetimeService(); + if (this.initialLeaseTime != TimeSpan.Zero) + { + lease.InitialLeaseTime = this.initialLeaseTime; + } + if (this.renewOnCallTime != TimeSpan.Zero) + { + lease.RenewOnCallTime = this.renewOnCallTime; + } + if (this.sponsorshipTimeout != TimeSpan.Zero) + { + lease.SponsorshipTimeout = this.sponsorshipTimeout; + } + + return lease; + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Services/Remoting/Support/ConfigurableLifetime.cs b/src/Spring/Spring.Services/Remoting/Support/ConfigurableLifetime.cs index c32cdcc3..8a7877b4 100644 --- a/src/Spring/Spring.Services/Remoting/Support/ConfigurableLifetime.cs +++ b/src/Spring/Spring.Services/Remoting/Support/ConfigurableLifetime.cs @@ -1,95 +1,94 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Remoting.Support -{ - /// - /// Configurable implementation of the interface. - /// - /// Bruno Baia - /// $Id: ConfigurableLifetime.cs,v 1.1 2006/09/13 20:20:16 bbaia Exp $ - public class ConfigurableLifetime : ILifetime - { - #region Fields - - private bool infinite = true; - private TimeSpan initialLeaseTime = TimeSpan.Zero; - private TimeSpan renewOnCallTime = TimeSpan.Zero; - private TimeSpan sponsorshipTimeout = TimeSpan.Zero; - - #endregion - - #region ILifetime Members - - /// - /// Gets or sets a value indicating whether this instance has infinite lifetime. - /// - /// - /// true if this instance has infinite lifetime; otherwise, false. - /// - public bool Infinite - { - get { return infinite; } - set { infinite = value; } - } - - /// - /// Gets or sets the initial lease time. - /// - /// The initial lease time. - public TimeSpan InitialLeaseTime - { - get { return initialLeaseTime; } - set { initialLeaseTime = value; } - } - - /// - /// Gets or sets the amount of time lease - /// should be extended for on each call to this object. - /// - /// The amount of time lease should be - /// extended for on each call to this object. - public TimeSpan RenewOnCallTime - { - get { return renewOnCallTime; } - set { renewOnCallTime = value; } - } - - /// - /// Gets or sets the amount of time lease manager - /// will for this object's sponsors to respond. - /// - /// The amount of time lease manager will for this object's - /// sponsors to respond. - public TimeSpan SponsorshipTimeout - { - get { return sponsorshipTimeout; } - set { sponsorshipTimeout = value; } - } - - #endregion - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Remoting.Support +{ + /// + /// Configurable implementation of the interface. + /// + /// Bruno Baia + public class ConfigurableLifetime : ILifetime + { + #region Fields + + private bool infinite = true; + private TimeSpan initialLeaseTime = TimeSpan.Zero; + private TimeSpan renewOnCallTime = TimeSpan.Zero; + private TimeSpan sponsorshipTimeout = TimeSpan.Zero; + + #endregion + + #region ILifetime Members + + /// + /// Gets or sets a value indicating whether this instance has infinite lifetime. + /// + /// + /// true if this instance has infinite lifetime; otherwise, false. + /// + public bool Infinite + { + get { return infinite; } + set { infinite = value; } + } + + /// + /// Gets or sets the initial lease time. + /// + /// The initial lease time. + public TimeSpan InitialLeaseTime + { + get { return initialLeaseTime; } + set { initialLeaseTime = value; } + } + + /// + /// Gets or sets the amount of time lease + /// should be extended for on each call to this object. + /// + /// The amount of time lease should be + /// extended for on each call to this object. + public TimeSpan RenewOnCallTime + { + get { return renewOnCallTime; } + set { renewOnCallTime = value; } + } + + /// + /// Gets or sets the amount of time lease manager + /// will for this object's sponsors to respond. + /// + /// The amount of time lease manager will for this object's + /// sponsors to respond. + public TimeSpan SponsorshipTimeout + { + get { return sponsorshipTimeout; } + set { sponsorshipTimeout = value; } + } + + #endregion + } +} diff --git a/src/Spring/Spring.Services/Remoting/Support/ICaoRemoteFactory.cs b/src/Spring/Spring.Services/Remoting/Support/ICaoRemoteFactory.cs index 37dbaadc..d5338e00 100644 --- a/src/Spring/Spring.Services/Remoting/Support/ICaoRemoteFactory.cs +++ b/src/Spring/Spring.Services/Remoting/Support/ICaoRemoteFactory.cs @@ -1,63 +1,62 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - - -#endregion - -namespace Spring.Remoting.Support -{ - /// - /// Interface for a CAO based object factory. - /// - /// - ///

- /// Provides a well known location for clients to retrieve - /// references to CAO references. - ///

- ///
- /// Aleksandar Seovic - /// Mark Pollack - /// Bruno Baia - /// $Id: ICaoRemoteFactory.cs,v 1.1 2006/09/13 20:20:16 bbaia Exp $ - public interface ICaoRemoteFactory - { - /// - /// Returns the CAO proxy. - /// - /// The remote object. - object GetObject(); - - /// - /// Returns the CAO proxy using the - /// argument list to call the constructor. - /// - /// - /// The matching of arguments to call the constructor is done - /// by type. The alternative ways, by index and by constructor - /// name are not supported. - /// - /// Constructor - /// arguments used to create the object. - /// The remote object. - object GetObject(object[] constructorArguments); - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + + +#endregion + +namespace Spring.Remoting.Support +{ + /// + /// Interface for a CAO based object factory. + /// + /// + ///

+ /// Provides a well known location for clients to retrieve + /// references to CAO references. + ///

+ ///
+ /// Aleksandar Seovic + /// Mark Pollack + /// Bruno Baia + public interface ICaoRemoteFactory + { + /// + /// Returns the CAO proxy. + /// + /// The remote object. + object GetObject(); + + /// + /// Returns the CAO proxy using the + /// argument list to call the constructor. + /// + /// + /// The matching of arguments to call the constructor is done + /// by type. The alternative ways, by index and by constructor + /// name are not supported. + /// + /// Constructor + /// arguments used to create the object. + /// The remote object. + object GetObject(object[] constructorArguments); + } +} diff --git a/src/Spring/Spring.Services/Remoting/Support/ILifetime.cs b/src/Spring/Spring.Services/Remoting/Support/ILifetime.cs index b94e25c0..8b08f000 100644 --- a/src/Spring/Spring.Services/Remoting/Support/ILifetime.cs +++ b/src/Spring/Spring.Services/Remoting/Support/ILifetime.cs @@ -1,66 +1,65 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -#endregion - -namespace Spring.Remoting.Support -{ - /// - /// Defines lifetime's properties of remote objects that is used by Spring. - /// - /// Bruno Baia - /// $Id: ILifetime.cs,v 1.1 2006/09/13 20:20:16 bbaia Exp $ - public interface ILifetime - { - /// - /// Gets or sets a value indicating whether this instance has infinite lifetime. - /// - /// - /// true if this instance has infinite lifetime; otherwise, false. - /// - bool Infinite { get; } - - /// - /// Gets the initial lease time. - /// - /// The initial lease time. - TimeSpan InitialLeaseTime { get; } - - /// - /// Gets the amount of time lease - /// should be extended for on each call to this object. - /// - /// The amount of time lease should be - /// extended for on each call to this object. - TimeSpan RenewOnCallTime { get; } - - /// - /// Gets the amount of time lease manager - /// will for this object's sponsors to respond. - /// - /// The amount of time lease manager will for this object's - /// sponsors to respond. - TimeSpan SponsorshipTimeout { get; } - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +#endregion + +namespace Spring.Remoting.Support +{ + /// + /// Defines lifetime's properties of remote objects that is used by Spring. + /// + /// Bruno Baia + public interface ILifetime + { + /// + /// Gets or sets a value indicating whether this instance has infinite lifetime. + /// + /// + /// true if this instance has infinite lifetime; otherwise, false. + /// + bool Infinite { get; } + + /// + /// Gets the initial lease time. + /// + /// The initial lease time. + TimeSpan InitialLeaseTime { get; } + + /// + /// Gets the amount of time lease + /// should be extended for on each call to this object. + /// + /// The amount of time lease should be + /// extended for on each call to this object. + TimeSpan RenewOnCallTime { get; } + + /// + /// Gets the amount of time lease manager + /// will for this object's sponsors to respond. + /// + /// The amount of time lease manager will for this object's + /// sponsors to respond. + TimeSpan SponsorshipTimeout { get; } + } +} diff --git a/src/Spring/Spring.Services/Remoting/Support/RemoteObjectProxyTypeBuilder.cs b/src/Spring/Spring.Services/Remoting/Support/RemoteObjectProxyTypeBuilder.cs index 89c857f6..b102b079 100644 --- a/src/Spring/Spring.Services/Remoting/Support/RemoteObjectProxyTypeBuilder.cs +++ b/src/Spring/Spring.Services/Remoting/Support/RemoteObjectProxyTypeBuilder.cs @@ -1,177 +1,176 @@ -#region License - -/* - * Copyright 2002-2004 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Proxy; - -#endregion - -namespace Spring.Remoting.Support -{ - /// - /// Builds a proxy type based on to wrap a target object - /// that is intended to be remotable. - /// - /// Bruno Baia - /// $Id: RemoteObjectProxyTypeBuilder.cs,v 1.3 2006/11/12 01:37:47 bbaia Exp $ - internal class RemoteObjectProxyTypeBuilder : CompositionProxyTypeBuilder - { - #region Fields - - private static readonly MethodInfo TimeSpan_FromTicks = - typeof(TimeSpan).GetMethod("FromTicks", BindingFlags.Public | BindingFlags.Static); - - private static readonly MethodInfo BaseRemoteObject_IsInfinite = - typeof(BaseRemoteObject).GetMethod("set_IsInfinite", BindingFlags.Public | BindingFlags.Instance); - - private static readonly MethodInfo BaseRemoteObject_InitialLeaseTime = - typeof(BaseRemoteObject).GetMethod("set_InitialLeaseTime", BindingFlags.Public | BindingFlags.Instance); - - private static readonly MethodInfo BaseRemoteObject_RenewOnCallTime = - typeof(BaseRemoteObject).GetMethod("set_RenewOnCallTime", BindingFlags.Public | BindingFlags.Instance); - - private static readonly MethodInfo BaseRemoteObject_SponsorshipTimeout = - typeof(BaseRemoteObject).GetMethod("set_SponsorshipTimeout", BindingFlags.Public | BindingFlags.Instance); - - private ILifetime lifetime; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// - /// The lifetime properties to be applied to the target object. - /// - public RemoteObjectProxyTypeBuilder(ILifetime lifetime) - { - this.lifetime = lifetime; - - Name = "RemoteObjectProxy"; - } - - #endregion - - #region IProxyTypeBuilder Members - - /// - /// Creates a remotable proxy type based on . - /// - /// The generated proxy class. - /// - /// If the is not - /// an instance of . - /// - public override Type BuildProxyType() - { - if (!typeof(BaseRemoteObject).IsAssignableFrom(this.BaseType)) - { - throw new ArgumentException( - "BaseRemoteObject cannot be assigned from BaseType.", "BaseType"); - } - - return base.BuildProxyType(); - } - - #endregion - - #region Protected Methods - - /// - /// Implements constructors for the proxy class. - /// - /// - /// The to use. - /// - protected override void ImplementConstructors(TypeBuilder builder) - { - MethodAttributes attributes = MethodAttributes.Public | - MethodAttributes.HideBySig | MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - ConstructorBuilder cb = builder.DefineConstructor(attributes, - CallingConventions.Standard, - new Type[1] { TargetType }); - - ILGenerator il = cb.GetILGenerator(); - - GenerateRemoteObjectLifetimeInitialization(il); - - PushProxy(il); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Stfld, targetInstance); - - il.Emit(OpCodes.Ret); - } - - /// - /// Generate initialization code for 's lifetime properties. - /// - /// ILGenerator - protected void GenerateRemoteObjectLifetimeInitialization(ILGenerator il) - { - // Set IsInfinite Property - if (this.lifetime.Infinite) - { - PushProxy(il); - il.Emit(OpCodes.Ldc_I4_1); // true - il.Emit(OpCodes.Call, BaseRemoteObject_IsInfinite); - } - else - { - // Set InitialLeaseTime Property - if (this.lifetime.InitialLeaseTime != TimeSpan.Zero) - { - PushProxy(il); - il.Emit(OpCodes.Ldc_I8, this.lifetime.InitialLeaseTime.Ticks); - il.Emit(OpCodes.Call, TimeSpan_FromTicks); - il.Emit(OpCodes.Call, BaseRemoteObject_InitialLeaseTime); - } - - // Set RenewOnCallTime Property - if (this.lifetime.RenewOnCallTime != TimeSpan.Zero) - { - PushProxy(il); - il.Emit(OpCodes.Ldc_I8, this.lifetime.RenewOnCallTime.Ticks); - il.Emit(OpCodes.Call, TimeSpan_FromTicks); - il.Emit(OpCodes.Call, BaseRemoteObject_RenewOnCallTime); - } - - // Set SponsorshipTimeout Property - if (this.lifetime.SponsorshipTimeout != TimeSpan.Zero) - { - PushProxy(il); - il.Emit(OpCodes.Ldc_I8, this.lifetime.SponsorshipTimeout.Ticks); - il.Emit(OpCodes.Call, TimeSpan_FromTicks); - il.Emit(OpCodes.Call, BaseRemoteObject_SponsorshipTimeout); - } - } - } - - #endregion - } -} +#region License + +/* + * Copyright 2002-2004 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Proxy; + +#endregion + +namespace Spring.Remoting.Support +{ + /// + /// Builds a proxy type based on to wrap a target object + /// that is intended to be remotable. + /// + /// Bruno Baia + internal class RemoteObjectProxyTypeBuilder : CompositionProxyTypeBuilder + { + #region Fields + + private static readonly MethodInfo TimeSpan_FromTicks = + typeof(TimeSpan).GetMethod("FromTicks", BindingFlags.Public | BindingFlags.Static); + + private static readonly MethodInfo BaseRemoteObject_IsInfinite = + typeof(BaseRemoteObject).GetMethod("set_IsInfinite", BindingFlags.Public | BindingFlags.Instance); + + private static readonly MethodInfo BaseRemoteObject_InitialLeaseTime = + typeof(BaseRemoteObject).GetMethod("set_InitialLeaseTime", BindingFlags.Public | BindingFlags.Instance); + + private static readonly MethodInfo BaseRemoteObject_RenewOnCallTime = + typeof(BaseRemoteObject).GetMethod("set_RenewOnCallTime", BindingFlags.Public | BindingFlags.Instance); + + private static readonly MethodInfo BaseRemoteObject_SponsorshipTimeout = + typeof(BaseRemoteObject).GetMethod("set_SponsorshipTimeout", BindingFlags.Public | BindingFlags.Instance); + + private ILifetime lifetime; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// + /// The lifetime properties to be applied to the target object. + /// + public RemoteObjectProxyTypeBuilder(ILifetime lifetime) + { + this.lifetime = lifetime; + + Name = "RemoteObjectProxy"; + } + + #endregion + + #region IProxyTypeBuilder Members + + /// + /// Creates a remotable proxy type based on . + /// + /// The generated proxy class. + /// + /// If the is not + /// an instance of . + /// + public override Type BuildProxyType() + { + if (!typeof(BaseRemoteObject).IsAssignableFrom(this.BaseType)) + { + throw new ArgumentException( + "BaseRemoteObject cannot be assigned from BaseType.", "BaseType"); + } + + return base.BuildProxyType(); + } + + #endregion + + #region Protected Methods + + /// + /// Implements constructors for the proxy class. + /// + /// + /// The to use. + /// + protected override void ImplementConstructors(TypeBuilder builder) + { + MethodAttributes attributes = MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName; + ConstructorBuilder cb = builder.DefineConstructor(attributes, + CallingConventions.Standard, + new Type[1] { TargetType }); + + ILGenerator il = cb.GetILGenerator(); + + GenerateRemoteObjectLifetimeInitialization(il); + + PushProxy(il); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Stfld, targetInstance); + + il.Emit(OpCodes.Ret); + } + + /// + /// Generate initialization code for 's lifetime properties. + /// + /// ILGenerator + protected void GenerateRemoteObjectLifetimeInitialization(ILGenerator il) + { + // Set IsInfinite Property + if (this.lifetime.Infinite) + { + PushProxy(il); + il.Emit(OpCodes.Ldc_I4_1); // true + il.Emit(OpCodes.Call, BaseRemoteObject_IsInfinite); + } + else + { + // Set InitialLeaseTime Property + if (this.lifetime.InitialLeaseTime != TimeSpan.Zero) + { + PushProxy(il); + il.Emit(OpCodes.Ldc_I8, this.lifetime.InitialLeaseTime.Ticks); + il.Emit(OpCodes.Call, TimeSpan_FromTicks); + il.Emit(OpCodes.Call, BaseRemoteObject_InitialLeaseTime); + } + + // Set RenewOnCallTime Property + if (this.lifetime.RenewOnCallTime != TimeSpan.Zero) + { + PushProxy(il); + il.Emit(OpCodes.Ldc_I8, this.lifetime.RenewOnCallTime.Ticks); + il.Emit(OpCodes.Call, TimeSpan_FromTicks); + il.Emit(OpCodes.Call, BaseRemoteObject_RenewOnCallTime); + } + + // Set SponsorshipTimeout Property + if (this.lifetime.SponsorshipTimeout != TimeSpan.Zero) + { + PushProxy(il); + il.Emit(OpCodes.Ldc_I8, this.lifetime.SponsorshipTimeout.Ticks); + il.Emit(OpCodes.Call, TimeSpan_FromTicks); + il.Emit(OpCodes.Call, BaseRemoteObject_SponsorshipTimeout); + } + } + } + + #endregion + } +} diff --git a/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactory.cs b/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactory.cs index 0e369b7e..2e24babb 100644 --- a/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactory.cs +++ b/src/Spring/Spring.Services/ServiceModel/Activation/ServiceHostFactory.cs @@ -1,78 +1,77 @@ -#if NET_3_0 -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.ServiceModel; -using System.ServiceModel.Activation; - -using Spring.Util; - -#endregion - -namespace Spring.ServiceModel.Activation -{ - /// - /// Factory that provides instances of - /// to host objects created by Spring's IoC container. - /// - /// Bruno Baia - /// $Id: ServiceHostFactory.cs,v 1.2 2007/05/18 21:04:37 bbaia Exp $ - public class ServiceHostFactory : ServiceHostFactoryBase - { - /// - /// Creates a for - /// a specified Spring-managed object with a specific base address. - /// - /// - /// A reference to a Spring-managed object 'contextName:objectName'. - /// - /// - /// The of type that contains - /// the base addresses for the service hosted. - /// - /// - /// A for the Spring-managed object. - /// - /// - /// If the Service attribute in the ServiceHost directive was not provided. - /// - public override ServiceHostBase CreateServiceHost(string reference, Uri[] baseAddresses) - { - if (StringUtils.IsNullOrEmpty(reference)) - { - throw new ArgumentException("The service name was not provided in the ServiceHost directive.", "Service"); - } - - string[] refSplitted = reference.Split(':'); - if (refSplitted.Length == 2) - { - return new ServiceHost(refSplitted[0], refSplitted[1], baseAddresses); - } - else - { - return new ServiceHost(reference, baseAddresses); - } - } - } -} +#if NET_3_0 +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.ServiceModel; +using System.ServiceModel.Activation; + +using Spring.Util; + +#endregion + +namespace Spring.ServiceModel.Activation +{ + /// + /// Factory that provides instances of + /// to host objects created by Spring's IoC container. + /// + /// Bruno Baia + public class ServiceHostFactory : ServiceHostFactoryBase + { + /// + /// Creates a for + /// a specified Spring-managed object with a specific base address. + /// + /// + /// A reference to a Spring-managed object 'contextName:objectName'. + /// + /// + /// The of type that contains + /// the base addresses for the service hosted. + /// + /// + /// A for the Spring-managed object. + /// + /// + /// If the Service attribute in the ServiceHost directive was not provided. + /// + public override ServiceHostBase CreateServiceHost(string reference, Uri[] baseAddresses) + { + if (StringUtils.IsNullOrEmpty(reference)) + { + throw new ArgumentException("The service name was not provided in the ServiceHost directive.", "Service"); + } + + string[] refSplitted = reference.Split(':'); + if (refSplitted.Length == 2) + { + return new ServiceHost(refSplitted[0], refSplitted[1], baseAddresses); + } + else + { + return new ServiceHost(reference, baseAddresses); + } + } + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Services/ServiceModel/ServiceExporter.cs b/src/Spring/Spring.Services/ServiceModel/ServiceExporter.cs index bf3449dd..c8221a11 100644 --- a/src/Spring/Spring.Services/ServiceModel/ServiceExporter.cs +++ b/src/Spring/Spring.Services/ServiceModel/ServiceExporter.cs @@ -1,222 +1,221 @@ -#if NET_3_0 -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; - -using Spring.Util; -using Spring.Context; -using Spring.Core.TypeResolution; -using Spring.Objects; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Support; -using Spring.ServiceModel.Support; -using Spring.Context.Support; -using Spring.Proxy; - -#endregion - -namespace Spring.ServiceModel -{ - /// - /// Registers an object type on the server as a WCF service. - /// - /// Bruno Baia - /// $Id: ServiceExporter.cs,v 1.2 2007/09/21 14:26:26 bbaia Exp $ - public class ServiceExporter : IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable - { - #region Logging - - private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(ServiceExporter)); - - #endregion - - #region Fields - - private string targetName; - private string[] _contracts; - private IList _typeAttributes = new ArrayList(); - private IDictionary _memberAttributes = new Hashtable(); - - private IApplicationContext applicationContext; - private AbstractObjectFactory objectFactory; - - private System.ServiceModel.ServiceHost serviceHost; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the class. - /// - public ServiceExporter() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets the name of the target object definition. - /// - public string TargetName - { - get { return targetName; } - set { targetName = value; } - } - - /// - /// Gets or sets the list of service contracts. - /// - /// - /// If not set, all the interfaces implemented or inherited - /// by the target type will be used. - /// - /// The interfaces. - public string[] Contracts - { - get { return _contracts; } - set { _contracts = value; } - } - - /// - /// Gets or sets a list of custom attributes - /// that should be applied to the WCF service class. - /// - public IList TypeAttributes - { - get { return _typeAttributes; } - set { _typeAttributes = value; } - } - - /// - /// Gets or sets a dictionary of custom attributes - /// that should be applied to the WCF service members. - /// - /// - /// Dictionary key is an expression that members can be matched against. - /// Value is a list of attributes that should be applied - /// to each member that matches expression. - /// - public IDictionary MemberAttributes - { - get { return _memberAttributes; } - set { _memberAttributes = value; } - } - - #endregion - - #region IApplicationContextAware Members - - /// - /// Gets or sets the that this - /// object runs in. - /// - public IApplicationContext ApplicationContext - { - get { return applicationContext; } - set { applicationContext = value; } - } - - #endregion - - #region IObjectFactoryAware Members - - /// - /// Sets object factory to use. - /// - public IObjectFactory ObjectFactory - { - set { objectFactory = (AbstractObjectFactory) value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Publish the object - /// - public void AfterPropertiesSet() - { - ValidateConfiguration(); - Export(); - } - - #endregion - - #region IDisposable Members - - /// - /// Closes the service host. - /// - public void Dispose() - { - serviceHost.Close(); - } - - #endregion - - #region Private Methods - - private void ValidateConfiguration() - { - if (TargetName == null) - { - throw new ArgumentException("The TargetName property is required."); - } - } - - private void Export() - { - string contextName = (applicationContext.Name == AbstractApplicationContext.DefaultRootContextName) ? null : applicationContext.Name; - Type targetType = objectFactory.GetType(targetName); - IProxyTypeBuilder builder = new ServiceProxyTypeBuilder(contextName, targetName, targetType); - if (Contracts != null && Contracts.Length > 0) - { - builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(Contracts); - } - builder.TypeAttributes = TypeAttributes; - builder.MemberAttributes = MemberAttributes; - - Type serviceType = builder.BuildProxyType(); - - serviceHost = new System.ServiceModel.ServiceHost(serviceType); - serviceHost.Open(); - - #region Instrumentation - - if (LOG.IsDebugEnabled) - { - LOG.Debug(String.Format("The service '{0}' is ready and can now be accessed.", targetName)); - } - - #endregion - } - - #endregion - } -} +#if NET_3_0 +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; + +using Spring.Util; +using Spring.Context; +using Spring.Core.TypeResolution; +using Spring.Objects; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Support; +using Spring.ServiceModel.Support; +using Spring.Context.Support; +using Spring.Proxy; + +#endregion + +namespace Spring.ServiceModel +{ + /// + /// Registers an object type on the server as a WCF service. + /// + /// Bruno Baia + public class ServiceExporter : IApplicationContextAware, IObjectFactoryAware, IInitializingObject, IDisposable + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(ServiceExporter)); + + #endregion + + #region Fields + + private string targetName; + private string[] _contracts; + private IList _typeAttributes = new ArrayList(); + private IDictionary _memberAttributes = new Hashtable(); + + private IApplicationContext applicationContext; + private AbstractObjectFactory objectFactory; + + private System.ServiceModel.ServiceHost serviceHost; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the class. + /// + public ServiceExporter() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the name of the target object definition. + /// + public string TargetName + { + get { return targetName; } + set { targetName = value; } + } + + /// + /// Gets or sets the list of service contracts. + /// + /// + /// If not set, all the interfaces implemented or inherited + /// by the target type will be used. + /// + /// The interfaces. + public string[] Contracts + { + get { return _contracts; } + set { _contracts = value; } + } + + /// + /// Gets or sets a list of custom attributes + /// that should be applied to the WCF service class. + /// + public IList TypeAttributes + { + get { return _typeAttributes; } + set { _typeAttributes = value; } + } + + /// + /// Gets or sets a dictionary of custom attributes + /// that should be applied to the WCF service members. + /// + /// + /// Dictionary key is an expression that members can be matched against. + /// Value is a list of attributes that should be applied + /// to each member that matches expression. + /// + public IDictionary MemberAttributes + { + get { return _memberAttributes; } + set { _memberAttributes = value; } + } + + #endregion + + #region IApplicationContextAware Members + + /// + /// Gets or sets the that this + /// object runs in. + /// + public IApplicationContext ApplicationContext + { + get { return applicationContext; } + set { applicationContext = value; } + } + + #endregion + + #region IObjectFactoryAware Members + + /// + /// Sets object factory to use. + /// + public IObjectFactory ObjectFactory + { + set { objectFactory = (AbstractObjectFactory) value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Publish the object + /// + public void AfterPropertiesSet() + { + ValidateConfiguration(); + Export(); + } + + #endregion + + #region IDisposable Members + + /// + /// Closes the service host. + /// + public void Dispose() + { + serviceHost.Close(); + } + + #endregion + + #region Private Methods + + private void ValidateConfiguration() + { + if (TargetName == null) + { + throw new ArgumentException("The TargetName property is required."); + } + } + + private void Export() + { + string contextName = (applicationContext.Name == AbstractApplicationContext.DefaultRootContextName) ? null : applicationContext.Name; + Type targetType = objectFactory.GetType(targetName); + IProxyTypeBuilder builder = new ServiceProxyTypeBuilder(contextName, targetName, targetType); + if (Contracts != null && Contracts.Length > 0) + { + builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(Contracts); + } + builder.TypeAttributes = TypeAttributes; + builder.MemberAttributes = MemberAttributes; + + Type serviceType = builder.BuildProxyType(); + + serviceHost = new System.ServiceModel.ServiceHost(serviceType); + serviceHost.Open(); + + #region Instrumentation + + if (LOG.IsDebugEnabled) + { + LOG.Debug(String.Format("The service '{0}' is ready and can now be accessed.", targetName)); + } + + #endregion + } + + #endregion + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Services/ServiceModel/ServiceHost.cs b/src/Spring/Spring.Services/ServiceModel/ServiceHost.cs index 23224a0b..da2405c2 100644 --- a/src/Spring/Spring.Services/ServiceModel/ServiceHost.cs +++ b/src/Spring/Spring.Services/ServiceModel/ServiceHost.cs @@ -1,97 +1,96 @@ -#if NET_3_0 -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; - -using Spring.Util; -using Spring.Context; -using Spring.Context.Support; -using Spring.ServiceModel.Support; - -#endregion - -namespace Spring.ServiceModel -{ - /// - /// Provides a host for Spring-managed services. - /// - /// Bruno Baia - /// $Id: ServiceHost.cs,v 1.1 2007/05/18 21:04:37 bbaia Exp $ - public class ServiceHost : System.ServiceModel.ServiceHost - { - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the class. - /// - /// The name of the service within Spring's IoC container. - /// The base addresses for the hosted service. - public ServiceHost(string serviceName, params Uri[] baseAddresses) - : this(null, serviceName, baseAddresses) - { - } - - /// - /// Creates a new instance of the class. - /// - /// The name of the context to use. - /// The name of the service within Spring's IoC container. - /// The base addresses for the hosted service. - public ServiceHost(string contextName, string serviceName, params Uri[] baseAddresses) - : base(CreateServiceType(contextName, serviceName), baseAddresses) - { - } - - private static Type CreateServiceType(string contextName, string serviceName) - { - if (StringUtils.IsNullOrEmpty(serviceName)) - { - throw new ArgumentException("The service name cannot be null or an empty string.", "serviceName"); - } - - IApplicationContext ctx; - if (StringUtils.IsNullOrEmpty(contextName)) - { - ctx = ContextRegistry.GetContext(); - if (ctx == null) - { - throw new ArgumentException("No context registered."); - } - } - else - { - ctx = ContextRegistry.GetContext(contextName); - if (ctx == null) - { - throw new ArgumentException(string.Format("Context '{0}' is not registered.", contextName)); - } - } - Type serviceType = ctx.GetType(serviceName); - - return new ServiceProxyTypeBuilder(contextName, serviceName, serviceType).BuildProxyType(); - } - - #endregion - } -} +#if NET_3_0 +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; + +using Spring.Util; +using Spring.Context; +using Spring.Context.Support; +using Spring.ServiceModel.Support; + +#endregion + +namespace Spring.ServiceModel +{ + /// + /// Provides a host for Spring-managed services. + /// + /// Bruno Baia + public class ServiceHost : System.ServiceModel.ServiceHost + { + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the class. + /// + /// The name of the service within Spring's IoC container. + /// The base addresses for the hosted service. + public ServiceHost(string serviceName, params Uri[] baseAddresses) + : this(null, serviceName, baseAddresses) + { + } + + /// + /// Creates a new instance of the class. + /// + /// The name of the context to use. + /// The name of the service within Spring's IoC container. + /// The base addresses for the hosted service. + public ServiceHost(string contextName, string serviceName, params Uri[] baseAddresses) + : base(CreateServiceType(contextName, serviceName), baseAddresses) + { + } + + private static Type CreateServiceType(string contextName, string serviceName) + { + if (StringUtils.IsNullOrEmpty(serviceName)) + { + throw new ArgumentException("The service name cannot be null or an empty string.", "serviceName"); + } + + IApplicationContext ctx; + if (StringUtils.IsNullOrEmpty(contextName)) + { + ctx = ContextRegistry.GetContext(); + if (ctx == null) + { + throw new ArgumentException("No context registered."); + } + } + else + { + ctx = ContextRegistry.GetContext(contextName); + if (ctx == null) + { + throw new ArgumentException(string.Format("Context '{0}' is not registered.", contextName)); + } + } + Type serviceType = ctx.GetType(serviceName); + + return new ServiceProxyTypeBuilder(contextName, serviceName, serviceType).BuildProxyType(); + } + + #endregion + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Services/ServiceModel/Support/ServiceProxyTypeBuilder.cs b/src/Spring/Spring.Services/ServiceModel/Support/ServiceProxyTypeBuilder.cs index 5dbd1730..ae76bb40 100644 --- a/src/Spring/Spring.Services/ServiceModel/Support/ServiceProxyTypeBuilder.cs +++ b/src/Spring/Spring.Services/ServiceModel/Support/ServiceProxyTypeBuilder.cs @@ -1,137 +1,136 @@ -#if NET_3_0 -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Reflection; -using System.Reflection.Emit; - -using Spring.Proxy; -using Spring.Context; -using Spring.Context.Support; -using Spring.Objects.Factory; - -#endregion - -namespace Spring.ServiceModel.Support -{ - /// - /// Builds a WCF service type. - /// - /// Bruno Baia - /// $Id: ServiceProxyTypeBuilder.cs,v 1.1 2007/05/18 21:04:37 bbaia Exp $ - public class ServiceProxyTypeBuilder : CompositionProxyTypeBuilder - { - #region Fields - - private static readonly MethodInfo GetObject = - typeof(IObjectFactory).GetMethod("GetObject", new Type[] { typeof(string) }); - - private static readonly MethodInfo GetContext = - typeof(ContextRegistry).GetMethod("GetContext", Type.EmptyTypes); - - private static readonly MethodInfo GetContextByName = - typeof(ContextRegistry).GetMethod("GetContext", new Type[] { typeof(string) }); - - private string contextName; - private string serviceName; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// The name of the context to use. - /// The name of the service within Spring's IoC container. - /// The type of the service. - public ServiceProxyTypeBuilder(string contextName, string serviceName, Type serviceType) - { - this.contextName = contextName; - this.serviceName = serviceName; - - this.Name = (contextName == null) ? serviceName : contextName + "." + serviceName; - this.TargetType = serviceType; - } - - #endregion - - #region Protected Methods - - /// - /// Implements constructors for the proxy class. - /// - /// - /// This implementation generates a constructor - /// that gets instance of the target object using - /// . - /// - /// - /// The builder to use. - /// - protected override void ImplementConstructors(TypeBuilder builder) - { - MethodAttributes attributes = MethodAttributes.Public | - MethodAttributes.HideBySig | MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - - ConstructorBuilder cb = builder.DefineConstructor( - attributes, CallingConventions.Standard, Type.EmptyTypes); - - ILGenerator il = cb.GetILGenerator(); - - il.Emit(OpCodes.Ldarg_0); - if (contextName == null) - { - // call ContextRegistry.GetContext() - il.EmitCall(OpCodes.Call, GetContext, null); - } - else - { - // call ContextRegistry.GetContext(contextName) - il.Emit(OpCodes.Ldstr, contextName); - il.EmitCall(OpCodes.Call, GetContextByName, null); - } - il.Emit(OpCodes.Ldstr, serviceName); - il.EmitCall(OpCodes.Callvirt, GetObject, null); - il.Emit(OpCodes.Stfld, targetInstance); - - il.Emit(OpCodes.Ret); - } - - /// - /// Creates an appropriate type builder. - /// - /// The name to use for the proxy type name. - /// The type to extends if provided. - /// The type builder to use. - protected override TypeBuilder CreateTypeBuilder(string name, Type baseType) - { - return DynamicProxyManager.CreateTypeBuilder(name, baseType); - } - - #endregion - } -} +#if NET_3_0 +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Reflection; +using System.Reflection.Emit; + +using Spring.Proxy; +using Spring.Context; +using Spring.Context.Support; +using Spring.Objects.Factory; + +#endregion + +namespace Spring.ServiceModel.Support +{ + /// + /// Builds a WCF service type. + /// + /// Bruno Baia + public class ServiceProxyTypeBuilder : CompositionProxyTypeBuilder + { + #region Fields + + private static readonly MethodInfo GetObject = + typeof(IObjectFactory).GetMethod("GetObject", new Type[] { typeof(string) }); + + private static readonly MethodInfo GetContext = + typeof(ContextRegistry).GetMethod("GetContext", Type.EmptyTypes); + + private static readonly MethodInfo GetContextByName = + typeof(ContextRegistry).GetMethod("GetContext", new Type[] { typeof(string) }); + + private string contextName; + private string serviceName; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// The name of the context to use. + /// The name of the service within Spring's IoC container. + /// The type of the service. + public ServiceProxyTypeBuilder(string contextName, string serviceName, Type serviceType) + { + this.contextName = contextName; + this.serviceName = serviceName; + + this.Name = (contextName == null) ? serviceName : contextName + "." + serviceName; + this.TargetType = serviceType; + } + + #endregion + + #region Protected Methods + + /// + /// Implements constructors for the proxy class. + /// + /// + /// This implementation generates a constructor + /// that gets instance of the target object using + /// . + /// + /// + /// The builder to use. + /// + protected override void ImplementConstructors(TypeBuilder builder) + { + MethodAttributes attributes = MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName; + + ConstructorBuilder cb = builder.DefineConstructor( + attributes, CallingConventions.Standard, Type.EmptyTypes); + + ILGenerator il = cb.GetILGenerator(); + + il.Emit(OpCodes.Ldarg_0); + if (contextName == null) + { + // call ContextRegistry.GetContext() + il.EmitCall(OpCodes.Call, GetContext, null); + } + else + { + // call ContextRegistry.GetContext(contextName) + il.Emit(OpCodes.Ldstr, contextName); + il.EmitCall(OpCodes.Call, GetContextByName, null); + } + il.Emit(OpCodes.Ldstr, serviceName); + il.EmitCall(OpCodes.Callvirt, GetObject, null); + il.Emit(OpCodes.Stfld, targetInstance); + + il.Emit(OpCodes.Ret); + } + + /// + /// Creates an appropriate type builder. + /// + /// The name to use for the proxy type name. + /// The type to extends if provided. + /// The type builder to use. + protected override TypeBuilder CreateTypeBuilder(string name, Type baseType) + { + return DynamicProxyManager.CreateTypeBuilder(name, baseType); + } + + #endregion + } +} #endif \ No newline at end of file diff --git a/src/Spring/Spring.Services/Web/Services/WebServiceProxyFactory.cs b/src/Spring/Spring.Services/Web/Services/WebServiceProxyFactory.cs index e3643fcd..844ea30e 100644 --- a/src/Spring/Spring.Services/Web/Services/WebServiceProxyFactory.cs +++ b/src/Spring/Spring.Services/Web/Services/WebServiceProxyFactory.cs @@ -1,1178 +1,1177 @@ -#region License - -/* - * Copyright © 2002-2007 the original author or authors. - * - * 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. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Xml; -using System.Xml.Schema; -using System.Xml.Serialization; -using System.Net; -using System.Reflection; -using System.Reflection.Emit; -using System.Web.Services; -using System.Web.Services.Description; -using System.Web.Services.Protocols; -using System.Web.Services.Discovery; - -using Spring.Core; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Proxy; -using Spring.Util; -using Spring.Objects; -using Spring.Core.IO; -using Spring.Expressions; - -#endregion - -namespace Spring.Web.Services -{ - /// - /// Factory Object that dynamically implements service interface for web service. - /// - /// - ///

- /// This factory object should be used to obtain reference to a web service - /// that can be safely cast to a service interface, which allows client code to code - /// against interface, and not directly against the web service. - ///

- ///

- /// The WSDL contract needs to conform to WS-I Basic Profiles. - ///

- ///
- /// Bruno Baia - /// Aleksandar Seovic - /// $Id: WebServiceProxyFactory.cs,v 1.33 2008/02/24 19:10:12 bbaia Exp $ - public class WebServiceProxyFactory : IConfigurableFactoryObject, IInitializingObject - { - #region Logging - - private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(WebServiceProxyFactory)); - - #endregion - - #region Fields - - private IObjectDefinition _productTemplate; - private Type _webServiceProxyBaseType = typeof(SoapHttpClientProtocol); - private IResource _serviceUri; - private Type _proxyType; - private Type _serviceInterface; - private NetworkCredential _credential; - private string _proxyUrl; - private NetworkCredential _proxyCredential; - private string _bindingName; - private IList _typeAttributes = new ArrayList(); - private IDictionary _memberAttributes = new Hashtable(); - - /// - /// The web service proxy default constructor. - /// - protected ConstructorInfo proxyConstructor; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public WebServiceProxyFactory() - { - } - - #endregion - - #region Properties - - /// - /// Gets or sets the base type that web service proxy should inherit. - /// - /// - /// Default is - /// - [Obsolete("This property is obsolete, it has been replaced by WebServiceProxyBaseType")] - public Type ClientProtocolType - { - get { return _webServiceProxyBaseType; } - set { _webServiceProxyBaseType = value; } - } - - /// - /// Gets or sets the base type that web service proxy should inherit. - /// - /// - /// Default is - /// - public Type WebServiceProxyBaseType - { - get { return _webServiceProxyBaseType; } - set { _webServiceProxyBaseType = value; } - } - - /// - /// Gets or sets the URI for an - /// that contains the web service description (WSDL). - /// - public IResource ServiceUri - { - get { return _serviceUri; } - set { _serviceUri = value; } - } - - /// - /// Gets or sets type of the proxy class to wrap. - /// - public Type ProxyType - { - get { return _proxyType; } - set { _proxyType = value; } - } - - /// - /// Gets or sets service interface that proxy should implement. - /// - public Type ServiceInterface - { - get { return _serviceInterface; } - set { _serviceInterface = value; } - } - - /// - /// Gets or sets the instance - /// to use when connecting to a server that requires authentication. - /// - public NetworkCredential Credential - { - get { return _credential; } - set { _credential = value; } - } - - /// - /// Gets or sets the url of the proxy server to use for retrieving the WSDL. - /// - /// - ///

- /// This only applies when using an as uri. - ///

- ///

- /// The default is to use the system proxy setting. - ///

- ///
- public string ProxyUrl - { - get { return _proxyUrl; } - set { _proxyUrl = value; } - } - - /// - /// Gets or sets the instance - /// to use when connecting to a proxy server that requires authentication. - /// - /// - ///

- /// This only applies when using an as uri. - ///

- ///
- public NetworkCredential ProxyCredential - { - get { return _proxyCredential; } - set { _proxyCredential = value; } - } - - /// - /// Gets or sets the web service binding name to use for the proxy. - /// - public string BindingName - { - get { return _bindingName; } - set { _bindingName = value; } - } - - /// - /// Gets or sets a list of custom attributes - /// that should be applied to a proxy class. - /// - public IList TypeAttributes - { - get { return _typeAttributes; } - set { _typeAttributes = value; } - } - - /// - /// Gets or sets a dictionary of custom attributes - /// that should be applied to web service members. - /// - /// - /// Dictionary key is an expression that members can be matched against. - /// Value is a list of attributes that should be applied - /// to each member that matches expression. - /// - public IDictionary MemberAttributes - { - get { return _memberAttributes; } - set { _memberAttributes = value; } - } - - #endregion - - #region IConfigurableFactoryObject Members - - /// - /// Returns type of the web service proxy. - /// - public virtual Type ObjectType - { - get { return (proxyConstructor != null ? proxyConstructor.DeclaringType : ServiceInterface); } - } - - /// - /// Creates new instance of the web service proxy. - /// - /// New instance of the web service proxy. - public virtual object GetObject() - { - if (proxyConstructor == null) - { - GenerateProxy(); - } - - return ObjectUtils.InstantiateType(proxyConstructor, ObjectUtils.EmptyObjects); - } - - /// - /// Always returns false. - /// - public virtual bool IsSingleton - { - get { return false; } - } - - /// - /// Gets or sets the template object definition - /// that should be used to configure proxy instance. - /// - public virtual IObjectDefinition ProductTemplate - { - get { return _productTemplate; } - set { _productTemplate = value; } - } - - #endregion - - #region IInitializingObject Members - - /// - /// Initializes factory object. - /// - public virtual void AfterPropertiesSet() - { - ValidateConfiguration(); - } - - #endregion - - #region Protected Methods - - /// - /// Validates the configuration. - /// - protected virtual void ValidateConfiguration() - { - if (ServiceUri == null && ProxyType == null) - { - throw new ArgumentException("ServiceUri or ProxyType property is required."); - } - if (ServiceInterface == null) - { - throw new ArgumentException("The ServiceInterface property is required."); - } - if (!ServiceInterface.IsInterface) - { - throw new ArgumentException("ServiceInterface must be an interface"); - } - if (WebServiceProxyBaseType.IsSealed) - { - throw new ArgumentException("Web service client proxy cannot be created for a sealed class [" + WebServiceProxyBaseType.FullName + "]"); - } - } - - /// - /// Generates the web service proxy type. - /// - protected virtual void GenerateProxy() - { - IProxyTypeBuilder builder; - if (ProxyType != null) - { - // Wrap .NET generated proxy class or another - builder = new WebServiceProxyProxyTypeBuilder(); - builder.TargetType = ProxyType; - } - else - { - // Dynamically generates proxy class from WSDL - builder = new SoapHttpClientProxyTypeBuilder( - ServiceUri, GetWsDocuments(ServiceUri), BindingName); - builder.BaseType = WebServiceProxyBaseType; - } - - builder.Interfaces = ReflectionUtils.ToInterfaceArray(ServiceInterface); - builder.TypeAttributes = TypeAttributes; - builder.MemberAttributes = MemberAttributes; - - Type wrapper = builder.BuildProxyType(); - - proxyConstructor = wrapper.GetConstructor(Type.EmptyTypes); - - #region Instrumentation - - if (LOG.IsDebugEnabled) - { - if (ServiceUri != null) - { - LOG.Debug( - String.Format("Generated client proxy type [{0}] for web service [{1}]", wrapper.FullName, - ServiceUri.Description)); - } - else if (ProxyType != null) - { - LOG.Debug( - String.Format("Generated client proxy type [{0}] for web service based on provided proxy type [{1}]", wrapper.FullName, - ProxyType.FullName)); - } - } - - #endregion - } - - #endregion - - #region Private Methods - - /// - /// Gets XML Web Services documents from a Spring resource. - /// - private DiscoveryClientDocumentCollection GetWsDocuments(IResource resource) - { - try - { - if (ServiceUri is UrlResource || - ServiceUri is FileSystemResource) - { - DiscoveryClientProtocol dcProtocol = new DiscoveryClientProtocol(); - dcProtocol.AllowAutoRedirect = true; - dcProtocol.Credentials = CreateCredentials(); - dcProtocol.Proxy = ConfigureProxy(); - dcProtocol.DiscoverAny(resource.Uri.AbsoluteUri); - dcProtocol.ResolveAll(); - - return dcProtocol.Documents; - } - else - { - DiscoveryClientDocumentCollection dcdc = new DiscoveryClientDocumentCollection(); - dcdc[resource.Description] = ServiceDescription.Read(resource.InputStream); - return dcdc; - } - } - catch (Exception ex) - { - throw new ArgumentException(String.Format("Couldn't retrieve the description of the web service located at '{0}'.", resource.Description), ex); - } - } - - private IWebProxy ConfigureProxy() - { - IWebProxy webProxy = null; - if (ProxyUrl != null) - { - webProxy = new WebProxy(ProxyUrl); - } - if (ProxyCredential != null) - { - if (webProxy == null) - { -#if !NET_2_0 - webProxy = GlobalProxySelection.Select; -#else - webProxy = WebRequest.DefaultWebProxy; -#endif - } - webProxy.Credentials = ProxyCredential; - } - - return webProxy; - } - - private ICredentials CreateCredentials() - { - if (Credential != null) - { - CredentialCache credentialCache = new CredentialCache(); - - Uri wsUri = new Uri(ServiceUri.Uri.AbsoluteUri.Substring(0, ServiceUri.Uri.AbsoluteUri.Length - ServiceUri.Uri.AbsolutePath.Length)); - IEnumerator enumerator = AuthenticationManager.RegisteredModules; - while (enumerator.MoveNext()) - { - credentialCache.Add(wsUri, ((IAuthenticationModule)enumerator.Current).AuthenticationType, Credential); - } - - return credentialCache; - } - else - { - return CredentialCache.DefaultCredentials; - } - } - - #endregion - - #region SoapHttpClientProxyTypeBuilder inner class implementation - - /// - /// Proxy type builder that can be used to create a proxy for - /// derived classes. - /// - private sealed class SoapHttpClientProxyTypeBuilder : AbstractProxyTypeBuilder - { - #region Logging - - private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(SoapHttpClientProxyTypeBuilder)); - - #endregion - - #region Fields - - // Binding/Type related - private IResource serviceUri; - private ServiceDescriptionCollection wsDescriptions; - private XmlSchemaImporter schemaImporter; - private Binding wsBinding; - private string wsUrl; - - // Operation/Method related - private Operation operation; - private OperationBinding operationBinding; - private SoapOperationBinding soapOperationBinding; - private XmlMembersMapping inputMembersMapping; - private XmlMembersMapping outputMembersMapping; - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - /// The URI that contains the Web Service meta info (WSDL). - /// The XML Web Service documents to use to create the proxy. - /// The name of the Web Service binding to use. - public SoapHttpClientProxyTypeBuilder(IResource serviceUri, - DiscoveryClientDocumentCollection wsDocuments, string bindingName) - { - this.serviceUri = serviceUri; - - Name = "SoapHttpClientProxy"; - ProxyTargetAttributes = false; - - Initialize(wsDocuments, bindingName); - } - - #endregion - - #region IProxyTypeBuilder Members - - /// - /// Creates the proxy type. - /// - /// The generated proxy class. - public override Type BuildProxyType() - { - if (Interfaces == null || Interfaces.Length == 0) - { - throw new ArgumentException( - "Web service client proxy must implement at least one interface."); - } - - TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); - - // apply custom attributes to the proxy type. - ApplyTypeAttributes(typeBuilder, TargetType); - - // create constructors - ImplementConstructors(typeBuilder); - - // implement service interfaces - foreach (Type intf in Interfaces) - { - ImplementInterface(typeBuilder, - new SoapHttpClientProxyMethodBuilder(typeBuilder, this), - intf, TargetType); - } - - return typeBuilder.CreateType(); - } - - #endregion - - #region IProxyTypeGenerator Members - - /// - /// Generates the IL instructions that pushes - /// the target instance on which calls should be delegated to. - /// - /// The IL generator to use. - public override void PushTarget(ILGenerator il) - { - PushProxy(il); - } - - #endregion - - #region Protected Methods - - /// - /// Implements constructors for the proxy class. - /// - /// - /// The to use. - /// - protected override void ImplementConstructors(TypeBuilder builder) - { - MethodAttributes attributes = MethodAttributes.Public | - MethodAttributes.HideBySig | MethodAttributes.SpecialName | - MethodAttributes.RTSpecialName; - ConstructorBuilder cb = builder.DefineConstructor(attributes, - CallingConventions.Standard, Type.EmptyTypes); - - ILGenerator il = cb.GetILGenerator(); - - PushProxy(il); - il.Emit(OpCodes.Call, this.BaseType.GetConstructor(Type.EmptyTypes)); - - // Set Url Property - PushProxy(il); - il.Emit(OpCodes.Ldstr, this.wsUrl); - il.Emit(OpCodes.Call, this.BaseType.GetMethod("set_Url", BindingFlags.Public | BindingFlags.Instance)); - - il.Emit(OpCodes.Ret); - } - - protected override void ApplyMethodAttributes( - MethodBuilder methodBuilder, MethodInfo targetMethod) - { - MoveToMethod(targetMethod); - - base.ApplyMethodAttributes(methodBuilder, targetMethod); - } - - protected override IList GetTypeAttributes(Type type) - { - IList attrs = base.GetTypeAttributes(type); - - // Add the WebServiceBindingAttribute - attrs.Add(CreateWebServiceBindingAttribute(this.wsBinding)); - - return attrs; - } - - protected override IList GetMethodAttributes(MethodInfo method) - { - IList attrs = base.GetMethodAttributes(method); - - // Add the SoapMethodAttribute - attrs.Add(CreateSoapMethodAttribute( - operation, operationBinding, soapOperationBinding, inputMembersMapping, outputMembersMapping)); - - return attrs; - } - -#if NET_2_0 - protected override IList GetMethodReturnTypeAttributes(MethodInfo method) - { - IList attrs = base.GetMethodReturnTypeAttributes(method); - - // Add the XmlElementAttribute if needed - if (operation.Messages.Output != null) - { - if (method.ReturnType != typeof(void)) - { - if (outputMembersMapping.Count > 0) - { - XmlMemberMapping outMemberMapping = outputMembersMapping[0]; - bool useMemberName = (outMemberMapping.MemberName != operation.Name + "Result"); - bool useNamespace = outMemberMapping.Namespace != outputMembersMapping.Namespace; - if (useMemberName || useNamespace) - { - ReflectionUtils.CustomAttributeBuilderBuilder cabb = - new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(XmlElementAttribute)); - if (useMemberName) - { - cabb.AddPropertyValue("ElementName", outMemberMapping.MemberName); - } - if (useNamespace) - { - cabb.AddPropertyValue("Namespace", outMemberMapping.Namespace); - } - - attrs.Add(cabb.Build()); - } - } - } - } - - return attrs; - } -#endif -/* - protected override IList GetMethodParameterAttributes(MethodInfo method, ParameterInfo paramInfo) - { - IList attrs = base.GetMethodParameterAttributes(method, paramInfo); - - // Add the XmlElementAttribute if needed - XmlMemberMapping inMemberMapping = inputMembersMapping[paramInfo.Position]; - if (inMemberMapping.Namespace != inputMembersMapping.Namespace) - { - CustomAttributeBuilderBuilder cabb = - new CustomAttributeBuilderBuilder(typeof(XmlElementAttribute)); - cabb.AddPropertyValue("Namespace", inMemberMapping.Namespace); - - attrs.Add(cabb.Build()); - } - - return attrs; - } -*/ - - #endregion - - #region Private Methods - - private void Initialize(DiscoveryClientDocumentCollection wsDocuments, string bindingName) - { - // Service descriptions - this.wsDescriptions = new ServiceDescriptionCollection(); - XmlSchemas schemas = new XmlSchemas(); - foreach (DictionaryEntry entry in wsDocuments) - { - if (entry.Value is ServiceDescription) - { - this.wsDescriptions.Add((ServiceDescription)entry.Value); - } - if (entry.Value is XmlSchema) - { - schemas.Add((XmlSchema)entry.Value); - } - } - - // XmlSchemaImporter - foreach (ServiceDescription serviceDescription in this.wsDescriptions) - { - foreach (XmlSchema schema in serviceDescription.Types.Schemas) - { - if (schemas[schema.TargetNamespace] == null) - { - schemas.Add(schema); - } - } - } - this.schemaImporter = new XmlSchemaImporter(schemas); - - this.wsBinding = GetWsBinding(this.wsDescriptions, bindingName); - this.wsUrl = GetWsUrl(this.wsDescriptions, this.wsBinding); - } - - /// - /// Search and returns the binding for the specified name. - /// - private Binding GetWsBinding(ServiceDescriptionCollection serviceDescriptions, string bindingName) - { - if (bindingName != null) - { - // Search for a specific binding - foreach (ServiceDescription description in serviceDescriptions) - { - foreach (Binding binding in description.Bindings) - { - if (binding.Name == bindingName) - { - return binding; - } - } - } - throw new ApplicationException(String.Format("Binding '{0}' does not exist in the WSDL document located at '{1}'", bindingName, this.serviceUri.Description)); - } - else - { - // Use the first one - foreach (ServiceDescription description in serviceDescriptions) - { - foreach (Binding binding in description.Bindings) - { - #region Instrumentation - - if (LOG.IsInfoEnabled) - { - LOG.Info(String.Format("The binding '{0}', found in the WSDL document located at '{1}', will be use.", binding.Name, this.serviceUri.Description)); - } - - #endregion - - return binding; - } - } - throw new ApplicationException(String.Format("No bindings exists in the WSDL document located at '{0}'", this.serviceUri.Description)); - } - } - - /// - /// Search and returns the url for the specified binding. - /// - private string GetWsUrl(ServiceDescriptionCollection serviceDescriptions, Binding binding) - { - foreach (ServiceDescription description in serviceDescriptions) - { - foreach (Service service in description.Services) - { - foreach (Port port in service.Ports) - { - if (port.Binding.Name == binding.Name) - { - SoapAddressBinding soapAddress = (SoapAddressBinding)port.Extensions.Find(typeof(SoapAddressBinding)); - return soapAddress.Location; - } - } - } - } - throw new ApplicationException(String.Format("No SoapAddressBinding has been found for binding '{0}' in the WSDL document located at '{1}'.", binding.Name, serviceUri)); - } - - /// - /// Search and returns the operation that matches the specified method. - /// - private Operation GetOperation(ServiceDescriptionCollection descriptions, Binding binding, MethodInfo method) - { - PortType portType = descriptions.GetPortType(binding.Type); - foreach (Operation operation in portType.Operations) - { - if (operation.Name == method.Name) - { - return operation; - } - } - throw new ApplicationException(String.Format("No Operation has been found for the method '{0}' in the WSDL document located at '{1}'.", method.Name, serviceUri.Description)); - } - - /// - /// Search and returns the OperationBinding that matches the specified Operation. - /// - private OperationBinding GetOperationBinding(Operation operation, Binding binding) - { - foreach (OperationBinding operationBinding in binding.Operations) - { - if (operation.IsBoundBy(operationBinding)) - { - return operationBinding; - } - } - throw new ApplicationException(String.Format("No OperationBinding matches the Operation '{0}' in the WSDL document located at '{2}'.", operation.Name, this.serviceUri.Description)); - } - - /// - /// Search and returns the type mapping between method parameters/return value - /// and the element parts of a literal-use SOAP message. - /// - private XmlMembersMapping GetMembersMapping(string messageName, MessagePartCollection messageParts, SoapBodyBinding soapBodyBinding, SoapBindingStyle soapBindingStyle) - { -#if NET_2_0 - if (soapBindingStyle == SoapBindingStyle.Rpc) - { - SoapSchemaMember[] soapSchemaMembers = new SoapSchemaMember[messageParts.Count]; - for (int i = 0; i < messageParts.Count; i++) - { - SoapSchemaMember ssm = new SoapSchemaMember(); - ssm.MemberName = messageParts[i].Name; - ssm.MemberType = messageParts[i].Type; - soapSchemaMembers[i] = ssm; - } - return this.schemaImporter.ImportMembersMapping(messageName, soapBodyBinding.Namespace, soapSchemaMembers); - } - else - { - return this.schemaImporter.ImportMembersMapping(messageParts[0].Element); - } -#else - return this.schemaImporter.ImportMembersMapping(messageParts[0].Element); -#endif - } - - private void MoveToMethod(MethodInfo targetMethod) - { - operation = GetOperation(this.wsDescriptions, this.wsBinding, targetMethod); - operationBinding = GetOperationBinding(operation, this.wsBinding); - soapOperationBinding = (SoapOperationBinding)operationBinding.Extensions.Find(typeof(SoapOperationBinding)); - - string inputMessageName = (!StringUtils.IsNullOrEmpty(operationBinding.Input.Name) && (soapOperationBinding.Style != SoapBindingStyle.Rpc)) ? operationBinding.Input.Name : operation.Name; - SoapBodyBinding inputSoapBodyBinding = (SoapBodyBinding)operationBinding.Input.Extensions.Find(typeof(SoapBodyBinding)); - -#if !NET_2_0 - if (soapOperationBinding.Style == SoapBindingStyle.Rpc && - inputSoapBodyBinding.Use == SoapBindingUse.Literal) - { - throw new NotSupportedException("rpc-literal SOAP messages are not supported on .NET Framework 1.1"); - } -#endif - if (inputSoapBodyBinding.Use != SoapBindingUse.Literal) - { - throw new NotSupportedException("WebServiceProxyFactory only supports document-literal and rpc-literal SOAP messages to conform to WS-I Basic Profiles."); - } - - Message inputMessage = this.wsDescriptions.GetMessage(operation.Messages.Input.Message); - inputMembersMapping = GetMembersMapping(inputMessageName, inputMessage.Parts, inputSoapBodyBinding, soapOperationBinding.Style); - - outputMembersMapping = null; - if (operation.Messages.Output != null) - { - string outputMessageName = (!StringUtils.IsNullOrEmpty(operationBinding.Output.Name) && (soapOperationBinding.Style != SoapBindingStyle.Rpc)) ? operationBinding.Output.Name : (operation.Name + "Response"); - SoapBodyBinding outputSoapBodyBinding = (SoapBodyBinding)operationBinding.Output.Extensions.Find(typeof(SoapBodyBinding)); - Message outputMessage = this.wsDescriptions.GetMessage(operation.Messages.Output.Message); - outputMembersMapping = GetMembersMapping(outputMessageName, outputMessage.Parts, outputSoapBodyBinding, soapOperationBinding.Style); - } - } - - /// - /// Creates a that should be applied to proxy type. - /// - private CustomAttributeBuilder CreateWebServiceBindingAttribute(Binding wsBinding) - { - ReflectionUtils.CustomAttributeBuilderBuilder cabb = - new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(WebServiceBindingAttribute)); - - cabb.AddContructorArgument(this.wsBinding.Name); - cabb.AddPropertyValue("Namespace", this.wsBinding.ServiceDescription.TargetNamespace); - - return cabb.Build(); - } - -#if !NET_2_0 - private static readonly PropertyInfo XmlMembersMapping_ElementName = - typeof(XmlMembersMapping).GetProperty("ElementName"); - - private static readonly PropertyInfo XmlMembersMapping_Namespace = - typeof(XmlMembersMapping).GetProperty("Namespace"); -#endif - - /// - /// Creates a or a - /// that should be applied to proxy method. - /// - private static CustomAttributeBuilder CreateSoapMethodAttribute(Operation operation, - OperationBinding operationBinding, SoapOperationBinding soapOperationBinding, - XmlMembersMapping inputMembersMapping, XmlMembersMapping outputMembersMapping) - { - ReflectionUtils.CustomAttributeBuilderBuilder cabb; - -#if !NET_2_0 - // Access XmlMembersMapping.ElementName and .Namespace property using reflection [SPRNET-520] - string inputMembersMappingElementName = XmlMembersMapping_ElementName.GetValue(inputMembersMapping, null) as string; - string inputMembersMappingNamespace = XmlMembersMapping_Namespace.GetValue(inputMembersMapping, null) as string; -#else - string inputMembersMappingElementName = inputMembersMapping.ElementName; - string inputMembersMappingNamespace = inputMembersMapping.Namespace; -#endif - - if (soapOperationBinding.Style == SoapBindingStyle.Rpc) - { - cabb = new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(SoapRpcMethodAttribute)); - } - else - { - cabb = new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(SoapDocumentMethodAttribute)); - cabb.AddPropertyValue("ParameterStyle", SoapParameterStyle.Wrapped); - } - - cabb.AddContructorArgument(soapOperationBinding.SoapAction); - -#if NET_2_0 - cabb.AddPropertyValue("Use", SoapBindingUse.Literal); -#else - if (soapOperationBinding.Style != SoapBindingStyle.Rpc) - { - cabb.AddPropertyValue("Use", SoapBindingUse.Literal); - } -#endif - - if (inputMembersMappingElementName.Length > 0 && - inputMembersMappingElementName != operation.Name) - { - cabb.AddPropertyValue("RequestElementName", inputMembersMappingElementName); - } - - if (inputMembersMappingNamespace != null) - { - cabb.AddPropertyValue("RequestNamespace", inputMembersMappingNamespace); - } - - if (outputMembersMapping == null) - { - cabb.AddPropertyValue("OneWay", true); - } - else - { -#if !NET_2_0 - // Access XmlMembersMapping.ElementName and .Namespace property using reflection [SPRNET-520] - string outputMembersMappingElementName = XmlMembersMapping_ElementName.GetValue(outputMembersMapping, null) as string; - string outputMembersMappingNamespace = XmlMembersMapping_Namespace.GetValue(outputMembersMapping, null) as string; -#else - string outputMembersMappingElementName = outputMembersMapping.ElementName; - string outputMembersMappingNamespace = outputMembersMapping.Namespace; -#endif - if (outputMembersMappingElementName.Length > 0 && - outputMembersMappingElementName != (operation.Name + "Response")) - { - cabb.AddPropertyValue("ResponseElementName", outputMembersMappingElementName); - } - - if (outputMembersMappingNamespace != null) - { - cabb.AddPropertyValue("ResponseNamespace", outputMembersMappingNamespace); - } - } - - return cabb.Build(); - } - - #endregion - - #region SoapHttpClientProxyMethodBuilder inner class implementation - - /// - /// Proxy method builder that can be used to create a proxy method - /// for web services operation invocation. - /// - private sealed class SoapHttpClientProxyMethodBuilder : AbstractProxyMethodBuilder - { - #region Fields - - private static readonly MethodInfo Invoke = - typeof(SoapHttpClientProtocol).GetMethod("Invoke", BindingFlags.NonPublic | BindingFlags.Instance); - - #endregion - - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the method builder. - /// - /// The type builder to use. - /// - /// The implementation to use. - /// - public SoapHttpClientProxyMethodBuilder( - TypeBuilder typeBuilder, IProxyTypeGenerator proxyGenerator) - : base(typeBuilder, proxyGenerator, false) - { - } - - #endregion - - #region Protected Methods - - /// - /// Generates the proxy method. - /// - /// The IL generator to use. - /// The method to proxy. - /// - /// The interface definition of the method, if applicable. - /// - protected override void GenerateMethod( - ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) - { - // In Parameters - ArrayList inParams = new ArrayList(); - // Ref or Out Parameters - ArrayList refOutParams = new ArrayList(); - - foreach (ParameterInfo paramInfo in interfaceMethod.GetParameters()) - { - if (paramInfo.IsRetval || paramInfo.IsOut) - { - refOutParams.Add(paramInfo); - } - else - { - inParams.Add(paramInfo); - } - } - - proxyGenerator.PushTarget(il); - - // Parameter #1 - il.Emit(OpCodes.Ldstr, interfaceMethod.Name); - - // Parameter #2 - LocalBuilder parameters = il.DeclareLocal(typeof(Object[])); - il.Emit(OpCodes.Ldc_I4, inParams.Count); - il.Emit(OpCodes.Newarr, typeof(Object)); - il.Emit(OpCodes.Stloc, parameters); - - int paramIndex = 0; - foreach (ParameterInfo paramInfo in inParams) - { - il.Emit(OpCodes.Ldloc, parameters); - il.Emit(OpCodes.Ldc_I4, paramIndex); - il.Emit(OpCodes.Ldarg, paramInfo.Position + 1); - if (paramInfo.ParameterType.IsValueType) - { - il.Emit(OpCodes.Box, paramInfo.ParameterType); - } - il.Emit(OpCodes.Stelem_Ref); - - paramIndex++; - } - - il.Emit(OpCodes.Ldloc, parameters); - - // Call Invoke method and save result - LocalBuilder results = il.DeclareLocal(typeof(Object[])); - il.EmitCall(OpCodes.Callvirt, Invoke, null); - il.Emit(OpCodes.Stloc, results); - - int resultIndex = (interfaceMethod.ReturnType == typeof(void) ? 0 : 1); - foreach (ParameterInfo paramInfo in refOutParams) - { - il.Emit(OpCodes.Ldarg, paramInfo.Position + 1); - il.Emit(OpCodes.Ldloc, results); - - // Cast / Unbox the return value - il.Emit(OpCodes.Ldc_I4, resultIndex); - il.Emit(OpCodes.Ldelem_Ref); - - Type elementType = paramInfo.ParameterType.GetElementType(); - if (elementType.IsValueType) - { - il.Emit(OpCodes.Unbox, elementType); - il.Emit(OpCodes.Ldobj, elementType); - il.Emit(OpCodes.Stobj, elementType); - } - else - { - il.Emit(OpCodes.Castclass, elementType); - il.Emit(OpCodes.Stind_Ref); - } - - resultIndex++; - } - - if (interfaceMethod.ReturnType != typeof(void)) - { - il.Emit(OpCodes.Ldloc, results); - - // Cast / Unbox the return value - il.Emit(OpCodes.Ldc_I4_0); - il.Emit(OpCodes.Ldelem_Ref); - if (interfaceMethod.ReturnType.IsValueType) - { - il.Emit(OpCodes.Unbox, interfaceMethod.ReturnType); - il.Emit(OpCodes.Ldobj, interfaceMethod.ReturnType); - } - else - { - il.Emit(OpCodes.Castclass, interfaceMethod.ReturnType); - } - } - } - - #endregion - } - - #endregion - } - - #endregion - - #region WebServiceProxyProxyTypeBuilder inner class implementation - - /// - /// Proxy type builder that can be used to create a proxy for - /// .Net-generated proxy class that can be safely cast to a service interface. - /// - private sealed class WebServiceProxyProxyTypeBuilder : InheritanceProxyTypeBuilder - { - #region Constructor(s) / Destructor - - /// - /// Creates a new instance of the - /// class. - /// - public WebServiceProxyProxyTypeBuilder() - { - this.Name = "WebServiceProxyProxy"; - } - - #endregion - - #region Protected Methods - - /// - /// Gets the mapping of the interface to proxy - /// into the actual methods on the target type - /// that does not need to implement that interface. - /// - /// - ///

- /// As the proxy type does not implement the interface, - /// we try to find matching methods. - ///

- ///
- /// - /// The of the target object. - /// - /// The interface to implement. - /// - /// An interface mapping for the interface to proxy. - /// - protected override InterfaceMapping GetInterfaceMapping( - Type targetType, Type intf) - { - InterfaceMapping mapping; - - mapping.TargetType = targetType; - mapping.InterfaceType = intf; - mapping.InterfaceMethods = intf.GetMethods(); - mapping.TargetMethods = ReflectionUtils.GetMatchingMethods( - targetType, mapping.InterfaceMethods, true); - - return mapping; - } - - #endregion - } - - #endregion - } +#region License + +/* + * Copyright © 2002-2007 the original author or authors. + * + * 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. + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; +using System.Net; +using System.Reflection; +using System.Reflection.Emit; +using System.Web.Services; +using System.Web.Services.Description; +using System.Web.Services.Protocols; +using System.Web.Services.Discovery; + +using Spring.Core; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Proxy; +using Spring.Util; +using Spring.Objects; +using Spring.Core.IO; +using Spring.Expressions; + +#endregion + +namespace Spring.Web.Services +{ + /// + /// Factory Object that dynamically implements service interface for web service. + /// + /// + ///

+ /// This factory object should be used to obtain reference to a web service + /// that can be safely cast to a service interface, which allows client code to code + /// against interface, and not directly against the web service. + ///

+ ///

+ /// The WSDL contract needs to conform to WS-I Basic Profiles. + ///

+ ///
+ /// Bruno Baia + /// Aleksandar Seovic + public class WebServiceProxyFactory : IConfigurableFactoryObject, IInitializingObject + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(WebServiceProxyFactory)); + + #endregion + + #region Fields + + private IObjectDefinition _productTemplate; + private Type _webServiceProxyBaseType = typeof(SoapHttpClientProtocol); + private IResource _serviceUri; + private Type _proxyType; + private Type _serviceInterface; + private NetworkCredential _credential; + private string _proxyUrl; + private NetworkCredential _proxyCredential; + private string _bindingName; + private IList _typeAttributes = new ArrayList(); + private IDictionary _memberAttributes = new Hashtable(); + + /// + /// The web service proxy default constructor. + /// + protected ConstructorInfo proxyConstructor; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public WebServiceProxyFactory() + { + } + + #endregion + + #region Properties + + /// + /// Gets or sets the base type that web service proxy should inherit. + /// + /// + /// Default is + /// + [Obsolete("This property is obsolete, it has been replaced by WebServiceProxyBaseType")] + public Type ClientProtocolType + { + get { return _webServiceProxyBaseType; } + set { _webServiceProxyBaseType = value; } + } + + /// + /// Gets or sets the base type that web service proxy should inherit. + /// + /// + /// Default is + /// + public Type WebServiceProxyBaseType + { + get { return _webServiceProxyBaseType; } + set { _webServiceProxyBaseType = value; } + } + + /// + /// Gets or sets the URI for an + /// that contains the web service description (WSDL). + /// + public IResource ServiceUri + { + get { return _serviceUri; } + set { _serviceUri = value; } + } + + /// + /// Gets or sets type of the proxy class to wrap. + /// + public Type ProxyType + { + get { return _proxyType; } + set { _proxyType = value; } + } + + /// + /// Gets or sets service interface that proxy should implement. + /// + public Type ServiceInterface + { + get { return _serviceInterface; } + set { _serviceInterface = value; } + } + + /// + /// Gets or sets the instance + /// to use when connecting to a server that requires authentication. + /// + public NetworkCredential Credential + { + get { return _credential; } + set { _credential = value; } + } + + /// + /// Gets or sets the url of the proxy server to use for retrieving the WSDL. + /// + /// + ///

+ /// This only applies when using an as uri. + ///

+ ///

+ /// The default is to use the system proxy setting. + ///

+ ///
+ public string ProxyUrl + { + get { return _proxyUrl; } + set { _proxyUrl = value; } + } + + /// + /// Gets or sets the instance + /// to use when connecting to a proxy server that requires authentication. + /// + /// + ///

+ /// This only applies when using an as uri. + ///

+ ///
+ public NetworkCredential ProxyCredential + { + get { return _proxyCredential; } + set { _proxyCredential = value; } + } + + /// + /// Gets or sets the web service binding name to use for the proxy. + /// + public string BindingName + { + get { return _bindingName; } + set { _bindingName = value; } + } + + /// + /// Gets or sets a list of custom attributes + /// that should be applied to a proxy class. + /// + public IList TypeAttributes + { + get { return _typeAttributes; } + set { _typeAttributes = value; } + } + + /// + /// Gets or sets a dictionary of custom attributes + /// that should be applied to web service members. + /// + /// + /// Dictionary key is an expression that members can be matched against. + /// Value is a list of attributes that should be applied + /// to each member that matches expression. + /// + public IDictionary MemberAttributes + { + get { return _memberAttributes; } + set { _memberAttributes = value; } + } + + #endregion + + #region IConfigurableFactoryObject Members + + /// + /// Returns type of the web service proxy. + /// + public virtual Type ObjectType + { + get { return (proxyConstructor != null ? proxyConstructor.DeclaringType : ServiceInterface); } + } + + /// + /// Creates new instance of the web service proxy. + /// + /// New instance of the web service proxy. + public virtual object GetObject() + { + if (proxyConstructor == null) + { + GenerateProxy(); + } + + return ObjectUtils.InstantiateType(proxyConstructor, ObjectUtils.EmptyObjects); + } + + /// + /// Always returns false. + /// + public virtual bool IsSingleton + { + get { return false; } + } + + /// + /// Gets or sets the template object definition + /// that should be used to configure proxy instance. + /// + public virtual IObjectDefinition ProductTemplate + { + get { return _productTemplate; } + set { _productTemplate = value; } + } + + #endregion + + #region IInitializingObject Members + + /// + /// Initializes factory object. + /// + public virtual void AfterPropertiesSet() + { + ValidateConfiguration(); + } + + #endregion + + #region Protected Methods + + /// + /// Validates the configuration. + /// + protected virtual void ValidateConfiguration() + { + if (ServiceUri == null && ProxyType == null) + { + throw new ArgumentException("ServiceUri or ProxyType property is required."); + } + if (ServiceInterface == null) + { + throw new ArgumentException("The ServiceInterface property is required."); + } + if (!ServiceInterface.IsInterface) + { + throw new ArgumentException("ServiceInterface must be an interface"); + } + if (WebServiceProxyBaseType.IsSealed) + { + throw new ArgumentException("Web service client proxy cannot be created for a sealed class [" + WebServiceProxyBaseType.FullName + "]"); + } + } + + /// + /// Generates the web service proxy type. + /// + protected virtual void GenerateProxy() + { + IProxyTypeBuilder builder; + if (ProxyType != null) + { + // Wrap .NET generated proxy class or another + builder = new WebServiceProxyProxyTypeBuilder(); + builder.TargetType = ProxyType; + } + else + { + // Dynamically generates proxy class from WSDL + builder = new SoapHttpClientProxyTypeBuilder( + ServiceUri, GetWsDocuments(ServiceUri), BindingName); + builder.BaseType = WebServiceProxyBaseType; + } + + builder.Interfaces = ReflectionUtils.ToInterfaceArray(ServiceInterface); + builder.TypeAttributes = TypeAttributes; + builder.MemberAttributes = MemberAttributes; + + Type wrapper = builder.BuildProxyType(); + + proxyConstructor = wrapper.GetConstructor(Type.EmptyTypes); + + #region Instrumentation + + if (LOG.IsDebugEnabled) + { + if (ServiceUri != null) + { + LOG.Debug( + String.Format("Generated client proxy type [{0}] for web service [{1}]", wrapper.FullName, + ServiceUri.Description)); + } + else if (ProxyType != null) + { + LOG.Debug( + String.Format("Generated client proxy type [{0}] for web service based on provided proxy type [{1}]", wrapper.FullName, + ProxyType.FullName)); + } + } + + #endregion + } + + #endregion + + #region Private Methods + + /// + /// Gets XML Web Services documents from a Spring resource. + /// + private DiscoveryClientDocumentCollection GetWsDocuments(IResource resource) + { + try + { + if (ServiceUri is UrlResource || + ServiceUri is FileSystemResource) + { + DiscoveryClientProtocol dcProtocol = new DiscoveryClientProtocol(); + dcProtocol.AllowAutoRedirect = true; + dcProtocol.Credentials = CreateCredentials(); + dcProtocol.Proxy = ConfigureProxy(); + dcProtocol.DiscoverAny(resource.Uri.AbsoluteUri); + dcProtocol.ResolveAll(); + + return dcProtocol.Documents; + } + else + { + DiscoveryClientDocumentCollection dcdc = new DiscoveryClientDocumentCollection(); + dcdc[resource.Description] = ServiceDescription.Read(resource.InputStream); + return dcdc; + } + } + catch (Exception ex) + { + throw new ArgumentException(String.Format("Couldn't retrieve the description of the web service located at '{0}'.", resource.Description), ex); + } + } + + private IWebProxy ConfigureProxy() + { + IWebProxy webProxy = null; + if (ProxyUrl != null) + { + webProxy = new WebProxy(ProxyUrl); + } + if (ProxyCredential != null) + { + if (webProxy == null) + { +#if !NET_2_0 + webProxy = GlobalProxySelection.Select; +#else + webProxy = WebRequest.DefaultWebProxy; +#endif + } + webProxy.Credentials = ProxyCredential; + } + + return webProxy; + } + + private ICredentials CreateCredentials() + { + if (Credential != null) + { + CredentialCache credentialCache = new CredentialCache(); + + Uri wsUri = new Uri(ServiceUri.Uri.AbsoluteUri.Substring(0, ServiceUri.Uri.AbsoluteUri.Length - ServiceUri.Uri.AbsolutePath.Length)); + IEnumerator enumerator = AuthenticationManager.RegisteredModules; + while (enumerator.MoveNext()) + { + credentialCache.Add(wsUri, ((IAuthenticationModule)enumerator.Current).AuthenticationType, Credential); + } + + return credentialCache; + } + else + { + return CredentialCache.DefaultCredentials; + } + } + + #endregion + + #region SoapHttpClientProxyTypeBuilder inner class implementation + + /// + /// Proxy type builder that can be used to create a proxy for + /// derived classes. + /// + private sealed class SoapHttpClientProxyTypeBuilder : AbstractProxyTypeBuilder + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(SoapHttpClientProxyTypeBuilder)); + + #endregion + + #region Fields + + // Binding/Type related + private IResource serviceUri; + private ServiceDescriptionCollection wsDescriptions; + private XmlSchemaImporter schemaImporter; + private Binding wsBinding; + private string wsUrl; + + // Operation/Method related + private Operation operation; + private OperationBinding operationBinding; + private SoapOperationBinding soapOperationBinding; + private XmlMembersMapping inputMembersMapping; + private XmlMembersMapping outputMembersMapping; + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + /// The URI that contains the Web Service meta info (WSDL). + /// The XML Web Service documents to use to create the proxy. + /// The name of the Web Service binding to use. + public SoapHttpClientProxyTypeBuilder(IResource serviceUri, + DiscoveryClientDocumentCollection wsDocuments, string bindingName) + { + this.serviceUri = serviceUri; + + Name = "SoapHttpClientProxy"; + ProxyTargetAttributes = false; + + Initialize(wsDocuments, bindingName); + } + + #endregion + + #region IProxyTypeBuilder Members + + /// + /// Creates the proxy type. + /// + /// The generated proxy class. + public override Type BuildProxyType() + { + if (Interfaces == null || Interfaces.Length == 0) + { + throw new ArgumentException( + "Web service client proxy must implement at least one interface."); + } + + TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType); + + // apply custom attributes to the proxy type. + ApplyTypeAttributes(typeBuilder, TargetType); + + // create constructors + ImplementConstructors(typeBuilder); + + // implement service interfaces + foreach (Type intf in Interfaces) + { + ImplementInterface(typeBuilder, + new SoapHttpClientProxyMethodBuilder(typeBuilder, this), + intf, TargetType); + } + + return typeBuilder.CreateType(); + } + + #endregion + + #region IProxyTypeGenerator Members + + /// + /// Generates the IL instructions that pushes + /// the target instance on which calls should be delegated to. + /// + /// The IL generator to use. + public override void PushTarget(ILGenerator il) + { + PushProxy(il); + } + + #endregion + + #region Protected Methods + + /// + /// Implements constructors for the proxy class. + /// + /// + /// The to use. + /// + protected override void ImplementConstructors(TypeBuilder builder) + { + MethodAttributes attributes = MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName; + ConstructorBuilder cb = builder.DefineConstructor(attributes, + CallingConventions.Standard, Type.EmptyTypes); + + ILGenerator il = cb.GetILGenerator(); + + PushProxy(il); + il.Emit(OpCodes.Call, this.BaseType.GetConstructor(Type.EmptyTypes)); + + // Set Url Property + PushProxy(il); + il.Emit(OpCodes.Ldstr, this.wsUrl); + il.Emit(OpCodes.Call, this.BaseType.GetMethod("set_Url", BindingFlags.Public | BindingFlags.Instance)); + + il.Emit(OpCodes.Ret); + } + + protected override void ApplyMethodAttributes( + MethodBuilder methodBuilder, MethodInfo targetMethod) + { + MoveToMethod(targetMethod); + + base.ApplyMethodAttributes(methodBuilder, targetMethod); + } + + protected override IList GetTypeAttributes(Type type) + { + IList attrs = base.GetTypeAttributes(type); + + // Add the WebServiceBindingAttribute + attrs.Add(CreateWebServiceBindingAttribute(this.wsBinding)); + + return attrs; + } + + protected override IList GetMethodAttributes(MethodInfo method) + { + IList attrs = base.GetMethodAttributes(method); + + // Add the SoapMethodAttribute + attrs.Add(CreateSoapMethodAttribute( + operation, operationBinding, soapOperationBinding, inputMembersMapping, outputMembersMapping)); + + return attrs; + } + +#if NET_2_0 + protected override IList GetMethodReturnTypeAttributes(MethodInfo method) + { + IList attrs = base.GetMethodReturnTypeAttributes(method); + + // Add the XmlElementAttribute if needed + if (operation.Messages.Output != null) + { + if (method.ReturnType != typeof(void)) + { + if (outputMembersMapping.Count > 0) + { + XmlMemberMapping outMemberMapping = outputMembersMapping[0]; + bool useMemberName = (outMemberMapping.MemberName != operation.Name + "Result"); + bool useNamespace = outMemberMapping.Namespace != outputMembersMapping.Namespace; + if (useMemberName || useNamespace) + { + ReflectionUtils.CustomAttributeBuilderBuilder cabb = + new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(XmlElementAttribute)); + if (useMemberName) + { + cabb.AddPropertyValue("ElementName", outMemberMapping.MemberName); + } + if (useNamespace) + { + cabb.AddPropertyValue("Namespace", outMemberMapping.Namespace); + } + + attrs.Add(cabb.Build()); + } + } + } + } + + return attrs; + } +#endif +/* + protected override IList GetMethodParameterAttributes(MethodInfo method, ParameterInfo paramInfo) + { + IList attrs = base.GetMethodParameterAttributes(method, paramInfo); + + // Add the XmlElementAttribute if needed + XmlMemberMapping inMemberMapping = inputMembersMapping[paramInfo.Position]; + if (inMemberMapping.Namespace != inputMembersMapping.Namespace) + { + CustomAttributeBuilderBuilder cabb = + new CustomAttributeBuilderBuilder(typeof(XmlElementAttribute)); + cabb.AddPropertyValue("Namespace", inMemberMapping.Namespace); + + attrs.Add(cabb.Build()); + } + + return attrs; + } +*/ + + #endregion + + #region Private Methods + + private void Initialize(DiscoveryClientDocumentCollection wsDocuments, string bindingName) + { + // Service descriptions + this.wsDescriptions = new ServiceDescriptionCollection(); + XmlSchemas schemas = new XmlSchemas(); + foreach (DictionaryEntry entry in wsDocuments) + { + if (entry.Value is ServiceDescription) + { + this.wsDescriptions.Add((ServiceDescription)entry.Value); + } + if (entry.Value is XmlSchema) + { + schemas.Add((XmlSchema)entry.Value); + } + } + + // XmlSchemaImporter + foreach (ServiceDescription serviceDescription in this.wsDescriptions) + { + foreach (XmlSchema schema in serviceDescription.Types.Schemas) + { + if (schemas[schema.TargetNamespace] == null) + { + schemas.Add(schema); + } + } + } + this.schemaImporter = new XmlSchemaImporter(schemas); + + this.wsBinding = GetWsBinding(this.wsDescriptions, bindingName); + this.wsUrl = GetWsUrl(this.wsDescriptions, this.wsBinding); + } + + /// + /// Search and returns the binding for the specified name. + /// + private Binding GetWsBinding(ServiceDescriptionCollection serviceDescriptions, string bindingName) + { + if (bindingName != null) + { + // Search for a specific binding + foreach (ServiceDescription description in serviceDescriptions) + { + foreach (Binding binding in description.Bindings) + { + if (binding.Name == bindingName) + { + return binding; + } + } + } + throw new ApplicationException(String.Format("Binding '{0}' does not exist in the WSDL document located at '{1}'", bindingName, this.serviceUri.Description)); + } + else + { + // Use the first one + foreach (ServiceDescription description in serviceDescriptions) + { + foreach (Binding binding in description.Bindings) + { + #region Instrumentation + + if (LOG.IsInfoEnabled) + { + LOG.Info(String.Format("The binding '{0}', found in the WSDL document located at '{1}', will be use.", binding.Name, this.serviceUri.Description)); + } + + #endregion + + return binding; + } + } + throw new ApplicationException(String.Format("No bindings exists in the WSDL document located at '{0}'", this.serviceUri.Description)); + } + } + + /// + /// Search and returns the url for the specified binding. + /// + private string GetWsUrl(ServiceDescriptionCollection serviceDescriptions, Binding binding) + { + foreach (ServiceDescription description in serviceDescriptions) + { + foreach (Service service in description.Services) + { + foreach (Port port in service.Ports) + { + if (port.Binding.Name == binding.Name) + { + SoapAddressBinding soapAddress = (SoapAddressBinding)port.Extensions.Find(typeof(SoapAddressBinding)); + return soapAddress.Location; + } + } + } + } + throw new ApplicationException(String.Format("No SoapAddressBinding has been found for binding '{0}' in the WSDL document located at '{1}'.", binding.Name, serviceUri)); + } + + /// + /// Search and returns the operation that matches the specified method. + /// + private Operation GetOperation(ServiceDescriptionCollection descriptions, Binding binding, MethodInfo method) + { + PortType portType = descriptions.GetPortType(binding.Type); + foreach (Operation operation in portType.Operations) + { + if (operation.Name == method.Name) + { + return operation; + } + } + throw new ApplicationException(String.Format("No Operation has been found for the method '{0}' in the WSDL document located at '{1}'.", method.Name, serviceUri.Description)); + } + + /// + /// Search and returns the OperationBinding that matches the specified Operation. + /// + private OperationBinding GetOperationBinding(Operation operation, Binding binding) + { + foreach (OperationBinding operationBinding in binding.Operations) + { + if (operation.IsBoundBy(operationBinding)) + { + return operationBinding; + } + } + throw new ApplicationException(String.Format("No OperationBinding matches the Operation '{0}' in the WSDL document located at '{2}'.", operation.Name, this.serviceUri.Description)); + } + + /// + /// Search and returns the type mapping between method parameters/return value + /// and the element parts of a literal-use SOAP message. + /// + private XmlMembersMapping GetMembersMapping(string messageName, MessagePartCollection messageParts, SoapBodyBinding soapBodyBinding, SoapBindingStyle soapBindingStyle) + { +#if NET_2_0 + if (soapBindingStyle == SoapBindingStyle.Rpc) + { + SoapSchemaMember[] soapSchemaMembers = new SoapSchemaMember[messageParts.Count]; + for (int i = 0; i < messageParts.Count; i++) + { + SoapSchemaMember ssm = new SoapSchemaMember(); + ssm.MemberName = messageParts[i].Name; + ssm.MemberType = messageParts[i].Type; + soapSchemaMembers[i] = ssm; + } + return this.schemaImporter.ImportMembersMapping(messageName, soapBodyBinding.Namespace, soapSchemaMembers); + } + else + { + return this.schemaImporter.ImportMembersMapping(messageParts[0].Element); + } +#else + return this.schemaImporter.ImportMembersMapping(messageParts[0].Element); +#endif + } + + private void MoveToMethod(MethodInfo targetMethod) + { + operation = GetOperation(this.wsDescriptions, this.wsBinding, targetMethod); + operationBinding = GetOperationBinding(operation, this.wsBinding); + soapOperationBinding = (SoapOperationBinding)operationBinding.Extensions.Find(typeof(SoapOperationBinding)); + + string inputMessageName = (!StringUtils.IsNullOrEmpty(operationBinding.Input.Name) && (soapOperationBinding.Style != SoapBindingStyle.Rpc)) ? operationBinding.Input.Name : operation.Name; + SoapBodyBinding inputSoapBodyBinding = (SoapBodyBinding)operationBinding.Input.Extensions.Find(typeof(SoapBodyBinding)); + +#if !NET_2_0 + if (soapOperationBinding.Style == SoapBindingStyle.Rpc && + inputSoapBodyBinding.Use == SoapBindingUse.Literal) + { + throw new NotSupportedException("rpc-literal SOAP messages are not supported on .NET Framework 1.1"); + } +#endif + if (inputSoapBodyBinding.Use != SoapBindingUse.Literal) + { + throw new NotSupportedException("WebServiceProxyFactory only supports document-literal and rpc-literal SOAP messages to conform to WS-I Basic Profiles."); + } + + Message inputMessage = this.wsDescriptions.GetMessage(operation.Messages.Input.Message); + inputMembersMapping = GetMembersMapping(inputMessageName, inputMessage.Parts, inputSoapBodyBinding, soapOperationBinding.Style); + + outputMembersMapping = null; + if (operation.Messages.Output != null) + { + string outputMessageName = (!StringUtils.IsNullOrEmpty(operationBinding.Output.Name) && (soapOperationBinding.Style != SoapBindingStyle.Rpc)) ? operationBinding.Output.Name : (operation.Name + "Response"); + SoapBodyBinding outputSoapBodyBinding = (SoapBodyBinding)operationBinding.Output.Extensions.Find(typeof(SoapBodyBinding)); + Message outputMessage = this.wsDescriptions.GetMessage(operation.Messages.Output.Message); + outputMembersMapping = GetMembersMapping(outputMessageName, outputMessage.Parts, outputSoapBodyBinding, soapOperationBinding.Style); + } + } + + /// + /// Creates a that should be applied to proxy type. + /// + private CustomAttributeBuilder CreateWebServiceBindingAttribute(Binding wsBinding) + { + ReflectionUtils.CustomAttributeBuilderBuilder cabb = + new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(WebServiceBindingAttribute)); + + cabb.AddContructorArgument(this.wsBinding.Name); + cabb.AddPropertyValue("Namespace", this.wsBinding.ServiceDescription.TargetNamespace); + + return cabb.Build(); + } + +#if !NET_2_0 + private static readonly PropertyInfo XmlMembersMapping_ElementName = + typeof(XmlMembersMapping).GetProperty("ElementName"); + + private static readonly PropertyInfo XmlMembersMapping_Namespace = + typeof(XmlMembersMapping).GetProperty("Namespace"); +#endif + + /// + /// Creates a or a + /// that should be applied to proxy method. + /// + private static CustomAttributeBuilder CreateSoapMethodAttribute(Operation operation, + OperationBinding operationBinding, SoapOperationBinding soapOperationBinding, + XmlMembersMapping inputMembersMapping, XmlMembersMapping outputMembersMapping) + { + ReflectionUtils.CustomAttributeBuilderBuilder cabb; + +#if !NET_2_0 + // Access XmlMembersMapping.ElementName and .Namespace property using reflection [SPRNET-520] + string inputMembersMappingElementName = XmlMembersMapping_ElementName.GetValue(inputMembersMapping, null) as string; + string inputMembersMappingNamespace = XmlMembersMapping_Namespace.GetValue(inputMembersMapping, null) as string; +#else + string inputMembersMappingElementName = inputMembersMapping.ElementName; + string inputMembersMappingNamespace = inputMembersMapping.Namespace; +#endif + + if (soapOperationBinding.Style == SoapBindingStyle.Rpc) + { + cabb = new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(SoapRpcMethodAttribute)); + } + else + { + cabb = new ReflectionUtils.CustomAttributeBuilderBuilder(typeof(SoapDocumentMethodAttribute)); + cabb.AddPropertyValue("ParameterStyle", SoapParameterStyle.Wrapped); + } + + cabb.AddContructorArgument(soapOperationBinding.SoapAction); + +#if NET_2_0 + cabb.AddPropertyValue("Use", SoapBindingUse.Literal); +#else + if (soapOperationBinding.Style != SoapBindingStyle.Rpc) + { + cabb.AddPropertyValue("Use", SoapBindingUse.Literal); + } +#endif + + if (inputMembersMappingElementName.Length > 0 && + inputMembersMappingElementName != operation.Name) + { + cabb.AddPropertyValue("RequestElementName", inputMembersMappingElementName); + } + + if (inputMembersMappingNamespace != null) + { + cabb.AddPropertyValue("RequestNamespace", inputMembersMappingNamespace); + } + + if (outputMembersMapping == null) + { + cabb.AddPropertyValue("OneWay", true); + } + else + { +#if !NET_2_0 + // Access XmlMembersMapping.ElementName and .Namespace property using reflection [SPRNET-520] + string outputMembersMappingElementName = XmlMembersMapping_ElementName.GetValue(outputMembersMapping, null) as string; + string outputMembersMappingNamespace = XmlMembersMapping_Namespace.GetValue(outputMembersMapping, null) as string; +#else + string outputMembersMappingElementName = outputMembersMapping.ElementName; + string outputMembersMappingNamespace = outputMembersMapping.Namespace; +#endif + if (outputMembersMappingElementName.Length > 0 && + outputMembersMappingElementName != (operation.Name + "Response")) + { + cabb.AddPropertyValue("ResponseElementName", outputMembersMappingElementName); + } + + if (outputMembersMappingNamespace != null) + { + cabb.AddPropertyValue("ResponseNamespace", outputMembersMappingNamespace); + } + } + + return cabb.Build(); + } + + #endregion + + #region SoapHttpClientProxyMethodBuilder inner class implementation + + /// + /// Proxy method builder that can be used to create a proxy method + /// for web services operation invocation. + /// + private sealed class SoapHttpClientProxyMethodBuilder : AbstractProxyMethodBuilder + { + #region Fields + + private static readonly MethodInfo Invoke = + typeof(SoapHttpClientProtocol).GetMethod("Invoke", BindingFlags.NonPublic | BindingFlags.Instance); + + #endregion + + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the method builder. + /// + /// The type builder to use. + /// + /// The implementation to use. + /// + public SoapHttpClientProxyMethodBuilder( + TypeBuilder typeBuilder, IProxyTypeGenerator proxyGenerator) + : base(typeBuilder, proxyGenerator, false) + { + } + + #endregion + + #region Protected Methods + + /// + /// Generates the proxy method. + /// + /// The IL generator to use. + /// The method to proxy. + /// + /// The interface definition of the method, if applicable. + /// + protected override void GenerateMethod( + ILGenerator il, MethodInfo method, MethodInfo interfaceMethod) + { + // In Parameters + ArrayList inParams = new ArrayList(); + // Ref or Out Parameters + ArrayList refOutParams = new ArrayList(); + + foreach (ParameterInfo paramInfo in interfaceMethod.GetParameters()) + { + if (paramInfo.IsRetval || paramInfo.IsOut) + { + refOutParams.Add(paramInfo); + } + else + { + inParams.Add(paramInfo); + } + } + + proxyGenerator.PushTarget(il); + + // Parameter #1 + il.Emit(OpCodes.Ldstr, interfaceMethod.Name); + + // Parameter #2 + LocalBuilder parameters = il.DeclareLocal(typeof(Object[])); + il.Emit(OpCodes.Ldc_I4, inParams.Count); + il.Emit(OpCodes.Newarr, typeof(Object)); + il.Emit(OpCodes.Stloc, parameters); + + int paramIndex = 0; + foreach (ParameterInfo paramInfo in inParams) + { + il.Emit(OpCodes.Ldloc, parameters); + il.Emit(OpCodes.Ldc_I4, paramIndex); + il.Emit(OpCodes.Ldarg, paramInfo.Position + 1); + if (paramInfo.ParameterType.IsValueType) + { + il.Emit(OpCodes.Box, paramInfo.ParameterType); + } + il.Emit(OpCodes.Stelem_Ref); + + paramIndex++; + } + + il.Emit(OpCodes.Ldloc, parameters); + + // Call Invoke method and save result + LocalBuilder results = il.DeclareLocal(typeof(Object[])); + il.EmitCall(OpCodes.Callvirt, Invoke, null); + il.Emit(OpCodes.Stloc, results); + + int resultIndex = (interfaceMethod.ReturnType == typeof(void) ? 0 : 1); + foreach (ParameterInfo paramInfo in refOutParams) + { + il.Emit(OpCodes.Ldarg, paramInfo.Position + 1); + il.Emit(OpCodes.Ldloc, results); + + // Cast / Unbox the return value + il.Emit(OpCodes.Ldc_I4, resultIndex); + il.Emit(OpCodes.Ldelem_Ref); + + Type elementType = paramInfo.ParameterType.GetElementType(); + if (elementType.IsValueType) + { + il.Emit(OpCodes.Unbox, elementType); + il.Emit(OpCodes.Ldobj, elementType); + il.Emit(OpCodes.Stobj, elementType); + } + else + { + il.Emit(OpCodes.Castclass, elementType); + il.Emit(OpCodes.Stind_Ref); + } + + resultIndex++; + } + + if (interfaceMethod.ReturnType != typeof(void)) + { + il.Emit(OpCodes.Ldloc, results); + + // Cast / Unbox the return value + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Ldelem_Ref); + if (interfaceMethod.ReturnType.IsValueType) + { + il.Emit(OpCodes.Unbox, interfaceMethod.ReturnType); + il.Emit(OpCodes.Ldobj, interfaceMethod.ReturnType); + } + else + { + il.Emit(OpCodes.Castclass, interfaceMethod.ReturnType); + } + } + } + + #endregion + } + + #endregion + } + + #endregion + + #region WebServiceProxyProxyTypeBuilder inner class implementation + + /// + /// Proxy type builder that can be used to create a proxy for + /// .Net-generated proxy class that can be safely cast to a service interface. + /// + private sealed class WebServiceProxyProxyTypeBuilder : InheritanceProxyTypeBuilder + { + #region Constructor(s) / Destructor + + /// + /// Creates a new instance of the + /// class. + /// + public WebServiceProxyProxyTypeBuilder() + { + this.Name = "WebServiceProxyProxy"; + } + + #endregion + + #region Protected Methods + + /// + /// Gets the mapping of the interface to proxy + /// into the actual methods on the target type + /// that does not need to implement that interface. + /// + /// + ///

+ /// As the proxy type does not implement the interface, + /// we try to find matching methods. + ///

+ ///
+ /// + /// The of the target object. + /// + /// The interface to implement. + /// + /// An interface mapping for the interface to proxy. + /// + protected override InterfaceMapping GetInterfaceMapping( + Type targetType, Type intf) + { + InterfaceMapping mapping; + + mapping.TargetType = targetType; + mapping.InterfaceType = intf; + mapping.InterfaceMethods = intf.GetMethods(); + mapping.TargetMethods = ReflectionUtils.GetMatchingMethods( + targetType, mapping.InterfaceMethods, true); + + return mapping; + } + + #endregion + } + + #endregion + } } \ No newline at end of file diff --git a/src/Spring/Spring.Testing.NUnit/Spring.Testing.NUnit.xml b/src/Spring/Spring.Testing.NUnit/Spring.Testing.NUnit.xml index 8cc6569d..4056d9d8 100644 --- a/src/Spring/Spring.Testing.NUnit/Spring.Testing.NUnit.xml +++ b/src/Spring/Spring.Testing.NUnit/Spring.Testing.NUnit.xml @@ -49,7 +49,6 @@ Rob Harrop Rick Evans Aleksandar Seovic (.NET) - $Id: AbstractDependencyInjectionSpringContextTests.cs,v 1.4 2008/03/14 12:02:45 oakinger Exp $ @@ -66,7 +65,6 @@ Rod Johnson Aleksandar Seovic (.NET) - $Id: AbstractSpringContextTests.cs,v 1.2 2007/08/20 18:38:11 markpollack Exp $ @@ -290,7 +288,6 @@ Rod Johnson Juergen Hoeller Mark Pollack (.NET) - $Id: AbstractTransactionalDbProviderSpringContextTests.cs,v 1.3 2007/08/03 19:51:16 markpollack Exp $ @@ -344,7 +341,6 @@ Juergen Hoeller Rick Evans Mark Pollack (.NET) - $Id: AbstractTransactionalSpringContextTests.cs,v 1.3 2007/06/01 14:05:57 oakinger Exp $ diff --git a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractDependencyInjectionSpringContextTests.cs b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractDependencyInjectionSpringContextTests.cs index a0d2bc04..a1787c7b 100644 --- a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractDependencyInjectionSpringContextTests.cs +++ b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractDependencyInjectionSpringContextTests.cs @@ -75,7 +75,6 @@ namespace Spring.Testing.NUnit /// Rob Harrop /// Rick Evans /// Aleksandar Seovic (.NET) - /// $Id: AbstractDependencyInjectionSpringContextTests.cs,v 1.4 2008/03/14 12:02:45 oakinger Exp $ public abstract class AbstractDependencyInjectionSpringContextTests : AbstractSpringContextTests { private bool populateProtectedVariables = false; diff --git a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractSpringContextTests.cs b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractSpringContextTests.cs index 7476c857..fc8122f2 100644 --- a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractSpringContextTests.cs +++ b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractSpringContextTests.cs @@ -37,7 +37,6 @@ namespace Spring.Testing.NUnit /// /// Rod Johnson /// Aleksandar Seovic (.NET) - /// $Id: AbstractSpringContextTests.cs,v 1.2 2007/08/20 18:38:11 markpollack Exp $ public abstract class AbstractSpringContextTests { /// diff --git a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalDbProviderSpringContextTests.cs b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalDbProviderSpringContextTests.cs index 5bc0b7c0..9e90754a 100644 --- a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalDbProviderSpringContextTests.cs +++ b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalDbProviderSpringContextTests.cs @@ -18,7 +18,6 @@ namespace Spring.Testing.NUnit /// Rod Johnson /// Juergen Hoeller /// Mark Pollack (.NET) - /// $Id: AbstractTransactionalDbProviderSpringContextTests.cs,v 1.3 2007/08/03 19:51:16 markpollack Exp $ public abstract class AbstractTransactionalDbProviderSpringContextTests : AbstractTransactionalSpringContextTests { /// diff --git a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalSpringContextTests.cs b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalSpringContextTests.cs index a5345cc4..6f3407fc 100644 --- a/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalSpringContextTests.cs +++ b/src/Spring/Spring.Testing.NUnit/Testing/NUnit/AbstractTransactionalSpringContextTests.cs @@ -55,7 +55,6 @@ namespace Spring.Testing.NUnit /// Juergen Hoeller /// Rick Evans /// Mark Pollack (.NET) - /// $Id: AbstractTransactionalSpringContextTests.cs,v 1.3 2007/06/01 14:05:57 oakinger Exp $ public abstract class AbstractTransactionalSpringContextTests : AbstractDependencyInjectionSpringContextTests { /// diff --git a/src/Spring/Spring.Web.Extensions/Spring.Web.Extensions.xml b/src/Spring/Spring.Web.Extensions/Spring.Web.Extensions.xml index 65f389c0..a891c5ec 100644 --- a/src/Spring/Spring.Web.Extensions/Spring.Web.Extensions.xml +++ b/src/Spring/Spring.Web.Extensions/Spring.Web.Extensions.xml @@ -11,7 +11,6 @@ Bruno Baia Thomas Broyer - $Id: ScriptHandlerFactory.cs,v 1.2 2008/03/27 11:11:22 bbaia Exp $ diff --git a/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs b/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs index bc3d7cf9..86d0460e 100644 --- a/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs +++ b/src/Spring/Spring.Web.Extensions/Web/Script/Services/ScriptHandlerFactory.cs @@ -41,7 +41,6 @@ namespace Spring.Web.Script.Services /// /// Bruno Baia /// Thomas Broyer - /// $Id: ScriptHandlerFactory.cs,v 1.2 2008/03/27 11:11:22 bbaia Exp $ public class ScriptHandlerFactory : AbstractHandlerFactory, IHttpHandlerFactory { private static readonly Type scriptHandlerFactoryType = diff --git a/src/Spring/Spring.Web/Caching/AspNetCache.cs b/src/Spring/Spring.Web/Caching/AspNetCache.cs index 911b5c17..f01f72ba 100644 --- a/src/Spring/Spring.Web/Caching/AspNetCache.cs +++ b/src/Spring/Spring.Web/Caching/AspNetCache.cs @@ -42,7 +42,6 @@ namespace Spring.Caching /// /// Aleksandar Seovic /// Erich Eichinger - /// $Id: AspNetCache.cs,v 1.6 2007/09/14 18:26:26 oakinger Exp $ public class AspNetCache : AbstractCache { #region Internal Abstractions diff --git a/src/Spring/Spring.Web/Context/Support/HttpApplicationConfigurer.cs b/src/Spring/Spring.Web/Context/Support/HttpApplicationConfigurer.cs index 42339d19..d7c4845d 100644 --- a/src/Spring/Spring.Web/Context/Support/HttpApplicationConfigurer.cs +++ b/src/Spring/Spring.Web/Context/Support/HttpApplicationConfigurer.cs @@ -36,7 +36,6 @@ namespace Spring.Context.Support /// /// /// Erich Eichinger - /// $Id: HttpApplicationConfigurer.cs,v 1.2 2007/07/29 19:39:42 markpollack Exp $ public class HttpApplicationConfigurer { private static readonly ILog Log = LogManager.GetLogger(typeof(HttpApplicationConfigurer)); diff --git a/src/Spring/Spring.Web/Context/Support/WebContextHandler.cs b/src/Spring/Spring.Web/Context/Support/WebContextHandler.cs index 18eba512..e076ca78 100644 --- a/src/Spring/Spring.Web/Context/Support/WebContextHandler.cs +++ b/src/Spring/Spring.Web/Context/Support/WebContextHandler.cs @@ -45,7 +45,6 @@ namespace Spring.Context.Support /// as default Context-Type. /// /// Erich Eichinger - /// $Id: WebContextHandler.cs,v 1.8 2008/03/13 20:07:43 bbaia Exp $ public class WebContextHandler : ContextHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(WebContextHandler)); diff --git a/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs b/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs index 26311495..43eae8c3 100644 --- a/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs +++ b/src/Spring/Spring.Web/Context/Support/WebSupportModule.cs @@ -44,7 +44,6 @@ namespace Spring.Context.Support /// Provides various support for proper handling requests. /// /// Erich Eichinger - /// $Id: WebSupportModule.cs,v 1.15 2007/08/08 17:48:19 bbaia Exp $ public class WebSupportModule : IHttpModule { private static readonly ILog s_log; diff --git a/src/Spring/Spring.Web/Core/IO/WebResource.cs b/src/Spring/Spring.Web/Core/IO/WebResource.cs index 3a628bfe..26716652 100644 --- a/src/Spring/Spring.Web/Core/IO/WebResource.cs +++ b/src/Spring/Spring.Web/Core/IO/WebResource.cs @@ -39,7 +39,6 @@ namespace Spring.Core.IO ///

/// /// Aleksandar Seovic - /// $Id: WebResource.cs,v 1.14 2008/03/14 12:02:45 oakinger Exp $ public class WebResource : FileSystemResource { private string absolutePath; diff --git a/src/Spring/Spring.Web/DataBinding/HttpRequestBindingContainer.cs b/src/Spring/Spring.Web/DataBinding/HttpRequestBindingContainer.cs index 9ecf3339..f388da04 100644 --- a/src/Spring/Spring.Web/DataBinding/HttpRequestBindingContainer.cs +++ b/src/Spring/Spring.Web/DataBinding/HttpRequestBindingContainer.cs @@ -19,7 +19,6 @@ namespace Spring.DataBinding /// can't use for binding to checkboxes. /// /// Aleksandar Seovic - /// $Id: HttpRequestBindingContainer.cs,v 1.6 2008/02/05 20:40:26 aseovic Exp $ public class HttpRequestListBindingContainer : BaseBindingContainer { private string[] requestParams; diff --git a/src/Spring/Spring.Web/Globalization/AspNetResourceCache.cs b/src/Spring/Spring.Web/Globalization/AspNetResourceCache.cs index 213143d1..76fbbc28 100644 --- a/src/Spring/Spring.Web/Globalization/AspNetResourceCache.cs +++ b/src/Spring/Spring.Web/Globalization/AspNetResourceCache.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization /// Resource cache implementation that uses ASP.NET to cache resources. ///
/// Aleksandar Seovic - /// $Id: AspNetResourceCache.cs,v 1.6 2007/08/03 06:08:59 oakinger Exp $ internal class AspNetResourceCache : AbstractResourceCache { /// diff --git a/src/Spring/Spring.Web/Globalization/Resolvers/CookieCultureResolver.cs b/src/Spring/Spring.Web/Globalization/Resolvers/CookieCultureResolver.cs index 5fd45e42..cd8d3efe 100644 --- a/src/Spring/Spring.Web/Globalization/Resolvers/CookieCultureResolver.cs +++ b/src/Spring/Spring.Web/Globalization/Resolvers/CookieCultureResolver.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Resolvers /// Culture resolver that uses cookie to store culture information. /// /// Aleksandar Seovic - /// $Id: CookieCultureResolver.cs,v 1.4 2007/08/25 14:26:35 oakinger Exp $ public class CookieCultureResolver : DefaultWebCultureResolver { private const string CultureKey = "Spring.UserLocale"; diff --git a/src/Spring/Spring.Web/Globalization/Resolvers/DefaultWebCultureResolver.cs b/src/Spring/Spring.Web/Globalization/Resolvers/DefaultWebCultureResolver.cs index 59418ac5..2305330e 100644 --- a/src/Spring/Spring.Web/Globalization/Resolvers/DefaultWebCultureResolver.cs +++ b/src/Spring/Spring.Web/Globalization/Resolvers/DefaultWebCultureResolver.cs @@ -30,7 +30,6 @@ namespace Spring.Globalization.Resolvers /// Default culture resolver for web applications. Contains some common utility methods for web culture resolvers. ///
/// Aleksandar Seovic - /// $Id: DefaultWebCultureResolver.cs,v 1.5 2007/08/25 14:26:35 oakinger Exp $ public class DefaultWebCultureResolver : DefaultCultureResolver { /// diff --git a/src/Spring/Spring.Web/Globalization/Resolvers/RequestCultureResolver.cs b/src/Spring/Spring.Web/Globalization/Resolvers/RequestCultureResolver.cs index 932f5e42..ae34b3b6 100644 --- a/src/Spring/Spring.Web/Globalization/Resolvers/RequestCultureResolver.cs +++ b/src/Spring/Spring.Web/Globalization/Resolvers/RequestCultureResolver.cs @@ -39,7 +39,6 @@ namespace Spring.Globalization.Resolvers /// the web browser. /// /// Aleksandar Seovic - /// $Id: RequestCultureResolver.cs,v 1.4 2007/08/25 14:26:35 oakinger Exp $ public class RequestCultureResolver : DefaultWebCultureResolver { /// diff --git a/src/Spring/Spring.Web/Globalization/Resolvers/SessionCultureResolver.cs b/src/Spring/Spring.Web/Globalization/Resolvers/SessionCultureResolver.cs index 592d25f6..37ff883a 100644 --- a/src/Spring/Spring.Web/Globalization/Resolvers/SessionCultureResolver.cs +++ b/src/Spring/Spring.Web/Globalization/Resolvers/SessionCultureResolver.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Resolvers /// Culture resolver that uses HTTP session to store culture information. /// /// Aleksandar Seovic - /// $Id: SessionCultureResolver.cs,v 1.3 2007/08/25 14:26:35 oakinger Exp $ public class SessionCultureResolver : DefaultWebCultureResolver { private const string CultureKey = "Spring.UserLocale"; diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/ChildWebObjectDefinition.cs b/src/Spring/Spring.Web/Objects/Factory/Support/ChildWebObjectDefinition.cs index a38e163b..9b690868 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/ChildWebObjectDefinition.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/ChildWebObjectDefinition.cs @@ -36,7 +36,6 @@ namespace Spring.Objects.Factory.Support ///

/// /// Aleksandar Seovic - /// $Id: ChildWebObjectDefinition.cs,v 1.3 2007/08/01 23:10:46 markpollack Exp $ public class ChildWebObjectDefinition : ChildObjectDefinition, IWebObjectDefinition { private ObjectScope _scope = ObjectScope.Default; diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/IWebObjectDefinition.cs b/src/Spring/Spring.Web/Objects/Factory/Support/IWebObjectDefinition.cs index 8a7ed3b6..ec9e377e 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/IWebObjectDefinition.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/IWebObjectDefinition.cs @@ -24,7 +24,6 @@ namespace Spring.Objects.Factory.Support /// Defines additional members web object definitions need to implement. ///
/// Aleksandar Seovic - /// $Id: IWebObjectDefinition.cs,v 1.2 2007/03/26 14:58:38 oakinger Exp $ public interface IWebObjectDefinition { /// diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/ObjectScope.cs b/src/Spring/Spring.Web/Objects/Factory/Support/ObjectScope.cs index 9d611f9f..51ab88ca 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/ObjectScope.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/ObjectScope.cs @@ -24,7 +24,6 @@ namespace Spring.Objects.Factory.Support /// The possible object scope values. /// /// Aleksandar Seovic - /// $Id: ObjectScope.cs,v 1.1 2007/02/17 06:57:44 bbaia Exp $ public enum ObjectScope { /// diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/RootWebObjectDefinition.cs b/src/Spring/Spring.Web/Objects/Factory/Support/RootWebObjectDefinition.cs index 064749f8..36226a50 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/RootWebObjectDefinition.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/RootWebObjectDefinition.cs @@ -40,7 +40,6 @@ namespace Spring.Objects.Factory.Support ///

/// /// Aleksandar Seovic - /// $Id: RootWebObjectDefinition.cs,v 1.4 2007/08/01 23:10:46 markpollack Exp $ public class RootWebObjectDefinition : RootObjectDefinition, IWebObjectDefinition { private ObjectScope _scope = ObjectScope.Default; diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/WebInstantiationStrategy.cs b/src/Spring/Spring.Web/Objects/Factory/Support/WebInstantiationStrategy.cs index 32f1c122..ba8b078d 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/WebInstantiationStrategy.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/WebInstantiationStrategy.cs @@ -39,7 +39,6 @@ namespace Spring.Objects.Factory.Support ///

/// /// Aleksandar Seovic - /// $Id: WebInstantiationStrategy.cs,v 1.4 2008/05/02 16:44:50 markpollack Exp $ [Serializable] public class WebInstantiationStrategy : MethodInjectingInstantiationStrategy { diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectDefinitionFactory.cs b/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectDefinitionFactory.cs index 8332f4a4..752251aa 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectDefinitionFactory.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectDefinitionFactory.cs @@ -40,7 +40,6 @@ namespace Spring.Objects.Factory.Support ///

/// /// Aleksandar Seovic - /// $Id: WebObjectDefinitionFactory.cs,v 1.9 2008/04/07 00:19:55 bbaia Exp $ public class WebObjectDefinitionFactory : DefaultObjectDefinitionFactory { diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectFactory.cs b/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectFactory.cs index 1b223e84..9e09a065 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectFactory.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectFactory.cs @@ -46,7 +46,6 @@ namespace Spring.Objects.Factory.Support ///

/// /// Aleksandar Seovic - /// $Id: WebObjectFactory.cs,v 1.10 2008/05/29 12:13:27 oakinger Exp $ public class WebObjectFactory : DefaultListableObjectFactory { private readonly static ILog log = LogManager.GetLogger(typeof(WebObjectFactory)); diff --git a/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectUtils.cs b/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectUtils.cs index d275a148..51dc3748 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectUtils.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Support/WebObjectUtils.cs @@ -37,7 +37,6 @@ namespace Spring.Objects.Factory.Support /// Miscellaneous utility methods to support web functionality within Spring.Objects ///
/// Aleksandar Seovic - /// $Id: WebObjectUtils.cs,v 1.3 2008/01/27 23:29:55 oakinger Exp $ public sealed class WebObjectUtils { private static ILog s_log = LogManager.GetLogger(typeof(WebObjectUtils)); diff --git a/src/Spring/Spring.Web/Objects/Factory/Xml/WebObjectsNamespaceParser.cs b/src/Spring/Spring.Web/Objects/Factory/Xml/WebObjectsNamespaceParser.cs index e83cb4ba..ce2ba041 100644 --- a/src/Spring/Spring.Web/Objects/Factory/Xml/WebObjectsNamespaceParser.cs +++ b/src/Spring/Spring.Web/Objects/Factory/Xml/WebObjectsNamespaceParser.cs @@ -45,7 +45,6 @@ namespace Spring.Objects.Factory.Xml ///

/// /// Aleksandar Seovic - /// $Id: WebObjectsNamespaceParser.cs,v 1.1 2007/08/07 23:22:30 markpollack Exp $ /// public class WebObjectsNamespaceParser : ObjectsNamespaceParser { diff --git a/src/Spring/Spring.Web/Threading/HttpContextStorage.cs b/src/Spring/Spring.Web/Threading/HttpContextStorage.cs index 4c0d19e0..ae70c40e 100644 --- a/src/Spring/Spring.Web/Threading/HttpContextStorage.cs +++ b/src/Spring/Spring.Web/Threading/HttpContextStorage.cs @@ -6,7 +6,6 @@ namespace Spring.Threading /// Implements by using . ///
/// Erich Eichinger - /// $Id: HttpContextStorage.cs,v 1.1 2007/02/02 21:31:25 oakinger Exp $ public class HttpContextStorage : IThreadStorage { /// diff --git a/src/Spring/Spring.Web/Threading/HybridContextStorage.cs b/src/Spring/Spring.Web/Threading/HybridContextStorage.cs index 7d76ea6d..0004f916 100644 --- a/src/Spring/Spring.Web/Threading/HybridContextStorage.cs +++ b/src/Spring/Spring.Web/Threading/HybridContextStorage.cs @@ -12,7 +12,6 @@ namespace Spring.Threading /// and System.Web.HttpContext to store data. /// /// Erich Eichinger - /// $Id: HybridContextStorage.cs,v 1.1 2007/02/02 21:31:25 oakinger Exp $ public class HybridContextStorage : IThreadStorage { /// diff --git a/src/Spring/Spring.Web/Util/ControlAccessor.cs b/src/Spring/Spring.Web/Util/ControlAccessor.cs index 27a5cc20..9e710bbf 100644 --- a/src/Spring/Spring.Web/Util/ControlAccessor.cs +++ b/src/Spring/Spring.Web/Util/ControlAccessor.cs @@ -34,7 +34,6 @@ namespace Spring.Util /// Helper class for easier access to reflected Control members. /// /// Erich Eichinger - /// $Id: ControlAccessor.cs,v 1.2 2008/05/13 14:22:47 oakinger Exp $ internal class ControlAccessor { private static readonly MethodInfo s_miClear = GetMethod("Clear"); diff --git a/src/Spring/Spring.Web/Util/ControlCollectionAccessor.cs b/src/Spring/Spring.Web/Util/ControlCollectionAccessor.cs index e06dcf1d..c736f651 100644 --- a/src/Spring/Spring.Web/Util/ControlCollectionAccessor.cs +++ b/src/Spring/Spring.Web/Util/ControlCollectionAccessor.cs @@ -31,7 +31,6 @@ namespace Spring.Util /// Helper class for easier access to reflected ControlCollection members. /// /// Erich Eichinger - /// $Id: ControlCollectionAccessor.cs,v 1.3 2008/05/13 23:23:03 oakinger Exp $ internal class ControlCollectionAccessor { private static readonly IDynamicField _owner = new SafeField(typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic)); diff --git a/src/Spring/Spring.Web/Util/HttpContextSwitch.cs b/src/Spring/Spring.Web/Util/HttpContextSwitch.cs index 397244aa..3cf8b0d4 100644 --- a/src/Spring/Spring.Web/Util/HttpContextSwitch.cs +++ b/src/Spring/Spring.Web/Util/HttpContextSwitch.cs @@ -47,7 +47,6 @@ namespace Spring.Util /// /// /// Erich Eichinger - /// $Id: HttpContextSwitch.cs,v 1.1 2007/08/01 23:10:51 markpollack Exp $ public class HttpContextSwitch : IDisposable { private HttpContext savedContext; diff --git a/src/Spring/Spring.Web/Util/VirtualEnvironment.cs b/src/Spring/Spring.Web/Util/VirtualEnvironment.cs index 53443793..9b0e5513 100644 --- a/src/Spring/Spring.Web/Util/VirtualEnvironment.cs +++ b/src/Spring/Spring.Web/Util/VirtualEnvironment.cs @@ -37,7 +37,6 @@ namespace Spring.Util /// For e.g. testing purposes, the default environment implementation may be replaced using . /// /// Erich Eichinger - /// $Id: VirtualEnvironment.cs,v 1.5 2008/03/14 12:02:45 oakinger Exp $ public sealed class VirtualEnvironment { // default to standard HttpRuntime diff --git a/src/Spring/Spring.Web/Util/WebUtils.cs b/src/Spring/Spring.Web/Util/WebUtils.cs index f0858fe5..237fea4a 100644 --- a/src/Spring/Spring.Web/Util/WebUtils.cs +++ b/src/Spring/Spring.Web/Util/WebUtils.cs @@ -32,7 +32,6 @@ namespace Spring.Util /// Miscellaneous web utility methods. ///
/// Aleksandar Seovic - /// $Id: WebUtils.cs,v 1.32 2008/03/19 18:05:07 oakinger Exp $ public sealed class WebUtils { #region Constructor (s) / Destructor diff --git a/src/Spring/Spring.Web/Web/Process/IProcessAware.cs b/src/Spring/Spring.Web/Web/Process/IProcessAware.cs index d8076e2c..427c4204 100644 --- a/src/Spring/Spring.Web/Web/Process/IProcessAware.cs +++ b/src/Spring/Spring.Web/Web/Process/IProcessAware.cs @@ -27,7 +27,6 @@ namespace Spring.Web.Process /// that want to be aware of the they belong to. ///
/// Aleksandar Seovic - /// $Id: IProcessAware.cs,v 1.2 2006/05/18 21:37:52 markpollack Exp $ public interface IProcessAware { /// diff --git a/src/Spring/Spring.Web/Web/Process/ProcessManager.cs b/src/Spring/Spring.Web/Web/Process/ProcessManager.cs index 5b5ae354..89c66723 100644 --- a/src/Spring/Spring.Web/Web/Process/ProcessManager.cs +++ b/src/Spring/Spring.Web/Web/Process/ProcessManager.cs @@ -26,7 +26,6 @@ namespace Spring.Web.Process /// Singleton that keeps track of all active process instances. /// /// Aleksandar Seovic - /// $Id: ProcessManager.cs,v 1.2 2006/05/18 21:37:52 markpollack Exp $ public class ProcessManager { private static readonly ProcessManager instance = new ProcessManager(); diff --git a/src/Spring/Spring.Web/Web/Providers/ConfigurableActiveDirectoryMembershipProvider.cs b/src/Spring/Spring.Web/Web/Providers/ConfigurableActiveDirectoryMembershipProvider.cs index d24b7caa..ac2da7ba 100644 --- a/src/Spring/Spring.Web/Web/Providers/ConfigurableActiveDirectoryMembershipProvider.cs +++ b/src/Spring/Spring.Web/Web/Providers/ConfigurableActiveDirectoryMembershipProvider.cs @@ -38,7 +38,6 @@ namespace Spring.Web.Providers /// A spring configurable version of /// /// Erich Eichinger - /// $Id: ConfigurableActiveDirectoryMembershipProvider.cs,v 1.1 2007/07/26 14:43:56 oakinger Exp $ [DirectoryServicesPermission(SecurityAction.InheritanceDemand, Unrestricted = true)] [DirectoryServicesPermission(SecurityAction.LinkDemand, Unrestricted = true)] [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] diff --git a/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlMembershipProvider.cs b/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlMembershipProvider.cs index 97353d41..75f1f239 100644 --- a/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlMembershipProvider.cs +++ b/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlMembershipProvider.cs @@ -36,7 +36,6 @@ namespace Spring.Web.Providers /// A spring configurable version of /// /// Erich Eichinger - /// $Id: ConfigurableSqlMembershipProvider.cs,v 1.1 2007/07/26 14:43:56 oakinger Exp $ [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class ConfigurableSqlMembershipProvider : SqlMembershipProvider, IMembershipProvider diff --git a/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlProfileProvider.cs b/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlProfileProvider.cs index b9907b2d..05c8a4ba 100644 --- a/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlProfileProvider.cs +++ b/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlProfileProvider.cs @@ -37,7 +37,6 @@ namespace Spring.Web.Providers /// /// /// Erich Eichinger - /// $Id: ConfigurableSqlProfileProvider.cs,v 1.1 2007/07/26 14:43:56 oakinger Exp $ [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class ConfigurableSqlProfileProvider : SqlProfileProvider, IProfileProvider diff --git a/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlRoleProvider.cs b/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlRoleProvider.cs index c5d5c46a..caec208a 100644 --- a/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlRoleProvider.cs +++ b/src/Spring/Spring.Web/Web/Providers/ConfigurableSqlRoleProvider.cs @@ -36,7 +36,6 @@ namespace Spring.Web.Providers /// A spring-configurable version of /// /// Erich Eichinger - /// $Id: ConfigurableSqlRoleProvider.cs,v 1.1 2007/07/26 14:43:56 oakinger Exp $ [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class ConfigurableSqlRoleProvider : SqlRoleProvider, IRoleProvider diff --git a/src/Spring/Spring.Web/Web/Providers/ConfigurableXmlSiteMapProvider.cs b/src/Spring/Spring.Web/Web/Providers/ConfigurableXmlSiteMapProvider.cs index 3b0f4245..0eb2bdd7 100644 --- a/src/Spring/Spring.Web/Web/Providers/ConfigurableXmlSiteMapProvider.cs +++ b/src/Spring/Spring.Web/Web/Providers/ConfigurableXmlSiteMapProvider.cs @@ -35,7 +35,6 @@ namespace Spring.Web.Providers /// A spring-configurable version of /// /// Erich Eichinger - /// $Id: ConfigurableXmlSiteMapProvider.cs,v 1.1 2007/07/26 14:43:56 oakinger Exp $ [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class ConfigurableXmlSiteMapProvider : XmlSiteMapProvider, ISiteMapProvider diff --git a/src/Spring/Spring.Web/Web/Providers/MembershipProviderAdapter.cs b/src/Spring/Spring.Web/Web/Providers/MembershipProviderAdapter.cs index e09be99b..12647e98 100644 --- a/src/Spring/Spring.Web/Web/Providers/MembershipProviderAdapter.cs +++ b/src/Spring/Spring.Web/Web/Providers/MembershipProviderAdapter.cs @@ -43,7 +43,6 @@ namespace Spring.Web.Providers ///

///
/// Damjan Tomic - /// $Id: MembershipProviderAdapter.cs,v 1.1 2007/07/26 14:43:56 oakinger Exp $ [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class MembershipProviderAdapter : MembershipProvider, IMembershipProvider diff --git a/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs b/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs index 8dee0d9d..e7ccb027 100644 --- a/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs +++ b/src/Spring/Spring.Web/Web/Services/WebServiceExporter.cs @@ -57,7 +57,6 @@ namespace Spring.Web.Services ///

/// /// Aleksandar Seovic - /// $Id: WebServiceExporter.cs,v 1.33 2008/04/07 11:00:24 bbaia Exp $ public class WebServiceExporter : IInitializingObject, IObjectFactoryAware, IFactoryObject, IObjectNameAware { #region Fields diff --git a/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs b/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs index f25c41ee..e17d8db9 100644 --- a/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs +++ b/src/Spring/Spring.Web/Web/Services/WebServiceHandlerFactory.cs @@ -46,7 +46,6 @@ namespace Spring.Web.Services /// to find web service object in the Spring context. /// /// Aleksandar Seovic - /// $Id: WebServiceHandlerFactory.cs,v 1.12 2008/03/19 18:05:08 oakinger Exp $ [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted=true)] public class WebServiceHandlerFactory : System.Web.Services.Protocols.WebServiceHandlerFactory, IHttpHandlerFactory { diff --git a/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs b/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs index 4be9f3c6..71496b61 100644 --- a/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs +++ b/src/Spring/Spring.Web/Web/Support/AbstractHandlerFactory.cs @@ -41,7 +41,6 @@ namespace Spring.Web.Support ///

/// /// Aleksandar Seovic - /// $Id: AbstractHandlerFactory.cs,v 1.5 2008/03/19 18:05:08 oakinger Exp $ public abstract class AbstractHandlerFactory : IHttpHandlerFactory { /// diff --git a/src/Spring/Spring.Web/Web/Support/AbstractProcessHandler.cs b/src/Spring/Spring.Web/Web/Support/AbstractProcessHandler.cs index cc2060e0..96588e88 100644 --- a/src/Spring/Spring.Web/Web/Support/AbstractProcessHandler.cs +++ b/src/Spring/Spring.Web/Web/Support/AbstractProcessHandler.cs @@ -38,7 +38,6 @@ namespace Spring.Web.Support /// An abstract base class that defines common behavior for different process implementations. /// /// Aleksandar Seovic - /// $Id: AbstractProcessHandler.cs,v 1.1 2007/08/03 08:31:25 oakinger Exp $ public abstract class AbstractProcessHandler : IProcess, ISharedStateAware, IApplicationContextAware, IHttpHandler, IRequiresSessionState { /// diff --git a/src/Spring/Spring.Web/Web/Support/ContextMonitor.cs b/src/Spring/Spring.Web/Web/Support/ContextMonitor.cs index 66d69310..c5c4cfec 100644 --- a/src/Spring/Spring.Web/Web/Support/ContextMonitor.cs +++ b/src/Spring/Spring.Web/Web/Support/ContextMonitor.cs @@ -39,7 +39,6 @@ namespace Spring.Web.Support ///

/// /// Aleksandar Seovic - /// $Id: ContextMonitor.cs,v 1.3 2007/07/29 19:39:48 markpollack Exp $ public class ContextMonitor : IHttpHandler { /// diff --git a/src/Spring/Spring.Web/Web/Support/ControlInterceptor.cs b/src/Spring/Spring.Web/Web/Support/ControlInterceptor.cs index ea0d0419..2d738bd1 100644 --- a/src/Spring/Spring.Web/Web/Support/ControlInterceptor.cs +++ b/src/Spring/Spring.Web/Web/Support/ControlInterceptor.cs @@ -31,7 +31,6 @@ namespace Spring.Web.Support /// Support Class providing a method to ensure a control has been intercepted /// /// Erich Eichinger - /// $Id: ControlInterceptor.cs,v 1.2 2008/05/13 14:22:47 oakinger Exp $ internal sealed class ControlInterceptor { /// diff --git a/src/Spring/Spring.Web/Web/Support/IInterceptionStrategy.cs b/src/Spring/Spring.Web/Web/Support/IInterceptionStrategy.cs index 611ab12d..9a716ff0 100644 --- a/src/Spring/Spring.Web/Web/Support/IInterceptionStrategy.cs +++ b/src/Spring/Spring.Web/Web/Support/IInterceptionStrategy.cs @@ -29,7 +29,6 @@ namespace Spring.Web.Support /// Any concrete interception strategy must implement this interface /// /// Erich Eichinger - /// $Id: IInterceptionStrategy.cs,v 1.1 2007/08/01 23:11:00 markpollack Exp $ internal interface IInterceptionStrategy { /// diff --git a/src/Spring/Spring.Web/Web/Support/ISupportsWebDependencyInjection.cs b/src/Spring/Spring.Web/Web/Support/ISupportsWebDependencyInjection.cs index ec884cf8..4718584a 100644 --- a/src/Spring/Spring.Web/Web/Support/ISupportsWebDependencyInjection.cs +++ b/src/Spring/Spring.Web/Web/Support/ISupportsWebDependencyInjection.cs @@ -89,7 +89,6 @@ namespace Spring.Web.Support /// /// /// Erich Eichinger - /// $Id: ISupportsWebDependencyInjection.cs,v 1.2 2007/08/01 23:11:00 markpollack Exp $ public interface ISupportsWebDependencyInjection { /// diff --git a/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionOwnerStrategy.cs b/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionOwnerStrategy.cs index ab1a4e6a..832cd085 100644 --- a/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionOwnerStrategy.cs +++ b/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionOwnerStrategy.cs @@ -29,7 +29,6 @@ namespace Spring.Web.Support /// This strategy replaces the original collection's owner with an intercepting proxy /// /// Erich Eichinger - /// $Id: InterceptControlCollectionOwnerStrategy.cs,v 1.1 2007/08/01 23:11:01 markpollack Exp $ internal class InterceptControlCollectionOwnerStrategy : IInterceptionStrategy { public bool Intercept(IApplicationContext defaultApplicationContext, ControlAccessor ctlAccessor, diff --git a/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs b/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs index cc4533b6..651eb182 100644 --- a/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs +++ b/src/Spring/Spring.Web/Web/Support/InterceptControlCollectionStrategy.cs @@ -43,7 +43,6 @@ namespace Spring.Web.Support /// dynamically implementing ISupportsWebDependencyInjection on this type /// /// Erich Eichinger - /// $Id: InterceptControlCollectionStrategy.cs,v 1.2 2008/05/13 14:22:47 oakinger Exp $ internal class InterceptControlCollectionStrategy : IInterceptionStrategy { /// diff --git a/src/Spring/Spring.Web/Web/Support/MimeMediaType.cs b/src/Spring/Spring.Web/Web/Support/MimeMediaType.cs index 5ee08d97..d46ab8b1 100644 --- a/src/Spring/Spring.Web/Web/Support/MimeMediaType.cs +++ b/src/Spring/Spring.Web/Web/Support/MimeMediaType.cs @@ -32,7 +32,6 @@ namespace Spring.Web.Support /// Represents a MIME media type as defined by http://www.iana.org/assignments/media-types/ /// /// Erich Eichinger - /// $Id: MimeMediaType.cs,v 1.1 2007/11/28 23:26:10 oakinger Exp $ public class MimeMediaType { private static readonly ArrayList ContentTypes = new ArrayList( new string[] { diff --git a/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs b/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs index ae15ced7..02527e19 100644 --- a/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs +++ b/src/Spring/Spring.Web/Web/Support/PageHandlerFactory.cs @@ -66,7 +66,6 @@ namespace Spring.Web.Support /// /// /// Aleksandar Seovic - /// $Id: PageHandlerFactory.cs,v 1.41 2008/05/15 12:35:27 oakinger Exp $ public class PageHandlerFactory : AbstractHandlerFactory { private readonly ILog Log = LogManager.GetLogger(typeof(PageHandlerFactory)); diff --git a/src/Spring/Spring.Web/Web/Support/Result.cs b/src/Spring/Spring.Web/Web/Support/Result.cs index 996f7d6c..528676c9 100644 --- a/src/Spring/Spring.Web/Web/Support/Result.cs +++ b/src/Spring/Spring.Web/Web/Support/Result.cs @@ -72,7 +72,6 @@ namespace Spring.Web.Support /// /// Aleksandar Seovic /// Matan Shapira - /// $Id: Result.cs,v 1.13 2008/02/02 09:12:44 oakinger Exp $ [Serializable] public class Result { diff --git a/src/Spring/Spring.Web/Web/Support/ResultMode.cs b/src/Spring/Spring.Web/Web/Support/ResultMode.cs index 6c0aca1e..43e03c55 100644 --- a/src/Spring/Spring.Web/Web/Support/ResultMode.cs +++ b/src/Spring/Spring.Web/Web/Support/ResultMode.cs @@ -30,7 +30,6 @@ namespace Spring.Web.Support /// The various result modes. ///
/// Aleksandar Seovic - /// $Id: ResultMode.cs,v 1.3 2007/04/19 07:49:01 oakinger Exp $ /// [Serializable] public enum ResultMode diff --git a/src/Spring/Spring.Web/Web/Support/Script.cs b/src/Spring/Spring.Web/Web/Support/Script.cs index 6798eb2a..bcfaac02 100644 --- a/src/Spring/Spring.Web/Web/Support/Script.cs +++ b/src/Spring/Spring.Web/Web/Support/Script.cs @@ -32,7 +32,6 @@ namespace Spring.Web.Support ///

/// /// Aleksandar Seovic - /// $Id: Script.cs,v 1.4 2007/11/28 23:26:10 oakinger Exp $ internal abstract class Script { internal static readonly MimeMediaType DefaultType = MimeMediaType.Text.Javascript; @@ -87,7 +86,6 @@ namespace Spring.Web.Support ///

/// /// Aleksandar Seovic - /// $Id: Script.cs,v 1.4 2007/11/28 23:26:10 oakinger Exp $ internal class ScriptBlock : Script { private string script; @@ -132,7 +130,6 @@ namespace Spring.Web.Support ///

/// /// Aleksandar Seovic - /// $Id: Script.cs,v 1.4 2007/11/28 23:26:10 oakinger Exp $ internal class ScriptFile : Script { private string fileName; @@ -178,7 +175,6 @@ namespace Spring.Web.Support ///

/// /// Aleksandar Seovic - /// $Id: Script.cs,v 1.4 2007/11/28 23:26:10 oakinger Exp $ internal class ScriptEvent : ScriptBlock { private string element; diff --git a/src/Spring/Spring.Web/Web/Support/SharedStateResourceCache.cs b/src/Spring/Spring.Web/Web/Support/SharedStateResourceCache.cs index e9e633af..9705d96c 100644 --- a/src/Spring/Spring.Web/Web/Support/SharedStateResourceCache.cs +++ b/src/Spring/Spring.Web/Web/Support/SharedStateResourceCache.cs @@ -32,7 +32,6 @@ namespace Spring.Web.Support /// Resource cache implementation that uses Spring.NET page/handler state to cache resources. /// /// Aleksandar Seovic - /// $Id: SharedStateResourceCache.cs,v 1.1 2007/08/03 08:31:25 oakinger Exp $ internal class SharedStateResourceCache : AbstractResourceCache { private readonly ISharedStateAware sharedStateHolder; diff --git a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionMethodBuilder.cs b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionMethodBuilder.cs index c8fa570c..16a9ff4f 100644 --- a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionMethodBuilder.cs +++ b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionMethodBuilder.cs @@ -30,7 +30,6 @@ namespace Spring.Web.Support /// This MethodBuilder emits a Callback-call before calling the base method /// /// Erich Eichinger - /// $Id: SupportsWebDependencyInjectionMethodBuilder.cs,v 1.1 2007/08/01 23:11:01 markpollack Exp $ internal class SupportsWebDependencyInjectionMethodBuilder : BaseProxyMethodBuilder { private FieldInfo _appContextField; diff --git a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs index 6711a42d..f3ea2bf3 100644 --- a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs +++ b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionOwnerProxy.cs @@ -32,7 +32,6 @@ namespace Spring.Web.Support /// Wraps a Control to make it DI aware /// /// Erich Eichinger - /// $Id: SupportsWebDependencyInjectionOwnerProxy.cs,v 1.2 2008/05/13 14:22:47 oakinger Exp $ internal class SupportsWebDependencyInjectionOwnerProxy : Control, ISupportsWebDependencyInjection { // Control Fields and Methods diff --git a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionTypeBuilder.cs b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionTypeBuilder.cs index e929a85e..2179bef7 100644 --- a/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionTypeBuilder.cs +++ b/src/Spring/Spring.Web/Web/Support/SupportsWebDependencyInjectionTypeBuilder.cs @@ -35,7 +35,6 @@ namespace Spring.Web.Support /// This TypeBuilder dynamically implements the contract on a given type. /// /// Erich Eichinger - /// $Id: SupportsWebDependencyInjectionTypeBuilder.cs,v 1.1 2007/08/01 23:11:01 markpollack Exp $ internal class SupportsWebDependencyInjectionTypeBuilder : InheritanceProxyTypeBuilder { private const string PROXY_TYPE_NAME = "SupportsWebDependencyInjectionControlProxy"; diff --git a/src/Spring/Spring.Web/Web/Support/WebDependencyInjectionUtils.cs b/src/Spring/Spring.Web/Web/Support/WebDependencyInjectionUtils.cs index 22a70d26..cea2a1cb 100644 --- a/src/Spring/Spring.Web/Web/Support/WebDependencyInjectionUtils.cs +++ b/src/Spring/Spring.Web/Web/Support/WebDependencyInjectionUtils.cs @@ -26,13 +26,8 @@ using Spring.Util; namespace Spring.Web.Support { /// - /// This is + /// Utilities for dependency injection in the web tier. /// - /// - /// - /// - /// Mark Pollack - /// $Id: WebDependencyInjectionUtils.cs,v 1.3 2008/05/13 14:22:47 oakinger Exp $ public class WebDependencyInjectionUtils { /// diff --git a/src/Spring/Spring.Web/Web/UI/AbstractWizard.cs b/src/Spring/Spring.Web/Web/UI/AbstractWizard.cs index e12c2a44..21203a9e 100644 --- a/src/Spring/Spring.Web/Web/UI/AbstractWizard.cs +++ b/src/Spring/Spring.Web/Web/UI/AbstractWizard.cs @@ -42,7 +42,6 @@ namespace Spring.Web.UI ///

/// /// Aleksandar Seovic - /// $Id: AbstractWizard.cs,v 1.7 2006/05/18 21:37:52 markpollack Exp $ public abstract class AbstractWizard : Page { private IList steps; diff --git a/src/Spring/Spring.Web/Web/UI/Controls/AbstractBaseValidator.cs b/src/Spring/Spring.Web/Web/UI/Controls/AbstractBaseValidator.cs index 8d7724c0..2d69b971 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/AbstractBaseValidator.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/AbstractBaseValidator.cs @@ -34,7 +34,6 @@ namespace Spring.Web.UI.Controls /// but are unfortunately not accessible from ///
/// Erich Eichinger - /// $Id: AbstractBaseValidator.cs,v 1.1 2007/07/31 10:40:58 oakinger Exp $ public abstract class AbstractBaseValidator : System.Web.UI.WebControls.BaseValidator { /// diff --git a/src/Spring/Spring.Web/Web/UI/Controls/AbstractValidationControl.cs b/src/Spring/Spring.Web/Web/UI/Controls/AbstractValidationControl.cs index 42d2a1f7..7a3b7b2b 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/AbstractValidationControl.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/AbstractValidationControl.cs @@ -33,7 +33,6 @@ namespace Spring.Web.UI.Controls /// Provides common functionality to all validation renderer controls. /// /// Erich Eichinger - /// $Id: AbstractValidationControl.cs,v 1.1 2008/03/19 12:07:14 oakinger Exp $ public abstract class AbstractValidationControl : Control { private string provider; diff --git a/src/Spring/Spring.Web/Web/UI/Controls/Calendar.cs b/src/Spring/Spring.Web/Web/UI/Controls/Calendar.cs index d3cea716..edf448e7 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/Calendar.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/Calendar.cs @@ -43,7 +43,6 @@ namespace Spring.Web.UI.Controls ///

/// /// Aleksandar Seovic - /// $Id: Calendar.cs,v 1.13 2007/12/07 21:06:35 oakinger Exp $ [ValidationProperty("SelectedDate")] public class Calendar : WebControl, IPostBackDataHandler { diff --git a/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxList.cs b/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxList.cs index 293776a5..7a28c9f4 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxList.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxList.cs @@ -35,7 +35,6 @@ namespace Spring.Web.UI.Controls /// When using Spring.Web's DataBinding, you should use this control for easier binding declaration. /// /// Erich Eichinger - /// $Id: CheckBoxList.cs,v 1.2 2007/12/14 16:38:44 oakinger Exp $ public class CheckBoxList : System.Web.UI.WebControls.CheckBoxList { /// diff --git a/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxValidator.cs b/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxValidator.cs index 09f35a02..b508f739 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxValidator.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/CheckBoxValidator.cs @@ -32,7 +32,6 @@ namespace Spring.Web.UI.Controls /// This validator allows for validating a CheckBox's "Checked" state. /// /// Erich Eichinger - /// $Id: CheckBoxValidator.cs,v 1.1 2007/07/31 10:40:59 oakinger Exp $ [ToolboxData("<{0}:RequiredCheckBoxValidator runat=\"server\" ErrorMessage=\"RequiredCheckBoxValidator\">")] public class RequiredCheckBoxValidator : AbstractBaseValidator { diff --git a/src/Spring/Spring.Web/Web/UI/Controls/Content.cs b/src/Spring/Spring.Web/Web/UI/Controls/Content.cs index 0186e910..cc566442 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/Content.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/Content.cs @@ -38,7 +38,6 @@ namespace Spring.Web.UI.Controls /// within the master page /// /// Aleksandar Seovic - /// $Id: Content.cs,v 1.6 2007/07/24 13:33:27 oakinger Exp $ #if NET_2_0 public class Content : System.Web.UI.WebControls.Content {} diff --git a/src/Spring/Spring.Web/Web/UI/Controls/ContentPlaceholder.cs b/src/Spring/Spring.Web/Web/UI/Controls/ContentPlaceholder.cs index 3cbf459e..a738a484 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/ContentPlaceholder.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/ContentPlaceholder.cs @@ -33,7 +33,6 @@ namespace Spring.Web.UI.Controls /// by defining matching control. /// /// Aleksandar Seovic - /// $Id: ContentPlaceholder.cs,v 1.6 2006/09/08 06:21:31 oakinger Exp $ #if NET_2_0 public class ContentPlaceHolder : System.Web.UI.WebControls.ContentPlaceHolder {} diff --git a/src/Spring/Spring.Web/Web/UI/Controls/ContentReplacer.cs b/src/Spring/Spring.Web/Web/UI/Controls/ContentReplacer.cs index 9d74e543..d9629be2 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/ContentReplacer.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/ContentReplacer.cs @@ -45,7 +45,6 @@ namespace Spring.Web.UI.Controls /// /// /// Erich Eichinger - /// $Id: ContentReplacer.cs,v 1.3 2007/07/24 13:33:27 oakinger Exp $ public class ContentReplacer : Control { private static readonly ILog log = LogManager.GetLogger(typeof(ContentReplacer)); diff --git a/src/Spring/Spring.Web/Web/UI/Controls/ControlState.cs b/src/Spring/Spring.Web/Web/UI/Controls/ControlState.cs index 9aa16ec2..91869ea5 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/ControlState.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/ControlState.cs @@ -31,7 +31,6 @@ namespace Spring.Web.UI.Controls /// Enumeration representing a control's current initialization state. /// /// Erich Eichinger - /// $Id: ControlState.cs,v 1.1 2007/07/24 13:33:27 oakinger Exp $ internal enum ControlState { Constructed, diff --git a/src/Spring/Spring.Web/Web/UI/Controls/DataBindingPanel.cs b/src/Spring/Spring.Web/Web/UI/Controls/DataBindingPanel.cs index 9de9efc0..446b9dcc 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/DataBindingPanel.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/DataBindingPanel.cs @@ -47,7 +47,6 @@ namespace Spring.Web.UI.Controls /// to a model by adding an attribute "BindingTarget" /// /// Erich Eichinger - /// $Id: DataBindingPanel.cs,v 1.13 2008/03/06 20:23:44 oakinger Exp $ [PersistChildren(true), ToolboxData("<{0}:DataBindingPanel runat=\"server\" Width=\"125px\" Height=\"50px\"> "), ParseChildren(false), diff --git a/src/Spring/Spring.Web/Web/UI/Controls/Form.cs b/src/Spring/Spring.Web/Web/UI/Controls/Form.cs index 37dca733..58f0adc9 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/Form.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/Form.cs @@ -39,7 +39,6 @@ namespace Spring.Web.UI.Controls /// and also JIRA SPRNET-560 for more info. /// /// Erich Eichinger - /// $Id: Form.cs,v 1.1 2007/07/24 14:32:58 oakinger Exp $ public class Form : HtmlForm { private bool suppressAction = false; diff --git a/src/Spring/Spring.Web/Web/UI/Controls/Head.cs b/src/Spring/Spring.Web/Web/UI/Controls/Head.cs index fc55867c..b4a2dd47 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/Head.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/Head.cs @@ -44,7 +44,6 @@ namespace Spring.Web.UI.Controls /// /// /// Aleksandar Seovic - /// $Id: Head.cs,v 1.8 2007/11/28 23:26:19 oakinger Exp $ public class Head : Control { private string _defaultStyleType = "text/css"; diff --git a/src/Spring/Spring.Web/Web/UI/Controls/LocalizedImage.cs b/src/Spring/Spring.Web/Web/UI/Controls/LocalizedImage.cs index 8977b0d3..5b694386 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/LocalizedImage.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/LocalizedImage.cs @@ -29,7 +29,6 @@ namespace Spring.Web.UI.Controls /// in order to render dynamicaly registered head scripts and stylesheets. /// /// Aleksandar Seovic - /// $Id: LocalizedImage.cs,v 1.4 2006/05/18 21:37:52 markpollack Exp $ public class LocalizedImage : System.Web.UI.WebControls.Image { private string imageName; diff --git a/src/Spring/Spring.Web/Web/UI/Controls/MultiView.cs b/src/Spring/Spring.Web/Web/UI/Controls/MultiView.cs index e6cf94bb..a086f9d8 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/MultiView.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/MultiView.cs @@ -38,7 +38,6 @@ namespace Spring.Web.UI.Controls /// This controls provides MultiView introduced with ASP.NET 2.0 for NET 1.1 Platform /// /// Erich Eichinger - /// $Id: MultiView.cs,v 1.1 2007/07/24 13:33:27 oakinger Exp $ [ DefaultEvent("ActiveViewChanged") , ToolboxData("<{0}:MultiView runat=\"server\">") diff --git a/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs b/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs index cd189094..de2e2b10 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/Panel.cs @@ -46,7 +46,6 @@ namespace Spring.Web.UI.Controls /// over which controls are to be injected or not. /// /// Erich Eichinger - /// $Id: Panel.cs,v 1.3 2008/03/09 15:20:37 oakinger Exp $ [PersistChildren(true), ToolboxData("<{0}:Panel runat=\"server\" Width=\"125px\" Height=\"50px\"> "), ParseChildren(false), diff --git a/src/Spring/Spring.Web/Web/UI/Controls/RadioButtonGroup.cs b/src/Spring/Spring.Web/Web/UI/Controls/RadioButtonGroup.cs index d44be09b..6b5b37f4 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/RadioButtonGroup.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/RadioButtonGroup.cs @@ -35,7 +35,6 @@ namespace Spring.Web.UI.Controls /// This control alows radio buttons to be data-bound to a data model of the page. /// /// Aleksandar Seovic - /// $Id: RadioButtonGroup.cs,v 1.5 2007/03/16 22:38:55 oakinger Exp $ [ParseChildren(false)] public class RadioButtonGroup : WebControl, IPostBackDataHandler { diff --git a/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventArgs.cs b/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventArgs.cs index 725f14ca..cc3dcc35 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventArgs.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventArgs.cs @@ -32,7 +32,6 @@ namespace Spring.Web.UI.Controls /// Provides information about a command raised from a /// /// Erich Eichinger - /// $Id: TabCommandEventArgs.cs,v 1.1 2007/07/24 13:33:27 oakinger Exp $ public class TabCommandEventArgs : CommandEventArgs { /// diff --git a/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventHandler.cs b/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventHandler.cs index db0ad439..92cb3288 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventHandler.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/TabCommandEventHandler.cs @@ -32,6 +32,5 @@ namespace Spring.Web.UI.Controls /// The source of the event. /// A that contains the event data. /// Erich Eichinger - /// $Id: TabCommandEventHandler.cs,v 1.1 2007/07/24 13:33:28 oakinger Exp $ public delegate void TabCommandEventHandler(object sender, TabCommandEventArgs e); } \ No newline at end of file diff --git a/src/Spring/Spring.Web/Web/UI/Controls/TabContainer.cs b/src/Spring/Spring.Web/Web/UI/Controls/TabContainer.cs index 82ae2fab..5405ea0b 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/TabContainer.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/TabContainer.cs @@ -36,7 +36,6 @@ namespace Spring.Web.UI.Controls /// render tabs. Override to change this behaviour. /// /// Erich Eichinger - /// $Id: TabContainer.cs,v 1.1 2007/07/24 13:33:28 oakinger Exp $ public class TabContainer : Control { /// diff --git a/src/Spring/Spring.Web/Web/UI/Controls/TabularMultiView.cs b/src/Spring/Spring.Web/Web/UI/Controls/TabularMultiView.cs index f06ae0ae..4e23804f 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/TabularMultiView.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/TabularMultiView.cs @@ -36,7 +36,6 @@ namespace Spring.Web.UI.Controls /// the user with content arranged in tabular form. /// /// Erich Eichinger - /// $Id: TabularMultiView.cs,v 1.1 2007/07/24 13:33:28 oakinger Exp $ [ToolboxData("<{0}:TabularMultiView runat=\"server\">")] [ParseChildren(false)] public class TabularMultiView : WebControl diff --git a/src/Spring/Spring.Web/Web/UI/Controls/TabularView.cs b/src/Spring/Spring.Web/Web/UI/Controls/TabularView.cs index 0ad74d99..6d580903 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/TabularView.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/TabularView.cs @@ -33,7 +33,6 @@ namespace Spring.Web.UI.Controls /// Represents a control that acts as a container for a group of controls within a control. /// /// Erich Eichinger - /// $Id: TabularView.cs,v 1.2 2007/07/24 14:32:58 oakinger Exp $ [ToolboxData("<{0}:TabularView runat=\"server\">")] public class TabularView : View { diff --git a/src/Spring/Spring.Web/Web/UI/Controls/TabularViewCollection.cs b/src/Spring/Spring.Web/Web/UI/Controls/TabularViewCollection.cs index f1535767..2c6ca4f4 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/TabularViewCollection.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/TabularViewCollection.cs @@ -34,7 +34,6 @@ namespace Spring.Web.UI.Controls /// Holds the collection of controls in a . /// /// Erich Eichinger - /// $Id: TabularViewCollection.cs,v 1.1 2007/07/24 13:33:28 oakinger Exp $ [ AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal) , AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] diff --git a/src/Spring/Spring.Web/Web/UI/Controls/ValidationError.cs b/src/Spring/Spring.Web/Web/UI/Controls/ValidationError.cs index 6c035010..98f4f2fb 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/ValidationError.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/ValidationError.cs @@ -31,7 +31,6 @@ namespace Spring.Web.UI.Controls /// /// Aleksandar Seovic /// Jonathan Allenby - /// $Id: ValidationError.cs,v 1.11 2008/03/19 12:07:14 oakinger Exp $ public class ValidationError : AbstractValidationControl { /// diff --git a/src/Spring/Spring.Web/Web/UI/Controls/ValidationSummary.cs b/src/Spring/Spring.Web/Web/UI/Controls/ValidationSummary.cs index 3f56d6d7..19cccabd 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/ValidationSummary.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/ValidationSummary.cs @@ -32,7 +32,6 @@ namespace Spring.Web.UI.Controls /// /// Aleksandar Seovic /// Jonathan Allenby - /// $Id: ValidationSummary.cs,v 1.11 2008/03/19 12:07:14 oakinger Exp $ public class ValidationSummary : AbstractValidationControl { /// diff --git a/src/Spring/Spring.Web/Web/UI/Controls/ViewCollection.cs b/src/Spring/Spring.Web/Web/UI/Controls/ViewCollection.cs index 81ffb7de..b7ef59cd 100644 --- a/src/Spring/Spring.Web/Web/UI/Controls/ViewCollection.cs +++ b/src/Spring/Spring.Web/Web/UI/Controls/ViewCollection.cs @@ -34,7 +34,6 @@ namespace Spring.Web.UI.Controls /// Represents a collection container that enables a control to maintain a list of its child controls. /// /// Erich Eichinger - /// $Id: ViewCollection.cs,v 1.1 2007/07/24 13:33:28 oakinger Exp $ [ AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal) , AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] diff --git a/src/Spring/Spring.Web/Web/UI/DialogAttribute.cs b/src/Spring/Spring.Web/Web/UI/DialogAttribute.cs index 0cafaa86..27540a20 100644 --- a/src/Spring/Spring.Web/Web/UI/DialogAttribute.cs +++ b/src/Spring/Spring.Web/Web/UI/DialogAttribute.cs @@ -36,7 +36,6 @@ namespace Spring.Web.UI ///

/// /// Aleksandar Seovic - /// $Id: DialogAttribute.cs,v 1.3 2006/05/18 21:37:52 markpollack Exp $ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public class DialogAttribute : Attribute { diff --git a/src/Spring/Spring.Web/Web/UI/IValidationContainer.cs b/src/Spring/Spring.Web/Web/UI/IValidationContainer.cs index 019d8363..52b29159 100644 --- a/src/Spring/Spring.Web/Web/UI/IValidationContainer.cs +++ b/src/Spring/Spring.Web/Web/UI/IValidationContainer.cs @@ -32,7 +32,6 @@ namespace Spring.Web.UI /// handling validation and error rendering /// /// Erich Eichinger - /// $Id: IValidationContainer.cs,v 1.1 2008/03/19 12:07:15 oakinger Exp $ public interface IValidationContainer { /// diff --git a/src/Spring/Spring.Web/Web/UI/MasterPage.cs b/src/Spring/Spring.Web/Web/UI/MasterPage.cs index e1ec4937..22d65b02 100644 --- a/src/Spring/Spring.Web/Web/UI/MasterPage.cs +++ b/src/Spring/Spring.Web/Web/UI/MasterPage.cs @@ -54,7 +54,6 @@ namespace Spring.Web.UI /// Spring.NET Master Page implementation for ASP.NET 1.1 /// /// Aleksandar Seovic - /// $Id: MasterPage.cs,v 1.15 2008/04/22 15:08:59 markpollack Exp $ public class MasterPage : UserControl { /// @@ -107,7 +106,6 @@ namespace Spring.Web.UI /// Spring.NET Master Page implementation for ASP.NET 2.0 /// /// Aleksandar Seovic - /// $Id: MasterPage.cs,v 1.15 2008/04/22 15:08:59 markpollack Exp $ public class MasterPage : System.Web.UI.MasterPage, IApplicationContextAware, ISupportsWebDependencyInjection { #region Instance Fields diff --git a/src/Spring/Spring.Web/Web/UI/Page.cs b/src/Spring/Spring.Web/Web/UI/Page.cs index b8f34263..9e039cd8 100644 --- a/src/Spring/Spring.Web/Web/UI/Page.cs +++ b/src/Spring/Spring.Web/Web/UI/Page.cs @@ -70,7 +70,6 @@ namespace Spring.Web.UI ///

/// /// Aleksandar Seovic - /// $Id: Page.cs,v 1.89 2008/04/03 04:32:29 markpollack Exp $ [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class Page : System.Web.UI.Page, IHttpHandler, IApplicationContextAware, ISharedStateAware, IProcessAware, diff --git a/src/Spring/Spring.Web/Web/UI/UserControl.cs b/src/Spring/Spring.Web/Web/UI/UserControl.cs index 7306003d..a61aa6a6 100644 --- a/src/Spring/Spring.Web/Web/UI/UserControl.cs +++ b/src/Spring/Spring.Web/Web/UI/UserControl.cs @@ -50,7 +50,6 @@ namespace Spring.Web.UI /// Extends standard .Net user control by adding data binding and localization functionality. /// /// Aleksandar Seovic - /// $Id: UserControl.cs,v 1.54 2008/04/03 05:31:25 markpollack Exp $ public class UserControl : System.Web.UI.UserControl, IApplicationContextAware, IWebDataBound, ISupportsWebDependencyInjection, IPostBackDataHandler,IValidationContainer { diff --git a/src/Spring/Spring.Web/Web/UI/Validation/AbstractValidationErrorsRenderer.cs b/src/Spring/Spring.Web/Web/UI/Validation/AbstractValidationErrorsRenderer.cs index fea552bf..aab95560 100644 --- a/src/Spring/Spring.Web/Web/UI/Validation/AbstractValidationErrorsRenderer.cs +++ b/src/Spring/Spring.Web/Web/UI/Validation/AbstractValidationErrorsRenderer.cs @@ -28,7 +28,6 @@ namespace Spring.Web.UI.Validation /// This class provides common members for all validation errors renderers. /// /// Aleksandar Seovic - /// $Id: AbstractValidationErrorsRenderer.cs,v 1.1 2007/08/02 19:50:28 markpollack Exp $ public abstract class AbstractValidationErrorsRenderer : IValidationErrorsRenderer { private string cssClass; diff --git a/src/Spring/Spring.Web/Web/UI/Validation/DivValidationErrorsRenderer.cs b/src/Spring/Spring.Web/Web/UI/Validation/DivValidationErrorsRenderer.cs index faac260e..accd1632 100644 --- a/src/Spring/Spring.Web/Web/UI/Validation/DivValidationErrorsRenderer.cs +++ b/src/Spring/Spring.Web/Web/UI/Validation/DivValidationErrorsRenderer.cs @@ -36,7 +36,6 @@ namespace Spring.Web.UI.Validation /// control. /// /// Aleksandar Seovic - /// $Id: DivValidationErrorsRenderer.cs,v 1.1 2007/08/02 19:50:28 markpollack Exp $ public class DivValidationErrorsRenderer : AbstractValidationErrorsRenderer { /// diff --git a/src/Spring/Spring.Web/Web/UI/Validation/IValidationErrorsRenderer.cs b/src/Spring/Spring.Web/Web/UI/Validation/IValidationErrorsRenderer.cs index ea335b1c..ce4c1e83 100644 --- a/src/Spring/Spring.Web/Web/UI/Validation/IValidationErrorsRenderer.cs +++ b/src/Spring/Spring.Web/Web/UI/Validation/IValidationErrorsRenderer.cs @@ -43,7 +43,6 @@ namespace Spring.Web.UI.Validation /// /// /// Aleksandar Seovic - /// $Id: IValidationErrorsRenderer.cs,v 1.1 2007/08/02 19:50:28 markpollack Exp $ public interface IValidationErrorsRenderer { /// diff --git a/src/Spring/Spring.Web/Web/UI/Validation/IconValidationErrorsRenderer.cs b/src/Spring/Spring.Web/Web/UI/Validation/IconValidationErrorsRenderer.cs index 0ff2b409..6457200a 100644 --- a/src/Spring/Spring.Web/Web/UI/Validation/IconValidationErrorsRenderer.cs +++ b/src/Spring/Spring.Web/Web/UI/Validation/IconValidationErrorsRenderer.cs @@ -37,7 +37,6 @@ namespace Spring.Web.UI.Validation /// /// /// Aleksandar Seovic - /// $Id: IconValidationErrorsRenderer.cs,v 1.1 2007/08/02 19:50:28 markpollack Exp $ public class IconValidationErrorsRenderer : AbstractValidationErrorsRenderer { private string iconSrc; diff --git a/src/Spring/Spring.Web/Web/UI/Validation/SpanValidationErrorsRenderer.cs b/src/Spring/Spring.Web/Web/UI/Validation/SpanValidationErrorsRenderer.cs index 98aaab46..aa39d9bd 100644 --- a/src/Spring/Spring.Web/Web/UI/Validation/SpanValidationErrorsRenderer.cs +++ b/src/Spring/Spring.Web/Web/UI/Validation/SpanValidationErrorsRenderer.cs @@ -38,7 +38,6 @@ namespace Spring.Web.UI.Validation /// control. /// /// Aleksandar Seovic - /// $Id: SpanValidationErrorsRenderer.cs,v 1.1 2007/08/02 19:50:28 markpollack Exp $ public class SpanValidationErrorsRenderer : AbstractValidationErrorsRenderer { /// diff --git a/test/Spring/Spring.Aop.Tests/Aop/Advice/DebugAdvice.cs b/test/Spring/Spring.Aop.Tests/Aop/Advice/DebugAdvice.cs index 41e2c090..dd5b23ce 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Advice/DebugAdvice.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Advice/DebugAdvice.cs @@ -41,7 +41,6 @@ namespace Spring.Aop.Advice /// Rod Johnson /// Federico Spinazzi (.NET) /// Aleksandar Seovic (.NET) - /// $Id: DebugAdvice.cs,v 1.1 2007/08/08 07:45:36 markpollack Exp $ /// public sealed class DebugAdvice : IMethodInterceptor { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Config/AopNamespaceParserTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Config/AopNamespaceParserTests.cs index bd590ca6..21e5cc07 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Config/AopNamespaceParserTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Config/AopNamespaceParserTests.cs @@ -36,7 +36,6 @@ namespace Spring.Aop.Config /// This class contains tests for the custom aop namespace. /// /// Mark Pollack - /// $Id: AopNamespaceParserTests.cs,v 1.7 2007/08/09 03:06:37 markpollack Exp $ [TestFixture] public class AopNamespaceParserTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AbstractMethodInvocationTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AbstractMethodInvocationTests.cs index 9e6e3032..950f89c6 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AbstractMethodInvocationTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AbstractMethodInvocationTests.cs @@ -38,7 +38,6 @@ namespace Spring.Aop.Framework /// /// Rick Evans /// Bruno Baia - /// $Id: AbstractMethodInvocationTests.cs,v 1.2 2008/02/06 18:29:05 bbaia Exp $ [TestFixture] public abstract class AbstractMethodInvocationTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/Adapter/UnknownAdviceTypeExceptionTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/Adapter/UnknownAdviceTypeExceptionTests.cs index 22637562..2c5c8085 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/Adapter/UnknownAdviceTypeExceptionTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/Adapter/UnknownAdviceTypeExceptionTests.cs @@ -32,7 +32,6 @@ namespace Spring.Aop.Framework.Adapter /// Unit tests for the UnknownAdviceTypeException class. /// /// Rick Evans - /// $Id: UnknownAdviceTypeExceptionTests.cs,v 1.2 2006/04/09 07:19:05 markpollack Exp $ [TestFixture] public sealed class UnknownAdviceTypeExceptionTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AopContextTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AopContextTests.cs index e682ad8e..fb324bd8 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AopContextTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AopContextTests.cs @@ -38,7 +38,6 @@ namespace Spring.Aop.Framework /// Unit tests for the AopContext class. /// /// Rick Evans - /// $Id: AopContextTests.cs,v 1.6 2007/05/30 21:06:25 oakinger Exp $ [TestFixture] public sealed class AopContextTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs index f0ff1d50..da9faa86 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs @@ -38,7 +38,6 @@ namespace Spring.Aop.Framework.AutoProxy /// Tests for auto proxy creation combined with factory object and circular references. /// /// Erich Eichinger (.NET) - /// $Id: AdvisorAutoProxyCreatorCircularReferencesTests.cs,v 1.4 2007/09/07 01:53:01 markpollack Exp $ [TestFixture] public class AdvisorAutoProxyCreatorCircularReferencesTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorTests.cs index f5d3f30c..d07419d1 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorTests.cs @@ -37,7 +37,6 @@ namespace Spring.Aop.Framework.AutoProxy /// /// Rod Johnson /// Mark Pollack (.NET) - /// $Id: AdvisorAutoProxyCreatorTests.cs,v 1.4 2007/08/01 17:56:25 markpollack Exp $ [TestFixture] public class AdvisorAutoProxyCreatorTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/CreatesTestObject.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/CreatesTestObject.cs index 5863c088..5c5f8829 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/CreatesTestObject.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/CreatesTestObject.cs @@ -28,7 +28,6 @@ namespace Spring.Aop.Framework.AutoProxy /// This is simple implementation of IFactoryObject that creates a TestObject. /// /// Mark Pollack - /// $Id: CreatesTestObject.cs,v 1.1 2007/09/07 01:53:02 markpollack Exp $ public class CreatesTestObject : IFactoryObject, IInitializingObject { private bool initialized = false; diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreatorTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreatorTests.cs index 996001f7..e85b48da 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreatorTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/ObjectNameAutoProxyCreatorTests.cs @@ -35,7 +35,6 @@ namespace Spring.Aop.Framework.AutoProxy /// Tests for ObjectNameAutoProxyCreator functionality /// /// Mark Pollack - /// $Id: ObjectNameAutoProxyCreatorTests.cs,v 1.6 2007/09/07 01:53:01 markpollack Exp $ [TestFixture] public class ObjectNameAutoProxyCreatorTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/OrderedLogicalThreadContextCheckAdvisor.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/OrderedLogicalThreadContextCheckAdvisor.cs index 9c77cfa5..c0f23f37 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/OrderedLogicalThreadContextCheckAdvisor.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/OrderedLogicalThreadContextCheckAdvisor.cs @@ -40,7 +40,6 @@ namespace Spring.Aop.Framework.AutoProxy /// LogicalThreadContext. /// /// Mark Pollack (.NET) - /// $Id: OrderedLogicalThreadContextCheckAdvisor.cs,v 1.2 2006/09/15 21:25:17 markpollack Exp $ public class OrderedLogicalThreadContextCheckAdvisor : StaticMethodMatcherPointcutAdvisor, IInitializingObject { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingAfterReturningAdvice.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingAfterReturningAdvice.cs index 4f16260c..e784dccf 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingAfterReturningAdvice.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingAfterReturningAdvice.cs @@ -31,7 +31,6 @@ namespace Spring.Aop.Framework /// /// Rod Johnson /// Bruno Baia (.NET) - /// $Id: CountingAfterReturningAdvice.cs,v 1.2 2007/03/16 04:01:47 aseovic Exp $ [Serializable] public class CountingAfterReturningAdvice : MethodCounter, IAfterReturningAdvice { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingBeforeAdvice.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingBeforeAdvice.cs index 51e58546..77304b2c 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingBeforeAdvice.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingBeforeAdvice.cs @@ -31,7 +31,6 @@ namespace Spring.Aop.Framework /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: CountingBeforeAdvice.cs,v 1.6 2007/03/16 04:01:47 aseovic Exp $ [Serializable] public class CountingBeforeAdvice : MethodCounter, IMethodBeforeAdvice { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingMultiAdvice.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingMultiAdvice.cs index 2a3b5e18..cc63534a 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingMultiAdvice.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingMultiAdvice.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Framework /// /// Juergen Hoeller /// Bruno Baia (.NET) - /// $Id: CountingMultiAdvice.cs,v 1.1 2006/08/10 18:45:57 bbaia Exp $ public class CountingMultiAdvice : MethodCounter, IMethodBeforeAdvice, IAfterReturningAdvice, IThrowsAdvice { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingThrowsAdvice.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingThrowsAdvice.cs index 6e08fe16..95be53d7 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingThrowsAdvice.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/CountingThrowsAdvice.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Framework /// /// Rod Johnson /// Bruno Baia (.NET) - /// $Id: CountingThrowsAdvice.cs,v 1.2 2007/03/16 04:01:47 aseovic Exp $ [Serializable] public class CountingThrowsAdvice : MethodCounter, IThrowsAdvice { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicMethodInvocationTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicMethodInvocationTests.cs index 1374af7e..c33437be 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicMethodInvocationTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicMethodInvocationTests.cs @@ -34,7 +34,6 @@ namespace Spring.Aop.Framework /// Unit tests for the DynamicMethodInvocation class. /// /// Bruno Baia - /// $Id: DynamicMethodInvocationTests.cs,v 1.2 2008/02/06 18:29:05 bbaia Exp $ [TestFixture] public class DynamicMethodInvocationTests : AbstractMethodInvocationTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AbstractAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AbstractAopProxyTests.cs index 82e25e26..d625f392 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AbstractAopProxyTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AbstractAopProxyTests.cs @@ -54,7 +54,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// Rod Johnson /// Juergen Hoeller /// Bruno Baia (.NET) - /// $Id: AbstractAopProxyTests.cs,v 1.21 2008/05/21 08:04:52 bbaia Exp $ public abstract class AbstractAopProxyTests { protected MockTargetSource mockTargetSource = new MockTargetSource(); diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AopUtilsTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AopUtilsTests.cs index 1a3fbb87..a8daecdd 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AopUtilsTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/AopUtilsTests.cs @@ -40,7 +40,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: AopUtilsTests.cs,v 1.2 2008/03/21 10:49:37 oakinger Exp $ [TestFixture] public sealed class AopUtilsTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs index 06eb0bfb..32ea96d7 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CachedAopProxyFactoryTests.cs @@ -36,7 +36,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// Unit tests for the CachedAopProxyFactoryTests class. /// /// Bruno Baia - /// $Id: CachedAopProxyFactoryTests.cs,v 1.1 2007/08/04 01:20:11 bbaia Exp $ [TestFixture] public sealed class CachedAopProxyFactoryTests : DefaultAopProxyFactoryTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CompositionAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CompositionAopProxyTests.cs index 10ea964e..abdb3fef 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CompositionAopProxyTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/CompositionAopProxyTests.cs @@ -34,7 +34,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// Rod Johnson /// Juergen Hoeller /// Bruno Baia (.NET) - /// $Id: CompositionAopProxyTests.cs,v 1.4 2007/08/02 04:15:37 markpollack Exp $ [TestFixture] public class CompositionAopProxyTests : AbstractAopProxyTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs index 7c76c3b3..a80a24da 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs @@ -36,7 +36,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// Rod Johnson /// Juergen Hoeller /// Bruno Baia (.NET) - /// $Id: DecoratorAopProxyTests.cs,v 1.6 2008/05/21 08:04:52 bbaia Exp $ [TestFixture] public class DecoratorAopProxyTests : AbstractAopProxyTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DefaultAopProxyFactoryTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DefaultAopProxyFactoryTests.cs index 143f572b..1cc24b03 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DefaultAopProxyFactoryTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DefaultAopProxyFactoryTests.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// Unit tests for the DefaultAopProxyFactory class. /// /// Bruno Baia - /// $Id: DefaultAopProxyFactoryTests.cs,v 1.1 2007/08/04 01:20:11 bbaia Exp $ [TestFixture] public class DefaultAopProxyFactoryTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs index 15bcba58..54122a4c 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs @@ -38,7 +38,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// Additional and overridden tests for the inheritance-based proxy. /// /// Bruno Baia - /// $Id: InheritanceAopProxyTests.cs,v 1.2 2008/03/03 09:29:17 bbaia Exp $ [TestFixture] public class InheritanceAopProxyTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/MockTargetSource.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/MockTargetSource.cs index a304066d..3b0cadea 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/MockTargetSource.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/MockTargetSource.cs @@ -34,7 +34,6 @@ namespace Spring.Aop.Framework.DynamicProxy /// /// Rod Johnson /// Bruno Baia (.NET) - /// $Id: MockTargetSource.cs,v 1.1 2006/08/10 18:45:58 bbaia Exp $ public class MockTargetSource : ITargetSource { private object _target; diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/HashtableCachingAdvisorChainFactoryTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/HashtableCachingAdvisorChainFactoryTests.cs index 29479b95..a89c2623 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/HashtableCachingAdvisorChainFactoryTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/HashtableCachingAdvisorChainFactoryTests.cs @@ -32,7 +32,6 @@ namespace Spring.Aop.Framework /// Unit tests for the HashtableCachingAdvisorChainFactory class. /// /// Rick Evans - /// $Id: HashtableCachingAdvisorChainFactoryTests.cs,v 1.2 2006/04/09 07:19:05 markpollack Exp $ [TestFixture] public sealed class HashtableCachingAdvisorChainFactoryTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/ITimeStamped.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/ITimeStamped.cs index 09be9cfd..b9b460cc 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/ITimeStamped.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/ITimeStamped.cs @@ -28,7 +28,6 @@ namespace Spring.Aop.Framework /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: ITimeStamped.cs,v 1.1 2004/08/01 10:20:20 choyrim Exp $ public interface ITimeStamped { /// diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/MethodCounter.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/MethodCounter.cs index 04fbadba..3167f390 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/MethodCounter.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/MethodCounter.cs @@ -28,7 +28,6 @@ namespace Spring.Aop.Framework /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: MethodCounter.cs,v 1.2 2007/03/16 04:01:47 aseovic Exp $ [Serializable] public class MethodCounter { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyConfigTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyConfigTests.cs index d982d3bf..1724488e 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyConfigTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyConfigTests.cs @@ -31,7 +31,6 @@ namespace Spring.Aop.Framework /// Unit tests for the ProxyConfig class. /// /// Rick Evans - /// $Id: ProxyConfigTests.cs,v 1.2 2006/04/09 07:19:05 markpollack Exp $ [TestFixture] public sealed class ProxyConfigTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs index 1d45e7dd..ec6dcc7d 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs @@ -59,7 +59,6 @@ namespace Spring.Aop.Framework /// Federico Spinazzi (.NET) /// Choy Rim (.NET) /// Aleksandar Seovic (.NET) - /// $Id: ProxyFactoryObjectTests.cs,v 1.35 2007/12/07 17:59:31 bbaia Exp $ [TestFixture] public sealed class ProxyFactoryObjectTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryTests.cs index b8e09904..38a07b02 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryTests.cs @@ -42,7 +42,6 @@ namespace Spring.Aop.Framework /// Rod Johnson /// Choy Rim (.NET) /// Rick Evans (.NET) - /// $Id: ProxyFactoryTests.cs,v 1.22 2008/03/21 10:49:38 oakinger Exp $ [TestFixture] public sealed class ProxyFactoryTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/ReflectiveMethodInvocationTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/ReflectiveMethodInvocationTests.cs index 2cb5fb4f..34316b4e 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/ReflectiveMethodInvocationTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/ReflectiveMethodInvocationTests.cs @@ -35,7 +35,6 @@ namespace Spring.Aop.Framework /// /// Rick Evans /// Bruno Baia - /// $Id: ReflectiveMethodInvocationTests.cs,v 1.8 2008/02/06 18:29:05 bbaia Exp $ [TestFixture] public class ReflectiveMethodInvocationTests : AbstractMethodInvocationTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Interceptor/NopInterceptor.cs b/test/Spring/Spring.Aop.Tests/Aop/Interceptor/NopInterceptor.cs index 05087806..036225c8 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Interceptor/NopInterceptor.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Interceptor/NopInterceptor.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Interceptor /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: NopInterceptor.cs,v 1.6 2008/01/14 20:49:47 oakinger Exp $ public class NopInterceptor : IMethodBeforeAdvice { protected int instanceId; diff --git a/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs index 560bd9aa..690ca913 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Support /// /// Rick Evans /// Ronald Wildenberg - /// $Id: AttributeMatchMethodPointcutTests.cs,v 1.3 2007/05/21 16:44:08 bbaia Exp $ [TestFixture] public sealed class AttributeMatchMethodPointcutTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Support/DelegatingIntroductionInterceptorTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Support/DelegatingIntroductionInterceptorTests.cs index 9b401c2e..054f73b3 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Support/DelegatingIntroductionInterceptorTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Support/DelegatingIntroductionInterceptorTests.cs @@ -39,7 +39,6 @@ namespace Spring.Aop.Support /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: DelegatingIntroductionInterceptorTests.cs,v 1.6 2004/10/10 08:01:49 gcaprio Exp $ [TestFixture] public class DelegatingIntroductionInterceptorTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Support/RootTypeFilterTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Support/RootTypeFilterTests.cs index 445935ed..818f9d52 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Support/RootTypeFilterTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Support/RootTypeFilterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Aop.Support /// Unit tests for the RootTypeFilter class. /// /// Rick Evans - /// $Id: RootTypeFilterTests.cs,v 1.2 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class RootTypeFilterTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Support/TypeFiltersTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Support/TypeFiltersTests.cs index 5a2fc844..02a8f501 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Support/TypeFiltersTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Support/TypeFiltersTests.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Support /// /// Rod Johnson /// Choy Rim (.NET) - /// $Id: TypeFiltersTests.cs,v 1.2 2005/07/21 16:01:12 springboy Exp $ [TestFixture] public sealed class TypeFiltersTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Target/EmptyTargetSourceTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Target/EmptyTargetSourceTests.cs index 048a63ba..0b8668aa 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Target/EmptyTargetSourceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Target/EmptyTargetSourceTests.cs @@ -33,7 +33,6 @@ namespace Spring.Aop.Target /// Unit tests for the EmptyTargetSource class. /// /// Rick Evans - /// $Id: EmptyTargetSourceTests.cs,v 1.2 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class EmptyTargetSourceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Target/HotSwappableTargetSourceTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Target/HotSwappableTargetSourceTests.cs index 76141c8e..14aa8002 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Target/HotSwappableTargetSourceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Target/HotSwappableTargetSourceTests.cs @@ -34,7 +34,6 @@ namespace Spring.Aop.Target /// /// Rod Johnson /// Federico Spinazzi (.NET) - /// $Id: HotSwappableTargetSourceTests.cs,v 1.4 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class HotSwappableTargetSourceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Target/PrototypeTargetSourceTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Target/PrototypeTargetSourceTests.cs index c0d21c45..63515083 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Target/PrototypeTargetSourceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Target/PrototypeTargetSourceTests.cs @@ -37,7 +37,6 @@ namespace Spring.Aop.Target /// /// Rod Johnson /// Federico Spinazzi - /// $Id: PrototypeTargetSourceTests.cs,v 1.8 2007/07/28 07:33:22 markpollack Exp $ [TestFixture] public sealed class PrototypeTargetSourceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Target/SimplePoolTargetSourceTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Target/SimplePoolTargetSourceTests.cs index 9426db2d..86575842 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Target/SimplePoolTargetSourceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Target/SimplePoolTargetSourceTests.cs @@ -26,8 +26,6 @@ namespace Spring.Aop.Target /// /// Rod Johnson /// Federico Spinazzi (.Net) - /// $Id: SimplePoolTargetSourceTests.cs,v 1.3 2006/02/08 08:31:05 aseovic Exp $ - /// [TestFixture] public class SimplePoolTargetSourceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Target/SingletonTargetSourceTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Target/SingletonTargetSourceTests.cs index 1ead5fa5..2a58cccf 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Target/SingletonTargetSourceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Target/SingletonTargetSourceTests.cs @@ -31,7 +31,6 @@ namespace Spring.Aop.Target /// Unit tests for the SingletonTargetSource class. /// /// Rick Evans - /// $Id: SingletonTargetSourceTests.cs,v 1.2 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class SingletonTargetSourceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Target/ThreadLocalTargetSourceTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Target/ThreadLocalTargetSourceTests.cs index 90898a57..ea5fe734 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Target/ThreadLocalTargetSourceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Target/ThreadLocalTargetSourceTests.cs @@ -27,8 +27,6 @@ namespace Spring.Aop.Target { /// Rod Johnson /// Federico Spinazzi - /// $Id: ThreadLocalTargetSourceTests.cs,v 1.5 2006/11/13 07:04:51 markpollack Exp $ - /// [TestFixture] public class ThreadLocalTargetSourceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/TrueMethodMatcherTests.cs b/test/Spring/Spring.Aop.Tests/Aop/TrueMethodMatcherTests.cs index 0522e392..f5077459 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/TrueMethodMatcherTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/TrueMethodMatcherTests.cs @@ -33,7 +33,6 @@ namespace Spring.Aop /// Unit tests for the TrueMethodMatcher class. /// /// Rick Evans - /// $Id: TrueMethodMatcherTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class TrueMethodMatcherTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/TruePointcutTests.cs b/test/Spring/Spring.Aop.Tests/Aop/TruePointcutTests.cs index 92710dc8..29d39e11 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/TruePointcutTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/TruePointcutTests.cs @@ -33,7 +33,6 @@ namespace Spring.Aop /// Unit tests for the TruePointcut class. /// /// Rick Evans - /// $Id: TruePointcutTests.cs,v 1.2 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class TruePointcutTests { diff --git a/test/Spring/Spring.Aop.Tests/Aop/TrueTypeFilterTests.cs b/test/Spring/Spring.Aop.Tests/Aop/TrueTypeFilterTests.cs index 79848407..2f30089f 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/TrueTypeFilterTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/TrueTypeFilterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Aop /// Unit tests for the TrueTypeFilter class. /// /// Rick Evans - /// $Id: TrueTypeFilterTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class TrueTypeFilterTests { diff --git a/test/Spring/Spring.Aop.Tests/AopExceptionTests.cs b/test/Spring/Spring.Aop.Tests/AopExceptionTests.cs index 0637d707..3ec1996b 100644 --- a/test/Spring/Spring.Aop.Tests/AopExceptionTests.cs +++ b/test/Spring/Spring.Aop.Tests/AopExceptionTests.cs @@ -33,7 +33,6 @@ namespace Spring /// Unit tests for all of the exception classes in the Spring.Aop library... /// /// Rick Evans - /// $Id: AopExceptionTests.cs,v 1.3 2006/04/09 07:19:04 markpollack Exp $ [TestFixture] public sealed class AopExceptionTests : ExceptionsTest { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheAspectIntegrationTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheAspectIntegrationTests.cs index 41ec6a54..2d4dea81 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheAspectIntegrationTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheAspectIntegrationTests.cs @@ -37,7 +37,6 @@ namespace Spring.Aspects.Cache /// Unit tests for the CacheParameterAdvice class. /// /// Aleksandar Seovic - /// $Id: CacheAspectIntegrationTests.cs,v 1.4 2007/08/03 14:38:39 markpollack Exp $ [TestFixture] public sealed class CacheAspectIntegrationTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheParameterAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheParameterAdviceTests.cs index 890768bc..e5fa3f59 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheParameterAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheParameterAdviceTests.cs @@ -35,7 +35,6 @@ namespace Spring.Aspects.Cache /// Unit tests for the CacheParameterAdvice class. /// /// Aleksandar Seovic - /// $Id: CacheParameterAdviceTests.cs,v 1.6 2007/04/01 15:05:33 bbaia Exp $ [TestFixture] public sealed class CacheParameterAdviceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheResultAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheResultAdviceTests.cs index b0076038..253b20dd 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheResultAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Cache/CacheResultAdviceTests.cs @@ -36,7 +36,6 @@ namespace Spring.Aspects.Cache /// Unit tests for the CacheResultAdvice class. /// /// Aleksandar Seovic - /// $Id: CacheResultAdviceTests.cs,v 1.4 2007/08/22 20:16:51 oakinger Exp $ [TestFixture] public sealed class CacheResultAdviceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Cache/InvalidateCacheAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Cache/InvalidateCacheAdviceTests.cs index c1c4f814..80c02714 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Cache/InvalidateCacheAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Cache/InvalidateCacheAdviceTests.cs @@ -35,7 +35,6 @@ namespace Spring.Aspects.Cache /// Unit tests for the InvalidateCacheAdvice class. /// /// Aleksandar Seovic - /// $Id: InvalidateCacheAdviceTests.cs,v 1.4 2007/04/01 15:05:34 bbaia Exp $ [TestFixture] public sealed class InvalidateCacheAdviceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Exception/ExceptionHandlerAspectIntegrationTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Exception/ExceptionHandlerAspectIntegrationTests.cs index 834efa56..8483a52b 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Exception/ExceptionHandlerAspectIntegrationTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Exception/ExceptionHandlerAspectIntegrationTests.cs @@ -39,7 +39,6 @@ namespace Spring.Aspects.Exceptions /// This class contains tests for ExceptionHandlerAdvice /// /// Mark Pollack - /// $Id: ExceptionHandlerAspectIntegrationTests.cs,v 1.6 2008/02/26 00:03:43 markpollack Exp $ [TestFixture] public class ExceptionHandlerAspectIntegrationTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs index bfb1983c..17fb7113 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Logging/SimpleLoggingAdviceTests.cs @@ -36,7 +36,6 @@ namespace Spring.Aspects.Logging /// This class contains tests for SimpleLoggingAdvice /// /// Mark Pollack - /// $Id: SimpleLoggingAdviceTests.cs,v 1.4 2008/04/04 14:59:47 bbaia Exp $ [TestFixture] public class SimpleLoggingAdviceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Logging/TestableSimpleLoggingAdvice.cs b/test/Spring/Spring.Aop.Tests/Aspects/Logging/TestableSimpleLoggingAdvice.cs index c83fea8b..ec27a19b 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Logging/TestableSimpleLoggingAdvice.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Logging/TestableSimpleLoggingAdvice.cs @@ -28,7 +28,6 @@ namespace Spring.Aspects.Logging /// SimpleLoggingAdvice for testing purposes. /// /// Mark Pollack - /// $Id: TestableSimpleLoggingAdvice.cs,v 1.2 2007/12/06 17:17:24 markpollack Exp $ public class TestableSimpleLoggingAdvice : SimpleLoggingAdvice { /// diff --git a/test/Spring/Spring.Aop.Tests/Aspects/RetryAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/RetryAdviceTests.cs index 326a597a..05ace27c 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/RetryAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/RetryAdviceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Aspects /// This class contains tests for RetryAdvice /// /// Mark Pollack - /// $Id: RetryAdviceTests.cs,v 1.3 2008/03/17 20:25:41 markpollack Exp $ [TestFixture] public class RetryAdviceTests { diff --git a/test/Spring/Spring.Aop.Tests/Aspects/Validation/ParameterValidationAdviceTests.cs b/test/Spring/Spring.Aop.Tests/Aspects/Validation/ParameterValidationAdviceTests.cs index e34b9a8b..593963d7 100644 --- a/test/Spring/Spring.Aop.Tests/Aspects/Validation/ParameterValidationAdviceTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aspects/Validation/ParameterValidationAdviceTests.cs @@ -36,7 +36,6 @@ namespace Spring.Aspects.Validation /// Unit tests for the CacheParameterAdvice class. /// /// Aleksandar Seovic - /// $Id: ParameterValidationAdviceTests.cs,v 1.2 2008/04/02 23:00:46 markpollack Exp $ [TestFixture] public sealed class ParameterValidationAdviceTests { diff --git a/test/Spring/Spring.Aop.Tests/Data/Spring/Aop/Framework/innerBeanTarget.xml b/test/Spring/Spring.Aop.Tests/Data/Spring/Aop/Framework/innerBeanTarget.xml index e757d0c8..048687b6 100644 --- a/test/Spring/Spring.Aop.Tests/Data/Spring/Aop/Framework/innerBeanTarget.xml +++ b/test/Spring/Spring.Aop.Tests/Data/Spring/Aop/Framework/innerBeanTarget.xml @@ -3,7 +3,6 @@ diff --git a/test/Spring/Spring.Core.Tests/Caching/AbstractCacheTests.cs b/test/Spring/Spring.Core.Tests/Caching/AbstractCacheTests.cs index 80ece55e..bb5b9a76 100644 --- a/test/Spring/Spring.Core.Tests/Caching/AbstractCacheTests.cs +++ b/test/Spring/Spring.Core.Tests/Caching/AbstractCacheTests.cs @@ -34,7 +34,6 @@ namespace Spring.Caching /// that derived classes maybe rely on this default behaviour /// /// Erich Eichinger - /// $Id: AbstractCacheTests.cs,v 1.1 2007/08/25 14:26:36 oakinger Exp $ [TestFixture] public class AbstractCacheTests { diff --git a/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs b/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs index 5d50d5b7..98302232 100644 --- a/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs +++ b/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs @@ -31,7 +31,6 @@ namespace Spring.Caching /// /// /// Erich Eichinger - /// $Id: BaseCacheAttributeTests.cs,v 1.1 2007/08/29 17:30:00 oakinger Exp $ [TestFixture] public class BaseCacheAttributeTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/AbstractQueueTests.cs b/test/Spring/Spring.Core.Tests/Collections/AbstractQueueTests.cs index 0039b9cf..7078881c 100644 --- a/test/Spring/Spring.Core.Tests/Collections/AbstractQueueTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/AbstractQueueTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the AbstractQueue class. /// /// Griffin Caprio - /// $Id: AbstractQueueTests.cs,v 1.7 2006/09/30 18:39:24 gcaprio Exp $ [TestFixture] public sealed class AbstractQueueTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/HashedSetTests.cs b/test/Spring/Spring.Core.Tests/Collections/HashedSetTests.cs index 52fffe4f..5d386ca4 100644 --- a/test/Spring/Spring.Core.Tests/Collections/HashedSetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/HashedSetTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the HashedSet class. /// /// Rick Evans - /// $Id: HashedSetTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public class HashedSetTests : SetTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/HybridSetTests.cs b/test/Spring/Spring.Core.Tests/Collections/HybridSetTests.cs index 894e5078..90dd5bb9 100644 --- a/test/Spring/Spring.Core.Tests/Collections/HybridSetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/HybridSetTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the HybridSet class. /// /// Rick Evans - /// $Id: HybridSetTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public class HybridSetTests : SetTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/ImmutableSetTests.cs b/test/Spring/Spring.Core.Tests/Collections/ImmutableSetTests.cs index 8804c55a..9cce1a76 100644 --- a/test/Spring/Spring.Core.Tests/Collections/ImmutableSetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/ImmutableSetTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the ImmutableSet wrapper class. /// /// Rick Evans - /// $Id: ImmutableSetTests.cs,v 1.2 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public class ImmutableSetTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/ListSetTests.cs b/test/Spring/Spring.Core.Tests/Collections/ListSetTests.cs index ff61f180..66899f9e 100644 --- a/test/Spring/Spring.Core.Tests/Collections/ListSetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/ListSetTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the ListSet class. /// /// Rick Evans - /// $Id: ListSetTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public class ListSetTests : SetTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/SetTests.cs b/test/Spring/Spring.Core.Tests/Collections/SetTests.cs index 75f5925d..03c40493 100644 --- a/test/Spring/Spring.Core.Tests/Collections/SetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/SetTests.cs @@ -47,7 +47,6 @@ namespace Spring.Collections ///

/// /// Rick Evans - /// $Id: SetTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ public abstract class SetTests { protected static readonly object StuffOne = "This Is"; diff --git a/test/Spring/Spring.Core.Tests/Collections/SortedSetTests.cs b/test/Spring/Spring.Core.Tests/Collections/SortedSetTests.cs index 7cd619eb..ebeea117 100644 --- a/test/Spring/Spring.Core.Tests/Collections/SortedSetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/SortedSetTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the SortedSet class. /// /// Rick Evans - /// $Id: SortedSetTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public class SortedSetTests : SetTests { diff --git a/test/Spring/Spring.Core.Tests/Collections/StaticSetTests.cs b/test/Spring/Spring.Core.Tests/Collections/StaticSetTests.cs index 558bd9cc..76b9f713 100644 --- a/test/Spring/Spring.Core.Tests/Collections/StaticSetTests.cs +++ b/test/Spring/Spring.Core.Tests/Collections/StaticSetTests.cs @@ -32,7 +32,6 @@ namespace Spring.Collections /// Unit tests for the static methods of the Set class. /// /// Rick Evans - /// $Id: StaticSetTests.cs,v 1.3 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class StaticSetTests { diff --git a/test/Spring/Spring.Core.Tests/Context/ContextExceptionTests.cs b/test/Spring/Spring.Core.Tests/Context/ContextExceptionTests.cs index 3d5a6028..66be8c9d 100644 --- a/test/Spring/Spring.Core.Tests/Context/ContextExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/ContextExceptionTests.cs @@ -33,7 +33,6 @@ namespace Spring.Context /// Unit tests for all of the exception classes in the Spring.Context library... /// /// Rick Evans - /// $Id: ContextExceptionTests.cs,v 1.2 2006/04/09 07:19:06 markpollack Exp $ [TestFixture] public sealed class ContextExceptionTests : ExceptionsTest { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/AbstractMessageSourceTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/AbstractMessageSourceTests.cs index 9e444438..ee2dced7 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/AbstractMessageSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/AbstractMessageSourceTests.cs @@ -28,8 +28,6 @@ using NUnit.Framework; namespace Spring.Context.Support { - /// - /// $Id: AbstractMessageSourceTests.cs,v 1.6 2007/08/23 14:31:18 oakinger Exp $ [TestFixture] public sealed class AbstractMessageSourceTests : AbstractMessageSource { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/Assembler.cs b/test/Spring/Spring.Core.Tests/Context/Support/Assembler.cs index c38a4c77..d64842ee 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/Assembler.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/Assembler.cs @@ -26,7 +26,6 @@ namespace Spring.Context.Support /// Mark Pollack - /// $Id: Assembler.cs,v 1.2 2007/07/17 14:55:47 oakinger Exp $ public class Assembler { private Service service; diff --git a/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs index 64f96534..369d635c 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs @@ -32,7 +32,6 @@ namespace Spring.Context.Support /// Unit tests for the ContextRegistry class. /// /// Rick Evans - /// $Id: ContextRegistryTests.cs,v 1.9 2008/03/21 10:49:38 oakinger Exp $ [TestFixture] public sealed class ContextRegistryTests { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/DelegatingMessageSourceTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/DelegatingMessageSourceTests.cs index e12bc6ad..15bee0fd 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/DelegatingMessageSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/DelegatingMessageSourceTests.cs @@ -33,7 +33,6 @@ namespace Spring.Context.Support /// Unit tests for the DelegatingMessageSource class. /// /// Rick Evans - /// $Id: DelegatingMessageSourceTests.cs,v 1.3 2006/04/09 07:19:07 markpollack Exp $ [TestFixture] public sealed class DelegatingMessageSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/Logic.cs b/test/Spring/Spring.Core.Tests/Context/Support/Logic.cs index 74cc23a2..157a6e13 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/Logic.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/Logic.cs @@ -23,7 +23,6 @@ using Spring.Objects.Factory; namespace Spring.Context.Support { /// Mark Pollack - /// $Id: Logic.cs,v 1.1 2007/07/10 05:48:37 markpollack Exp $ public class Logic : IObjectNameAware { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/NullMessageSourceTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/NullMessageSourceTests.cs index 8def2dad..f585deae 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/NullMessageSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/NullMessageSourceTests.cs @@ -27,7 +27,6 @@ namespace Spring.Context.Support /// Unit tests for the NullMessageSource class. /// /// - /// $Id: NullMessageSourceTests.cs,v 1.3 2007/07/02 21:24:48 markpollack Exp $ [TestFixture] public sealed class NullMessageSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/ResourceSetMessageSourceTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/ResourceSetMessageSourceTests.cs index 8f1a5087..3debc0df 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/ResourceSetMessageSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/ResourceSetMessageSourceTests.cs @@ -41,7 +41,6 @@ namespace Spring.Context.Support /// Unit tests for the ResourceSetMessageSource class. /// /// - /// $Id: ResourceSetMessageSourceTests.cs,v 1.13 2007/07/18 21:26:07 oakinger Exp $ [TestFixture] public sealed class ResourceSetMessageSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Context/Support/Service.cs b/test/Spring/Spring.Core.Tests/Context/Support/Service.cs index 8fefee3d..6fa2a785 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/Service.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/Service.cs @@ -23,7 +23,6 @@ using System; namespace Spring.Context.Support { /// Mark Pollack - /// $Id: Service.cs,v 1.1 2007/07/10 05:48:37 markpollack Exp $ public class Service : IApplicationContextAware, IMessageSourceAware, IDisposable { private IApplicationContext applicationContext; diff --git a/test/Spring/Spring.Core.Tests/Context/Support/StaticMessageSourceTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/StaticMessageSourceTests.cs index 3755b8e9..1019c77d 100644 --- a/test/Spring/Spring.Core.Tests/Context/Support/StaticMessageSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Context/Support/StaticMessageSourceTests.cs @@ -29,8 +29,6 @@ namespace Spring.Context.Support /// /// Unit tests for the StaticMessageSource class. /// - /// - /// $Id: StaticMessageSourceTests.cs,v 1.9 2007/07/24 17:26:40 oakinger Exp $ [TestFixture] public sealed class StaticMessageSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Core/ControlFlowFactoryTests.cs b/test/Spring/Spring.Core.Tests/Core/ControlFlowFactoryTests.cs index 3c8a12bb..6df64550 100644 --- a/test/Spring/Spring.Core.Tests/Core/ControlFlowFactoryTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/ControlFlowFactoryTests.cs @@ -34,7 +34,6 @@ namespace Spring.Core /// ControlFlowFactory class. /// /// Rick Evans - /// $Id: ControlFlowFactoryTests.cs,v 1.2 2006/04/09 07:24:48 markpollack Exp $ [TestFixture] public sealed class ControlFlowFactoryTests { diff --git a/test/Spring/Spring.Core.Tests/Core/IO/AssemblyResourceTest.cs b/test/Spring/Spring.Core.Tests/Core/IO/AssemblyResourceTest.cs index a4e95777..f6a6bdfb 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/AssemblyResourceTest.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/AssemblyResourceTest.cs @@ -34,7 +34,6 @@ namespace Spring.Core.IO /// /// Aleksandar Seovic /// Federico Spinazzi - /// $Id: AssemblyResourceTest.cs,v 1.10 2007/08/08 17:49:59 bbaia Exp $ [TestFixture] public class AssemblyResourceTest { diff --git a/test/Spring/Spring.Core.Tests/Core/IO/ConfigurableResourceLoaderTests.cs b/test/Spring/Spring.Core.Tests/Core/IO/ConfigurableResourceLoaderTests.cs index 4fad0307..d3548f23 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/ConfigurableResourceLoaderTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/ConfigurableResourceLoaderTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.IO /// Unit tests for the ConfigurableResourceLoader class. /// /// Aleksandar Seovic - /// $Id: ConfigurableResourceLoaderTests.cs,v 1.6 2007/08/08 17:49:59 bbaia Exp $ [TestFixture] public sealed class ConfigurableResourceLoaderTests { diff --git a/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceCommonTests.cs b/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceCommonTests.cs index 39015805..f1ed96cb 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceCommonTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceCommonTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.IO /// Common Unit tests for all FileSystemResource derived classes. /// /// Erich Eichinger - /// $Id: FileSystemResourceCommonTests.cs,v 1.4 2007/08/08 17:49:59 bbaia Exp $ public abstract class FileSystemResourceCommonTests { protected const string TemporaryFileName = "temp.file"; diff --git a/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceTests.cs b/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceTests.cs index 3f4e4642..985abc33 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/FileSystemResourceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.IO /// Unit tests for the FileSystemResourceTest class. /// /// Rick Evans - /// $Id: FileSystemResourceTests.cs,v 1.9 2007/08/08 17:49:59 bbaia Exp $ [TestFixture] public class FileSystemResourceTests : FileSystemResourceCommonTests { diff --git a/test/Spring/Spring.Core.Tests/Core/IO/InputStreamResourceTests.cs b/test/Spring/Spring.Core.Tests/Core/IO/InputStreamResourceTests.cs index 951e1d6b..b6898070 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/InputStreamResourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/InputStreamResourceTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.IO /// Unit tests for the InputStreamResource class. /// /// Rick Evans - /// $Id: InputStreamResourceTests.cs,v 1.5 2007/08/08 17:49:59 bbaia Exp $ [TestFixture] public sealed class InputStreamResourceTests { diff --git a/test/Spring/Spring.Core.Tests/Core/IO/ResourceConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/IO/ResourceConverterTests.cs index e10d7009..21995a48 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/ResourceConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/ResourceConverterTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.IO /// Unit tests for the ResourceConverter class. /// /// Rick Evans - /// $Id: ResourceConverterTests.cs,v 1.7 2007/08/08 17:49:59 bbaia Exp $ [TestFixture] public sealed class ResourceConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/IO/ResourceHandlerRegistryTests.cs b/test/Spring/Spring.Core.Tests/Core/IO/ResourceHandlerRegistryTests.cs index 079ebacb..0fd14c47 100644 --- a/test/Spring/Spring.Core.Tests/Core/IO/ResourceHandlerRegistryTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/IO/ResourceHandlerRegistryTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.IO /// Unit tests for the ConfigurableResourceLoader class. /// /// Aleksandar Seovic - /// $Id: ResourceHandlerRegistryTests.cs,v 1.4 2007/08/08 17:49:59 bbaia Exp $ [TestFixture] public sealed class ResourceHandlerRegistryTests { diff --git a/test/Spring/Spring.Core.Tests/Core/MethodGenericArgumentsCountCriteriaTests.cs b/test/Spring/Spring.Core.Tests/Core/MethodGenericArgumentsCountCriteriaTests.cs index b551bbbf..ff862902 100644 --- a/test/Spring/Spring.Core.Tests/Core/MethodGenericArgumentsCountCriteriaTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/MethodGenericArgumentsCountCriteriaTests.cs @@ -35,7 +35,6 @@ namespace Spring.Core /// Unit tests for the MethodGenericArgumentsCountCriteria class. /// /// Bruno Baia - /// $Id: MethodGenericArgumentsCountCriteriaTests.cs,v 1.1 2007/08/04 01:05:52 bbaia Exp $ [TestFixture] public sealed class MethodGenericArgumentsCountCriteriaTests { diff --git a/test/Spring/Spring.Core.Tests/Core/MethodParametersCountCriteriaTests.cs b/test/Spring/Spring.Core.Tests/Core/MethodParametersCountCriteriaTests.cs index 1a65be37..4d58e23b 100644 --- a/test/Spring/Spring.Core.Tests/Core/MethodParametersCountCriteriaTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/MethodParametersCountCriteriaTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core /// Unit tests for the MethodParametersCountCriteria class. /// /// Rick Evans - /// $Id: MethodParametersCountCriteriaTests.cs,v 1.3 2007/09/20 14:35:29 bbaia Exp $ [TestFixture] public sealed class MethodParametersCountCriteriaTests { diff --git a/test/Spring/Spring.Core.Tests/Core/MethodParametersCriteriaTests.cs b/test/Spring/Spring.Core.Tests/Core/MethodParametersCriteriaTests.cs index 69551603..b50fd1b4 100644 --- a/test/Spring/Spring.Core.Tests/Core/MethodParametersCriteriaTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/MethodParametersCriteriaTests.cs @@ -34,7 +34,6 @@ namespace Spring.Core /// Unit tests for the MethodParametersCriteria class. /// /// Rick Evans - /// $Id: MethodParametersCriteriaTests.cs,v 1.2 2007/09/20 14:20:47 bbaia Exp $ [TestFixture] public sealed class MethodParametersCriteriaTests { diff --git a/test/Spring/Spring.Core.Tests/Core/MethodReturnTypeCriteriaTests.cs b/test/Spring/Spring.Core.Tests/Core/MethodReturnTypeCriteriaTests.cs index 7714385a..31657d6b 100644 --- a/test/Spring/Spring.Core.Tests/Core/MethodReturnTypeCriteriaTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/MethodReturnTypeCriteriaTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core /// /// Unit tests for the MethodReturnTypeCriteria class. /// - /// $Id: MethodReturnTypeCriteriaTests.cs,v 1.1 2007/08/04 01:05:52 bbaia Exp $ [TestFixture] public sealed class MethodReturnTypeCriteriaTests { diff --git a/test/Spring/Spring.Core.Tests/Core/OrderComparatorTests.cs b/test/Spring/Spring.Core.Tests/Core/OrderComparatorTests.cs index e0c691d3..2a298c90 100644 --- a/test/Spring/Spring.Core.Tests/Core/OrderComparatorTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/OrderComparatorTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core /// Unit tests for the OrderComparator class. /// /// Rick Evans - /// $Id: OrderComparatorTests.cs,v 1.2 2006/04/09 07:24:48 markpollack Exp $ [TestFixture] public sealed class OrderComparatorTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/CredentialConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/CredentialConverterTests.cs index 12c8d1ee..4690060f 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/CredentialConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/CredentialConverterTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the CredentialConverter class. /// /// Bruno Baia - /// $Id: CredentialConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class CredentialConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/CustomNumberConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/CustomNumberConverterTests.cs index 4453bbd2..1f6b2fdc 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/CustomNumberConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/CustomNumberConverterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeConversion /// /// Unit tests for the CustomNumberConverter class. /// - /// $Id: CustomNumberConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public class CustomNumberConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/FileInfoConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/FileInfoConverterTests.cs index d4a28e15..5a3f3946 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/FileInfoConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/FileInfoConverterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the FileInfoConverter class. /// /// Rick Evans - /// $Id: FileInfoConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class FileInfoConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/NameValueConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/NameValueConverterTests.cs index 16383aaf..08b49e43 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/NameValueConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/NameValueConverterTests.cs @@ -34,7 +34,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the NameValueConverter class. /// /// Rick Evans - /// $Id: NameValueConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class NameValueConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RGBColorConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RGBColorConverterTests.cs index a3602220..27fb09dd 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RGBColorConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RGBColorConverterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the RGBColorConverter class. /// /// Rick Evans - /// $Id: RGBColorConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class RGBColorConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegexConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegexConverterTests.cs index c0452df3..1b7b38cb 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegexConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegexConverterTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the RegexConverter class. /// /// Bruno Baia - /// $Id: RegexConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class RegexConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegistryKeyConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegistryKeyConverterTests.cs index 0d27226a..4b0417f8 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegistryKeyConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RegistryKeyConverterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the RegistryKeyConverter class. /// /// Aleksandar Seovic - /// $Id: RegistryKeyConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class RegistryKeyConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RuntimeTypeConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RuntimeTypeConverterTests.cs index ac50caeb..5154f93b 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/RuntimeTypeConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/RuntimeTypeConverterTests.cs @@ -31,7 +31,6 @@ namespace Spring.Core.TypeConversion /// /// Unit tests for the RuntimeTypeConverter class. /// - /// $Id: RuntimeTypeConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public class RuntimeTypeConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/StreamConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/StreamConverterTests.cs index f8943bad..0dcaa135 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/StreamConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/StreamConverterTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the StreamConverter class. /// /// Rick Evans - /// $Id: StreamConverterTests.cs,v 1.1 2007/07/31 18:21:01 bbaia Exp $ [TestFixture] public sealed class StreamConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/StringArrayConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/StringArrayConverterTests.cs index 7e82ca8e..5fe0fce9 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/StringArrayConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/StringArrayConverterTests.cs @@ -34,7 +34,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the StringArrayConverter class. /// /// Rick Evans - /// $Id: StringArrayConverterTests.cs,v 1.1 2007/07/31 18:21:02 bbaia Exp $ [TestFixture] public sealed class StringArrayConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/TimeSpanConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/TimeSpanConverterTests.cs index 7ca68e7c..9bbfa346 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/TimeSpanConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/TimeSpanConverterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the TimeSpanConverter class. /// /// Bruno Baia - /// $Id: TimeSpanConverterTests.cs,v 1.2 2007/08/29 17:29:41 oakinger Exp $ [TestFixture] public sealed class TimeSpanConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/TypeConverterRegistryTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/TypeConverterRegistryTests.cs index b7a4cc72..466997dd 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/TypeConverterRegistryTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/TypeConverterRegistryTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the TypeConverterRegistry class. /// /// Bruno Baia - /// $Id: TypeConverterRegistryTests.cs,v 1.1 2007/07/31 18:21:02 bbaia Exp $ [TestFixture] public sealed class TypeConverterRegistryTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/UniqueKeyConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/UniqueKeyConverterTests.cs index 77df652b..6b923483 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/UniqueKeyConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/UniqueKeyConverterTests.cs @@ -33,7 +33,6 @@ namespace Spring.Core.TypeConversion /// Tests functionality. /// /// Erich Eichinger - /// $Id: UniqueKeyConverterTests.cs,v 1.1 2007/08/22 20:17:05 oakinger Exp $ [TestFixture] public class UniqueKeyConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeConversion/UriConverterTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeConversion/UriConverterTests.cs index 5043ddc9..08ef0bad 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeConversion/UriConverterTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeConversion/UriConverterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeConversion /// Unit tests for the UriConverter class. /// /// Rick Evans - /// $Id: UriConverterTests.cs,v 1.1 2007/07/31 18:21:02 bbaia Exp $ [TestFixture] public sealed class UriConverterTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeResolution/CachedTypeResolverTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeResolution/CachedTypeResolverTests.cs index 48555ea6..4c6527f1 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeResolution/CachedTypeResolverTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeResolution/CachedTypeResolverTests.cs @@ -32,7 +32,6 @@ namespace Spring.Core.TypeResolution /// Unit tests for the CachedTypeResolver class. /// /// Rick Evans - /// $Id: CachedTypeResolverTests.cs,v 1.1 2007/07/31 18:21:02 bbaia Exp $ [TestFixture] public sealed class CachedTypeResolverTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs index 7e22d854..5e08da11 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeResolution/GenericTypeResolverTests.cs @@ -36,7 +36,6 @@ namespace Spring.Core.TypeResolution /// Unit tests for the GenericTypeResolver class. /// /// Bruno Baia - /// $Id: GenericTypeResolverTests.cs,v 1.2 2007/08/16 05:42:33 markpollack Exp $ [TestFixture] public class GenericTypeResolverTests : TypeResolverTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolutionUtilsTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolutionUtilsTests.cs index bcfa2a02..8d3bda36 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolutionUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolutionUtilsTests.cs @@ -34,7 +34,6 @@ namespace Spring.Core.TypeResolution /// /// Unit tests for the TypeResolutionUtils class. /// - /// $Id: TypeResolutionUtilsTests.cs,v 1.2 2007/08/02 14:19:03 markpollack Exp $ [TestFixture] public sealed class TypeResolutionUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolverTests.cs b/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolverTests.cs index b072338d..7aed5b21 100644 --- a/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolverTests.cs +++ b/test/Spring/Spring.Core.Tests/Core/TypeResolution/TypeResolverTests.cs @@ -34,7 +34,6 @@ namespace Spring.Core.TypeResolution /// /// Rick Evans /// Bruno Baia - /// $Id: TypeResolverTests.cs,v 1.1 2007/07/31 18:21:02 bbaia Exp $ [TestFixture] public class TypeResolverTests { diff --git a/test/Spring/Spring.Core.Tests/CoreExceptionTests.cs b/test/Spring/Spring.Core.Tests/CoreExceptionTests.cs index 47d84c23..804812c5 100644 --- a/test/Spring/Spring.Core.Tests/CoreExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/CoreExceptionTests.cs @@ -32,7 +32,6 @@ namespace Spring /// Unit tests for all of the exception classes in the Spring.Core library... /// /// Rick Evans - /// $Id: CoreExceptionTests.cs,v 1.3 2007/01/03 06:27:43 aseovic Exp $ [TestFixture] public sealed class CoreExceptionTests : ExceptionsTest { diff --git a/test/Spring/Spring.Core.Tests/DataBinding/BaseBindingManagerTests.cs b/test/Spring/Spring.Core.Tests/DataBinding/BaseBindingManagerTests.cs index af7c08ed..3eebc25c 100644 --- a/test/Spring/Spring.Core.Tests/DataBinding/BaseBindingManagerTests.cs +++ b/test/Spring/Spring.Core.Tests/DataBinding/BaseBindingManagerTests.cs @@ -33,7 +33,6 @@ namespace Spring.DataBinding /// Test cases for the BaseBindingManager. /// /// Aleksandar Seovic - /// $Id: BaseBindingManagerTests.cs,v 1.6 2008/03/20 14:02:47 oakinger Exp $ [TestFixture] public class BaseBindingManagerTests { diff --git a/test/Spring/Spring.Core.Tests/DataBinding/SimpleExpressionBindingTests.cs b/test/Spring/Spring.Core.Tests/DataBinding/SimpleExpressionBindingTests.cs index 75f122b7..3de89eac 100644 --- a/test/Spring/Spring.Core.Tests/DataBinding/SimpleExpressionBindingTests.cs +++ b/test/Spring/Spring.Core.Tests/DataBinding/SimpleExpressionBindingTests.cs @@ -28,7 +28,6 @@ namespace Spring.DataBinding /// Test cases for the SimpleExpressionBinding class. /// /// Aleksandar Seovic - /// $Id: SimpleExpressionBindingTests.cs,v 1.1 2006/11/21 05:47:00 aseovic Exp $ [TestFixture] public class SimpleExpressionBindingTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs b/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs index 627d6f70..014dd3ca 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs @@ -55,7 +55,6 @@ namespace Spring.Expressions /// This class contains tests for ExpressionEvaluator. /// /// Aleksandar Seovic - /// $Id: ExpressionEvaluatorTests.cs,v 1.72 2008/03/20 23:58:16 oakinger Exp $ [TestFixture] public sealed class ExpressionEvaluatorTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/FunctionNodeTests.cs b/test/Spring/Spring.Core.Tests/Expressions/FunctionNodeTests.cs index da59a1ab..022ffbfb 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/FunctionNodeTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/FunctionNodeTests.cs @@ -32,7 +32,6 @@ namespace Spring.Expressions /// /// /// Erich Eichinger - /// $Id: FunctionNodeTests.cs,v 1.1 2008/03/20 23:58:16 oakinger Exp $ [TestFixture] public class FunctionNodeTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/MethodNodeTests.cs b/test/Spring/Spring.Core.Tests/Expressions/MethodNodeTests.cs index a9e886fa..a84325a2 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/MethodNodeTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/MethodNodeTests.cs @@ -33,7 +33,6 @@ namespace Spring.Expressions /// /// /// Erich Eichinger - /// $Id: MethodNodeTests.cs,v 1.2 2008/03/20 23:58:16 oakinger Exp $ [TestFixture] public class MethodNodeTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/Processors/ConversionProcessorTests.cs b/test/Spring/Spring.Core.Tests/Expressions/Processors/ConversionProcessorTests.cs index 82cc91c6..af22592f 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/Processors/ConversionProcessorTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/Processors/ConversionProcessorTests.cs @@ -34,7 +34,6 @@ namespace Spring.Expressions.Processors /// /// /// Erich Eichinger - /// $Id: ConversionProcessorTests.cs,v 1.1 2008/03/20 23:58:17 oakinger Exp $ [TestFixture] public class ConversionProcessorTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/Processors/OrderByProcessorTests.cs b/test/Spring/Spring.Core.Tests/Expressions/Processors/OrderByProcessorTests.cs index 5f9d5f9a..c12edba8 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/Processors/OrderByProcessorTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/Processors/OrderByProcessorTests.cs @@ -32,7 +32,6 @@ namespace Spring.Expressions.Processors /// /// /// Erich Eichinger - /// $Id: OrderByProcessorTests.cs,v 1.1 2008/03/20 23:58:17 oakinger Exp $ [TestFixture] public class OrderByProcessorTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/ReferenceNodeTests.cs b/test/Spring/Spring.Core.Tests/Expressions/ReferenceNodeTests.cs index 0cff296f..086f2710 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/ReferenceNodeTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/ReferenceNodeTests.cs @@ -35,7 +35,6 @@ namespace Spring.Expressions /// /// /// Erich Eichinger - /// $Id: ReferenceNodeTests.cs,v 1.1 2008/03/20 10:35:55 oakinger Exp $ [TestFixture] public class ReferenceNodeTests { diff --git a/test/Spring/Spring.Core.Tests/Expressions/SelectionNodeTests.cs b/test/Spring/Spring.Core.Tests/Expressions/SelectionNodeTests.cs index 3621f721..f3346dae 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/SelectionNodeTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/SelectionNodeTests.cs @@ -32,7 +32,6 @@ namespace Spring.Expressions /// /// /// Erich Eichinger - /// $Id: SelectionNodeTests.cs,v 1.1 2008/03/25 22:33:04 oakinger Exp $ [TestFixture] public class SelectionNodeTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/AbstractLocalizerTests.cs b/test/Spring/Spring.Core.Tests/Globalization/AbstractLocalizerTests.cs index 4852377b..2f36295e 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/AbstractLocalizerTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/AbstractLocalizerTests.cs @@ -35,7 +35,6 @@ namespace Spring.Globalization /// Unit tests for the localizers. /// /// Aleksandar Seovic - /// $Id: AbstractLocalizerTests.cs,v 1.5 2007/07/24 17:26:47 oakinger Exp $ public abstract class AbstractLocalizerTests { private ILocalizer localizer; diff --git a/test/Spring/Spring.Core.Tests/Globalization/CultureTestScope.cs b/test/Spring/Spring.Core.Tests/Globalization/CultureTestScope.cs index e6fbd5ca..f0e22149 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/CultureTestScope.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/CultureTestScope.cs @@ -32,7 +32,6 @@ namespace Spring.Globalization /// Helps setting/resetting current thread cultures. /// /// Erich Eichinger - /// $Id: CultureTestScope.cs,v 1.1 2007/07/24 17:26:47 oakinger Exp $ public class CultureTestScope : IDisposable { [ThreadStatic] diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/CurrencyFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/CurrencyFormatterTests.cs index ec9f4b09..ae50d291 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/CurrencyFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/CurrencyFormatterTests.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Formatters /// Unit tests for CurrencyFormatter class. /// /// Aleksandar Seovic - /// $Id: CurrencyFormatterTests.cs,v 1.3 2007/05/04 18:13:22 markpollack Exp $ [TestFixture] public class CurrencyFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/DateTimeFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/DateTimeFormatterTests.cs index 287d52e8..74b34bf4 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/DateTimeFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/DateTimeFormatterTests.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Formatters /// Unit tests for DateTimeFormatter class. /// /// Aleksandar Seovic - /// $Id: DateTimeFormatterTests.cs,v 1.3 2007/05/04 18:13:22 markpollack Exp $ [TestFixture] public class DateTimeFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/FilteringFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/FilteringFormatterTests.cs index d647a10e..57ec3ccb 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/FilteringFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/FilteringFormatterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Globalization.Formatters /// /// /// Erich Eichinger - /// $Id: FilteringFormatterTests.cs,v 1.1 2008/03/20 13:19:47 oakinger Exp $ [TestFixture] public class FilteringFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/FloatFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/FloatFormatterTests.cs index 0474bc7f..0c0e9091 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/FloatFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/FloatFormatterTests.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Formatters /// Unit tests for FloatFormatter class. /// /// Aleksandar Seovic - /// $Id: FloatFormatterTests.cs,v 1.3 2006/04/09 07:24:49 markpollack Exp $ [TestFixture] public class FloatFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/HasTextFilteringFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/HasTextFilteringFormatterTests.cs index 93551515..7d212c3b 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/HasTextFilteringFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/HasTextFilteringFormatterTests.cs @@ -31,7 +31,6 @@ namespace Spring.Globalization.Formatters /// /// /// Erich Eichinger - /// $Id: HasTextFilteringFormatterTests.cs,v 1.1 2008/03/20 13:19:47 oakinger Exp $ [TestFixture] public class HasTextFilteringFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/IntegerFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/IntegerFormatterTests.cs index efb79d9e..d02bb9f1 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/IntegerFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/IntegerFormatterTests.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Formatters /// Unit tests for IntegerFormatter class. /// /// Aleksandar Seovic - /// $Id: IntegerFormatterTests.cs,v 1.3 2007/06/01 08:53:06 oakinger Exp $ [TestFixture] public class IntegerFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/NumberFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/NumberFormatterTests.cs index 9db42539..fd709597 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/NumberFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/NumberFormatterTests.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Formatters /// Unit tests for NumberFormatter class. /// /// Aleksandar Seovic - /// $Id: NumberFormatterTests.cs,v 1.2 2006/04/09 07:24:49 markpollack Exp $ [TestFixture] public class NumberFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Formatters/PercentFormatterTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Formatters/PercentFormatterTests.cs index 185e5208..a96ac55c 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Formatters/PercentFormatterTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Formatters/PercentFormatterTests.cs @@ -28,7 +28,6 @@ namespace Spring.Globalization.Formatters /// Unit tests for PercentFormatter class. /// /// Aleksandar Seovic - /// $Id: PercentFormatterTests.cs,v 1.2 2006/04/09 07:24:49 markpollack Exp $ [TestFixture] public class PercentFormatterTests { diff --git a/test/Spring/Spring.Core.Tests/Globalization/Localizers/ResourceSetLocalizerTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Localizers/ResourceSetLocalizerTests.cs index 23b81b7b..07f3dee1 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Localizers/ResourceSetLocalizerTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Localizers/ResourceSetLocalizerTests.cs @@ -37,8 +37,6 @@ namespace Spring.Globalization.Localizers /// Unit tests for the ResourceSetLocalizer class. /// /// Aleksandar Seovic - /// $Id: ResourceSetLocalizerTests.cs,v 1.4 2007/07/24 17:26:47 oakinger Exp $ - #if ! NET_1_0 [TestFixture] #endif diff --git a/test/Spring/Spring.Core.Tests/Globalization/Resolvers/DefaultCultureResolverTests.cs b/test/Spring/Spring.Core.Tests/Globalization/Resolvers/DefaultCultureResolverTests.cs index 3a2541e7..3d9bc7d8 100644 --- a/test/Spring/Spring.Core.Tests/Globalization/Resolvers/DefaultCultureResolverTests.cs +++ b/test/Spring/Spring.Core.Tests/Globalization/Resolvers/DefaultCultureResolverTests.cs @@ -33,7 +33,6 @@ namespace Spring.Globalization.Resolvers /// Unit tests for the DefaultCultureResolver class. /// /// Rick Evans - /// $Id: DefaultCultureResolverTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class DefaultCultureResolverTests { diff --git a/test/Spring/Spring.Core.Tests/HookableContextHandler.cs b/test/Spring/Spring.Core.Tests/HookableContextHandler.cs index f8c0add1..65c81363 100644 --- a/test/Spring/Spring.Core.Tests/HookableContextHandler.cs +++ b/test/Spring/Spring.Core.Tests/HookableContextHandler.cs @@ -33,7 +33,6 @@ namespace Spring /// Replace the original context handler with this hookable version for testing ContextRegistry /// /// Erich Eichinger - /// $Id: HookableContextHandler.cs,v 1.1 2008/03/21 10:49:38 oakinger Exp $ public class HookableContextHandler : ContextHandler, IConfigurationSectionHandler { public delegate object CreateContextFromSectionHandler(object parent, object configContext, XmlNode section); diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/MyRequiredAttribute.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/MyRequiredAttribute.cs index 9a5bfcc0..421a62ac 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/MyRequiredAttribute.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/MyRequiredAttribute.cs @@ -26,7 +26,6 @@ namespace Spring.Objects.Factory.Attributes /// Custom attribute to indicate required setter property /// /// Mark Pollack - /// $Id: MyRequiredAttribute.cs,v 1.1 2008/04/02 18:02:31 markpollack Exp $ [AttributeUsage(AttributeTargets.Property)] public class MyRequiredAttribute : Attribute { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessorTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessorTests.cs index 2cb91ec0..0ab3a68d 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessorTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredAttributeObjectPostProcessorTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Attributes /// This class contains tests for RequiredAttributeObjectPostProcessor. /// /// Mark Pollack - /// $Id: RequiredAttributeObjectPostProcessorTests.cs,v 1.1 2008/04/02 18:02:31 markpollack Exp $ [TestFixture] public class RequiredAttributeObjectPostProcessorTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredTestObject.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredTestObject.cs index 5fe6e0be..a852ee2b 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredTestObject.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Attributes/RequiredTestObject.cs @@ -25,7 +25,6 @@ namespace Spring.Objects.Factory.Attributes /// Test object for testing 'required' attribute functionality. /// /// Mark Pollack - /// $Id: RequiredTestObject.cs,v 1.1 2008/04/02 18:02:31 markpollack Exp $ public class RequiredTestObject : IObjectNameAware, IObjectFactoryAware { private string name; diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/AbstractFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/AbstractFactoryObjectTests.cs index 55050f32..4d033a8a 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/AbstractFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/AbstractFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the basic functionality of the AbstractFactoryObject class. /// /// Rick Evans - /// $Id: AbstractFactoryObjectTests.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class AbstractFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CommandLineArgsVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CommandLineArgsVariableSourceTests.cs index 539ac1e8..36823207 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CommandLineArgsVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CommandLineArgsVariableSourceTests.cs @@ -30,7 +30,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the CommandLineArgsVariableSource class. /// /// Aleksandar Seovic - /// $Id: CommandLineArgsVariableSourceTests.cs,v 1.1 2007/03/10 01:44:40 aseovic Exp $ [TestFixture] public sealed class CommandLineArgsVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigSectionVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigSectionVariableSourceTests.cs index 3ccbb3b8..bbc1781a 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigSectionVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigSectionVariableSourceTests.cs @@ -31,7 +31,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the ConfigSectionVariableSource class. /// /// Aleksandar Seovic - /// $Id: ConfigSectionVariableSourceTests.cs,v 1.3 2007/08/08 17:49:04 bbaia Exp $ [TestFixture] public sealed class ConfigSectionVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigurationReaderTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigurationReaderTests.cs index 13246d8a..a3a57b6c 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigurationReaderTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConfigurationReaderTests.cs @@ -37,7 +37,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the ConfigurationReader class. /// /// Rick Evans - /// $Id: ConfigurationReaderTests.cs,v 1.7 2007/08/08 17:49:04 bbaia Exp $ [TestFixture] public sealed class ConfigurationReaderTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConnectionStringsVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConnectionStringsVariableSourceTests.cs index 1ef5622a..4d7b98f4 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConnectionStringsVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ConnectionStringsVariableSourceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the ConnectionStringsVariableSource class. /// /// Aleksandar Seovic - /// $Id: ConnectionStringsVariableSourceTests.cs,v 1.2 2007/05/30 17:32:37 oakinger Exp $ [TestFixture] public sealed class ConnectionStringsVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CustomConverterConfigurerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CustomConverterConfigurerTests.cs index 82b15cf3..be965797 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CustomConverterConfigurerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/CustomConverterConfigurerTests.cs @@ -35,7 +35,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the CustomConverterConfigurer class. /// /// Rick Evans - /// $Id: CustomConverterConfigurerTests.cs,v 1.6 2007/05/11 02:32:31 markpollack Exp $ [TestFixture] public sealed class CustomConverterConfigurerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DelegateFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DelegateFactoryObjectTests.cs index e361bc3a..7ba4c988 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DelegateFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DelegateFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the DelegateFactoryObject class. /// /// Rick Evans - /// $Id: DelegateFactoryObjectTests.cs,v 1.5 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class DelegateFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DictionaryFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DictionaryFactoryObjectTests.cs index bda44582..dfa50086 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DictionaryFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DictionaryFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the DictionaryFactoryObject class. /// /// Rick Evans - /// $Id: DictionaryFactoryObjectTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class DictionaryFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/EnvironmentVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/EnvironmentVariableSourceTests.cs index 6f267340..da85ee45 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/EnvironmentVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/EnvironmentVariableSourceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the EnvironmentVariableSource class. /// /// Aleksandar Seovic - /// $Id: EnvironmentVariableSourceTests.cs,v 1.1 2007/03/10 01:44:40 aseovic Exp $ [TestFixture] public sealed class EnvironmentVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/FieldRetrievingFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/FieldRetrievingFactoryObjectTests.cs index 00e9a5e1..30c82297 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/FieldRetrievingFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/FieldRetrievingFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// /// Juergen Hoeller /// Rick Evans - /// $Id: FieldRetrievingFactoryObjectTests.cs,v 1.5 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class FieldRetrievingFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ListFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ListFactoryObjectTests.cs index e249ac59..6e95696c 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ListFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ListFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the ListFactoryObject class. /// /// Rick Evans - /// $Id: ListFactoryObjectTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class ListFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/LogFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/LogFactoryObjectTests.cs index a8bf2d32..ae7f3377 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/LogFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/LogFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the LogFactoryObject class. /// /// Rick Evans (.NET) - /// $Id: LogFactoryObjectTests.cs,v 1.1 2006/11/15 20:31:08 aseovic Exp $ [TestFixture] public sealed class LogFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ObjectReferenceFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ObjectReferenceFactoryObjectTests.cs index 33176de5..364e4b34 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ObjectReferenceFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/ObjectReferenceFactoryObjectTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the ObjectReferenceFactoryObject class. /// /// Rick Evans - /// $Id: ObjectReferenceFactoryObjectTests.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class ObjectReferenceFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyFileVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyFileVariableSourceTests.cs index e6050d65..7b7f62ee 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyFileVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyFileVariableSourceTests.cs @@ -31,7 +31,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the PropertyFileVariableSource class. /// /// Aleksandar Seovic - /// $Id: PropertyFileVariableSourceTests.cs,v 1.3 2007/08/08 17:49:04 bbaia Exp $ [TestFixture] public sealed class PropertyFileVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyOverrideConfigurerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyOverrideConfigurerTests.cs index e579c4f6..eb3543ba 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyOverrideConfigurerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyOverrideConfigurerTests.cs @@ -37,7 +37,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the PropertyOverrideConfigurer class. /// /// Rick Evans - /// $Id: PropertyOverrideConfigurerTests.cs,v 1.9 2007/10/10 16:31:50 bbaia Exp $ [TestFixture] public sealed class PropertyOverrideConfigurerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPathFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPathFactoryObjectTests.cs index f4d6a1c3..0420df87 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPathFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPathFactoryObjectTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the PropertyPathFactoryObject class. /// /// Rick Evans - /// $Id: PropertyPathFactoryObjectTests.cs,v 1.3 2007/07/31 00:09:30 markpollack Exp $ [TestFixture] public sealed class PropertyPathFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPlaceholderConfigurerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPlaceholderConfigurerTests.cs index 6a4e00db..97fc4f0d 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPlaceholderConfigurerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyPlaceholderConfigurerTests.cs @@ -41,7 +41,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the PropertyPlaceholderConfigurer class. /// /// Rick Evans - /// $Id: PropertyPlaceholderConfigurerTests.cs,v 1.11 2007/11/26 14:16:29 bbaia Exp $ [TestFixture] public sealed class PropertyPlaceholderConfigurerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyRetrievingFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyRetrievingFactoryObjectTests.cs index 6ce1abfc..eda10aae 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyRetrievingFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/PropertyRetrievingFactoryObjectTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the PropertyRetrievingFactoryObject class. /// /// Rick Evans - /// $Id: PropertyRetrievingFactoryObjectTests.cs,v 1.6 2007/07/31 00:09:30 markpollack Exp $ [TestFixture] public sealed class PropertyRetrievingFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RegistryVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RegistryVariableSourceTests.cs index 6549a999..97acb79d 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RegistryVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RegistryVariableSourceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the RegistryVariableSource class. /// /// Aleksandar Seovic - /// $Id: RegistryVariableSourceTests.cs,v 1.3 2007/08/03 08:31:25 oakinger Exp $ [TestFixture] public sealed class RegistryVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RuntimeObjectReferenceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RuntimeObjectReferenceTests.cs index 8857605a..2470cda7 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RuntimeObjectReferenceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/RuntimeObjectReferenceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the RuntimeObjectReference class. /// /// Rick Evans - /// $Id: RuntimeObjectReferenceTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class RuntimeObjectReferenceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SetFactoryObjectTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SetFactoryObjectTests.cs index 2628f3f8..d1ca8c49 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SetFactoryObjectTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SetFactoryObjectTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the SetFactoryObject class. /// /// Rick Evans - /// $Id: SetFactoryObjectTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class SetFactoryObjectTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SpecialFolderVariableSourceTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SpecialFolderVariableSourceTests.cs index abc8229c..fe295fc6 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SpecialFolderVariableSourceTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/SpecialFolderVariableSourceTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Unit tests for the SpecialFolderVariableSource class. /// /// Aleksandar Seovic - /// $Id: SpecialFolderVariableSourceTests.cs,v 1.1 2007/03/10 01:44:40 aseovic Exp $ [TestFixture] public sealed class SpecialFolderVariableSourceTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs index ccbef7d4..ad67be66 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Config /// /// Juergen Hoeller /// Rick Evans (.NET) - /// $Id: TypedStringValueTests.cs,v 1.4 2007/05/29 20:00:47 markpollack Exp $ [TestFixture] public sealed class TypedStringValueTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariableAccessorTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariableAccessorTests.cs index 7b01ebb5..92d7208f 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariableAccessorTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariableAccessorTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// Tests functionality. /// /// Erich Eichinger - /// $Id: VariableAccessorTests.cs,v 1.1 2007/08/22 20:17:05 oakinger Exp $ [TestFixture] public class VariableAccessorTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariablePlaceholderConfigurerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariablePlaceholderConfigurerTests.cs index bc48482a..2f4a4499 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariablePlaceholderConfigurerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/VariablePlaceholderConfigurerTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Config /// This calss contains tests for /// /// Mark Pollack - /// $Id: VariablePlaceholderConfigurerTests.cs,v 1.1 2007/07/10 05:48:43 markpollack Exp $ [TestFixture] public class VariablePlaceholderConfigurerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/DefaultListableObjectFactoryPerfTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/DefaultListableObjectFactoryPerfTests.cs index 2ae2f3e8..895dd1fa 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/DefaultListableObjectFactoryPerfTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/DefaultListableObjectFactoryPerfTests.cs @@ -35,7 +35,6 @@ namespace Spring.Objects.Factory /// This class contains tests related to performance of the object factory implementation. Ignored by default. /// /// Mark Pollack - /// $Id: DefaultListableObjectFactoryPerfTests.cs,v 1.1 2008/01/29 20:11:19 markpollack Exp $ [TestFixture] public class DefaultListableObjectFactoryPerfTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/DummyConfigurableFactory.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/DummyConfigurableFactory.cs index 11299ba7..d7971134 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/DummyConfigurableFactory.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/DummyConfigurableFactory.cs @@ -31,7 +31,6 @@ namespace Spring.Objects.Factory /// of IConfigurableFactoryObject support in AbstractObjectFactory. /// /// Bruno Baia - /// $Id: DummyConfigurableFactory.cs,v 1.2 2007/03/04 20:42:06 bbaia Exp $ public class DummyConfigurableFactory : DummyFactory, IConfigurableFactoryObject { #region Fields diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/MethodReplacerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/MethodReplacerTests.cs index 2de2739d..3c21d9fa 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/MethodReplacerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/MethodReplacerTests.cs @@ -39,7 +39,6 @@ namespace Spring.Objects.Factory ///

/// /// Rick Evans - /// $Id: MethodReplacerTests.cs,v 1.4 2008/05/02 20:08:23 markpollack Exp $ [TestFixture] public sealed class MethodReplacerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/NoSuchObjectDefinitionExceptionTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/NoSuchObjectDefinitionExceptionTests.cs index c21fa118..f749c393 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/NoSuchObjectDefinitionExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/NoSuchObjectDefinitionExceptionTests.cs @@ -29,7 +29,6 @@ namespace Spring.Objects.Factory /// Unit tests for the NoSuchObjectDefinitionException class. /// /// Rick Evans - /// $Id: NoSuchObjectDefinitionExceptionTests.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class NoSuchObjectDefinitionExceptionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectDefinitionStoreExceptionTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectDefinitionStoreExceptionTests.cs index 100dbeeb..6e0f5df9 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectDefinitionStoreExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectDefinitionStoreExceptionTests.cs @@ -34,7 +34,6 @@ namespace Spring.Objects.Factory /// Unit tests for the ObjectDefinitionStoreException class. /// /// Rick Evans - /// $Id: ObjectDefinitionStoreExceptionTests.cs,v 1.5 2007/08/08 17:49:04 bbaia Exp $ [TestFixture] public sealed class ObjectDefinitionStoreExceptionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/AutowireUtilsTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/AutowireUtilsTests.cs index dcebd7ff..fa7f90e2 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/AutowireUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/AutowireUtilsTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the AutowireUtilsTests class. /// /// Rick Evans - /// $Id: AutowireUtilsTests.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class AutowireUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ChildObjectDefinitionTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ChildObjectDefinitionTests.cs index 37926969..6045df9b 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ChildObjectDefinitionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ChildObjectDefinitionTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the ChildObjectDefinition class. /// /// Rick Evans - /// $Id: ChildObjectDefinitionTests.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class ChildObjectDefinitionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DefaultObjectDefinitionFactoryTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DefaultObjectDefinitionFactoryTests.cs index 55b12610..87ebe97f 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DefaultObjectDefinitionFactoryTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DefaultObjectDefinitionFactoryTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the DefaultObjectDefinitionFactory class. /// /// Rick Evans - /// $Id: DefaultObjectDefinitionFactoryTests.cs,v 1.3 2007/05/28 19:14:18 markpollack Exp $ [TestFixture] public sealed class DefaultObjectDefinitionFactoryTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DelegatingMethodReplacerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DelegatingMethodReplacerTests.cs index ad8fbd55..1ea25914 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DelegatingMethodReplacerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/DelegatingMethodReplacerTests.cs @@ -34,7 +34,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the DelegatingMethodReplacer class. /// /// Rick Evans - /// $Id: DelegatingMethodReplacerTests.cs,v 1.3 2007/07/30 17:52:33 markpollack Exp $ [TestFixture] public sealed class DelegatingMethodReplacerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodOverrideTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodOverrideTests.cs index 4381e99e..940b6562 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodOverrideTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodOverrideTests.cs @@ -31,7 +31,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the LookupMethodOverride class. /// /// Rick Evans - /// $Id: LookupMethodOverrideTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class LookupMethodOverrideTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodReplacerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodReplacerTests.cs index 7f66a77e..4c866297 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodReplacerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/LookupMethodReplacerTests.cs @@ -34,7 +34,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the LookupMethodReplacer class. /// /// Rick Evans - /// $Id: LookupMethodReplacerTests.cs,v 1.3 2007/07/30 17:52:33 markpollack Exp $ [TestFixture] public sealed class LookupMethodReplacerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionBuilderTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionBuilderTests.cs index 5ff11cc5..22322544 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionBuilderTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionBuilderTests.cs @@ -35,7 +35,6 @@ namespace Spring.Objects.Factory.Support /// This class contains tests for ObjectDefinitionBuilder /// /// Mark Pollack - /// $Id: ObjectDefinitionBuilderTests.cs,v 1.4 2008/01/28 23:03:05 markpollack Exp $ [TestFixture] public class ObjectDefinitionBuilderTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionReaderUtilsTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionReaderUtilsTests.cs index 94de5f8e..4217524d 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionReaderUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ObjectDefinitionReaderUtilsTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the ObjectDefinitionReaderUtils class. /// /// Rick Evans - /// $Id: ObjectDefinitionReaderUtilsTests.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class ObjectDefinitionReaderUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ReplacedMethodOverrideTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ReplacedMethodOverrideTests.cs index 5445634d..7fecd8dc 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ReplacedMethodOverrideTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/ReplacedMethodOverrideTests.cs @@ -31,7 +31,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the ReplacedMethodOverride class. /// /// Rick Evans - /// $Id: ReplacedMethodOverrideTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class ReplacedMethodOverrideTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/RootObjectDefinitionTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/RootObjectDefinitionTests.cs index dbb60b08..ca8b028e 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/RootObjectDefinitionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/RootObjectDefinitionTests.cs @@ -35,7 +35,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the RootObjectDefinition class. /// /// Rick Evans - /// $Id: RootObjectDefinitionTests.cs,v 1.6 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class RootObjectDefinitionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/SimpleInstantiationStrategyTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/SimpleInstantiationStrategyTests.cs index bd6f9210..00fcd4d4 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Support/SimpleInstantiationStrategyTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Support/SimpleInstantiationStrategyTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the SimpleInstantiationStrategy class. /// /// Rick Evans - /// $Id: SimpleInstantiationStrategyTests.cs,v 1.5 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class SimpleInstantiationStrategyTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/FactoryMethods.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/FactoryMethods.cs index 578a9e44..afcb2c80 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/FactoryMethods.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/FactoryMethods.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Xml /// /// Rod Johnson /// Rick Evans (.NET) - /// $Id: FactoryMethods.cs,v 1.3 2006/04/09 07:24:51 markpollack Exp $ public class FactoryMethods { #region Constructor (s) / Destructor diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/InstanceFactory.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/InstanceFactory.cs index 78e996e9..f81bc31b 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/InstanceFactory.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/InstanceFactory.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Xml /// /// Rod Johnson /// Rick Evans - /// $Id: InstanceFactory.cs,v 1.3 2007/06/14 19:52:07 markpollack Exp $ public class InstanceFactory { private string _factoryObjectProperty; diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/LocaleTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/LocaleTests.cs index 98848346..3015dae1 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/LocaleTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/LocaleTests.cs @@ -35,7 +35,6 @@ namespace Spring.Objects.Factory.Xml /// as comma delimited strings. /// /// Mark Pollack - /// $Id: LocaleTests.cs,v 1.1 2007/08/25 16:08:36 markpollack Exp $ [TestFixture] public class LocaleTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/NullAppender.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/NullAppender.cs index 8325bd75..6eac8384 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/NullAppender.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/NullAppender.cs @@ -31,8 +31,6 @@ namespace Spring.Objects.Factory.Xml /// A log4Net appender that does nothing (by intention). /// /// Rick Evans - /// $Id: NullAppender.cs,v 1.4 2006/11/13 07:04:59 markpollack Exp $ - public sealed class NullAppender //: AppenderSkeleton { /* diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/TestObjectCreator.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/TestObjectCreator.cs index 07048d08..cda12a35 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/TestObjectCreator.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/TestObjectCreator.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Factory.Xml /// /// Rod Johnson /// Rick Evans (.NET) - /// $Id: TestObjectCreator.cs,v 1.3 2006/04/09 07:24:51 markpollack Exp $ public class TestObjectCreator { public static TestObject CreateTestObject(string name, int age) diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectCollectionTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectCollectionTests.cs index 81a7b807..9e42035d 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectCollectionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectCollectionTests.cs @@ -40,7 +40,6 @@ namespace Spring.Objects.Factory.Xml /// Tests for collections in XML object definitions. /// /// Rick Evans - /// $Id: XmlObjectCollectionTests.cs,v 1.9 2007/08/08 17:49:04 bbaia Exp $ [TestFixture] public sealed class XmlObjectCollectionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs index d240ee38..7040b9cc 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs @@ -54,7 +54,6 @@ namespace Spring.Objects.Factory.Xml /// /// Juergen Hoeller /// Rick Evans (.NET) - /// $Id: XmlObjectFactoryTests.cs,v 1.80 2008/05/02 20:08:23 markpollack Exp $ [TestFixture] public sealed class XmlObjectFactoryTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlParserResolverTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlParserResolverTests.cs index bda700c3..87ef9a28 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlParserResolverTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlParserResolverTests.cs @@ -35,7 +35,6 @@ namespace Spring.Objects.Factory.Xml /// /// Rick Evans /// Aleksandar Seovic 2006.11.21 - /// $Id: XmlParserResolverTests.cs,v 1.10 2007/08/07 21:23:59 markpollack Exp $ [TestFixture] public sealed class XmlParserResolverTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/IOther.cs b/test/Spring/Spring.Core.Tests/Objects/IOther.cs index 803f36a8..0dfd4f9f 100644 --- a/test/Spring/Spring.Core.Tests/Objects/IOther.cs +++ b/test/Spring/Spring.Core.Tests/Objects/IOther.cs @@ -26,7 +26,6 @@ namespace Spring.Objects /// /// Spring.Java Folks /// Choy Rim (.NET) - /// $Id: IOther.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ public interface IOther { diff --git a/test/Spring/Spring.Core.Tests/Objects/LazyTestObject.cs b/test/Spring/Spring.Core.Tests/Objects/LazyTestObject.cs index 1acc0602..971be7b1 100644 --- a/test/Spring/Spring.Core.Tests/Objects/LazyTestObject.cs +++ b/test/Spring/Spring.Core.Tests/Objects/LazyTestObject.cs @@ -33,7 +33,6 @@ namespace Spring.Objects /// XmlObjectFactoryTests. /// /// Mark Pollack (.NET) - /// $Id: LazyTestObject.cs,v 1.1 2006/04/23 19:34:38 markpollack Exp $ public class LazyTestObject { #region Fields diff --git a/test/Spring/Spring.Core.Tests/Objects/MutablePropertyValuesTests.cs b/test/Spring/Spring.Core.Tests/Objects/MutablePropertyValuesTests.cs index ac5b09cd..37aeb084 100644 --- a/test/Spring/Spring.Core.Tests/Objects/MutablePropertyValuesTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/MutablePropertyValuesTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects /// Unit tests for the MutablePropertyValues class. /// /// Rick Evans - /// $Id: MutablePropertyValuesTests.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class MutablePropertyValuesTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/NotWritablePropertyExceptionTests.cs b/test/Spring/Spring.Core.Tests/Objects/NotWritablePropertyExceptionTests.cs index a65658fb..3444fe2a 100644 --- a/test/Spring/Spring.Core.Tests/Objects/NotWritablePropertyExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/NotWritablePropertyExceptionTests.cs @@ -28,7 +28,6 @@ namespace Spring.Objects /// Unit tests for the NotWritablePropertyException class. /// /// Rick Evans - /// $Id: NotWritablePropertyExceptionTests.cs,v 1.4 2007/07/31 00:09:24 markpollack Exp $ [TestFixture] public sealed class NotWritablePropertyExceptionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/ObjectWrapperTests.cs b/test/Spring/Spring.Core.Tests/Objects/ObjectWrapperTests.cs index ccc0f7c8..639c229a 100644 --- a/test/Spring/Spring.Core.Tests/Objects/ObjectWrapperTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/ObjectWrapperTests.cs @@ -51,7 +51,6 @@ namespace Spring.Objects /// Rod Johnson /// Mark Pollack (.NET) /// Rick Evans (.NET) - /// $Id: ObjectWrapperTests.cs,v 1.14 2007/07/31 18:19:58 bbaia Exp $ [TestFixture] public sealed class ObjectWrapperTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/PropertyAccessExceptionsExceptionTests.cs b/test/Spring/Spring.Core.Tests/Objects/PropertyAccessExceptionsExceptionTests.cs index be0a59ae..2ef00dfb 100644 --- a/test/Spring/Spring.Core.Tests/Objects/PropertyAccessExceptionsExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/PropertyAccessExceptionsExceptionTests.cs @@ -29,8 +29,6 @@ namespace Spring.Objects /// /// Unit tests for the PropertyAccessExceptionsException class. /// - /// - /// $Id: PropertyAccessExceptionsExceptionTests.cs,v 1.4 2007/07/31 00:09:24 markpollack Exp $ [TestFixture] public sealed class PropertyAccessExceptionsExceptionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/PropertyValueTests.cs b/test/Spring/Spring.Core.Tests/Objects/PropertyValueTests.cs index 06162169..c4a17a1c 100644 --- a/test/Spring/Spring.Core.Tests/Objects/PropertyValueTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/PropertyValueTests.cs @@ -31,7 +31,6 @@ namespace Spring.Objects /// Unit tests for the PropertyValue class. /// /// Rick Evans - /// $Id: PropertyValueTests.cs,v 1.6 2006/04/09 07:24:50 markpollack Exp $ [TestFixture] public sealed class PropertyValueTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/StaticTestEventHandler.cs b/test/Spring/Spring.Core.Tests/Objects/StaticTestEventHandler.cs index 0de5a8ac..d8549229 100644 --- a/test/Spring/Spring.Core.Tests/Objects/StaticTestEventHandler.cs +++ b/test/Spring/Spring.Core.Tests/Objects/StaticTestEventHandler.cs @@ -30,7 +30,6 @@ namespace Spring.Objects { /// Exposes a static method that has a signature compatible with the /// EventHandler delegate. /// - /// $Id: StaticTestEventHandler.cs,v 1.3 2006/04/09 07:24:50 markpollack Exp $ public class StaticTestEventHandler { public static void HandleArbitraryEvent (object sender, EventArgs e) diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/ArgumentConvertingMethodInvokerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/ArgumentConvertingMethodInvokerTests.cs index ff6481a3..d8d00f76 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/ArgumentConvertingMethodInvokerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/ArgumentConvertingMethodInvokerTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Support /// Unit tests for the ArgumentConvertingMethodInvoker class. /// /// Rick Evans - /// $Id: ArgumentConvertingMethodInvokerTests.cs,v 1.4 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class ArgumentConvertingMethodInvokerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/AutoWiringEventHandlerValueTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/AutoWiringEventHandlerValueTests.cs index cf493419..919b32a4 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/AutoWiringEventHandlerValueTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/AutoWiringEventHandlerValueTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Support /// Unit tests for the AutoWiringEventHandlerValue class. /// /// Rick Evans - /// $Id: AutoWiringEventHandlerValueTests.cs,v 1.3 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public class AutoWiringEventHandlerValueTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/InstanceEventHandlerValueTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/InstanceEventHandlerValueTests.cs index c07a752b..6500e05f 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/InstanceEventHandlerValueTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/InstanceEventHandlerValueTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Support /// Unit tests for the InstanceEventHandlerValue class. /// /// Rick Evans - /// $Id: InstanceEventHandlerValueTests.cs,v 1.5 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class InstanceEventHandlerValueTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/MethodInvokerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/MethodInvokerTests.cs index 7668c8b1..374ed6d7 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/MethodInvokerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/MethodInvokerTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Support /// Unit tests for the MethodInvoker class. /// /// Rick Evans - /// $Id: MethodInvokerTests.cs,v 1.4 2007/08/04 01:05:41 bbaia Exp $ [TestFixture] public sealed class MethodInvokerTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/MutableSortDefinitionTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/MutableSortDefinitionTests.cs index 7187c285..31e054ee 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/MutableSortDefinitionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/MutableSortDefinitionTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Support /// Unit tests for the MutableSortDefinition class. /// /// Rick Evans - /// $Id: MutableSortDefinitionTests.cs,v 1.3 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class MutableSortDefinitionTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/PropertyComparatorTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/PropertyComparatorTests.cs index ca2dad56..0e5e4eb1 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/PropertyComparatorTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/PropertyComparatorTests.cs @@ -41,7 +41,6 @@ namespace Spring.Objects.Support /// /// Rick Evans /// Michael Loll - /// $Id: PropertyComparatorTests.cs,v 1.10 2007/07/31 00:09:35 markpollack Exp $ [TestFixture] public sealed class PropertyComparatorTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/Support/StaticEventHandlerValueTests.cs b/test/Spring/Spring.Core.Tests/Objects/Support/StaticEventHandlerValueTests.cs index adaf807c..436206ab 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Support/StaticEventHandlerValueTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Support/StaticEventHandlerValueTests.cs @@ -32,7 +32,6 @@ namespace Spring.Objects.Support /// Unit tests for the StaticEventHandlerValue class. /// /// Rick Evans - /// $Id: StaticEventHandlerValueTests.cs,v 1.4 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class StaticEventHandlerValueTests { diff --git a/test/Spring/Spring.Core.Tests/Objects/TestGenericObject.cs b/test/Spring/Spring.Core.Tests/Objects/TestGenericObject.cs index a0376d4a..a4b4bdc6 100644 --- a/test/Spring/Spring.Core.Tests/Objects/TestGenericObject.cs +++ b/test/Spring/Spring.Core.Tests/Objects/TestGenericObject.cs @@ -32,7 +32,6 @@ namespace Spring.Objects /// Simple test object used for testing generic objects. /// /// Bruno Baia - /// $Id: TestGenericObject.cs,v 1.2 2006/04/09 07:24:50 markpollack Exp $ public class TestGenericObject { #region Fields diff --git a/test/Spring/Spring.Core.Tests/Objects/TypeMismatchExceptionTests.cs b/test/Spring/Spring.Core.Tests/Objects/TypeMismatchExceptionTests.cs index 40044198..8bba3c37 100644 --- a/test/Spring/Spring.Core.Tests/Objects/TypeMismatchExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/TypeMismatchExceptionTests.cs @@ -29,7 +29,6 @@ namespace Spring.Objects /// Unit tests for the TypeMismatchException class. /// /// Rick Evans - /// $Id: TypeMismatchExceptionTests.cs,v 1.4 2007/07/31 00:09:24 markpollack Exp $ [TestFixture] public sealed class TypeMismatchExceptionTests { diff --git a/test/Spring/Spring.Core.Tests/Proxy/AbstractProxyTypeBuilderTests.cs b/test/Spring/Spring.Core.Tests/Proxy/AbstractProxyTypeBuilderTests.cs index 33bd0487..dd23852b 100644 --- a/test/Spring/Spring.Core.Tests/Proxy/AbstractProxyTypeBuilderTests.cs +++ b/test/Spring/Spring.Core.Tests/Proxy/AbstractProxyTypeBuilderTests.cs @@ -44,7 +44,6 @@ namespace Spring.Proxy /// /// Rick Evans /// Bruno Baia - /// $Id: AbstractProxyTypeBuilderTests.cs,v 1.21 2007/12/05 00:28:39 bbaia Exp $ public abstract class AbstractProxyTypeBuilderTests { [Test] diff --git a/test/Spring/Spring.Core.Tests/Proxy/CompositionProxyTypeBuilderTests.cs b/test/Spring/Spring.Core.Tests/Proxy/CompositionProxyTypeBuilderTests.cs index a0201e8c..09b1c061 100644 --- a/test/Spring/Spring.Core.Tests/Proxy/CompositionProxyTypeBuilderTests.cs +++ b/test/Spring/Spring.Core.Tests/Proxy/CompositionProxyTypeBuilderTests.cs @@ -31,7 +31,6 @@ namespace Spring.Proxy /// Unit tests for the CompositionProxyTypeBuilder class. /// /// Rick Evans - /// $Id: CompositionProxyTypeBuilderTests.cs,v 1.6 2006/11/16 02:30:51 bbaia Exp $ [TestFixture] public class CompositionProxyTypeBuilderTests : AbstractProxyTypeBuilderTests { diff --git a/test/Spring/Spring.Core.Tests/Proxy/DynamicProxyManagerTests.cs b/test/Spring/Spring.Core.Tests/Proxy/DynamicProxyManagerTests.cs index c7d4e9f7..f8b1cea7 100644 --- a/test/Spring/Spring.Core.Tests/Proxy/DynamicProxyManagerTests.cs +++ b/test/Spring/Spring.Core.Tests/Proxy/DynamicProxyManagerTests.cs @@ -32,7 +32,6 @@ namespace Spring.Proxy /// /// /// Erich Eichinger - /// $Id: DynamicProxyManagerTests.cs,v 1.2 2007/05/02 11:35:43 bbaia Exp $ [TestFixture] public class DynamicProxyManagerTests { diff --git a/test/Spring/Spring.Core.Tests/Proxy/ExplicitCompositionProxyTypeBuilderTests.cs b/test/Spring/Spring.Core.Tests/Proxy/ExplicitCompositionProxyTypeBuilderTests.cs index e124975d..eebd1a2b 100644 --- a/test/Spring/Spring.Core.Tests/Proxy/ExplicitCompositionProxyTypeBuilderTests.cs +++ b/test/Spring/Spring.Core.Tests/Proxy/ExplicitCompositionProxyTypeBuilderTests.cs @@ -33,7 +33,6 @@ namespace Spring.Proxy /// Unit tests for the CompositionProxyTypeBuilder class. /// /// Rick Evans - /// $Id: ExplicitCompositionProxyTypeBuilderTests.cs,v 1.3 2006/08/10 18:45:58 bbaia Exp $ [TestFixture] public sealed class ExplicitCompositionProxyTypeBuilderTests : CompositionProxyTypeBuilderTests { diff --git a/test/Spring/Spring.Core.Tests/Proxy/InheritanceProxyTypeBuilderTests.cs b/test/Spring/Spring.Core.Tests/Proxy/InheritanceProxyTypeBuilderTests.cs index 012448df..8247d77b 100644 --- a/test/Spring/Spring.Core.Tests/Proxy/InheritanceProxyTypeBuilderTests.cs +++ b/test/Spring/Spring.Core.Tests/Proxy/InheritanceProxyTypeBuilderTests.cs @@ -36,7 +36,6 @@ namespace Spring.Proxy /// /// Rick Evans /// Bruno Baia - /// $Id: InheritanceProxyTypeBuilderTests.cs,v 1.9 2007/06/27 15:34:47 bbaia Exp $ [TestFixture] public sealed class InheritanceProxyTypeBuilderTests : AbstractProxyTypeBuilderTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs index 17c9a505..87d2328c 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/BasePropertyTests.cs @@ -11,7 +11,6 @@ namespace Spring.Reflection.Dynamic /// /// Aleksandar Seovic /// Erich Eichinger - /// $Id: BasePropertyTests.cs,v 1.1 2008/05/17 11:05:27 oakinger Exp $ public abstract class BasePropertyTests { protected Inventor tesla; diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicConstructorTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicConstructorTests.cs index 7f6a13d0..061883f4 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicConstructorTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicConstructorTests.cs @@ -34,7 +34,6 @@ namespace Spring.Reflection.Dynamic /// Unit tests for the DynamicConstructor class. /// /// Aleksandar Seovic - /// $Id: DynamicConstructorTests.cs,v 1.1 2007/08/08 04:06:01 bbaia Exp $ [TestFixture] public sealed class DynamicConstructorTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs index 5ed6c81a..297f6deb 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicFieldTests.cs @@ -34,7 +34,6 @@ namespace Spring.Reflection.Dynamic /// Unit tests for the DynamicField class. /// /// Aleksandar Seovic - /// $Id: DynamicFieldTests.cs,v 1.2 2008/05/16 10:02:41 oakinger Exp $ [TestFixture] public class DynamicFieldTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicIndexerTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicIndexerTests.cs index 934fa3b2..e247e2e2 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicIndexerTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicIndexerTests.cs @@ -35,7 +35,6 @@ namespace Spring.Reflection.Dynamic /// Unit tests for the DynamicIndexer class. /// /// Aleksandar Seovic - /// $Id: DynamicIndexerTests.cs,v 1.1 2007/08/08 04:06:01 bbaia Exp $ [TestFixture] public sealed class DynamicIndexerTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicMethodTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicMethodTests.cs index 2b485327..b4933522 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicMethodTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicMethodTests.cs @@ -36,7 +36,6 @@ namespace Spring.Reflection.Dynamic /// Unit tests for the DynamicMethod class. /// /// Aleksandar Seovic - /// $Id: DynamicMethodTests.cs,v 1.1 2007/08/08 04:06:01 bbaia Exp $ [TestFixture] public sealed class DynamicMethodTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicPropertyTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicPropertyTests.cs index 021a7893..69978cc0 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicPropertyTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/DynamicPropertyTests.cs @@ -34,7 +34,6 @@ namespace Spring.Reflection.Dynamic /// Unit tests for the DynamicProperty class. /// /// Aleksandar Seovic - /// $Id: DynamicPropertyTests.cs,v 1.3 2008/05/17 11:05:27 oakinger Exp $ [TestFixture] public class DynamicPropertyTests : BasePropertyTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafeFieldTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafeFieldTests.cs index 0a366d40..2505c55d 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafeFieldTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafeFieldTests.cs @@ -33,7 +33,6 @@ namespace Spring.Reflection.Dynamic /// as DynamicField plus tests for accessing private members. /// /// Erich Eichinger - /// $Id: SafeFieldTests.cs,v 1.1 2008/05/16 10:02:41 oakinger Exp $ [TestFixture] public class SafeFieldTests : DynamicFieldTests { diff --git a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafePropertyTests.cs b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafePropertyTests.cs index f2388504..0b3407bc 100644 --- a/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafePropertyTests.cs +++ b/test/Spring/Spring.Core.Tests/Reflection/Dynamic/SafePropertyTests.cs @@ -33,7 +33,6 @@ namespace Spring.Reflection.Dynamic /// as DynamicField plus tests for accessing private members. /// /// Erich Eichinger - /// $Id: SafePropertyTests.cs,v 1.1 2008/05/17 11:05:27 oakinger Exp $ [TestFixture] public class SafePropertyTests : BasePropertyTests { diff --git a/test/Spring/Spring.Core.Tests/StopWatch.cs b/test/Spring/Spring.Core.Tests/StopWatch.cs index 667762e0..f2a43563 100644 --- a/test/Spring/Spring.Core.Tests/StopWatch.cs +++ b/test/Spring/Spring.Core.Tests/StopWatch.cs @@ -42,7 +42,6 @@ namespace Spring /// The example above will print Duration: 0.123s. /// /// Erich Eichinger - /// $Id: StopWatch.cs,v 1.1 2008/05/16 10:02:42 oakinger Exp $ public class StopWatch { private DateTime _startTime; diff --git a/test/Spring/Spring.Core.Tests/StreamHelperDecorator.cs b/test/Spring/Spring.Core.Tests/StreamHelperDecorator.cs index bb9a6fa2..c7c6efcd 100644 --- a/test/Spring/Spring.Core.Tests/StreamHelperDecorator.cs +++ b/test/Spring/Spring.Core.Tests/StreamHelperDecorator.cs @@ -29,7 +29,6 @@ namespace Spring /// Helper class for template style Stream usage. /// /// Rick Evans - /// $Id: StreamHelperDecorator.cs,v 1.2 2006/04/09 07:24:48 markpollack Exp $ public class StreamHelperDecorator { private StreamHelperCallback callback; diff --git a/test/Spring/Spring.Core.Tests/StringResource.cs b/test/Spring/Spring.Core.Tests/StringResource.cs index 2bac8839..8f717af2 100644 --- a/test/Spring/Spring.Core.Tests/StringResource.cs +++ b/test/Spring/Spring.Core.Tests/StringResource.cs @@ -34,7 +34,6 @@ namespace Spring /// A adapter implementation encapsulating a simply string. /// /// Erich Eichinger - /// $Id: StringResource.cs,v 1.1 2008/03/20 10:35:54 oakinger Exp $ public class StringResource : AbstractResource { #region Fields diff --git a/test/Spring/Spring.Core.Tests/Threading/AsyncTestMethod.cs b/test/Spring/Spring.Core.Tests/Threading/AsyncTestMethod.cs index 49b2d1dc..a26e35e3 100644 --- a/test/Spring/Spring.Core.Tests/Threading/AsyncTestMethod.cs +++ b/test/Spring/Spring.Core.Tests/Threading/AsyncTestMethod.cs @@ -32,7 +32,6 @@ namespace Spring.Threading /// /// /// Erich Eichinger - /// $Id: AsyncTestMethod.cs,v 1.2 2008/02/02 10:24:38 oakinger Exp $ public class AsyncTestMethod : AsyncTestTask { public delegate object TestMethod(object[] args); diff --git a/test/Spring/Spring.Core.Tests/Threading/AsyncTestTask.cs b/test/Spring/Spring.Core.Tests/Threading/AsyncTestTask.cs index bfe616f9..185f957c 100644 --- a/test/Spring/Spring.Core.Tests/Threading/AsyncTestTask.cs +++ b/test/Spring/Spring.Core.Tests/Threading/AsyncTestTask.cs @@ -31,7 +31,6 @@ namespace Spring.Threading /// Base class for async test operations /// /// Erich Eichinger - /// $Id: AsyncTestTask.cs,v 1.2 2008/02/02 10:24:38 oakinger Exp $ public abstract class AsyncTestTask { private Exception exception; diff --git a/test/Spring/Spring.Core.Tests/Threading/CallContextStorageTests.cs b/test/Spring/Spring.Core.Tests/Threading/CallContextStorageTests.cs index 6d191aaa..864de5a4 100644 --- a/test/Spring/Spring.Core.Tests/Threading/CallContextStorageTests.cs +++ b/test/Spring/Spring.Core.Tests/Threading/CallContextStorageTests.cs @@ -30,7 +30,6 @@ namespace Spring.Threading /// Apply common thread-storage tests for /// /// Erich Eichinger - /// $Id: CallContextStorageTests.cs,v 1.1 2007/02/02 21:31:08 oakinger Exp $ [TestFixture] public class CallContextStorageTests : CommonThreadStorageTests { diff --git a/test/Spring/Spring.Core.Tests/Threading/CommonThreadStorageTests.cs b/test/Spring/Spring.Core.Tests/Threading/CommonThreadStorageTests.cs index 4ec9de82..de4eaa71 100644 --- a/test/Spring/Spring.Core.Tests/Threading/CommonThreadStorageTests.cs +++ b/test/Spring/Spring.Core.Tests/Threading/CommonThreadStorageTests.cs @@ -32,7 +32,6 @@ namespace Spring.Threading /// Any implementation must pass these tests. /// /// Erich Eichinger - /// $Id: CommonThreadStorageTests.cs,v 1.2 2007/05/14 21:31:32 oakinger Exp $ public abstract class CommonThreadStorageTests { protected abstract IThreadStorage CreateStorage(); diff --git a/test/Spring/Spring.Core.Tests/Threading/LogicalThreadContextTest.cs b/test/Spring/Spring.Core.Tests/Threading/LogicalThreadContextTest.cs index c5d4f38d..a729a14f 100644 --- a/test/Spring/Spring.Core.Tests/Threading/LogicalThreadContextTest.cs +++ b/test/Spring/Spring.Core.Tests/Threading/LogicalThreadContextTest.cs @@ -32,7 +32,6 @@ namespace Spring.Threading /// Test behaviour of LogicalThreadContext /// /// Erich Eichinger - /// $Id: LogicalThreadContextTest.cs,v 1.1 2007/02/02 21:31:08 oakinger Exp $ [TestFixture] public class LogicalThreadContextTest { diff --git a/test/Spring/Spring.Core.Tests/Threading/ThreadStaticStorageTests.cs b/test/Spring/Spring.Core.Tests/Threading/ThreadStaticStorageTests.cs index 7356ba00..8368fd4b 100644 --- a/test/Spring/Spring.Core.Tests/Threading/ThreadStaticStorageTests.cs +++ b/test/Spring/Spring.Core.Tests/Threading/ThreadStaticStorageTests.cs @@ -30,7 +30,6 @@ namespace Spring.Threading /// Apply common thread-storage tests for /// /// Erich Eichinger - /// $Id: ThreadStaticStorageTests.cs,v 1.1 2007/02/02 21:31:08 oakinger Exp $ [TestFixture] public class ThreadStaticStorageTests : CommonThreadStorageTests { diff --git a/test/Spring/Spring.Core.Tests/Util/ArrayUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/ArrayUtilsTests.cs index 44e5dc88..fad07444 100644 --- a/test/Spring/Spring.Core.Tests/Util/ArrayUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/ArrayUtilsTests.cs @@ -33,7 +33,6 @@ namespace Spring.Util /// Unit tests for the ArrayUtils class. /// /// Rick Evans - /// $Id: ArrayUtilsTests.cs,v 1.5 2007/02/02 12:33:30 oakinger Exp $ [TestFixture] public sealed class ArrayUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/AssertUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/AssertUtilsTests.cs index 3008a480..cdfdb5d1 100644 --- a/test/Spring/Spring.Core.Tests/Util/AssertUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/AssertUtilsTests.cs @@ -32,7 +32,6 @@ namespace Spring.Util /// Unit tests for the AssertUtils class. /// /// Rick Evans - /// $Id: AssertUtilsTests.cs,v 1.8 2007/05/30 22:39:28 markpollack Exp $ [TestFixture] public sealed class AssertUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/DefensiveEventRaiserTests.cs b/test/Spring/Spring.Core.Tests/Util/DefensiveEventRaiserTests.cs index 3487e919..72df72ae 100644 --- a/test/Spring/Spring.Core.Tests/Util/DefensiveEventRaiserTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/DefensiveEventRaiserTests.cs @@ -32,7 +32,6 @@ namespace Spring.Util /// Unit tests for the DefensiveEventRaiser class. /// /// Rick Evans - /// $Id: DefensiveEventRaiserTests.cs,v 1.2 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class DefensiveEventRaiserTests { diff --git a/test/Spring/Spring.Core.Tests/Util/DelegateInfoTests.cs b/test/Spring/Spring.Core.Tests/Util/DelegateInfoTests.cs index 9dabc074..78d1b4fb 100644 --- a/test/Spring/Spring.Core.Tests/Util/DelegateInfoTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/DelegateInfoTests.cs @@ -32,7 +32,6 @@ namespace Spring.Util /// Unit tests for the DelegateInfo class. /// /// Rick Evans - /// $Id: DelegateInfoTests.cs,v 1.6 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class DelegateInfoTests { diff --git a/test/Spring/Spring.Core.Tests/Util/EventRaiserTests.cs b/test/Spring/Spring.Core.Tests/Util/EventRaiserTests.cs index f525741e..3e45653f 100644 --- a/test/Spring/Spring.Core.Tests/Util/EventRaiserTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/EventRaiserTests.cs @@ -32,7 +32,6 @@ namespace Spring.Util /// Unit tests for the EventRaiser class. /// /// Rick Evans - /// $Id: EventRaiserTests.cs,v 1.3 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class EventRaiserTests { diff --git a/test/Spring/Spring.Core.Tests/Util/NumberUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/NumberUtilsTests.cs index 3ce4c19a..2fd967ba 100644 --- a/test/Spring/Spring.Core.Tests/Util/NumberUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/NumberUtilsTests.cs @@ -31,7 +31,6 @@ namespace Spring.Util /// Unit tests for the NumberUtils class. /// /// Rick Evans - /// $Id: NumberUtilsTests.cs,v 1.2 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class NumberUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/ObjectUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/ObjectUtilsTests.cs index 5c52e08a..a41555ec 100644 --- a/test/Spring/Spring.Core.Tests/Util/ObjectUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/ObjectUtilsTests.cs @@ -39,7 +39,6 @@ namespace Spring.Util /// Unit tests for the ObjectUtils class. /// /// Rick Evans (.NET) - /// $Id: ObjectUtilsTests.cs,v 1.4 2007/08/17 02:43:30 markpollack Exp $ [TestFixture] public class ObjectUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/PatternMatchUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/PatternMatchUtilsTests.cs index 49f474ee..54214bae 100644 --- a/test/Spring/Spring.Core.Tests/Util/PatternMatchUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/PatternMatchUtilsTests.cs @@ -29,7 +29,6 @@ namespace Spring.Util /// /// Unit tests for the PatternMatchUtils class. /// - /// $Id: PatternMatchUtilsTests.cs,v 1.2 2007/07/31 18:19:59 bbaia Exp $ [TestFixture] public sealed class PatternMatchUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsTests.cs index 62a05448..89010ad3 100644 --- a/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/ReflectionUtilsTests.cs @@ -45,7 +45,6 @@ namespace Spring.Util /// /// Unit tests for the ReflectionUtils class. /// - /// $Id: ReflectionUtilsTests.cs,v 1.22 2008/04/02 16:21:49 markpollack Exp $ [TestFixture] public sealed class ReflectionUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/StringUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/StringUtilsTests.cs index 10b75894..35cb64da 100644 --- a/test/Spring/Spring.Core.Tests/Util/StringUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/StringUtilsTests.cs @@ -34,7 +34,6 @@ namespace Spring.Util /// Aleksandar Seovic /// Rick Evans /// Griffin Caprio - /// $Id: StringUtilsTests.cs,v 1.3 2006/04/09 07:24:51 markpollack Exp $ [TestFixture] public sealed class StringUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/SystemUtilsTests.cs b/test/Spring/Spring.Core.Tests/Util/SystemUtilsTests.cs index 47581d52..1ee82412 100644 --- a/test/Spring/Spring.Core.Tests/Util/SystemUtilsTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/SystemUtilsTests.cs @@ -32,7 +32,6 @@ namespace Spring.Util /// This class contains tests for SystemUtils /// /// Mark Pollack - /// $Id: SystemUtilsTests.cs,v 1.1 2007/09/07 02:47:08 markpollack Exp $ [TestFixture] public class SystemUtilsTests { diff --git a/test/Spring/Spring.Core.Tests/Util/UniqueKeyTests.cs b/test/Spring/Spring.Core.Tests/Util/UniqueKeyTests.cs index be6ac8fd..e27c9be0 100644 --- a/test/Spring/Spring.Core.Tests/Util/UniqueKeyTests.cs +++ b/test/Spring/Spring.Core.Tests/Util/UniqueKeyTests.cs @@ -31,7 +31,6 @@ namespace Spring.Util /// Tests functionality. /// /// Erich Eichinger - /// $Id: UniqueKeyTests.cs,v 1.1 2007/08/22 20:17:05 oakinger Exp $ [TestFixture] public class UniqueKeyTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/Actions/ErrorMessageActionTests.cs b/test/Spring/Spring.Core.Tests/Validation/Actions/ErrorMessageActionTests.cs index 4220f2a8..8989a97d 100644 --- a/test/Spring/Spring.Core.Tests/Validation/Actions/ErrorMessageActionTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/Actions/ErrorMessageActionTests.cs @@ -31,7 +31,6 @@ namespace Spring.Validation.Actions /// Unit tests for the ErrorMessageAction class. /// /// Aleksandar Seovic - /// $Id: ErrorMessageActionTests.cs,v 1.4 2008/02/05 20:40:26 aseovic Exp $ [TestFixture] public class ErrorMessageActionTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/Actions/ExpressionActionTests.cs b/test/Spring/Spring.Core.Tests/Validation/Actions/ExpressionActionTests.cs index f4462cf4..b8eccdd5 100644 --- a/test/Spring/Spring.Core.Tests/Validation/Actions/ExpressionActionTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/Actions/ExpressionActionTests.cs @@ -31,7 +31,6 @@ namespace Spring.Validation.Actions /// Unit tests for the ExpressionAction class. /// /// Aleksandar Seovic - /// $Id: ExpressionActionTests.cs,v 1.3 2006/04/09 07:24:52 markpollack Exp $ [TestFixture] public class ExpressionActionTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/AnyValidatorGroupTests.cs b/test/Spring/Spring.Core.Tests/Validation/AnyValidatorGroupTests.cs index 3d63e69c..942af532 100644 --- a/test/Spring/Spring.Core.Tests/Validation/AnyValidatorGroupTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/AnyValidatorGroupTests.cs @@ -32,7 +32,6 @@ namespace Spring.Validation /// Unit tests for the AnyValidatorGroup class. /// /// Aleksandar Seovic - /// $Id: AnyValidatorGroupTests.cs,v 1.4 2008/02/05 20:40:26 aseovic Exp $ [TestFixture] public sealed class AnyValidatorGroupTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/ExclusiveValidatorGroupTests.cs b/test/Spring/Spring.Core.Tests/Validation/ExclusiveValidatorGroupTests.cs index 62d75ac9..cc1b7228 100644 --- a/test/Spring/Spring.Core.Tests/Validation/ExclusiveValidatorGroupTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/ExclusiveValidatorGroupTests.cs @@ -33,7 +33,6 @@ namespace Spring.Validation /// Unit tests for the ExclusiveValidatorGroup class. /// /// Aleksandar Seovic - /// $Id: ExclusiveValidatorGroupTests.cs,v 1.4 2008/02/05 20:40:26 aseovic Exp $ [TestFixture] public sealed class ExclusiveValidatorGroupTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/HelperClasses.cs b/test/Spring/Spring.Core.Tests/Validation/HelperClasses.cs index d46bbe94..96aa4299 100644 --- a/test/Spring/Spring.Core.Tests/Validation/HelperClasses.cs +++ b/test/Spring/Spring.Core.Tests/Validation/HelperClasses.cs @@ -31,7 +31,6 @@ namespace Spring.Validation /// Helper classes for validation tests. /// /// Aleksandar Seovic - /// $Id: HelperClasses.cs,v 1.2 2006/04/09 07:24:52 markpollack Exp $ public class TrueValidator : BaseValidator { public TrueValidator() diff --git a/test/Spring/Spring.Core.Tests/Validation/ValidationConfigParserTests.cs b/test/Spring/Spring.Core.Tests/Validation/ValidationConfigParserTests.cs index 94eabda7..d5c0cc74 100644 --- a/test/Spring/Spring.Core.Tests/Validation/ValidationConfigParserTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/ValidationConfigParserTests.cs @@ -40,7 +40,6 @@ namespace Spring.Validation /// Unit tests for the ValidationNamespaceParser class. /// /// Rick Evans - /// $Id: ValidationConfigParserTests.cs,v 1.14 2007/08/08 17:48:45 bbaia Exp $ [TestFixture] public sealed class ValidationConfigParserTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/ValidationErrorsTests.cs b/test/Spring/Spring.Core.Tests/Validation/ValidationErrorsTests.cs index d3102db7..ea62791a 100644 --- a/test/Spring/Spring.Core.Tests/Validation/ValidationErrorsTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/ValidationErrorsTests.cs @@ -37,7 +37,6 @@ namespace Spring.Validation /// /// Rick Evans /// Goran Milosavljevic - /// $Id: ValidationErrorsTests.cs,v 1.7 2008/02/05 20:40:26 aseovic Exp $ [TestFixture] public sealed class ValidationErrorsTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/ValidationExceptionTests.cs b/test/Spring/Spring.Core.Tests/Validation/ValidationExceptionTests.cs index 2971989d..5e922c34 100644 --- a/test/Spring/Spring.Core.Tests/Validation/ValidationExceptionTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/ValidationExceptionTests.cs @@ -29,7 +29,6 @@ namespace Spring.Validation /// Unit tests for the ValidationException class. /// /// Aleksandar Seovic - /// $Id: ValidationExceptionTests.cs,v 1.1 2008/02/05 20:40:27 aseovic Exp $ [TestFixture] public sealed class ValidationExceptionTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/ValidatorGroupTests.cs b/test/Spring/Spring.Core.Tests/Validation/ValidatorGroupTests.cs index c9a0fa9b..f1be5848 100644 --- a/test/Spring/Spring.Core.Tests/Validation/ValidatorGroupTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/ValidatorGroupTests.cs @@ -35,7 +35,6 @@ namespace Spring.Validation /// Unit tests for the ValidatorGroup class. /// /// Aleksandar Seovic - /// $Id: ValidatorGroupTests.cs,v 1.4 2008/02/05 20:40:26 aseovic Exp $ [TestFixture] public sealed class ValidatorGroupTests : ValidatorGroup { diff --git a/test/Spring/Spring.Core.Tests/Validation/ValidatorReferenceTests.cs b/test/Spring/Spring.Core.Tests/Validation/ValidatorReferenceTests.cs index 3a22c0b0..8e29f440 100644 --- a/test/Spring/Spring.Core.Tests/Validation/ValidatorReferenceTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/ValidatorReferenceTests.cs @@ -31,7 +31,6 @@ namespace Spring.Validation /// Unit tests for ValidatorReference class. /// /// Aleksandar Seovic - /// $Id: ValidatorReferenceTests.cs,v 1.3 2008/02/05 20:40:27 aseovic Exp $ [TestFixture] public class ValidatorReferenceTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/Validators/ConditionValidatorTests.cs b/test/Spring/Spring.Core.Tests/Validation/Validators/ConditionValidatorTests.cs index 805609ea..f6a78ad3 100644 --- a/test/Spring/Spring.Core.Tests/Validation/Validators/ConditionValidatorTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/Validators/ConditionValidatorTests.cs @@ -36,7 +36,6 @@ namespace Spring.Validation.Validators /// Unit tests for the ConditionValidator class. /// /// Rick Evans - /// $Id: ConditionValidatorTests.cs,v 1.9 2008/02/05 20:40:27 aseovic Exp $ [TestFixture] public sealed class ConditionValidatorTests { diff --git a/test/Spring/Spring.Core.Tests/Validation/Validators/RequiredValidatorTests.cs b/test/Spring/Spring.Core.Tests/Validation/Validators/RequiredValidatorTests.cs index d82ec0cf..992cab38 100644 --- a/test/Spring/Spring.Core.Tests/Validation/Validators/RequiredValidatorTests.cs +++ b/test/Spring/Spring.Core.Tests/Validation/Validators/RequiredValidatorTests.cs @@ -32,7 +32,6 @@ namespace Spring.Validation.Validators /// Unit tests for the RequiredValidator class. /// /// Rick Evans - /// $Id: RequiredValidatorTests.cs,v 1.7 2008/02/05 20:40:27 aseovic Exp $ [TestFixture] public sealed class RequiredValidatorTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplatePerformanceTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplatePerformanceTests.cs index 40606197..162862ec 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplatePerformanceTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplatePerformanceTests.cs @@ -43,7 +43,6 @@ namespace Spring.Data /// This calss contains tests for /// /// Mark Pollack - /// $Id: AdoTemplatePerformanceTests.cs,v 1.1 2008/02/04 22:44:59 markpollack Exp $ [TestFixture] public class AdoTemplatePerformanceTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplateTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplateTests.cs index 553e98af..f6b4a1c0 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplateTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/AdoTemplateTests.cs @@ -41,7 +41,6 @@ namespace Spring.Data /// Simple exercising of the AdoTemplate /// /// Mark Pollack (.NET) - /// $Id: AdoTemplateTests.cs,v 1.11 2008/01/29 18:22:33 markpollack Exp $ [TestFixture] public class AdoTemplateTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/AutoDeclarativeTxTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/AutoDeclarativeTxTests.cs index 4956d835..60c7aa39 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/AutoDeclarativeTxTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/AutoDeclarativeTxTests.cs @@ -36,7 +36,6 @@ namespace Spring.Data /// of transaction attributes. /// /// Mark Pollack (.NET) - /// $Id: AutoDeclarativeTxTests.cs,v 1.4 2007/05/26 00:43:01 markpollack Exp $ [TestFixture] public class AutoDeclarativeTxTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/CallCreateTestObject.cs b/test/Spring/Spring.Data.Integration.Tests/Data/CallCreateTestObject.cs index b292e42a..389cbf71 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/CallCreateTestObject.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/CallCreateTestObject.cs @@ -33,7 +33,6 @@ namespace Spring.Data /// Simple stored procedure with only 'in' args to create a testobject record /// /// Mark Pollack (.NET) - /// $Id: CallCreateTestObject.cs,v 1.2 2006/06/21 14:07:30 markpollack Exp $ public class CallCreateTestObject : StoredProcedure { private static string procedureName = "CreateTestObject"; diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/CreateTestObjectNonQuery.cs b/test/Spring/Spring.Data.Integration.Tests/Data/CreateTestObjectNonQuery.cs index c5446208..79e3dc4f 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/CreateTestObjectNonQuery.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/CreateTestObjectNonQuery.cs @@ -34,7 +34,6 @@ namespace Spring.Data /// Simple insert non query object with 'in' args to create a testobject. /// /// Mark Pollack (.NET) - /// $Id: CreateTestObjectNonQuery.cs,v 1.2 2008/01/29 18:22:33 markpollack Exp $ public class CreateTestObjectNonQuery : AdoNonQuery { private static string sql = "insert into TestObjects(Age,Name) values (@Age,@Name)"; diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/DeclarativeTxTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/DeclarativeTxTests.cs index efeba24a..54484bae 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/DeclarativeTxTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/DeclarativeTxTests.cs @@ -34,7 +34,6 @@ namespace Spring.Data /// TODO: /// /// Mark Pollack (.NET) - /// $Id: DeclarativeTxTests.cs,v 1.4 2006/11/15 20:31:08 aseovic Exp $ [TestFixture] public class DeclarativeTxTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectDao.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectDao.cs index 1401bd62..bd87ad93 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectDao.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectDao.cs @@ -34,7 +34,6 @@ namespace Spring.Data.Generic /// /// /// Mark Pollack - /// $Id: TestObjectDao.cs,v 1.3 2008/01/29 18:22:33 markpollack Exp $ public class TestObjectDao : AdoDaoSupport, ITestObjectDao { public IList FindAll() diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectRowMapper.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectRowMapper.cs index 07cc7751..db94ce88 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectRowMapper.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Generic/TestObjectRowMapper.cs @@ -34,7 +34,6 @@ namespace Spring.Data.Generic /// /// /// Mark Pollack - /// $Id: TestObjectRowMapper.cs,v 1.3 2007/08/07 19:50:44 markpollack Exp $ public class TestObjectRowMapper : IRowMapper where T : TestObject, new() { public T MapRow(IDataReader reader, int rowNum) diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/MappingAdoQueryTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/MappingAdoQueryTests.cs index 969ececc..a4a440ea 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/MappingAdoQueryTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/MappingAdoQueryTests.cs @@ -36,7 +36,6 @@ namespace Spring.Data /// TODO: /// /// Mark Pollack (.NET) - /// $Id: MappingAdoQueryTests.cs,v 1.3 2006/11/13 07:05:00 markpollack Exp $ [TestFixture] public class MappingAdoQueryTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/NestedTxScopeTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/NestedTxScopeTests.cs index 6ac147cd..1c049ca7 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/NestedTxScopeTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/NestedTxScopeTests.cs @@ -40,7 +40,6 @@ namespace Spring.Data /// This class contains tests for nesting transaction scopes. /// /// Mark Pollack - /// $Id: NestedTxScopeTests.cs,v 1.3 2008/05/02 20:08:29 markpollack Exp $ [TestFixture] public class NestedTxScopeTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/AdoTemplateShipperDao.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/AdoTemplateShipperDao.cs index ffce1db9..f631f25c 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/AdoTemplateShipperDao.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/AdoTemplateShipperDao.cs @@ -34,7 +34,6 @@ namespace Spring.Data.Northwind /// TODO: /// /// Mark Pollack (.NET) - /// $Id: AdoTemplateShipperDao.cs,v 1.3 2007/08/03 19:51:22 markpollack Exp $ public class AdoTemplateShipperDao : AdoDaoSupport, IShipperDao { #region IShipperDao Members diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/IShipperDao.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/IShipperDao.cs index a3adc553..b5324d68 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/IShipperDao.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/IShipperDao.cs @@ -30,7 +30,6 @@ namespace Spring.Data.Northwind /// TODO: /// /// Mark Pollack (.NET) - /// $Id: IShipperDao.cs,v 1.1 2006/06/21 14:07:30 markpollack Exp $ public interface IShipperDao { Shipper Create(string name, string phone); diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/NativeAdoShipperDao.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/NativeAdoShipperDao.cs index 6eaa9ebe..e34f043d 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/NativeAdoShipperDao.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/NativeAdoShipperDao.cs @@ -28,11 +28,7 @@ using System.Data.SqlClient; namespace Spring.Data.Northwind { - /// - /// TODO: - /// /// Mark Pollack (.NET) - /// $Id: NativeAdoShipperDao.cs,v 1.1 2006/06/21 14:07:30 markpollack Exp $ public class NativeAdoShipperDao : IShipperDao { #region IShipperDao Members diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/Shipper.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/Shipper.cs index e610df5f..aa7f432a 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/Shipper.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Northwind/Shipper.cs @@ -26,11 +26,7 @@ using System; namespace Spring.Data.Northwind { - /// - /// TODO: - /// /// Mark Pollack (.NET) - /// $Id: Shipper.cs,v 1.1 2006/06/21 14:07:30 markpollack Exp $ public class Shipper { #region Fields diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/StoredProcedureTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/StoredProcedureTests.cs index 85726274..dd3e6f17 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/StoredProcedureTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/StoredProcedureTests.cs @@ -41,7 +41,6 @@ namespace Spring.Data.Objects.Generic /// This calss contains tests for /// /// Mark Pollack - /// $Id: StoredProcedureTests.cs,v 1.3 2007/08/07 19:50:44 markpollack Exp $ [TestFixture] public class StoredProcedureTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/VacationRowMapper.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/VacationRowMapper.cs index 640a1320..f84ef01e 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/VacationRowMapper.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Objects/Generic/VacationRowMapper.cs @@ -34,7 +34,6 @@ namespace Spring.Data.Objects.Generic /// /// /// Mark Pollack - /// $Id: VacationRowMapper.cs,v 1.2 2007/07/25 18:43:28 markpollack Exp $ public class VacationRowMapper : IRowMapper where T : Vacation, new() { public T MapRow(IDataReader reader, int rowNum) diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/SQLiteTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/SQLiteTests.cs index 6182dce5..4296729d 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/SQLiteTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/SQLiteTests.cs @@ -43,7 +43,6 @@ namespace Spring.Data /// This class contains misc tests for specific providers /// /// Mark Pollack - /// $Id: SQLiteTests.cs,v 1.1 2008/02/04 22:49:42 markpollack Exp $ [TestFixture] public class SQLiteTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/StoredProcedureTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/StoredProcedureTests.cs index ff467699..3ef76092 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/StoredProcedureTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/StoredProcedureTests.cs @@ -37,7 +37,6 @@ namespace Spring.Data /// Integration tests for StoredProcedure support. /// /// Mark Pollack (.NET) - /// $Id: StoredProcedureTests.cs,v 1.5 2008/01/29 18:22:33 markpollack Exp $ [TestFixture] public class StoredProcedureTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/Support/SimpleExceptionTranslationTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/Support/SimpleExceptionTranslationTests.cs index e2c9bdb7..225c32eb 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/Support/SimpleExceptionTranslationTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/Support/SimpleExceptionTranslationTests.cs @@ -33,11 +33,6 @@ using Spring.Data.Core; namespace Spring.Data.Support { - /// - /// TODO: - /// - /// Mark Pollack (.NET) - /// $Id: SimpleExceptionTranslationTests.cs,v 1.4 2007/08/03 19:51:23 markpollack Exp $ [TestFixture] public class SimpleExceptionTranslationTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectManager.cs b/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectManager.cs index d38b5c74..07da64da 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectManager.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectManager.cs @@ -34,7 +34,6 @@ namespace Spring.Data /// Group together multiple ITestObjectDao operations. /// /// Mark Pollack (.NET) - /// $Id: TestObjectManager.cs,v 1.4 2008/03/21 14:10:23 markpollack Exp $ public class TestObjectManager : ITestObjectManager { #region Fields diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectQuery.cs b/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectQuery.cs index 6c90a7ab..873f8b51 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectQuery.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectQuery.cs @@ -34,7 +34,6 @@ namespace Spring.Data /// TODO: /// /// Mark Pollack (.NET) - /// $Id: TestObjectQuery.cs,v 1.2 2006/06/12 08:43:41 markpollack Exp $ public class TestObjectQuery : MappingAdoQuery { private static string sql = "select TestObjectNo, Age, Name from TestObjects where Name = @UName"; diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectStoredProcedure.cs b/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectStoredProcedure.cs index eb74ec6b..6cca1f7d 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectStoredProcedure.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/TestObjectStoredProcedure.cs @@ -33,7 +33,6 @@ namespace Spring.Data /// TODO: /// /// Mark Pollack (.NET) - /// $Id: TestObjectStoredProcedure.cs,v 1.3 2008/01/29 18:22:33 markpollack Exp $ public class TestObjectStoredProcedure : StoredProcedure { private static string procedureName = "SelectByNameWithReturnAndOutValue"; diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/TestTxIsolationLevelTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/TestTxIsolationLevelTests.cs index f6f1223d..8d40d2f1 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/TestTxIsolationLevelTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/TestTxIsolationLevelTests.cs @@ -41,7 +41,6 @@ namespace Spring.Data /// Simple exercising of the AdoTemplate /// /// Mark Pollack (.NET) - /// $Id: TestTxIsolationLevelTests.cs,v 1.1 2008/04/03 05:41:46 markpollack Exp $ [TestFixture] public class TestTxIsolationLevelTests { diff --git a/test/Spring/Spring.Data.Integration.Tests/Data/TransactionTemplateTests.cs b/test/Spring/Spring.Data.Integration.Tests/Data/TransactionTemplateTests.cs index 9f3de8b8..fa0d6ae4 100644 --- a/test/Spring/Spring.Data.Integration.Tests/Data/TransactionTemplateTests.cs +++ b/test/Spring/Spring.Data.Integration.Tests/Data/TransactionTemplateTests.cs @@ -39,7 +39,6 @@ namespace Spring.Data /// Integration tests for transaction template functionality /// /// Mark Pollack - /// $Id: TransactionTemplateTests.cs,v 1.7 2007/08/03 19:51:22 markpollack Exp $ [TestFixture] public class TransactionTemplateTests { diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/DbProviderTemplateTests.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/DbProviderTemplateTests.cs index 27193782..8ae55441 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/DbProviderTemplateTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/DbProviderTemplateTests.cs @@ -34,7 +34,6 @@ namespace Spring.Data.NHibernate /// This class contains tests for execution of misc Hibernate usage, including userCredentialsDbProvider /// /// Mark Pollack - /// $Id: DbProviderTemplateTests.cs,v 1.2 2008/03/21 14:10:37 markpollack Exp $ [TestFixture] public class DbProviderTemplateTests { diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/ITestObjectDao.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/ITestObjectDao.cs index 8a25a5ec..343e4ee6 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/ITestObjectDao.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/ITestObjectDao.cs @@ -26,7 +26,6 @@ namespace Spring.Data.NHibernate /// TODO: /// /// Mark Pollack (.NET) - /// $Id: ITestObjectDao.cs,v 1.1 2007/05/31 20:25:14 markpollack Exp $ public interface ITestObjectDao { void Create(TestObject to); diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/MultipleDbTests.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/MultipleDbTests.cs index 3f1a54b2..b82d6465 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/MultipleDbTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/MultipleDbTests.cs @@ -40,7 +40,6 @@ namespace Spring.Data.NHibernate /// Use of Hibernate Template against database. /// /// Mark Pollack (.NET) - /// $Id: MultipleDbTests.cs,v 1.1 2007/05/31 20:25:14 markpollack Exp $ [TestFixture] public class MultipleDbTests { diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHDAOTests.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHDAOTests.cs index 8526dc8e..6e950abc 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHDAOTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHDAOTests.cs @@ -33,11 +33,6 @@ using Spring.Data.NHibernate.Support; namespace Spring.Data.NHibernate { - /// - /// TODO: - /// - /// Mark Pollack (.NET) - /// $Id: NHDAOTests.cs,v 1.1 2007/05/31 20:25:14 markpollack Exp $ [TestFixture] public class NHDAOTests { diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHTestObjectDao.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHTestObjectDao.cs index 646cd20f..9f549b97 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHTestObjectDao.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NHTestObjectDao.cs @@ -30,11 +30,6 @@ using Spring.Transaction.Interceptor; namespace Spring.Data.NHibernate { - /// - /// TODO: - /// - /// Mark Pollack (.NET) - /// $Id: NHTestObjectDao.cs,v 1.1 2007/05/31 20:25:14 markpollack Exp $ public class NHTestObjectDao : HibernateDaoSupport, ITestObjectDao { diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NativeNHTestObjectDao.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NativeNHTestObjectDao.cs index cdef2842..e86c8d23 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NativeNHTestObjectDao.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/NativeNHTestObjectDao.cs @@ -26,11 +26,6 @@ using NHibernate; namespace Spring.Data.NHibernate { - /// - /// TODO: - /// - /// Mark Pollack (.NET) - /// $Id: NativeNHTestObjectDao.cs,v 1.1 2007/05/31 20:25:14 markpollack Exp $ public class NativeNHTestObjectDao : ITestObjectDao { public ISessionFactory SessionFactory diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TemplateTests.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TemplateTests.cs index 5c5c3c3d..ea75616f 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TemplateTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TemplateTests.cs @@ -42,7 +42,6 @@ namespace Spring.Data.NHibernate /// Use of Hibernate Template against database. /// /// Mark Pollack (.NET) - /// $Id: TemplateTests.cs,v 1.2 2008/02/04 22:42:50 markpollack Exp $ [TestFixture] public class TemplateTests { diff --git a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TestObject.cs b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TestObject.cs index 9a744c8f..22fe0d94 100644 --- a/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TestObject.cs +++ b/test/Spring/Spring.Data.NHibernate.Integration.Tests/Data/NHibernate/TestObject.cs @@ -25,7 +25,6 @@ namespace Spring.Data.NHibernate /// TODO: /// /// Mark Pollack (.NET) - /// $Id: TestObject.cs,v 1.2 2008/02/04 22:42:50 markpollack Exp $ public class TestObject { #region Fields diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Config/AopConfiguration.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Config/AopConfiguration.cs index 62cf9e99..55865d28 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Config/AopConfiguration.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Config/AopConfiguration.cs @@ -36,7 +36,6 @@ namespace Spring.Data.NHibernate.Config /// This class contains tests for /// /// Mark Pollack - /// $Id: AopConfiguration.cs,v 1.2 2007/08/01 17:51:58 markpollack Exp $ [TestFixture] public class AopConfiguration { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/HibernateTransactionManagerTests.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/HibernateTransactionManagerTests.cs index baae9730..bbe4f162 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/HibernateTransactionManagerTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/HibernateTransactionManagerTests.cs @@ -42,7 +42,6 @@ namespace Spring.Data.NHibernate /// This class contains tests for the HibernateTransactionManager /// /// Mark Pollack - /// $Id: HibernateTransactionManagerTests.cs,v 1.5 2008/01/29 20:07:38 markpollack Exp $ [TestFixture] public class HibernateTransactionManagerTests { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/ITestObjectDao.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/ITestObjectDao.cs index 46e48760..79af863f 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/ITestObjectDao.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/ITestObjectDao.cs @@ -25,7 +25,6 @@ namespace Spring.Data.NHibernate /// TODO: /// /// Mark Pollack (.NET) - /// $Id: ITestObjectDao.cs,v 1.1 2007/07/18 18:44:57 oakinger Exp $ public interface ITestObjectDao { void Create(TestObject to); diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/LocalSessionFactoryObjectTests.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/LocalSessionFactoryObjectTests.cs index 877eac9d..606a6f45 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/LocalSessionFactoryObjectTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/LocalSessionFactoryObjectTests.cs @@ -35,7 +35,6 @@ namespace Spring.Data.NHibernate /// This class contains tests for LocalSessionFactoryObject /// /// Mark Pollack - /// $Id: LocalSessionFactoryObjectTests.cs,v 1.1 2008/01/29 20:07:18 markpollack Exp $ [TestFixture] public class LocalSessionFactoryObjectTests { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/NHTestObjectDao.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/NHTestObjectDao.cs index b5637055..0cdf7219 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/NHTestObjectDao.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/NHTestObjectDao.cs @@ -34,7 +34,6 @@ namespace Spring.Data.NHibernate /// NHibernate based DAO implementation of ITestObjectDAao: /// /// Mark Pollack (.NET) - /// $Id: NHTestObjectDao.cs,v 1.1 2007/07/18 18:44:57 oakinger Exp $ public class TestObjectDao : HibernateDaoSupport, ITestObjectDao { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/SimpleService.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/SimpleService.cs index 0c6b2de5..8cb2527f 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/SimpleService.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/SimpleService.cs @@ -23,14 +23,6 @@ using Spring.Transaction.Interceptor; namespace Spring.Data.NHibernate { - /// - /// This is - /// - /// - /// - /// - /// Mark Pollack - /// $Id: SimpleService.cs,v 1.1 2007/07/18 18:44:57 oakinger Exp $ public class SimpleService : ISimpleService { private ITestObjectDao testObjectDao; diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/ConfigSectionSessionScopeSettingsTests.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/ConfigSectionSessionScopeSettingsTests.cs index a2cbcbf9..0ed676e0 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/ConfigSectionSessionScopeSettingsTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/ConfigSectionSessionScopeSettingsTests.cs @@ -36,7 +36,6 @@ namespace Spring.Data.NHibernate.Support /// Tests behaviour. /// /// Erich Eichinger - /// $Id: ConfigSectionSessionScopeSettingsTests.cs,v 1.1 2007/08/22 20:17:43 oakinger Exp $ [TestFixture] public class ConfigSectionSessionScopeSettingsTests { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeSettingsTests.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeSettingsTests.cs index e71a5fa6..c0f6990d 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeSettingsTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeSettingsTests.cs @@ -33,7 +33,6 @@ namespace Spring.Data.NHibernate.Support /// Tests functionality. /// /// Erich Eichinger - /// $Id: SessionScopeSettingsTests.cs,v 1.2 2008/04/25 13:25:09 markpollack Exp $ [TestFixture] public class SessionScopeSettingsTests { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeTests.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeTests.cs index 64bf223f..cd4c3ca3 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeTests.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/Support/SessionScopeTests.cs @@ -34,7 +34,6 @@ namespace Spring.Data.NHibernate.Support /// Tests for SessionScope /// /// Erich Eichinger - /// $Id: SessionScopeTests.cs,v 1.5 2008/05/13 14:22:47 oakinger Exp $ [TestFixture] public class SessionScopeTests { diff --git a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/TestObject.cs b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/TestObject.cs index 5076a2b0..12bc72a1 100644 --- a/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/TestObject.cs +++ b/test/Spring/Spring.Data.NHibernate.Tests/Data/NHibernate/TestObject.cs @@ -25,7 +25,6 @@ namespace Spring.Data.NHibernate /// TODO: /// /// Mark Pollack (.NET) - /// $Id: TestObject.cs,v 1.1 2007/07/18 18:44:57 oakinger Exp $ public class TestObject { #region Fields diff --git a/test/Spring/Spring.Data.Tests/Data/AdoPlatformTransactionManagerTests.cs b/test/Spring/Spring.Data.Tests/Data/AdoPlatformTransactionManagerTests.cs index fccacd8d..632be796 100644 --- a/test/Spring/Spring.Data.Tests/Data/AdoPlatformTransactionManagerTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/AdoPlatformTransactionManagerTests.cs @@ -41,7 +41,6 @@ namespace Spring.Data /// This class contains tests for AdoPlatformTransactionManager /// /// Mark Pollack - /// $Id: AdoPlatformTransactionManagerTests.cs,v 1.8 2007/12/07 07:31:05 markpollack Exp $ [TestFixture] public class AdoPlatformTransactionManagerTests { diff --git a/test/Spring/Spring.Data.Tests/Data/AutoDeclarativeTxTests.cs b/test/Spring/Spring.Data.Tests/Data/AutoDeclarativeTxTests.cs index 89cb582e..d631c966 100644 --- a/test/Spring/Spring.Data.Tests/Data/AutoDeclarativeTxTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/AutoDeclarativeTxTests.cs @@ -41,7 +41,6 @@ namespace Spring.Data /// of transaction attributes. /// /// Mark Pollack (.NET) - /// $Id: AutoDeclarativeTxTests.cs,v 1.4 2007/08/21 19:26:04 markpollack Exp $ [TestFixture] public class AutoDeclarativeTxTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Common/DbParametersTests.cs b/test/Spring/Spring.Data.Tests/Data/Common/DbParametersTests.cs index 1506bbb8..838cda59 100644 --- a/test/Spring/Spring.Data.Tests/Data/Common/DbParametersTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Common/DbParametersTests.cs @@ -33,7 +33,6 @@ namespace Spring.Data.Common /// This class contains tests for DbParameters /// /// Mark Pollack - /// $Id: DbParametersTests.cs,v 1.3 2007/12/06 06:58:54 markpollack Exp $ [TestFixture] public class DbParametersTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Common/DbProviderFactoryTests.cs b/test/Spring/Spring.Data.Tests/Data/Common/DbProviderFactoryTests.cs index 796bb27b..29cb5d2f 100644 --- a/test/Spring/Spring.Data.Tests/Data/Common/DbProviderFactoryTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Common/DbProviderFactoryTests.cs @@ -34,7 +34,6 @@ namespace Spring.Data.Common /// Test for loading of DbProviders /// /// Mark Pollack (.NET) - /// $Id: DbProviderFactoryTests.cs,v 1.13 2008/04/02 19:37:20 markpollack Exp $ [TestFixture] public class DbProviderFactoryTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Common/UserCredentialsDbProviderTests.cs b/test/Spring/Spring.Data.Tests/Data/Common/UserCredentialsDbProviderTests.cs index 199e744b..8a3960da 100644 --- a/test/Spring/Spring.Data.Tests/Data/Common/UserCredentialsDbProviderTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Common/UserCredentialsDbProviderTests.cs @@ -32,7 +32,6 @@ namespace Spring.Data.Common /// This class contains tests for UserCredentialsDbProvider /// /// Mark Pollack - /// $Id: UserCredentialsDbProviderTests.cs,v 1.1 2008/01/29 18:17:48 markpollack Exp $ [TestFixture] public class UserCredentialsDbProviderTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Core/ServiceDomainTransactionManagerTests.cs b/test/Spring/Spring.Data.Tests/Data/Core/ServiceDomainTransactionManagerTests.cs index 0805b5ef..70d32551 100644 --- a/test/Spring/Spring.Data.Tests/Data/Core/ServiceDomainTransactionManagerTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Core/ServiceDomainTransactionManagerTests.cs @@ -39,7 +39,6 @@ namespace Spring.Data.Core /// This class contains tests for ServiceDomainTransactionManager /// /// Mark Pollack - /// $Id: ServiceDomainTransactionManagerTests.cs,v 1.5 2007/12/07 07:31:05 markpollack Exp $ [TestFixture] public class ServiceDomainTransactionManagerTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerIntegrationTests.cs b/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerIntegrationTests.cs index 5da87c9c..fee1993e 100644 --- a/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerIntegrationTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerIntegrationTests.cs @@ -39,7 +39,6 @@ namespace Spring.Data.Core /// but does not access any database /// /// Mark Pollack - /// $Id: TxScopeTransactionManagerIntegrationTests.cs,v 1.1 2007/11/30 18:38:59 markpollack Exp $ [TestFixture] public class TxScopeTransactionManagerIntegrationTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs b/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs index ae839b1e..a223a50f 100644 --- a/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs @@ -38,7 +38,6 @@ namespace Spring.Data.Core /// This calss contains tests for /// /// Mark Pollack - /// $Id: TxScopeTransactionManagerTests.cs,v 1.3 2007/12/07 07:31:05 markpollack Exp $ [TestFixture] public class TxScopeTransactionManagerTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Objects/AdoOperationTests.cs b/test/Spring/Spring.Data.Tests/Data/Objects/AdoOperationTests.cs index 509d0a45..2b9afc0b 100644 --- a/test/Spring/Spring.Data.Tests/Data/Objects/AdoOperationTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Objects/AdoOperationTests.cs @@ -52,7 +52,6 @@ namespace Spring.Data.Objects /// Tests for AdoOperation /// /// Mark Pollack - /// $Id: AdoOperationTests.cs,v 1.1 2008/05/30 21:10:00 markpollack Exp $ [TestFixture] public class AdoOperationTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Objects/AdoQueryTests.cs b/test/Spring/Spring.Data.Tests/Data/Objects/AdoQueryTests.cs index da25b255..c87f1654 100644 --- a/test/Spring/Spring.Data.Tests/Data/Objects/AdoQueryTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Objects/AdoQueryTests.cs @@ -55,7 +55,6 @@ namespace Spring.Data.Objects /// Tests for AdoQuery /// /// Mark Pollack - /// $Id: AdoQueryTests.cs,v 1.4 2008/05/30 21:10:00 markpollack Exp $ [TestFixture] public class AdoQueryTests : AbstractAdoQueryTests { diff --git a/test/Spring/Spring.Data.Tests/Data/Objects/StoredProcedureTests.cs b/test/Spring/Spring.Data.Tests/Data/Objects/StoredProcedureTests.cs index 356c8e7f..bbd5bb6c 100644 --- a/test/Spring/Spring.Data.Tests/Data/Objects/StoredProcedureTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Objects/StoredProcedureTests.cs @@ -54,7 +54,6 @@ namespace Spring.Data.Objects /// Tests for StoredProcedure /// /// Mark Pollack - /// $Id: StoredProcedureTests.cs,v 1.1 2008/05/30 21:10:00 markpollack Exp $ [TestFixture] public class StoredProcedureTests : AbstractAdoQueryTests { diff --git a/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs b/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs index 6792cfec..3812c9b6 100644 --- a/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs +++ b/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs @@ -36,7 +36,6 @@ namespace Spring.Data /// Group together multiple ITestObjectDao operations. /// /// Mark Pollack (.NET) - /// $Id: TestObjectMgr.cs,v 1.3 2007/10/21 18:32:41 markpollack Exp $ public class TestObjectMgr : ITestObjectMgr { #region Fields diff --git a/test/Spring/Spring.Data.Tests/DataExceptionTests.cs b/test/Spring/Spring.Data.Tests/DataExceptionTests.cs index f3da3195..a43236f0 100644 --- a/test/Spring/Spring.Data.Tests/DataExceptionTests.cs +++ b/test/Spring/Spring.Data.Tests/DataExceptionTests.cs @@ -33,7 +33,6 @@ namespace Spring /// Unit tests for all of the exception classes in the Spring.Data library... /// /// Rick Evans - /// $Id: DataExceptionTests.cs,v 1.6 2006/05/18 21:37:53 markpollack Exp $ [TestFixture] public sealed class DataExceptionTests : ExceptionsTest { diff --git a/test/Spring/Spring.Data.Tests/Support/ErrorCodeExceptionTranslatorTests.cs b/test/Spring/Spring.Data.Tests/Support/ErrorCodeExceptionTranslatorTests.cs index ab43bdfa..07c7114c 100644 --- a/test/Spring/Spring.Data.Tests/Support/ErrorCodeExceptionTranslatorTests.cs +++ b/test/Spring/Spring.Data.Tests/Support/ErrorCodeExceptionTranslatorTests.cs @@ -36,7 +36,6 @@ namespace Spring.Support /// Test the database exception translation. /// /// Mark Pollack (.NET) - /// $Id: ErrorCodeExceptionTranslatorTests.cs,v 1.8 2007/12/06 20:14:39 markpollack Exp $ [TestFixture] public class ErrorCodeExceptionTranslatorTests { diff --git a/test/Spring/Spring.Data.Tests/Support/TestDbProvider.cs b/test/Spring/Spring.Data.Tests/Support/TestDbProvider.cs index 94addf3e..4ea6b79c 100644 --- a/test/Spring/Spring.Data.Tests/Support/TestDbProvider.cs +++ b/test/Spring/Spring.Data.Tests/Support/TestDbProvider.cs @@ -32,7 +32,6 @@ namespace Spring.Support /// A fake provider class used to test exception translation functionality /// /// Mark Pollack (.NET) - /// $Id: TestDbProvider.cs,v 1.11 2007/12/06 05:48:32 markpollack Exp $ public class TestDbProvider : IDbProvider { private string connectionString; diff --git a/test/Spring/Spring.Data.Tests/Support/TestSqlException.cs b/test/Spring/Spring.Data.Tests/Support/TestSqlException.cs index b7fb34cf..79e65f75 100644 --- a/test/Spring/Spring.Data.Tests/Support/TestSqlException.cs +++ b/test/Spring/Spring.Data.Tests/Support/TestSqlException.cs @@ -31,7 +31,6 @@ namespace Spring.Support /// A simple exception class to test exception translation functionality /// /// Mark Pollack (.NET) - /// $Id: TestSqlException.cs,v 1.2 2006/06/26 18:57:31 markpollack Exp $ [Serializable] public class TestSqlException : Exception { diff --git a/test/Spring/Spring.Data.Tests/Transaction/CallCountingTransactionManager.cs b/test/Spring/Spring.Data.Tests/Transaction/CallCountingTransactionManager.cs index 7341e7fc..34ef70c0 100644 --- a/test/Spring/Spring.Data.Tests/Transaction/CallCountingTransactionManager.cs +++ b/test/Spring/Spring.Data.Tests/Transaction/CallCountingTransactionManager.cs @@ -27,7 +27,6 @@ namespace Spring.Transaction /// have been called. /// /// Mark Pollack - /// $Id: CallCountingTransactionManager.cs,v 1.1 2007/05/26 00:43:07 markpollack Exp $ public class CallCountingTransactionManager : AbstractPlatformTransactionManager { diff --git a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/AbstractTransactionAspectTests.cs b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/AbstractTransactionAspectTests.cs index 1b0da2e3..3695cf6f 100644 --- a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/AbstractTransactionAspectTests.cs +++ b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/AbstractTransactionAspectTests.cs @@ -35,7 +35,6 @@ namespace Spring.Transaction.Interceptor /// Mock object based tests for transaction aspects. /// /// Mark Pollack - /// $Id: AbstractTransactionAspectTests.cs,v 1.5 2007/10/21 18:16:58 markpollack Exp $ [TestFixture] public abstract class AbstractTransactionAspectTests { diff --git a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/MatchAlwaysTransactionAttributeSourceTests.cs b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/MatchAlwaysTransactionAttributeSourceTests.cs index c6f4e821..ef0ed4a6 100644 --- a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/MatchAlwaysTransactionAttributeSourceTests.cs +++ b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/MatchAlwaysTransactionAttributeSourceTests.cs @@ -12,7 +12,6 @@ namespace Spring.Transaction.Interceptor /// Test MatchAlwaysTransactionAttributeSourceTests /// /// Mark Pollack - /// $Id: MatchAlwaysTransactionAttributeSourceTests.cs,v 1.7 2008/05/27 19:07:03 markpollack Exp $ [TestFixture] public class MatchAlwaysTransactionAttributeSourceTests { diff --git a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionAttributeSourceTests.cs b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionAttributeSourceTests.cs index d65bdd59..0775b023 100644 --- a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionAttributeSourceTests.cs +++ b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionAttributeSourceTests.cs @@ -33,7 +33,6 @@ namespace Spring.Transaction.Interceptor /// implementations. /// /// Mark Pollack - /// $Id: TransactionAttributeSourceTests.cs,v 1.1 2008/05/27 19:07:03 markpollack Exp $ [TestFixture] public class TransactionAttributeSourceTests { diff --git a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionInterceptorTests.cs b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionInterceptorTests.cs index 65ce4dfb..a779219e 100644 --- a/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionInterceptorTests.cs +++ b/test/Spring/Spring.Data.Tests/Transaction/Interceptor/TransactionInterceptorTests.cs @@ -31,7 +31,6 @@ namespace Spring.Transaction.Interceptor /// This class contains mock objects tests the TransactionInterceptor /// /// Mark Pollack - /// $Id: TransactionInterceptorTests.cs,v 1.3 2007/10/21 18:16:58 markpollack Exp $ [TestFixture] public class TransactionInterceptorTests : AbstractTransactionAspectTests { diff --git a/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs b/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs index b96b91f2..fd1c83f4 100644 --- a/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs +++ b/test/Spring/Spring.Services.Tests/EnterpriseServices/ServicedComponentExporterTests.cs @@ -41,7 +41,6 @@ namespace Spring.EnterpriseServices /// Unit tests for the ServicedComponentExporter class. /// /// Bruno Baia - /// $Id: ServicedComponentExporterTests.cs,v 1.2 2007/05/16 10:03:25 oakinger Exp $ [TestFixture] public class ServicedComponentExporterTests { diff --git a/test/Spring/Spring.Services.Tests/Remoting/CaoExporterTests.cs b/test/Spring/Spring.Services.Tests/Remoting/CaoExporterTests.cs index c9d4ebae..2fa29d00 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/CaoExporterTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/CaoExporterTests.cs @@ -36,7 +36,6 @@ namespace Spring.Remoting /// Unit tests for the CaoExporter class. /// /// Bruno Baia - /// $Id: CaoExporterTests.cs,v 1.11 2007/02/20 19:39:47 aseovic Exp $ [TestFixture] public class CaoExporterTests : BaseRemotingTestFixture { diff --git a/test/Spring/Spring.Services.Tests/Remoting/CaoFactoryObjectTests.cs b/test/Spring/Spring.Services.Tests/Remoting/CaoFactoryObjectTests.cs index aa16f428..de8b5cbd 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/CaoFactoryObjectTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/CaoFactoryObjectTests.cs @@ -33,7 +33,6 @@ namespace Spring.Remoting /// Unit tests for the CaoFactoryObject class. /// /// Bruno Baia - /// $Id: CaoFactoryObjectTests.cs,v 1.12 2007/02/20 19:39:52 aseovic Exp $ [TestFixture] public class CaoFactoryObjectTests : BaseRemotingTestFixture { diff --git a/test/Spring/Spring.Services.Tests/Remoting/RemoteObjectFactoryTests.cs b/test/Spring/Spring.Services.Tests/Remoting/RemoteObjectFactoryTests.cs index 754fa29d..80d6daf1 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/RemoteObjectFactoryTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/RemoteObjectFactoryTests.cs @@ -33,7 +33,6 @@ namespace Spring.Remoting /// Unit tests for the RemoteObjectFactory class. /// /// Bruno Baia - /// $Id: RemoteObjectFactoryTests.cs,v 1.5 2007/08/22 20:17:19 oakinger Exp $ [TestFixture] public class RemoteObjectFactoryTests { diff --git a/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigParserTests.cs b/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigParserTests.cs index 34d4f5cb..d068d81f 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigParserTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigParserTests.cs @@ -30,7 +30,6 @@ namespace Spring.Remoting /// Unit tests for the RemotingConfigParserTests class. /// /// Bruno Baia - /// $Id: RemotingConfigParserTests.cs,v 1.1 2006/05/20 22:16:59 bbaia Exp $ [TestFixture] public class RemotingConfigParserTests { diff --git a/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigurerTests.cs b/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigurerTests.cs index 585d2e15..ebce1dcf 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigurerTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/RemotingConfigurerTests.cs @@ -33,7 +33,6 @@ namespace Spring.Remoting /// Unit tests for the RemotingConfigurerTests class. /// /// Bruno Baia - /// $Id: RemotingConfigurerTests.cs,v 1.3 2007/02/20 19:40:02 aseovic Exp $ [TestFixture] public class RemotingConfigurerTests : BaseRemotingTestFixture { diff --git a/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs b/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs index 699b6db4..433d9510 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs @@ -32,7 +32,6 @@ namespace Spring.Remoting /// /// Bruno Baia /// Mark Pollack - /// $Id: SaoExporterTests.cs,v 1.4 2007/02/20 19:40:12 aseovic Exp $ [TestFixture] public class SaoExporterTests : BaseRemotingTestFixture { diff --git a/test/Spring/Spring.Services.Tests/Remoting/SaoFactoryObjectTests.cs b/test/Spring/Spring.Services.Tests/Remoting/SaoFactoryObjectTests.cs index 030786dd..3cc5b6eb 100644 --- a/test/Spring/Spring.Services.Tests/Remoting/SaoFactoryObjectTests.cs +++ b/test/Spring/Spring.Services.Tests/Remoting/SaoFactoryObjectTests.cs @@ -39,7 +39,6 @@ namespace Spring.Remoting /// /// Mark Pollack /// Bruno Baia - /// $Id: SaoFactoryObjectTests.cs,v 1.12 2007/10/09 22:25:31 markpollack Exp $ [TestFixture] public class SaoFactoryObjectTests : BaseRemotingTestFixture { diff --git a/test/Spring/Spring.Services.Tests/Web/Services/WebServiceProxyFactoryTests.cs b/test/Spring/Spring.Services.Tests/Web/Services/WebServiceProxyFactoryTests.cs index 8e70cc22..547bf639 100644 --- a/test/Spring/Spring.Services.Tests/Web/Services/WebServiceProxyFactoryTests.cs +++ b/test/Spring/Spring.Services.Tests/Web/Services/WebServiceProxyFactoryTests.cs @@ -46,7 +46,6 @@ namespace Spring.Web.Services /// Unit tests for the WebServiceProxyFactory class. /// /// Bruno Baia - /// $Id: WebServiceProxyFactoryTests.cs,v 1.8 2007/12/07 20:26:26 bbaia Exp $ [TestFixture] public class WebServiceProxyFactoryTests { diff --git a/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/AnotherTest/LoadAppContextTests.cs b/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/AnotherTest/LoadAppContextTests.cs index 85227876..c4602142 100644 --- a/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/AnotherTest/LoadAppContextTests.cs +++ b/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/AnotherTest/LoadAppContextTests.cs @@ -36,7 +36,6 @@ namespace Spring.Testing.NUnit.Another /// assembly. /// /// Mark Pollack - /// $Id: LoadAppContextTests.cs,v 1.3 2007/08/25 14:26:35 oakinger Exp $ [TestFixture] public class LoadAppContextTests : BaseTestAppContextTests { diff --git a/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/BaseTestAppContextTests.cs b/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/BaseTestAppContextTests.cs index b74faf34..09395374 100644 --- a/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/BaseTestAppContextTests.cs +++ b/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/BaseTestAppContextTests.cs @@ -29,7 +29,6 @@ namespace Spring.Testing.NUnit /// /// /// Mark Pollack - /// $Id: BaseTestAppContextTests.cs,v 1.1 2007/08/20 18:38:11 markpollack Exp $ public class BaseTestAppContextTests : AbstractTransactionalDbProviderSpringContextTests { diff --git a/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/CachedAppContextTests.cs b/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/CachedAppContextTests.cs index c7605df0..58d3f724 100644 --- a/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/CachedAppContextTests.cs +++ b/test/Spring/Spring.Testing.NUnit.Tests/Testing/NUnit/CachedAppContextTests.cs @@ -33,7 +33,6 @@ namespace Spring.Testing.NUnit /// NUnit. The first one should be LoadAppContextTests. /// /// Mark Pollack - /// $Id: CachedAppContextTests.cs,v 1.2 2007/08/21 19:26:14 markpollack Exp $ [TestFixture] public class CachedAppContextTests : BaseTestAppContextTests { diff --git a/test/Spring/Spring.Web.Tests/Caching/AspNetCacheTests.cs b/test/Spring/Spring.Web.Tests/Caching/AspNetCacheTests.cs index 2c6ebb53..f9795c13 100644 --- a/test/Spring/Spring.Web.Tests/Caching/AspNetCacheTests.cs +++ b/test/Spring/Spring.Web.Tests/Caching/AspNetCacheTests.cs @@ -36,7 +36,6 @@ namespace Spring.Caching /// Test AspNetCache behaviour. /// /// Erich Eichinger - /// $Id: AspNetCacheTests.cs,v 1.2 2007/08/25 10:22:13 oakinger Exp $ [TestFixture] public class AspNetCacheTests { diff --git a/test/Spring/Spring.Web.Tests/Context/Support/HttpApplicationConfigurerTests.cs b/test/Spring/Spring.Web.Tests/Context/Support/HttpApplicationConfigurerTests.cs index b034fe62..152f6a66 100644 --- a/test/Spring/Spring.Web.Tests/Context/Support/HttpApplicationConfigurerTests.cs +++ b/test/Spring/Spring.Web.Tests/Context/Support/HttpApplicationConfigurerTests.cs @@ -37,7 +37,6 @@ namespace Spring.Context.Support /// /// /// Erich Eichinger - /// $Id: HttpApplicationConfigurerTests.cs,v 1.1 2007/07/27 13:29:21 oakinger Exp $ [TestFixture] public class HttpApplicationConfigurerTests { diff --git a/test/Spring/Spring.Web.Tests/Context/Support/WebApplicationContextTests.cs b/test/Spring/Spring.Web.Tests/Context/Support/WebApplicationContextTests.cs index ea0be410..1b0e4902 100644 --- a/test/Spring/Spring.Web.Tests/Context/Support/WebApplicationContextTests.cs +++ b/test/Spring/Spring.Web.Tests/Context/Support/WebApplicationContextTests.cs @@ -38,7 +38,6 @@ namespace Spring.Context.Support /// /// /// Erich Eichinger - /// $Id: WebApplicationContextTests.cs,v 1.1 2008/02/02 10:24:39 oakinger Exp $ [AspTestFixture("/Test", "/Spring/Context/Support/WebApplicationContextTests")] public class WebApplicationContextTests : WebFormTestCase { diff --git a/test/Spring/Spring.Web.Tests/Core/IO/WebResourceTests.cs b/test/Spring/Spring.Web.Tests/Core/IO/WebResourceTests.cs index f178f5d6..3b9da676 100644 --- a/test/Spring/Spring.Web.Tests/Core/IO/WebResourceTests.cs +++ b/test/Spring/Spring.Web.Tests/Core/IO/WebResourceTests.cs @@ -31,7 +31,6 @@ namespace Spring.Core.IO /// Unit tests for the WebResource class. /// /// Erich Eichinger - /// $Id: WebResourceTests.cs,v 1.6 2008/03/14 12:02:45 oakinger Exp $ [TestFixture] public class WebResourceTests : FileSystemResourceCommonTests { diff --git a/test/Spring/Spring.Web.Tests/Globalization/Resolvers/DefaultWebCultureResolverTests.cs b/test/Spring/Spring.Web.Tests/Globalization/Resolvers/DefaultWebCultureResolverTests.cs index f041d292..824d7415 100644 --- a/test/Spring/Spring.Web.Tests/Globalization/Resolvers/DefaultWebCultureResolverTests.cs +++ b/test/Spring/Spring.Web.Tests/Globalization/Resolvers/DefaultWebCultureResolverTests.cs @@ -33,7 +33,6 @@ namespace Spring.Globalization.Resolvers /// Tests DefaultWebCultureResolver behaviour. /// /// Erich Eichinger - /// $Id: DefaultWebCultureResolverTests.cs,v 1.1 2007/08/25 14:26:36 oakinger Exp $ [TestFixture] public class DefaultWebCultureResolverTests { diff --git a/test/Spring/Spring.Web.Tests/MyNUnitAddinHelper.cs b/test/Spring/Spring.Web.Tests/MyNUnitAddinHelper.cs index 412db0cf..1eb3c26d 100644 --- a/test/Spring/Spring.Web.Tests/MyNUnitAddinHelper.cs +++ b/test/Spring/Spring.Web.Tests/MyNUnitAddinHelper.cs @@ -31,7 +31,6 @@ namespace Spring /// Required for auto-registering NUnitAspEx extension with NUnit for this assembly /// /// Erich Eichinger - /// $Id: MyNUnitAddinHelper.cs,v 1.1 2007/12/03 16:11:31 oakinger Exp $ [NUnitAddin] public class MyNUnitAddinHelper : NUnitAspEx.NUnitAddinHelper { diff --git a/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectDefinitionFactoryTests.cs b/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectDefinitionFactoryTests.cs index 31d1d9d8..d8cc8e05 100644 --- a/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectDefinitionFactoryTests.cs +++ b/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectDefinitionFactoryTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the WebObjectDefinitionFactory class. /// /// Erich Eichinger - /// $Id: WebObjectDefinitionFactoryTests.cs,v 1.4 2008/03/14 12:02:45 oakinger Exp $ [AspTestFixture("/Test", "/Spring/Objects/Factory/Support")] public class WebObjectDefinitionFactoryTests { diff --git a/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectFactoryTests.cs b/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectFactoryTests.cs index 6111a7fb..0d742a5b 100644 --- a/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectFactoryTests.cs +++ b/test/Spring/Spring.Web.Tests/Objects/Factory/Support/WebObjectFactoryTests.cs @@ -33,7 +33,6 @@ namespace Spring.Objects.Factory.Support /// Unit tests for the WebObjectFactory class. /// /// Rick Evans - /// $Id: WebObjectFactoryTests.cs,v 1.5 2008/03/14 12:02:45 oakinger Exp $ [TestFixture] public sealed class WebObjectFactoryTests { diff --git a/test/Spring/Spring.Web.Tests/TestSupport/TestWebContextTests.cs b/test/Spring/Spring.Web.Tests/TestSupport/TestWebContextTests.cs index e499218c..5aa4334e 100644 --- a/test/Spring/Spring.Web.Tests/TestSupport/TestWebContextTests.cs +++ b/test/Spring/Spring.Web.Tests/TestSupport/TestWebContextTests.cs @@ -31,7 +31,6 @@ namespace Spring.TestSupport /// The base class for tests to run within a TestWebContext /// /// Erich Eichinger - /// $Id: TestWebContextTests.cs,v 1.1 2008/03/15 11:19:39 oakinger Exp $ public abstract class TestWebContextTests { [SetUp] diff --git a/test/Spring/Spring.Web.Tests/TestSupport/VirtualEnvironmentMock.cs b/test/Spring/Spring.Web.Tests/TestSupport/VirtualEnvironmentMock.cs index 5c63a4ae..d1abb1cf 100644 --- a/test/Spring/Spring.Web.Tests/TestSupport/VirtualEnvironmentMock.cs +++ b/test/Spring/Spring.Web.Tests/TestSupport/VirtualEnvironmentMock.cs @@ -8,7 +8,6 @@ namespace Spring.TestSupport /// Test environment implementation. /// /// Erich Eichinger - /// $Id: VirtualEnvironmentMock.cs,v 1.5 2008/03/14 12:02:46 oakinger Exp $ internal class VirtualEnvironmentMock : IVirtualEnvironment, IDisposable { private readonly IVirtualEnvironment _prevEnvironment; diff --git a/test/Spring/Spring.Web.Tests/Threading/HttpContextStorageTests.cs b/test/Spring/Spring.Web.Tests/Threading/HttpContextStorageTests.cs index 69129c2b..ebe43e0a 100644 --- a/test/Spring/Spring.Web.Tests/Threading/HttpContextStorageTests.cs +++ b/test/Spring/Spring.Web.Tests/Threading/HttpContextStorageTests.cs @@ -32,7 +32,6 @@ namespace Spring.Threading /// Apply common thread-storage tests for /// /// Erich Eichinger - /// $Id: HttpContextStorageTests.cs,v 1.1 2007/02/02 21:31:18 oakinger Exp $ [TestFixture] public class HttpContextStorageTests : CommonThreadStorageTests { diff --git a/test/Spring/Spring.Web.Tests/Threading/HybridContextStorageTests.cs b/test/Spring/Spring.Web.Tests/Threading/HybridContextStorageTests.cs index 1ff54849..cb1f8975 100644 --- a/test/Spring/Spring.Web.Tests/Threading/HybridContextStorageTests.cs +++ b/test/Spring/Spring.Web.Tests/Threading/HybridContextStorageTests.cs @@ -32,7 +32,6 @@ namespace Spring.Threading /// Apply common thread-storage tests for /// /// Erich Eichinger - /// $Id: HybridContextStorageTests.cs,v 1.1 2007/02/02 21:31:18 oakinger Exp $ [TestFixture] public class HybridContextStorageTests : CommonThreadStorageTests { diff --git a/test/Spring/Spring.Web.Tests/Util/ControlInterceptionTests.cs b/test/Spring/Spring.Web.Tests/Util/ControlInterceptionTests.cs index abe77f38..6428021e 100644 --- a/test/Spring/Spring.Web.Tests/Util/ControlInterceptionTests.cs +++ b/test/Spring/Spring.Web.Tests/Util/ControlInterceptionTests.cs @@ -36,7 +36,6 @@ namespace Spring.Util /// Unit tests for the ControlInterceptor class. /// /// Erich Eichinger - /// $Id: ControlInterceptionTests.cs,v 1.9 2008/03/14 12:02:46 oakinger Exp $ [TestFixture] public class ControlInterceptionTests { diff --git a/test/Spring/Spring.Web.Tests/Util/WebUtilsTests.cs b/test/Spring/Spring.Web.Tests/Util/WebUtilsTests.cs index d8a903da..065b11e5 100644 --- a/test/Spring/Spring.Web.Tests/Util/WebUtilsTests.cs +++ b/test/Spring/Spring.Web.Tests/Util/WebUtilsTests.cs @@ -34,7 +34,6 @@ namespace Spring.Util /// Unit tests for the WebUtilsTests class. /// /// Rick Evans - /// $Id: WebUtilsTests.cs,v 1.9 2008/03/19 18:05:08 oakinger Exp $ [TestFixture] public sealed class WebUtilsTests { diff --git a/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs b/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs index 583a9d90..4d88532f 100644 --- a/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/Services/WebServiceExporterTests.cs @@ -42,7 +42,6 @@ namespace Spring.Web.Services /// Unit tests for the WebServiceExporter class. /// /// Bruno Baia - /// $Id: WebServiceExporterTests.cs,v 1.7 2007/12/07 20:26:38 bbaia Exp $ [TestFixture] public sealed class WebServiceExporterTests { diff --git a/test/Spring/Spring.Web.Tests/Web/Support/AbstractHandlerFactoryTests.cs b/test/Spring/Spring.Web.Tests/Web/Support/AbstractHandlerFactoryTests.cs index 153946fc..00083135 100644 --- a/test/Spring/Spring.Web.Tests/Web/Support/AbstractHandlerFactoryTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/Support/AbstractHandlerFactoryTests.cs @@ -34,7 +34,6 @@ namespace Spring.Web.Support /// /// /// Erich Eichinger - /// $Id: AbstractHandlerFactoryTests.cs,v 1.1 2008/03/19 18:05:08 oakinger Exp $ [TestFixture] public class AbstractHandlerFactoryTests : AbstractHandlerFactory { diff --git a/test/Spring/Spring.Web.Tests/Web/Support/MimeMediaTypeTests.cs b/test/Spring/Spring.Web.Tests/Web/Support/MimeMediaTypeTests.cs index e1ba007e..548bd7f5 100644 --- a/test/Spring/Spring.Web.Tests/Web/Support/MimeMediaTypeTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/Support/MimeMediaTypeTests.cs @@ -31,7 +31,6 @@ namespace Spring.Web.Support /// Tests the MediaType class according to http://www.iana.org/assignments/media-types/ /// /// Erich Eichinger - /// $Id: MimeMediaTypeTests.cs,v 1.1 2007/11/28 23:26:28 oakinger Exp $ [TestFixture] public class MimeMediaTypeTests { diff --git a/test/Spring/Spring.Web.Tests/Web/Support/PageHandlerFactoryTests.cs b/test/Spring/Spring.Web.Tests/Web/Support/PageHandlerFactoryTests.cs index 39606add..714902bc 100644 --- a/test/Spring/Spring.Web.Tests/Web/Support/PageHandlerFactoryTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/Support/PageHandlerFactoryTests.cs @@ -36,7 +36,6 @@ namespace Spring.Web.Support /// /// /// Erich Eichinger - /// $Id: PageHandlerFactoryTests.cs,v 1.4 2008/01/27 23:29:55 oakinger Exp $ [AspTestFixture("/Test", "/Spring/Web/Support/PageHandlerFactoryTests")] public class PageHandlerFactoryTests : WebFormTestCase { diff --git a/test/Spring/Spring.Web.Tests/Web/Support/ResultTests.cs b/test/Spring/Spring.Web.Tests/Web/Support/ResultTests.cs index ea6a44b1..cd563f80 100644 --- a/test/Spring/Spring.Web.Tests/Web/Support/ResultTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/Support/ResultTests.cs @@ -31,7 +31,6 @@ namespace Spring.Web.Support /// Unit tests for the Result class. /// /// Rick Evans - /// $Id: ResultTests.cs,v 1.4 2007/04/19 07:49:36 oakinger Exp $ [TestFixture] public sealed class ResultTests { diff --git a/test/Spring/Spring.Web.Tests/Web/UI/Controls/AbstractValidationControlTests.cs b/test/Spring/Spring.Web.Tests/Web/UI/Controls/AbstractValidationControlTests.cs index 2f395ec7..b22eee81 100644 --- a/test/Spring/Spring.Web.Tests/Web/UI/Controls/AbstractValidationControlTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/UI/Controls/AbstractValidationControlTests.cs @@ -34,7 +34,6 @@ namespace Spring.Web.UI.Controls /// /// /// Erich Eichinger - /// $Id: AbstractValidationControlTests.cs,v 1.1 2008/03/19 12:07:15 oakinger Exp $ [TestFixture] public class AbstractValidationControlTests { diff --git a/test/Spring/Spring.Web.Tests/Web/UI/Controls/HeadTests.cs b/test/Spring/Spring.Web.Tests/Web/UI/Controls/HeadTests.cs index 27c10ff8..681a40ca 100644 --- a/test/Spring/Spring.Web.Tests/Web/UI/Controls/HeadTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/UI/Controls/HeadTests.cs @@ -36,7 +36,6 @@ namespace Spring.Web.UI.Controls /// Tests behaviour of the <Head> server control /// /// Erich Eichinger - /// $Id: HeadTests.cs,v 1.1 2007/11/28 23:26:28 oakinger Exp $ [TestFixture] public class HeadTests { diff --git a/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationErrorsTests.cs b/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationErrorsTests.cs index 576b1dbc..ddba7a4f 100644 --- a/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationErrorsTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationErrorsTests.cs @@ -32,7 +32,6 @@ namespace Spring.Web.UI.Controls /// /// /// Erich Eichinger - /// $Id: ValidationErrorsTests.cs,v 1.1 2008/03/19 12:07:15 oakinger Exp $ [TestFixture] public class ValidationErrorsTests { diff --git a/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationSummaryTests.cs b/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationSummaryTests.cs index 5e5172bc..e729a3b9 100644 --- a/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationSummaryTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/UI/Controls/ValidationSummaryTests.cs @@ -32,7 +32,6 @@ namespace Spring.Web.UI.Controls /// /// /// Erich Eichinger - /// $Id: ValidationSummaryTests.cs,v 1.1 2008/03/19 12:07:17 oakinger Exp $ [TestFixture] public class ValidationSummaryTests { diff --git a/test/Spring/Spring.Web.Tests/Web/UI/PageTests.cs b/test/Spring/Spring.Web.Tests/Web/UI/PageTests.cs index adb01c75..21a315b9 100644 --- a/test/Spring/Spring.Web.Tests/Web/UI/PageTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/UI/PageTests.cs @@ -43,7 +43,6 @@ namespace Spring.Web.UI /// /// Goran Milosavljevic /// Erich Eichinger - /// $Id: PageTests.cs,v 1.7 2008/03/15 11:19:39 oakinger Exp $ [TestFixture] public class PageTests : TestWebContextTests { diff --git a/test/Spring/Spring.Web.Tests/Web/UI/UserControlTests.cs b/test/Spring/Spring.Web.Tests/Web/UI/UserControlTests.cs index c8750d97..f401cb34 100644 --- a/test/Spring/Spring.Web.Tests/Web/UI/UserControlTests.cs +++ b/test/Spring/Spring.Web.Tests/Web/UI/UserControlTests.cs @@ -36,7 +36,6 @@ namespace Spring.Web.UI /// /// /// Erich Eichinger - /// $Id: UserControlTests.cs,v 1.2 2008/03/15 11:19:39 oakinger Exp $ [TestFixture] public class UserControlTests : TestWebContextTests {