Coverage Report - org.seasar.uruma.ui.UrumaApplicationWindow
 
Classes in this File Line Coverage Branch Coverage Complexity
UrumaApplicationWindow
88%
82/93
58%
22/38
0
 
 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.ui;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.List;
 20  
 
 21  
 import org.eclipse.jface.action.MenuManager;
 22  
 import org.eclipse.jface.window.ApplicationWindow;
 23  
 import org.eclipse.swt.SWT;
 24  
 import org.eclipse.swt.widgets.Composite;
 25  
 import org.eclipse.swt.widgets.Control;
 26  
 import org.eclipse.swt.widgets.Display;
 27  
 import org.eclipse.swt.widgets.Shell;
 28  
 import org.seasar.framework.container.annotation.tiger.AutoBindingType;
 29  
 import org.seasar.framework.container.annotation.tiger.Component;
 30  
 import org.seasar.framework.util.StringUtil;
 31  
 import org.seasar.uruma.binding.context.ApplicationContextBinder;
 32  
 import org.seasar.uruma.binding.enables.EnablesDependingListenerSupport;
 33  
 import org.seasar.uruma.binding.method.MethodBindingSupport;
 34  
 import org.seasar.uruma.binding.method.WindowCloseListener;
 35  
 import org.seasar.uruma.binding.value.ValueBindingSupport;
 36  
 import org.seasar.uruma.component.Template;
 37  
 import org.seasar.uruma.component.jface.WindowComponent;
 38  
 import org.seasar.uruma.context.ApplicationContext;
 39  
 import org.seasar.uruma.context.ContextFactory;
 40  
 import org.seasar.uruma.context.PartContext;
 41  
 import org.seasar.uruma.context.WidgetHandle;
 42  
 import org.seasar.uruma.context.WindowContext;
 43  
 import org.seasar.uruma.core.ComponentUtil;
 44  
 import org.seasar.uruma.core.UrumaConstants;
 45  
 import org.seasar.uruma.core.UrumaMessageCodes;
 46  
 import org.seasar.uruma.core.UrumaWindowManager;
 47  
 import org.seasar.uruma.desc.PartActionDesc;
 48  
 import org.seasar.uruma.desc.PartActionDescFactory;
 49  
 import org.seasar.uruma.exception.NotFoundException;
 50  
 import org.seasar.uruma.exception.RenderException;
 51  
 import org.seasar.uruma.renderer.impl.WindowRenderer;
 52  
 import org.seasar.uruma.util.AssertionUtil;
 53  
 
 54  
 /**
 55  
  * {@link Template} オブジェクトを元にして画面描画を行う、{@link ApplicationWindow} です。
 56  
  * 
 57  
  * @author y-komori
 58  
  */
 59  
 @Component(autoBinding = AutoBindingType.NONE)
 60  
 public class UrumaApplicationWindow extends ApplicationWindow implements
 61  
         UrumaConstants, UrumaMessageCodes {
 62  
     private UrumaWindowManager windowManager;
 63  
 
 64  
     private WindowComponent windowComponent;
 65  
 
 66  
     private WindowContext windowContext;
 67  
 
 68  
     private PartContext partContext;
 69  
 
 70  
     private PartActionDesc desc;
 71  
 
 72  
     private Object partActionComponent;
 73  
 
 74  
     private List<WindowCloseListener> closeListeners;
 75  
 
 76  
     private boolean block;
 77  
 
 78  
     /**
 79  
      * {@link UrumaApplicationWindow} を構築します。<br />
 80  
      */
 81  
     public UrumaApplicationWindow(final UrumaWindowManager manager) {
 82  112
         super(null);
 83  112
         AssertionUtil.assertNotNull("manager", manager);
 84  
 
 85  112
         this.windowManager = manager;
 86  112
     }
 87  
 
 88  
     /**
 89  
      * {@link UrumaApplicationWindow} を構築します。<br />
 90  
      * 
 91  
      * @param context
 92  
      *            {@link WindowContext} オブジェクト
 93  
      * @param component
 94  
      *            {@link WindowComponent} オブジェクト
 95  
      * @param modal
 96  
      *            <code>true</code> の場合、モーダルウィンドウとして開く。<code>false</code>
 97  
      *            の場合、モーダレスウィンドウとして開く。
 98  
      */
 99  
     public UrumaApplicationWindow(final UrumaWindowManager manager,
 100  
             final WindowContext context, final WindowComponent component,
 101  
             final boolean modal) {
 102  0
         this(manager);
 103  0
         init(context, component, modal);
 104  0
     }
 105  
 
 106  
     /**
 107  
      * {@link UrumaApplicationWindow} を初期化します。<br/>
 108  
      * <p>
 109  
      * デフォルトコンストラクタを使用して本クラスを生成した場合は、必ず本メソッドを呼び出してから利用してください。
 110  
      * </p>
 111  
      * 
 112  
      * @param context
 113  
      *            {@link ApplicationContext} オブジェクト
 114  
      * @param component
 115  
      *            {@link WindowComponent} オブジェクト
 116  
      * @param modal
 117  
      *            <code>true</code> の場合、モーダルウィンドウとして開く
 118  
      */
 119  
     public void init(final WindowContext context,
 120  
             final WindowComponent component, final boolean modal) {
 121  112
         this.windowComponent = component;
 122  112
         this.windowContext = context;
 123  112
         this.partContext = ContextFactory.createPartContext(windowContext,
 124  
                 component.getId());
 125  
 
 126  
         // プリレンダリング処理を実施
 127  112
         component.preRender(null, windowContext);
 128  
 
 129  112
         setupActionComponent();
 130  112
         ComponentUtil.setupFormComponent(partContext, windowComponent.getId());
 131  
 
 132  112
         setupMenuBar();
 133  112
         setupShellStyle(component, modal);
 134  112
         setupStatusLine();
 135  
 
 136  
         // パートアクションの @Initialize メソッドを呼び出す
 137  112
         ComponentUtil
 138  
                 .invokeInitMethodOnAction(partActionComponent, partContext);
 139  112
     }
 140  
 
 141  
     protected void setupActionComponent() {
 142  112
         partActionComponent = ComponentUtil.setupPartAction(partContext,
 143  
                 windowComponent.getId());
 144  112
         if (partActionComponent != null) {
 145  112
             this.desc = PartActionDescFactory
 146  
                     .getPartActionDesc(partActionComponent.getClass());
 147  
         }
 148  112
     }
 149  
 
 150  
     protected void setupShellStyle(final WindowComponent component,
 151  
             final boolean modal) {
 152  112
         WindowRenderer renderer = (WindowRenderer) component.getRenderer();
 153  112
         int style = (renderer.getShellStyle(component));
 154  
 
 155  112
         if (modal) {
 156  112
             if ((style & (SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL)) == 0) {
 157  112
                 style |= SWT.PRIMARY_MODAL;
 158  
             }
 159  
         } else {
 160  0
             style &= ~(SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL);
 161  
         }
 162  112
         setShellStyle(style);
 163  112
     }
 164  
 
 165  
     protected void setupMenuBar() {
 166  112
         if (StringUtil.isNotBlank(windowComponent.menu)) {
 167  8
             addMenuBar();
 168  
         }
 169  112
     }
 170  
 
 171  
     /*
 172  
      * @see org.eclipse.jface.window.ApplicationWindow#createMenuManager()
 173  
      */
 174  
     @Override
 175  
     protected MenuManager createMenuManager() {
 176  8
         String menuId = windowComponent.menu;
 177  
 
 178  8
         WidgetHandle handle = partContext.getWindowContext().getWidgetHandle(
 179  
                 menuId);
 180  8
         if (handle != null) {
 181  8
             if (handle.instanceOf(MenuManager.class)) {
 182  8
                 return handle.<MenuManager> getCastWidget();
 183  
             } else {
 184  0
                 throw new RenderException(UNSUPPORTED_TYPE_ERROR, menuId,
 185  
                         MenuManager.class.getName());
 186  
             }
 187  
         } else {
 188  0
             throw new NotFoundException(UICOMPONENT_NOT_FOUND, menuId);
 189  
         }
 190  
     }
 191  
 
 192  
     protected void setupStatusLine() {
 193  112
         String statusLine = windowComponent.statusLine;
 194  112
         if ("true".equals(statusLine)) {
 195  4
             addStatusLine();
 196  4
             WidgetHandle handle = ContextFactory
 197  
                     .createWidgetHandle(getStatusLineManager());
 198  4
             handle.setId(STATUS_LINE_MANAGER_CID);
 199  4
             partContext.putWidgetHandle(handle);
 200  
         }
 201  112
     }
 202  
 
 203  
     /*
 204  
      * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
 205  
      */
 206  
     @Override
 207  
     protected Control createContents(final Composite parent) {
 208  
         // ウィンドウのレンダリングを開始する
 209  112
         WidgetHandle windowHandle = ContextFactory.createWidgetHandle(this);
 210  112
         windowHandle.setId(WINDOW_CID);
 211  112
         partContext.putWidgetHandle(windowHandle);
 212  
 
 213  112
         WidgetHandle shellHandle = ContextFactory.createWidgetHandle(parent);
 214  112
         shellHandle.setId(SHELL_CID);
 215  112
         partContext.putWidgetHandle(shellHandle);
 216  
 
 217  112
         windowComponent.render(shellHandle, partContext);
 218  
 
 219  112
         MethodBindingSupport.createListeners(partContext);
 220  
 
 221  
         // 画面初期表示時の、フォームから画面へのエクスポート処理を実施
 222  112
         ValueBindingSupport.exportValue(partContext);
 223  112
         ValueBindingSupport.exportSelection(partContext);
 224  
 
 225  112
         EnablesDependingListenerSupport
 226  
                 .setupEnableDependingListeners(windowContext);
 227  
 
 228  112
         return parent;
 229  
     }
 230  
 
 231  
     /**
 232  
      * パートアクションコンポーネントを取得します。<br />
 233  
      * 
 234  
      * @return パートアクションコンポーネント
 235  
      */
 236  
     public Object getPartActionComponent() {
 237  0
         return this.partActionComponent;
 238  
     }
 239  
 
 240  
     /**
 241  
      * ウィンドウIDを返します。<br />
 242  
      * 
 243  
      * @return ウィンドウID
 244  
      */
 245  
     public String getWindowId() {
 246  224
         return windowComponent.getId();
 247  
     }
 248  
 
 249  
     /**
 250  
      * {@link WindowCloseListener} を追加します。<br />
 251  
      * 
 252  
      * @param listener
 253  
      *            {@link WindowCloseListener} オブジェクト
 254  
      */
 255  
     public void addWindowCloseListener(final WindowCloseListener listener) {
 256  4
         AssertionUtil.assertNotNull("listener", listener);
 257  
 
 258  4
         if (closeListeners == null) {
 259  4
             closeListeners = new ArrayList<WindowCloseListener>();
 260  
         }
 261  4
         closeListeners.add(listener);
 262  4
     }
 263  
 
 264  
     /*
 265  
      * @see org.eclipse.jface.window.Window#open()
 266  
      */
 267  
     @Override
 268  
     public int open() {
 269  112
         super.open();
 270  
 
 271  112
         ComponentUtil.invokePostOpenMethodOnAction(partActionComponent,
 272  
                 partContext);
 273  
 
 274  112
         if (block) {
 275  112
             Shell shell = getShell();
 276  
             Display display;
 277  112
             if (shell == null) {
 278  112
                 display = Display.getCurrent();
 279  
             } else {
 280  0
                 display = shell.getDisplay();
 281  
             }
 282  
 
 283  112
             while (shell != null && !shell.isDisposed()) {
 284  0
                 if (!display.readAndDispatch()) {
 285  0
                     display.sleep();
 286  
                 }
 287  
                 // TODO ExceptionHandlerによる例外処理を行う
 288  
             }
 289  112
             display.update();
 290  
         }
 291  
 
 292  112
         return getReturnCode();
 293  
     }
 294  
 
 295  
     /*
 296  
      * @see org.eclipse.jface.window.ApplicationWindow#close()
 297  
      */
 298  
     @Override
 299  
     public boolean close() {
 300  
         // ウィンドウをクローズしてよいか確認する
 301  112
         boolean canClose = true;
 302  112
         if (closeListeners != null) {
 303  4
             for (WindowCloseListener listener : closeListeners) {
 304  4
                 canClose &= listener.canWindowClose(this);
 305  
             }
 306  
         }
 307  
 
 308  112
         if (canClose && super.close()) {
 309  
             // ApplicationContext へのエクスポート処理
 310  112
             if (partActionComponent != null) {
 311  112
                 ApplicationContextBinder.exportObjects(partActionComponent,
 312  
                         desc.getApplicationContextDefList(), windowContext
 313  
                                 .getApplicationContext());
 314  
             }
 315  
 
 316  112
             if (closeListeners != null) {
 317  4
                 closeListeners.clear();
 318  4
                 closeListeners = null;
 319  
             }
 320  
 
 321  112
             this.windowManager.close(getWindowId());
 322  
 
 323  112
             return true;
 324  
         } else {
 325  0
             return false;
 326  
         }
 327  
     }
 328  
 
 329  
     /*
 330  
      * @see org.eclipse.jface.window.Window#setBlockOnOpen(boolean)
 331  
      */
 332  
     @Override
 333  
     public void setBlockOnOpen(final boolean shouldBlock) {
 334  112
         this.block = shouldBlock;
 335  112
     }
 336  
 }