Skip to content

Commit eaf551d

Browse files
author
Dariusz Suchojad
committed
SESPRINGPYTHONPY-148: Merging the fix to trunk.
git-svn-id: https://src.springframework.org/svn/se-springpython-py/trunk@783 ce8fead1-4192-4296-8608-a705134b927f
2 parents 9df6a97 + 2afe569 commit eaf551d

File tree

3 files changed

+62
-31
lines changed

3 files changed

+62
-31
lines changed

springpython/src/springpython/aop/__init__.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
distributed under the License is distributed on an "AS IS" BASIS,
1212
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
14-
limitations under the License.
14+
limitations under the License.
1515
"""
1616
import copy
1717
import logging
@@ -45,7 +45,7 @@ def __init__(self, instance, method_name, args, kwargs, interceptors):
4545
self.args = args
4646
self.kwargs = kwargs
4747
self.intercept_stack = copy.copy(interceptors)
48-
self.intercept_stack.append(FinalInterceptor())
48+
self.intercept_stack.append(FinalInterceptor())
4949
self.logger = logging.getLogger("springpython.aop.MethodInvocation")
5050

5151
def getInterceptor(self):
@@ -139,7 +139,7 @@ def invoke(self, invocation):
139139

140140
def __setattr__(self, name, value):
141141
"""If "advice", make sure it is a list. Anything else, pass through to simple assignment.
142-
Also, if "patterns", initialize the regular expression parsers.
142+
Also, if "patterns", initialize the regular expression parsers.
143143
"""
144144
if name == "advice" and type(value) != list:
145145
self.__dict__[name] = [value]
@@ -165,7 +165,7 @@ class AopProxy(object):
165165
"""AopProxy acts like the target object by dispatching all method calls to the target through a MethodInvocation.
166166
The MethodInvocation object actually deals with potential "around" advice, referred to as interceptors. Attribute
167167
lookups are not intercepted, but instead fetched from the actual target object."""
168-
168+
169169
def __init__(self, target, interceptors):
170170
if type(target).__name__ != "instance":
171171
raise Exception("Target attribute must be an instance.")
@@ -186,24 +186,24 @@ def __getattr__(self, name):
186186
attr = getattr(self.target, name)
187187
if not callable(attr):
188188
return attr
189-
189+
190190
def dispatch(*args, **kwargs):
191-
"""This method is returned to the caller emulating the function call being sent to the
191+
"""This method is returned to the caller emulating the function call being sent to the
192192
target object. This services as a proxying agent for the target object."""
193193
invocation = MethodInvocation(self.target, name, args, kwargs, self.interceptors)
194194
##############################################################################
195195
# NOTE:
196196
# getattr(invocation, name) doesn't work here, because __str__ will print
197197
# the MethodInvocation's string, instead of trigger the interceptor stack.
198198
##############################################################################
199-
return invocation.__getattr__(name)(*args, **kwargs)
199+
return invocation.__getattr__(name)(*args, **kwargs)
200200

201201
return dispatch
202-
202+
203203
class ProxyFactory(object):
204204
"""This object helps to build AopProxy objects programmatically. It allows configuring advice and target objects.
205205
Then it will produce an AopProxy when needed. To use similar behavior in an IoC environment, see ProxyFactoryObject."""
206-
206+
207207
def __init__(self, target = None, interceptors = None):
208208
self.logger = logging.getLogger("springpython.aop.ProxyFactory")
209209
self.target = target
@@ -218,20 +218,22 @@ def getProxy(self):
218218
"""Generate an AopProxy given the current target and list of interceptors. Any changes to the factory after
219219
proxy creation do NOT propagate to the proxies."""
220220
return AopProxy(self.target, self.interceptors)
221-
221+
222222
def __setattr__(self, name, value):
223223
if name == "target" and type(value) == types.StringType:
224-
self.__dict__[name] = utils.getClass(value)()
225-
else:
226-
self.__dict__[name] = value
224+
value = utils.getClass(value)()
225+
elif name == "interceptors" and not isinstance(value, list):
226+
value = [value]
227+
228+
self.__dict__[name] = value
227229

228230
class ProxyFactoryObject(ProxyFactory, AopProxy):
229231
"""This class acts as both a ProxyFactory to build and an AopProxy. It makes itself look like the target object.
230232
Any changes to the target and list of interceptors is immediately seen when using this as a proxy."""
231233
def __init__(self, target = None, interceptors = None):
232234
ProxyFactory.__init__(self, target, interceptors)
233235
self.logger = logging.getLogger("springpython.aop.ProxyFactoryObject")
234-
236+
235237
def __str__(self):
236238
return self.__getattr__("__str__")()
237239

