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 java.util.List;
19  
20  import org.eclipse.jface.action.MenuManager;
21  import org.eclipse.swt.graphics.Font;
22  import org.eclipse.swt.widgets.Control;
23  import org.eclipse.swt.widgets.Menu;
24  import org.seasar.framework.beans.BeanDesc;
25  import org.seasar.framework.beans.PropertyDesc;
26  import org.seasar.framework.beans.factory.BeanDescFactory;
27  import org.seasar.framework.util.StringUtil;
28  import org.seasar.uruma.annotation.RenderingPolicy;
29  import org.seasar.uruma.component.CommonAttributes;
30  import org.seasar.uruma.component.LayoutDataInfo;
31  import org.seasar.uruma.component.LayoutInfo;
32  import org.seasar.uruma.component.UIComponent;
33  import org.seasar.uruma.component.UICompositeComponent;
34  import org.seasar.uruma.component.UIControlComponent;
35  import org.seasar.uruma.component.jface.ControlComponent;
36  import org.seasar.uruma.component.jface.MenuComponent;
37  import org.seasar.uruma.context.WidgetHandle;
38  import org.seasar.uruma.core.UrumaMessageCodes;
39  import org.seasar.uruma.exception.NotFoundException;
40  import org.seasar.uruma.exception.RenderException;
41  import org.seasar.uruma.renderer.RendererSupportUtil;
42  import org.seasar.uruma.renderer.layout.LayoutSupport;
43  import org.seasar.uruma.renderer.layout.LayoutSupportFactory;
44  import org.seasar.uruma.util.AnnotationUtil;
45  
46  /**
47   * {@link Control} のレンダリングを行うための基底クラスです。<br />
48   * 
49   * @param <COMPONENT_TYPE>
50   *            レンダラに対応するコンポーネントの型
51   * @param <CONTROL_TYPE>
52   *            レンダラが生成するコントロールの型
53   * @author y-komori
54   */
55  public abstract class AbstractControlRenderer<COMPONENT_TYPE extends ControlComponent, CONTROL_TYPE extends Control>
56          extends AbstractWidgetRenderer<COMPONENT_TYPE, CONTROL_TYPE> {
57  
58      /*
59       * @see org.seasar.uruma.renderer.impl.AbstractWidgetRenderer#inherit(org.seasar.uruma.component.UIComponent)
60       */
61      @Override
62      protected void inherit(final COMPONENT_TYPE uiComponent) {
63          // 親コンポーネントの持つ共通属性を設定する
64          setCommonAttributes(uiComponent);
65  
66          // レイアウトデータの一括指定
67          inheritLayoutData(uiComponent);
68      }
69  
70      /*
71       * @see org.seasar.uruma.renderer.impl.AbstractWidgetRenderer#doRender(org.seasar.uruma.component.UIComponent,
72       *      java.lang.Object)
73       */
74      @Override
75      public final void doRender(final COMPONENT_TYPE uiComponent,
76              final CONTROL_TYPE control) {
77          ControlComponent controlComponent = uiComponent;
78  
79          setLayoutData(controlComponent, control);
80          setLocation(controlComponent, control);
81          setSize(controlComponent, control);
82          setFont(controlComponent, control);
83          setMenu(controlComponent, control);
84  
85          doRenderControl(uiComponent, control);
86      }
87  
88      /**
89       * 生成したコントロールに対するレンダリングを行います。<br />
90       * コントロールに対する独自のレンダリング処理を追加したい場合、サブクラスでオーバーライドしてください。<br />
91       * 
92       * @param controlComponent
93       *            {@link UIComponent} オブジェクト
94       * @param control
95       *            生成した {@link Control} オブジェクト
96       */
97      protected abstract void doRenderControl(COMPONENT_TYPE controlComponent,
98              CONTROL_TYPE control);
99  
100     protected void setLocation(final ControlComponent controlComponent,
101             final Control control) {
102         if ((controlComponent.x != null) && (controlComponent.y != null)) {
103             int x = Integer.parseInt(controlComponent.x);
104             int y = Integer.parseInt(controlComponent.y);
105             control.setLocation(x, y);
106         }
107     }
108 
109     protected void setSize(final ControlComponent controlComponent,
110             final Control control) {
111         if ((controlComponent.width != null)
112                 && (controlComponent.height != null)) {
113             int width = Integer.parseInt(controlComponent.width);
114             int height = Integer.parseInt(controlComponent.height);
115             control.setSize(width, height);
116         }
117     }
118 
119     protected void setFont(final ControlComponent controlComponent,
120             final Control control) {
121         if (controlComponent.fontName == null
122                 && controlComponent.fontStyle == null
123                 && controlComponent.fontHeight == null) {
124             return;
125         }
126         Font font = RendererSupportUtil.getFont(control.getFont(),
127                 controlComponent.fontName, controlComponent.fontStyle,
128                 controlComponent.fontHeight);
129         control.setFont(font);
130     }
131 
132     protected void setMenu(final ControlComponent controlComponent,
133             final Control control) {
134         String menuId = controlComponent.menu;
135         if (!StringUtil.isEmpty(menuId)) {
136             WidgetHandle handle = getWindowContext().getWidgetHandle(menuId);
137             if (handle != null) {
138                 if (handle.instanceOf(MenuManager.class)) {
139                     MenuManager manager = handle.<MenuManager> getCastWidget();
140                     Menu menu = manager.createContextMenu(control);
141                     MenuComponent menuComponent = (MenuComponent) handle
142                             .getUiComponent();
143                     MenuManagerRenderer renderer = (MenuManagerRenderer) menuComponent
144                             .getRenderer();
145                     renderer.renderMenu(menuComponent, menu);
146 
147                     control.setMenu(menu);
148                 } else {
149                     throw new RenderException(
150                             UrumaMessageCodes.UNSUPPORTED_TYPE_ERROR, menuId,
151                             MenuManager.class.getName());
152                 }
153             } else {
154                 throw new NotFoundException(
155                         UrumaMessageCodes.UICOMPONENT_NOT_FOUND, menuId);
156             }
157         }
158     }
159 
160     @SuppressWarnings("unchecked")
161     protected void setLayoutData(final UIControlComponent uiComponent,
162             final Control control) {
163         UIComponent parent = uiComponent.getParent();
164         if (parent == null) {
165             return;
166         }
167 
168         if (!(parent instanceof UICompositeComponent)) {
169             return;
170         }
171 
172         LayoutInfo<?> layoutInfo = ((UICompositeComponent) parent)
173                 .getLayoutInfo();
174         if (layoutInfo == null) {
175             return;
176         }
177 
178         LayoutSupport support = LayoutSupportFactory
179                 .getLayoutSupport((Class<? extends LayoutInfo<?>>) layoutInfo
180                         .getClass());
181         LayoutDataInfo layoutDataInfo = uiComponent.getLayoutDataInfo();
182         if ((support != null) && (layoutDataInfo != null)) {
183             Object layoutData = support.createLayoutData(uiComponent,
184                     layoutDataInfo);
185             if (layoutData != null) {
186                 control.setLayoutData(layoutData);
187             }
188         }
189     }
190 
191     protected ControlComponent getParentComponent(
192             final ControlComponent component) {
193         UIComponent parentUI = component.getParent();
194         if (parentUI != null && parentUI instanceof ControlComponent) {
195             return (ControlComponent) parentUI;
196         } else {
197             return null;
198         }
199     }
200 
201     protected void setCommonAttributes(final UIComponent uiComponent) {
202         UIComponent parent = uiComponent.getParent();
203         if (parent == null) {
204             return;
205         }
206 
207         if (!(parent instanceof UICompositeComponent)) {
208             return;
209         }
210 
211         CommonAttributes commonAttributes = ((UICompositeComponent) parent)
212                 .getCommonAttributes();
213         if (commonAttributes == null) {
214             return;
215         }
216 
217         BeanDesc commonDesc = BeanDescFactory.getBeanDesc(commonAttributes
218                 .getClass());
219         BeanDesc uiDesc = BeanDescFactory.getBeanDesc(uiComponent.getClass());
220         int size = commonDesc.getPropertyDescSize();
221         for (int i = 0; i < size; i++) {
222             PropertyDesc commonPd = commonDesc.getPropertyDesc(i);
223             PropertyDesc uiPd = uiDesc.getPropertyDesc(commonPd
224                     .getPropertyName());
225             // 未設定の属性のみ設定する
226             if (uiPd.getValue(uiComponent) == null) {
227                 uiPd.setValue(uiComponent, commonPd.getValue(commonAttributes));
228             }
229         }
230     }
231 
232     protected void inheritLayoutData(final UIControlComponent uiComponent) {
233         LayoutDataInfo parentLayoutDataInfo = getParentLayoutDataInfo(uiComponent);
234 
235         // 親が一括指定すべきレイアウトデータを持っていない場合は何もしない
236         if (parentLayoutDataInfo == null) {
237             return;
238         }
239 
240         LayoutDataInfo layoutDataInfo = uiComponent.getLayoutDataInfo();
241         if (layoutDataInfo == null) {
242             // LayoutDataInfo が未設定の場合はそのまま設定する
243             uiComponent.setLayoutDataInfo(parentLayoutDataInfo);
244         } else {
245             // 既に設定されている場合は未設定の属性のみ設定する
246             BeanDesc parentDesc = BeanDescFactory
247                     .getBeanDesc(parentLayoutDataInfo.getClass());
248             List<PropertyDesc> pdList = AnnotationUtil
249                     .getAnnotatedPropertyDescs(layoutDataInfo.getClass(),
250                             RenderingPolicy.class);
251 
252             for (PropertyDesc pd : pdList) {
253                 if (pd.getValue(layoutDataInfo) == null) {
254                     PropertyDesc parentPd = parentDesc.getPropertyDesc(pd
255                             .getPropertyName());
256                     pd.setValue(layoutDataInfo, parentPd
257                             .getValue(parentLayoutDataInfo));
258                 }
259             }
260         }
261     }
262 
263     protected LayoutDataInfo getParentLayoutDataInfo(
264             final UIComponent uiComponent) {
265         UIComponent parent = uiComponent.getParent();
266         if (parent == null) {
267             return null;
268         }
269 
270         if (!(parent instanceof UICompositeComponent)) {
271             return null;
272         }
273 
274         LayoutInfo<?> layoutInfo = ((UICompositeComponent) parent)
275                 .getLayoutInfo();
276         if (layoutInfo != null) {
277             return layoutInfo.getCommonLayoutDataInfo();
278         }
279         return null;
280     }
281 }