View Javadoc

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 }