1 | /* |
2 | * Copyright 2006-2007 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 | package org.springframework.batch.classify; |
17 | |
18 | import org.springframework.batch.support.MethodInvoker; |
19 | import org.springframework.batch.support.MethodInvokerUtils; |
20 | import org.springframework.util.Assert; |
21 | |
22 | /** |
23 | * Wrapper for an object to adapt it to the {@link Classifier} interface. |
24 | * |
25 | * @author Dave Syer |
26 | * |
27 | */ |
28 | public class ClassifierAdapter<C, T> implements Classifier<C, T> { |
29 | |
30 | private MethodInvoker invoker; |
31 | |
32 | private Classifier<C, T> classifier; |
33 | |
34 | /** |
35 | * Default constructor for use with setter injection. |
36 | */ |
37 | public ClassifierAdapter() { |
38 | super(); |
39 | } |
40 | |
41 | /** |
42 | * Create a new {@link Classifier} from the delegate provided. Use the |
43 | * constructor as an alternative to the {@link #setDelegate(Object)} method. |
44 | * |
45 | * @param delegate |
46 | */ |
47 | public ClassifierAdapter(Object delegate) { |
48 | setDelegate(delegate); |
49 | } |
50 | |
51 | /** |
52 | * Create a new {@link Classifier} from the delegate provided. Use the |
53 | * constructor as an alternative to the {@link #setDelegate(Classifier)} |
54 | * method. |
55 | * |
56 | * @param delegate |
57 | */ |
58 | public ClassifierAdapter(Classifier<C, T> delegate) { |
59 | classifier = delegate; |
60 | } |
61 | |
62 | public void setDelegate(Classifier<C, T> delegate) { |
63 | classifier = delegate; |
64 | invoker = null; |
65 | } |
66 | |
67 | /** |
68 | * Search for the |
69 | * {@link org.springframework.batch.support.annotation.Classifier |
70 | * Classifier} annotation on a method in the supplied delegate and use that |
71 | * to create a {@link Classifier} from the parameter type to the return |
72 | * type. If the annotation is not found a unique non-void method with a |
73 | * single parameter will be used, if it exists. The signature of the method |
74 | * cannot be checked here, so might be a runtime exception when the method |
75 | * is invoked if the signature doesn't match the classifier types. |
76 | * |
77 | * @param delegate an object with an annotated method |
78 | */ |
79 | public final void setDelegate(Object delegate) { |
80 | classifier = null; |
81 | invoker = MethodInvokerUtils.getMethodInvokerByAnnotation( |
82 | org.springframework.batch.support.annotation.Classifier.class, delegate); |
83 | if (invoker == null) { |
84 | invoker = MethodInvokerUtils.<C, T> getMethodInvokerForSingleArgument(delegate); |
85 | } |
86 | Assert.state(invoker != null, "No single argument public method with or without " |
87 | + "@Classifier was found in delegate of type " + delegate.getClass()); |
88 | } |
89 | |
90 | /** |
91 | * {@inheritDoc} |
92 | */ |
93 | @SuppressWarnings("unchecked") |
94 | public T classify(C classifiable) { |
95 | if (classifier != null) { |
96 | return classifier.classify(classifiable); |
97 | } |
98 | return (T) invoker.invokeMethod(classifiable); |
99 | } |
100 | |
101 | } |