View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
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,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.plugins.s2.spi;
17  
18  import java.lang.reflect.Modifier;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.seasar.cubby.plugins.s2.detector.ClassDetector;
23  import org.seasar.cubby.plugins.s2.detector.DetectClassProcessor;
24  import org.seasar.cubby.routing.PathResolver;
25  import org.seasar.cubby.spi.PathResolverProvider;
26  import org.seasar.cubby.util.ActionUtils;
27  import org.seasar.framework.convention.NamingConvention;
28  import org.seasar.framework.util.ClassUtil;
29  import org.seasar.framework.util.Disposable;
30  import org.seasar.framework.util.DisposableUtil;
31  
32  /**
33   * クラスパスを走査しアクションクラスを登録します。
34   * 
35   * @author baba
36   * @since 2.0.0
37   */
38  public class S2PathResolverProvider implements PathResolverProvider,
39  		DetectClassProcessor, Disposable {
40  
41  	public static final String pathResolver_BINDING = "bindingType=must";
42  
43  	public static final String namingConvention_BINDING = "bindingType=must";
44  
45  	public static final String classDetector_BINDING = "bindingType=must";
46  
47  	/** パスに対応するアクションメソッドを解決するためのクラス。 */
48  	private PathResolver pathResolver;
49  
50  	/** 命名規約。 */
51  	private NamingConvention namingConvention;
52  
53  	/** クラスパスを走査してクラスを検出するクラス。 */
54  	public ClassDetector classDetector;
55  
56  	/** インスタンスが初期化済みであることを示します。 */
57  	private boolean initialized;
58  
59  	/** アクションクラスのリスト。 */
60  	private final List<Class<?>> actionClasses = new ArrayList<Class<?>>();
61  
62  	/**
63  	 * パスに対応するアクションメソッドを解決するためのクラスを設定します。
64  	 * 
65  	 * @param pathResolver
66  	 *            パスに対応するアクションメソッドを解決するためのクラス
67  	 * 
68  	 */
69  	public void setPathResolver(final PathResolver pathResolver) {
70  		this.pathResolver = pathResolver;
71  	}
72  
73  	/**
74  	 * クラスパスを走査してクラスを検出するクラスを設定します。
75  	 * 
76  	 * @param classDetector
77  	 *            クラスパスを走査してクラスを検出するクラス
78  	 */
79  	public void setClassDetector(final ClassDetector classDetector) {
80  		this.classDetector = classDetector;
81  	}
82  
83  	/**
84  	 * 命名規約を設定します。
85  	 * 
86  	 * @param namingConvention
87  	 *            命名規約
88  	 */
89  	public void setNamingConvention(final NamingConvention namingConvention) {
90  		this.namingConvention = namingConvention;
91  	}
92  
93  	/**
94  	 * 初期化します。
95  	 */
96  	public void initialize() {
97  		if (initialized) {
98  			return;
99  		}
100 		classDetector.detect();
101 		pathResolver.addAll(actionClasses);
102 
103 		DisposableUtil.add(this);
104 		initialized = true;
105 	}
106 
107 	/**
108 	 * {@inheritDoc}
109 	 */
110 	public void dispose() {
111 		actionClasses.clear();
112 		pathResolver.clear();
113 		initialized = false;
114 	}
115 
116 	/**
117 	 * {@inheritDoc}
118 	 * <p>
119 	 * 指定されたパッケージ名、クラス名から導出されるクラスがアクションクラスだった場合はルーティングを登録します。
120 	 * </p>
121 	 */
122 	public void processClass(final String packageName,
123 			final String shortClassName) {
124 		if (shortClassName.indexOf('$') != -1) {
125 			return;
126 		}
127 		final String className = ClassUtil.concatName(packageName,
128 				shortClassName);
129 		if (!namingConvention.isTargetClassName(className)) {
130 			return;
131 		}
132 		if (!className.endsWith(namingConvention.getActionSuffix())) {
133 			return;
134 		}
135 		final Class<?> clazz = ClassUtil.forName(className);
136 		if (namingConvention.isSkipClass(clazz)) {
137 			return;
138 		}
139 		if (Modifier.isAbstract(clazz.getModifiers())) {
140 			return;
141 		}
142 		if (!ActionUtils.isActionClass(clazz)) {
143 			return;
144 		}
145 		actionClasses.add(clazz);
146 	}
147 
148 	/**
149 	 * {@inheritDoc}
150 	 */
151 	public PathResolver getPathResolver() {
152 		initialize();
153 		return pathResolver;
154 	}
155 
156 }