View Javadoc

1   /*
2    * Copyright 2007-2008 Naoki NOSE.
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 jp.liq.container.reflect;
17  
18  import java.lang.annotation.Annotation;
19  
20  import jp.liq.container.util.AbstractFinder;
21  import jp.liq.container.util.Matcher;
22  /**
23   * クラスのメンバから指定した条件にマッチしたものを順に返す Iterable の実装です。
24   * @param T 検索するメンバ
25   * @param C メンバを保持するクラスの型
26   * @param S このクラスのサブクラスの型
27   * @author nose
28   */
29  public abstract class MemberFinder<T extends Member,  S extends MemberFinder<T, S>> 
30          extends AbstractFinder<T, S> {
31  
32      /**
33       * このクラスのインスタンスを構築します。
34       */
35      public MemberFinder() {
36      }
37  
38      /**
39       * 指定されたアクセス修飾子を絞込み条件に追加します。
40       * @param i アクセス修飾子。
41       *          java.lang.reflect.Modifier の持つ定数値を指定します。
42       * @return このインスタンス自身
43       */
44      public S withModifier(int i) {
45          addMatcher(new ModifierMatcher<T>(i));
46          return getThis();
47      }
48  
49      /**
50       * 指定されたアノテーションを絞込み条件に追加します。
51       * @param ann アノテーションのクラス 
52       * @return このインスタンス自身
53       */
54      public S withAnnotation(Class<? extends Annotation> ann) {
55          addMatcher(new AnnotationMatcher<T>(ann));
56          return getThis();
57      }
58      /**
59       * 指定されたプリフィックスを絞込み条件に追加します。
60       * @param prefix メンバの名前のプリフィックス
61       * @return このインスタンス自身
62       */
63      public S withPrefix(String prefix) {
64          addMatcher(new PrefixMatcher<T>(prefix));
65          return getThis();
66      }
67  
68      private class ModifierMatcher<M extends Member> implements Matcher<M> {
69          private final int modifier;
70          ModifierMatcher(int modifier) {
71              this.modifier = modifier;
72          }
73  
74          public boolean matches(M m) {
75              return m.hasModifier(modifier);
76          }
77          
78      }
79      
80      private class AnnotationMatcher<M extends Member> implements Matcher<M> {
81          private final Class<? extends Annotation> annotationClass;
82  
83          AnnotationMatcher(Class<? extends Annotation> ann) {
84              annotationClass = ann;
85          }
86  
87          public boolean matches(M m) {
88              return m.isAnnotationPresent(annotationClass);
89          }
90          
91      }
92  
93      private class PrefixMatcher<M extends Member> implements Matcher<M> {
94          private final String prefix;
95          PrefixMatcher(String prefix) {
96              this.prefix = prefix;
97          }
98          public boolean matches(M m) {
99              return m.name().startsWith(prefix);
100         }
101         
102     }
103 
104 }