1
+ /*
2
+ * Copyright 2002-2010 the original author or authors.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package org .springframework .conversation .annotation ;
18
+
19
+ import java .lang .reflect .Method ;
20
+ import java .util .Collections ;
21
+ import java .util .LinkedHashSet ;
22
+ import java .util .Set ;
23
+
24
+ import org .springframework .aop .support .AopUtils ;
25
+ import org .springframework .conversation .interceptor .ConversationAttribute ;
26
+ import org .springframework .conversation .interceptor .ConversationAttributeSource ;
27
+ import org .springframework .util .Assert ;
28
+
29
+ /**
30
+ * ConversationAttributeSource implementation that uses annotation meta-data to provide a ConversationAttribute instance
31
+ * for a particular method.
32
+ *
33
+ * @author Agim Emruli
34
+ */
35
+ public class AnnotationConversationAttributeSource implements ConversationAttributeSource {
36
+
37
+ private final Set <ConversationAnnotationParser > conversationAnnotationParsers ;
38
+
39
+ /**
40
+ * Default constructor that uses the Spring standard ConversationAnnotationParser instances to parse the annotation
41
+ * meta-data.
42
+ *
43
+ * @see org.springframework.conversation.annotation.BeginConversationAnnotationParser
44
+ * @see org.springframework.conversation.annotation.EndConversationAnnotationParser
45
+ * @see org.springframework.conversation.annotation.ConversationAnnotationParser
46
+ */
47
+ public AnnotationConversationAttributeSource () {
48
+ Set <ConversationAnnotationParser > defaultParsers = new LinkedHashSet <ConversationAnnotationParser >();
49
+ Collections
50
+ .addAll (defaultParsers , new BeginConversationAnnotationParser (), new EndConversationAnnotationParser (),
51
+ new ConversationalAnnotationParser ());
52
+ conversationAnnotationParsers = defaultParsers ;
53
+ }
54
+
55
+ /**
56
+ * Constructor that uses the custom ConversationAnnotationParser to parse the annotation meta-data.
57
+ *
58
+ * @param conversationAnnotationParsers The ConversationAnnotationParser instance that will be used to parse annotation
59
+ * meta-data
60
+ */
61
+ public AnnotationConversationAttributeSource (ConversationAnnotationParser conversationAnnotationParsers ) {
62
+ this (Collections .singleton (conversationAnnotationParsers ));
63
+ }
64
+
65
+ /**
66
+ * Constructor that uses a pre-built set with annotation parsers to retrieve the conversation meta-data. It is up to
67
+ * the caller to provide a sorted set of annotation parsers if the order of them is important.
68
+ *
69
+ * @param parsers The Set of annotation parsers used to retrieve conversation meta-data.
70
+ */
71
+ public AnnotationConversationAttributeSource (Set <ConversationAnnotationParser > parsers ) {
72
+ Assert .notNull (parsers , "ConversationAnnotationParsers must not be null" );
73
+ conversationAnnotationParsers = parsers ;
74
+ }
75
+
76
+ /**
77
+ * Resolves the conversation meta-data by delegating to the ConversationAnnotationParser instances. This implementation
78
+ * returns the first ConversationAttribute instance that will be returned by a ConversationAnnotationParser. This
79
+ * method returns null if no ConversationAnnotationParser returns a non-null result.
80
+ *
81
+ * The implementation searches for the most specific method (e.g. if there is a interface method this methods searches
82
+ * for the implementation method) before calling the underlying ConversationAnnotationParser instances. If there is no
83
+ * Annotation available on the implementation method, this methods falls back to the interface method.
84
+ *
85
+ * @param method The method for which the ConversationAttribute should be returned.
86
+ * @param targetClass The target class where the implementation should look for.
87
+ */
88
+ public ConversationAttribute getConversationAttribute (Method method , Class <?> targetClass ) {
89
+ Method specificMethod = AopUtils .getMostSpecificMethod (method , targetClass );
90
+
91
+ for (ConversationAnnotationParser parser : conversationAnnotationParsers ) {
92
+ ConversationAttribute attribute = parser .parseConversationAnnotation (specificMethod );
93
+ if (attribute != null ) {
94
+ return attribute ;
95
+ }
96
+
97
+ if (method != specificMethod ){
98
+ attribute = parser .parseConversationAnnotation (method );
99
+ if (attribute != null ){
100
+ return attribute ;
101
+ }
102
+ }
103
+ }
104
+ return null ;
105
+ }
106
+ }
0 commit comments