springpython/test/springpythontest/aopTestCases.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
distributed under the License is distributed on an "AS IS" BASIS,
1212
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
14-
limitations under the License.
14+
limitations under the License.
1515
"""
1616
import logging
1717
import unittest
@@ -33,11 +33,11 @@ def testPointcutInterface(self):
3333
pointcut = Pointcut()
3434
self.assertRaises(NotImplementedError, pointcut.class_filter)
3535
self.assertRaises(NotImplementedError, pointcut.method_matcher)
36-
36+
3737
def testMethodMatcherInterface(self):
3838
methodMatcher = MethodMatcher()
3939
self.assertRaises(NotImplementedError, methodMatcher.matches_method_and_target, None, None, None)
40-
40+
4141
def testMethodInterceptorInterface(self):
4242
methodInterceptor = MethodInterceptor()
4343
self.assertRaises(NotImplementedError, methodInterceptor.invoke, None)
@@ -55,7 +55,7 @@ def testCreatingAProxyFactoryAndAddingAnInterceptorProgrammatically(self):
5555
self.assertEquals("<Wrapped>Alright!</Wrapped>", service.doSomething())
5656
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method("test"))
5757
self.assertEquals("sample", service.attribute)
58-
58+
5959
def testCreatingAProxyFactoryAndAddingAnInterceptorIoC(self):
6060
factory = self.appContext.get_object("factory")
6161
service = factory.getProxy()
@@ -71,7 +71,7 @@ def testWrappingStringFunctionWithInterceptor(self):
7171
self.assertEquals("This is a sample service.", str(service.target))
7272
self.assertEquals("<Wrapped>This is a sample service.</Wrapped>", str(service))
7373
self.assertEquals("<Wrapped>This is a sample service.</Wrapped>", service.__str__())
74-
74+
7575
def testCreatingAProxyFactoryObjectAndAddingAnInterceptorProgrammatically(self):
7676
service = ProxyFactoryObject()
7777
service.target = SampleService()
@@ -95,7 +95,7 @@ def testApplyingTwoConditionalPointcutsIoC(self):
9595
sampleService = self.appContext.get_object("sampleService2")
9696
self.assertEquals(sampleService.doSomething(), "BEFORE => <Wrapped>Alright!</Wrapped> <= AFTER")
9797
self.assertEquals(sampleService.method("testdata"), "You made it! => testdata")
98-
98+
9999
def testApplyingASingleConditionalPointcutProgrammatically(self):
100100
wrappingAdvice = WrappingInterceptor()
101101
pointcutAdvisor = RegexpMethodPointcutAdvisor()
@@ -118,13 +118,32 @@ def testApplyingTwoConditionalPointcutsProgrammatically(self):
118118
sampleService.target = targetService
119119
self.assertEquals(sampleService.doSomething(), "BEFORE => <Wrapped>Alright!</Wrapped> <= AFTER")
120120
self.assertEquals(sampleService.method("testdata"), "You made it! => testdata")
121-
121+
122122
def testCreatingAProxyFactoryObjectWithAnInterceptorByClassNameInsteadOfInstanceIoC(self):
123123
service = self.appContext.get_object("sampleService5")
124124
self.assertEquals("<Wrapped>Alright!</Wrapped>", service.doSomething())
125125
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method("test"))
126126
self.assertEquals("sample", service.attribute)
127-
127+
128+
def testProxyFactoryObjectInterceptorsNotWrappedInAList(self):
129+
service = ProxyFactoryObject()
130+
service.target = SampleService()
131+
132+
# Note that it isn't wrapped in a list.
133+
service.interceptors = WrappingInterceptor()
134+
135+
self.assertEquals("This is a sample service.", service.target.__str__())
136+
self.assertEquals("This is a sample service.", str(service.target))
137+
self.assertEquals("<Wrapped>This is a sample service.</Wrapped>", str(service))
138+
self.assertEquals("<Wrapped>This is a sample service.</Wrapped>", service.__str__())
139+
140+
# sampleService6 has an interceptor which isn't wrapped in a list
141+
# inside its XMLConfig.
142+
service = self.appContext.get_object("sampleService6")
143+
self.assertEquals("<Wrapped>Alright!</Wrapped>", service.doSomething())
144+
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method("test"))
145+
self.assertEquals("sample", service.attribute)
146+
128147
#class AopProxyFactoryCombinedWithPyroTestCase(unittest.TestCase):
129148
# """Tests mixing AOP proxies and Pyro with the point cut on either the client or the server side."""
130149
# def __init__(self, methodName='runTest'):
@@ -143,7 +162,7 @@ def testCreatingAProxyFactoryObjectWithAnInterceptorByClassNameInsteadOfInstance
143162
#
144163
# # TODO: There is some issue with running this and the previous test at the same time. It is some type of unforseeable
145164
# # dependency. Each test works fine when the other is commented out. Must resolve.
146-
#
165+
#
147166
# #def testWrappingPyroProxyOnServerSideIoC(self):
148167
# # remoteService = self.appContext.get_object("remoteService2")
149168
# # clientService = self.appContext.get_object("service2")
@@ -154,9 +173,9 @@ def testCreatingAProxyFactoryObjectWithAnInterceptorByClassNameInsteadOfInstance
154173
class AopProxiedArgumentsTest(unittest.TestCase):
155174
def testCallingProxiedMethodWithProxiedPositionalArguments(self):
156175
targetService = SampleService()
157-
176+
158177
service = ProxyFactoryObject(target = targetService, interceptors = WrappingInterceptor())
159-
178+
160179
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method("test"))
161180
self.assertEquals("<Wrapped>Alright!</Wrapped>", service.doSomething())
162181
self.assertEquals("<Wrapped>You made it! => Alright!</Wrapped>",
@@ -167,7 +186,7 @@ def testCallingProxiedMethodWithProxiedPositionalArguments(self):
167186
def testCallingProxiedMethodWithProxiedNamedArguments(self):
168187
targetService = SampleService()
169188
service = ProxyFactoryObject(target = targetService, interceptors = WrappingInterceptor())
170-
189+
171190
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method(data="test"))
172191
self.assertEquals("<Wrapped>Alright!</Wrapped>", service.doSomething())
173192
self.assertEquals("<Wrapped>You made it! => Alright!</Wrapped>",
@@ -179,17 +198,17 @@ def testCallingRegExpProxiedMethodThatHasArgumentsWithProxiedPositionalArguments
179198
pointcutAdvisor = RegexpMethodPointcutAdvisor(advice = WrappingInterceptor(),
180199
patterns = ["SampleService.method"])
181200
service = ProxyFactoryObject(target = SampleService(), interceptors = pointcutAdvisor)
182-
201+
183202
self.assertEquals("Alright!", service.doSomething())
184203
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method("test"))
185204
self.assertEquals("<Wrapped>You made it! => Alright!</Wrapped>",
186205
service.method(service.doSomething()))
187-
206+
188207
def testCallingRegExpProxiedMethodThatHasArgumentsWithProxiedNamedArguments(self):
189208
pointcutAdvisor = RegexpMethodPointcutAdvisor(advice = WrappingInterceptor(),
190209
patterns = ["SampleService.method"])
191210
service = ProxyFactoryObject(target = SampleService(), interceptors = pointcutAdvisor)
192-
211+
193212
self.assertEquals("<Wrapped>You made it! => test</Wrapped>", service.method(data="test"))
194213
self.assertEquals("<Wrapped>You made it! => Alright!</Wrapped>",
195214
service.method(data=service.doSomething()))
@@ -203,7 +222,7 @@ def testCallingRegExpProxiedMethodThatHasNoArgumentsWithProxiedPositionalArgumen
203222
self.assertEquals("You made it! => test", service.method("test"))
204223
self.assertEquals("You made it! => <Wrapped>Alright!</Wrapped>",
205224
service.method(service.doSomething()))
206-
225+
207226
def testCallingRegExpProxiedMethodThatHasNoArgumentsWithProxiedNamedArguments(self):
208227
pointcutAdvisor = RegexpMethodPointcutAdvisor(advice = WrappingInterceptor(),
209228
patterns = ["SampleService.doSomething"])
@@ -219,7 +238,7 @@ def testCallingRegExpProxiedMethodThatHasNoArgumentsWithProxiedNamedArguments(se
219238
logger.setLevel(loggingLevel)
220239
ch = logging.StreamHandler()
221240
ch.setLevel(loggingLevel)
222-
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
241+
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
223242
ch.setFormatter(formatter)
224243
logger.addHandler(ch)
225244

springpython/test/springpythontest/support/aopApplicationContext.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,14 @@
8686
</property>
8787
</object>
8888

89+
<object id="sampleService6" class="springpython.aop.ProxyFactoryObject">
90+
<property name="target">
91+
<value>springpythontest.support.testSupportClasses.SampleService</value>
92+
</property>
93+
<property name="interceptors">
94+
<!-- Note that it isn't wrapped in a list -->
95+
<ref object="wrappingInterceptor"/>
96+
</property>
97+
</object>
98+
8999
</objects>

0 commit comments

Comments
 (0)