1 /*
2 * Copyright 2004-2008 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.uruma.renderer.impl;
17
18 import org.eclipse.jface.viewers.ContentViewer;
19 import org.eclipse.jface.viewers.IBaseLabelProvider;
20 import org.eclipse.jface.viewers.IContentProvider;
21 import org.eclipse.jface.viewers.StructuredViewer;
22 import org.eclipse.jface.viewers.Viewer;
23 import org.eclipse.jface.viewers.ViewerComparator;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.swt.widgets.Control;
26 import org.seasar.framework.util.StringUtil;
27 import org.seasar.uruma.component.UIComponent;
28 import org.seasar.uruma.component.UICompositeComponent;
29 import org.seasar.uruma.component.jface.CompositeComponent;
30 import org.seasar.uruma.context.PartContext;
31 import org.seasar.uruma.context.WidgetHandle;
32 import org.seasar.uruma.core.ComponentUtil;
33 import org.seasar.uruma.core.UrumaMessageCodes;
34 import org.seasar.uruma.log.UrumaLogger;
35 import org.seasar.uruma.util.ClassUtil;
36 import org.seasar.uruma.viewer.GenericContentProvider;
37 import org.seasar.uruma.viewer.PojoLabelProvider;
38
39 /**
40 * {@link Viewer} のレンダリングを行うための基底クラスです。<br />
41 *
42 * @param <COMPONENT_TYPE>
43 * レンダラに対応するコンポーネントの実際の型
44 * @param <VIEWER_TYPE>
45 * レンダラが生成するビューアの実際の型
46 * @param <CONTROL_TYPE>
47 * ビューアが内包する {@link Control} オブジェクトの実際の型
48 * @author y-komori
49 */
50 public abstract class AbstractViewerRenderer<COMPONENT_TYPE extends CompositeComponent, VIEWER_TYPE extends Viewer, CONTROL_TYPE extends Control>
51 extends AbstractControlRenderer<COMPONENT_TYPE, CONTROL_TYPE> {
52 private UrumaLogger logger = UrumaLogger.getLogger(getClass());
53
54 /*
55 * @see org.seasar.uruma.renderer.Renderer#render(org.seasar.uruma.component.UIComponent,
56 * org.seasar.uruma.context.WidgetHandle,
57 * org.seasar.uruma.context.PartContext)
58 */
59 @Override
60 @SuppressWarnings("unchecked")
61 public WidgetHandle render(final UIComponent uiComponent,
62 final WidgetHandle parent, final PartContext context) {
63 if (!canCreateViewer(UICompositeComponent.class.cast(uiComponent))) {
64 // ビューアを生成しない場合の処理
65 return super.render(uiComponent, parent, context);
66 }
67
68 setContext(context);
69
70 inherit((COMPONENT_TYPE) uiComponent);
71
72 VIEWER_TYPE viewer = createViewer(parent.<Composite> getCastWidget(),
73 getStyle(uiComponent));
74
75 // ビューアに内包されるウィジットのレンダリングを行う
76 renderWidget((COMPONENT_TYPE) uiComponent, (CONTROL_TYPE) viewer
77 .getControl());
78
79 String id = uiComponent.getId();
80 if (viewer instanceof ContentViewer) {
81 ComponentUtil.setupContentProvider((ContentViewer) viewer, id,
82 getDefaultContentProvider());
83 }
84
85 if (viewer instanceof StructuredViewer) {
86 ComponentUtil.setupLabelProvider((StructuredViewer) viewer, id,
87 getDefaultLabelProvider(), getLabelProviderClass(),
88 getPojoLabelProviderClass());
89 }
90
91 doRenderViewer((COMPONENT_TYPE) uiComponent, viewer);
92
93 WidgetHandle viewerHandle = createWidgetHandle(uiComponent, viewer);
94 if (!StringUtil.isEmpty(id)) {
95 viewerHandle.setId(id);
96 }
97
98 return viewerHandle;
99 }
100
101 /*
102 * @see org.seasar.uruma.renderer.Renderer#renderAfter(org.seasar.uruma.context.WidgetHandle,
103 * org.seasar.uruma.component.UIComponent,
104 * org.seasar.uruma.context.WidgetHandle,
105 * org.seasar.uruma.context.PartContext)
106 */
107 @Override
108 @SuppressWarnings("unchecked")
109 public void renderAfter(final WidgetHandle handle,
110 final UIComponent uiComponent, final WidgetHandle parent,
111 final PartContext context) {
112
113 if (handle.instanceOf(Viewer.class)) {
114 VIEWER_TYPE viewer = getViewerType().cast(handle.getWidget());
115 WidgetHandle controlHandle = createWidgetHandle(uiComponent, viewer
116 .getControl());
117
118 super.renderAfter(controlHandle, uiComponent, parent, context);
119
120 doRenderAfter(viewer, (COMPONENT_TYPE) uiComponent, parent, context);
121
122 if (viewer instanceof StructuredViewer) {
123 ComponentUtil.setupComparator((StructuredViewer) viewer,
124 uiComponent.getId(), getDefaultComparator());
125 }
126 } else {
127 super.renderAfter(handle, uiComponent, parent, context);
128 }
129 }
130
131 /*
132 * @see org.seasar.uruma.renderer.impl.AbstractControlRenderer#doRenderControl(org.seasar.uruma.component.jface.ControlComponent,
133 * org.eclipse.swt.widgets.Control)
134 */
135 @Override
136 protected void doRenderControl(final COMPONENT_TYPE controlComponent,
137 final CONTROL_TYPE control) {
138 // Do nothing.
139 }
140
141 /**
142 * ビューアを生成します。<br />
143 * ビューアの生成を独自に行いたい場合、サブクラスで本メソッドをオーバーライドしてください。<br />
144 *
145 * @param parent
146 * 親 {@link Composite}
147 * @param style
148 * スタイル
149 * @return 生成したビューアのインタンス
150 */
151 protected VIEWER_TYPE createViewer(final Composite parent, final int style) {
152 VIEWER_TYPE viewer = ClassUtil.<VIEWER_TYPE> newInstance(
153 getViewerType(), parent, style);
154
155 if (logger.isTraceEnabled()) {
156 logger.log(UrumaMessageCodes.WIDGET_CREATED, UrumaLogger
157 .getObjectDescription(viewer));
158 }
159
160 return viewer;
161 }
162
163 /**
164 * デフォルトの {@link IContentProvider} を返します。<br />
165 * ユーザ指定の {@link IContentProvider} が S2Container
166 * 上に登録されていない場合に使用する、デフォルトのコンテントプロバイダを返します。<br />
167 * デフォルトでは、 {@link GenericContentProvider} を返します。<br />
168 * デフォルトのコンテントプロバイダを変更したい場合、本メソッドをオーバーライドしてください。<br />
169 *
170 * @return デフォルトの {@link IContentProvider}
171 */
172 protected IContentProvider getDefaultContentProvider() {
173 return new GenericContentProvider();
174 }
175
176 /**
177 * デフォルトの {@link IBaseLabelProvider} を返します。<br />
178 * ユーザ指定の {@link IBaseLabelProvider} が S2Container
179 * 上に登録されていない場合に使用する、デフォルトのラベルプロバイダを返します。<br />
180 * デフォルトでは、 <code>null</code> (ラベルプロバイダを使用しない) を返します。<br />
181 * デフォルトのラベルプロバイダを変更したい場合、本メソッドをオーバーライドしてください。<br />
182 *
183 * @return デフォルトの {@link IBaseLabelProvider}
184 */
185 protected IBaseLabelProvider getDefaultLabelProvider() {
186 return null;
187 }
188
189 /**
190 * ラベルプロバイダとして使用すべきクラスを返します。<br />
191 * S2Container 上でラベルプロバイダを検索する際、本メソッドの戻り値で示される型のインスタンスであるかどうかをチェックします。<br />
192 * デフォルトでは、 {@link IBaseLabelProvider} の {@link Class} オブジェクトを返します。<br />
193 * ラベルプロバイダのクラスをさらに絞りたい場合、本メソッドをオーバーライドしてください。<br />
194 *
195 * @return ラベルプロバイダとして使用すべきクラス
196 */
197 protected Class<? extends IBaseLabelProvider> getLabelProviderClass() {
198 return IBaseLabelProvider.class;
199 }
200
201 /**
202 * POJO をラベルプロバイダとして利用する場合のアダプタクラスを返します。<br />
203 * デフォルトでは <code>null</code>
204 * を返しますので、必要に応じてサブクラスでオーバーライドして、適切なクラスオブジェクトを返してください。
205 *
206 * @return {@link PojoLabelProvider} のクラス
207 */
208 protected Class<? extends PojoLabelProvider> getPojoLabelProviderClass() {
209 return null;
210 }
211
212 /**
213 * デフォルトの {@link ViewerComparator} を返します。<br />
214 * ユーザ指定の {@link ViewerComparator} が S2Container
215 * 上に登録されていない場合に使用する、デフォルトのソータを返します。<br />
216 * デフォルトのコンパレータを変更したい場合、本メソッドをオーバーライドしてください。<br />
217 * デフォルトでは <code>null</code> (ソートしない) を返します。<br />
218 *
219 * @return デフォルトの {@link ViewerComparator}}
220 */
221 protected ViewerComparator getDefaultComparator() {
222 return null;
223 }
224
225 /**
226 * 生成するビューアの型を返します。<br />
227 * ビューアのインスタンス生成は本クラスで実施するので、サブクラスで本メソッドを実装してビューアの型のみを返してください。
228 *
229 * @return 生成するビューアの型
230 */
231 protected abstract Class<VIEWER_TYPE> getViewerType();
232
233 /**
234 * ビューアを生成するかどうかを判定します。<br />
235 * ビューアの生成を制御したい場合、サブクラスでオーバーライドしてください。<br />
236 * デフォルトでは <code>true</code> を返します。<br />
237 *
238 * @param component
239 * 対応する {@link UICompositeComponent}
240 * @return 生成する場合は <code>true</code>。しない場合は <code>false</code>
241 */
242 protected boolean canCreateViewer(final UICompositeComponent component) {
243 return true;
244 }
245
246 /**
247 * 生成されたビューアに対して各種属性を設定します。<br />
248 * 必要な場合は本メソッドをオーバーライドして、<code>uiComponent</code> の保持する属性を
249 * <code>viewer</code> に対して設定してください。<br />
250 * デフォルトの実装では何も行いません。<br />
251 *
252 * @param uiComponent
253 * {@link UIComponent} オブジェクト
254 * @param viewer
255 * 生成されたビューア
256 */
257 protected void doRenderViewer(final COMPONENT_TYPE uiComponent,
258 final VIEWER_TYPE viewer) {
259 // Do nothing.
260 }
261
262 /**
263 * 子のレンダリング終了後にレンダリング処理を行います。<br />
264 * 子のレンダリング終了後にレンダリング処理を行う場合、本メソッドをオーバーライドしてレンダリング処理を実装してください。<br />
265 * デフォルトでは何も行いません。<br />
266 *
267 * @param viewer
268 * レンダリング対象ビューア
269 * @param uiComponent
270 * レンダリング対象の {@link UIComponent} オブジェクト
271 * @param parent
272 * 親のウィジットハンドル
273 * @param context
274 * {@link PartContext} オブジェクト
275 */
276 protected void doRenderAfter(final VIEWER_TYPE viewer,
277 final COMPONENT_TYPE uiComponent, final WidgetHandle parent,
278 final PartContext context) {
279 // do nothing.
280 }
281 }