Coverage Report - org.seasar.uruma.rcp.ui.GenericViewPart
 
Classes in this File Line Coverage Branch Coverage Complexity
GenericViewPart
0%
0/111
0%
0/24
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.rcp.ui;
 17  
 
 18  
 import java.lang.reflect.Method;
 19  
 import java.lang.reflect.Modifier;
 20  
 import java.util.ArrayList;
 21  
 import java.util.List;
 22  
 
 23  
 import org.eclipse.jface.action.GroupMarker;
 24  
 import org.eclipse.jface.action.MenuManager;
 25  
 import org.eclipse.jface.viewers.ISelectionProvider;
 26  
 import org.eclipse.jface.viewers.TreeViewer;
 27  
 import org.eclipse.jface.viewers.Viewer;
 28  
 import org.eclipse.swt.widgets.Composite;
 29  
 import org.eclipse.swt.widgets.Control;
 30  
 import org.eclipse.swt.widgets.Menu;
 31  
 import org.eclipse.ui.IMemento;
 32  
 import org.eclipse.ui.ISelectionListener;
 33  
 import org.eclipse.ui.IViewPart;
 34  
 import org.eclipse.ui.IViewSite;
 35  
 import org.eclipse.ui.IWorkbenchActionConstants;
 36  
 import org.eclipse.ui.IWorkbenchPage;
 37  
 import org.eclipse.ui.IWorkbenchPartSite;
 38  
 import org.eclipse.ui.PartInitException;
 39  
 import org.eclipse.ui.part.ViewPart;
 40  
 import org.seasar.framework.container.S2Container;
 41  
 import org.seasar.framework.container.factory.S2ContainerFactory;
 42  
 import org.seasar.framework.util.StringUtil;
 43  
 import org.seasar.uruma.annotation.SelectionListener;
 44  
 import org.seasar.uruma.binding.method.MethodBindingSupport;
 45  
 import org.seasar.uruma.binding.method.SingleParamTypeMethodBinding;
 46  
 import org.seasar.uruma.binding.value.ValueBindingSupport;
 47  
 import org.seasar.uruma.component.Template;
 48  
 import org.seasar.uruma.component.UIComponent;
 49  
 import org.seasar.uruma.component.UIComponentContainer;
 50  
 import org.seasar.uruma.component.UIHasMenuCompositeComponent;
 51  
 import org.seasar.uruma.component.rcp.ViewPartComponent;
 52  
 import org.seasar.uruma.context.ApplicationContext;
 53  
 import org.seasar.uruma.context.ContextFactory;
 54  
 import org.seasar.uruma.context.PartContext;
 55  
 import org.seasar.uruma.context.WidgetHandle;
 56  
 import org.seasar.uruma.context.WindowContext;
 57  
 import org.seasar.uruma.core.ComponentUtil;
 58  
 import org.seasar.uruma.core.TemplateManager;
 59  
 import org.seasar.uruma.core.UrumaConstants;
 60  
 import org.seasar.uruma.core.UrumaMessageCodes;
 61  
 import org.seasar.uruma.exception.RenderException;
 62  
 import org.seasar.uruma.log.UrumaLogger;
 63  
 import org.seasar.uruma.rcp.UrumaService;
 64  
 import org.seasar.uruma.rcp.binding.GenericSelectionListener;
 65  
 import org.seasar.uruma.rcp.binding.NullGenericSelectionListener;
 66  
 import org.seasar.uruma.rcp.util.UrumaServiceUtil;
 67  
 import org.seasar.uruma.rcp.util.ViewPartUtil;
 68  
 import org.seasar.uruma.util.AnnotationUtil;
 69  
 import org.seasar.uruma.util.S2ContainerUtil;
 70  
 
 71  
 /**
 72  
  * 汎用的な {@link IViewPart} クラスです。<br />
 73  
  * <p>
 74  
  * 本クラスのインタンスは、Uruma アプリケーションの {@link S2Container} の子コンテナとして、独自の
 75  
  * {@link S2Container} (ローカルコンテナと呼びます)を生成します。<br />
 76  
  * ローカルコンテナh、Uruma アプリケーションの {@link S2Container} をインクルードします。<br />
 77  
  * ローカルコンテナ へは、デフォルトで以下のコンポーネントが登録されており、パートアクション・オブジェクトに対しては、ローカルコンテナから DI
 78  
  * が行われます。
 79  
  * </p>
 80  
  * <dl>
 81  
  * <dt> {@link IViewPart}</dt>
 82  
  * <dd>このパートに対応する {@link GenericViewPart} のインスタンス</dd>
 83  
  * <dt> {@link PartContext}</dt>
 84  
  * <dd>このパートに対応する {@link PartContext} インスタンス</dd>
 85  
  * </dt>
 86  
  * <p>
 87  
  * また、当該 {@link IViewPart} の中で使用されている {@link Viewer} が一つしか存在しない場合、その {@link
 88  
  * Viewer} を自動的に {@link ISelectionProvider} として {@link IWorkbenchPartSite}
 89  
  * へ登録します。<br />
 90  
  * {@link Viewer} が複数存在する場合、自動登録は行いません。<br />
 91  
  * </p>
 92  
  * 
 93  
  * @author y-komori
 94  
  */
 95  
 public class GenericViewPart extends ViewPart implements UrumaViewPart,
 96  
         UrumaMessageCodes {
 97  0
     private UrumaService service = UrumaServiceUtil.getService();
 98  
 
 99  0
     private static final UrumaLogger logger = UrumaLogger
 100  
             .getLogger(GenericViewPart.class);
 101  
 
 102  
     /**
 103  
      * {@link TemplateManager} オブジェクト
 104  
      */
 105  
     public TemplateManager templateManager;
 106  
 
 107  
     /**
 108  
      * {@link ApplicationContext} オブジェクト
 109  
      */
 110  
     public ApplicationContext applicationContext;
 111  
 
 112  
     private PartContext partContext;
 113  
 
 114  
     private ViewPartComponent viewPart;
 115  
 
 116  
     private String componentId;
 117  
 
 118  
     private String secondaryId;
 119  
 
 120  
     private String fullComponentId;
 121  
 
 122  
     private Object partAction;
 123  
 
 124  0
     private List<ISelectionListener> listeners = new ArrayList<ISelectionListener>();
 125  
 
 126  
     private S2Container localContainer;
 127  
 
 128  
     /*
 129  
      * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite,
 130  
      *      org.eclipse.ui.IMemento)
 131  
      */
 132  
     @Override
 133  
     public void init(final IViewSite site, final IMemento memento)
 134  
             throws PartInitException {
 135  0
         super.init(site, memento);
 136  
         try {
 137  0
             initInternal(site, memento);
 138  
 
 139  0
             logger.log(VIEW_INIT_END, fullComponentId);
 140  0
         } catch (RuntimeException e) {
 141  0
             logger.log(VIEW_INIT_FAILED, e, fullComponentId, e.getMessage());
 142  0
             throw e;
 143  0
         }
 144  0
     }
 145  
 
 146  
     protected void initInternal(final IViewSite site, final IMemento memento) {
 147  0
         S2ContainerUtil.injectDependency(this, service.getContainer());
 148  
 
 149  0
         this.componentId = service.getLocalId(getSite().getId());
 150  0
         this.secondaryId = site.getSecondaryId();
 151  0
         this.fullComponentId = ViewPartUtil.createFullId(componentId,
 152  
                 secondaryId);
 153  
 
 154  0
         logger.log(VIEW_INIT_START, fullComponentId);
 155  
 
 156  0
         Template template = templateManager.getTemplateById(componentId);
 157  0
         UIComponentContainer root = template.getRootComponent();
 158  0
         if (root instanceof ViewPartComponent) {
 159  0
             this.viewPart = (ViewPartComponent) root;
 160  
 
 161  0
             this.partContext = createPartContext(fullComponentId);
 162  
 
 163  0
             createLocalContainer();
 164  0
             setupLocalContainer();
 165  
 
 166  0
             this.partAction = ComponentUtil.setupPartAction(partContext,
 167  
                     componentId, localContainer);
 168  
 
 169  0
             if (partAction != null) {
 170  0
                 ComponentUtil.setupFormComponent(partContext, componentId);
 171  
             }
 172  
         } else {
 173  0
             throw new RenderException(
 174  
                     UrumaMessageCodes.REQUIRED_VIEWPART_ERROR, template
 175  
                             .getPath());
 176  
         }
 177  0
     }
 178  
 
 179  
     /**
 180  
      * {@link GenericViewPart} を構築します。<br />
 181  
      */
 182  0
     public GenericViewPart() {
 183  0
     }
 184  
 
 185  
     @Override
 186  
     public void createPartControl(final Composite parent) {
 187  
         try {
 188  0
             createPartControlInternal(parent);
 189  0
             registerContextMenu();
 190  0
         } catch (RuntimeException e) {
 191  0
             logger.log(e);
 192  0
             throw e;
 193  0
         }
 194  0
     }
 195  
 
 196  
     protected void createPartControlInternal(final Composite parent) {
 197  0
         WidgetHandle parentHandle = ContextFactory.createWidgetHandle(parent);
 198  0
         parentHandle.setUiComponent(service.getWorkbenchComponent());
 199  
 
 200  0
         viewPart.preRender(parentHandle, partContext.getWindowContext());
 201  0
         viewPart.render(parentHandle, partContext);
 202  
 
 203  0
         prepareSelectionProvider(partContext);
 204  
 
 205  0
         setupSelectionListeners();
 206  
 
 207  
         // PartActionの@Initialize メソッドの呼び出し
 208  0
         ComponentUtil.invokeInitMethodOnAction(partAction, partContext);
 209  
 
 210  
         // 画面初期表示時の、フォームから画面へのエクスポート処理を実施
 211  0
         ValueBindingSupport.exportValue(partContext);
 212  0
         ValueBindingSupport.exportSelection(partContext);
 213  
 
 214  
         // // Enable Depending の準備
 215  
         // WindowContext context = UrumaServiceUtil.getService()
 216  
         // .getWorkbenchWindowContext();
 217  
         // EnablesDependingListenerSupport.setupEnableDependingListeners(context
 218  
         // );
 219  
 
 220  
         // Method Binding の準備
 221  0
         MethodBindingSupport.createListeners(partContext);
 222  0
     }
 223  
 
 224  
     /*
 225  
      * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
 226  
      */
 227  
     @Override
 228  
     public void setFocus() {
 229  
         // Do nothing.
 230  0
     }
 231  
 
 232  
     /*
 233  
      * @see org.eclipse.ui.part.WorkbenchPart#dispose()
 234  
      */
 235  
     @Override
 236  
     public void dispose() {
 237  0
         IWorkbenchPage page = getSite().getPage();
 238  0
         for (ISelectionListener listener : listeners) {
 239  0
             page.removeSelectionListener(listener);
 240  
         }
 241  0
         WindowContext windowContext = applicationContext
 242  
                 .getWindowContext(UrumaConstants.WORKBENCH_WINDOW_CONTEXT_ID);
 243  0
         windowContext.disposePartContext(partContext.getName());
 244  
 
 245  0
         super.dispose();
 246  0
     }
 247  
 
 248  
     /**
 249  
      * 本 ViewPart 専用のローカル {@link S2Container} を生成します。<br />
 250  
      */
 251  
     protected void createLocalContainer() {
 252  0
         S2Container container = S2ContainerFactory.create();
 253  0
         container.include(service.getContainer());
 254  0
         this.localContainer = container;
 255  0
     }
 256  
 
 257  
     protected void setupLocalContainer() {
 258  0
         localContainer.register(this);
 259  0
         localContainer.register(partContext);
 260  0
     }
 261  
 
 262  
     protected PartContext createPartContext(final String id) {
 263  0
         WindowContext windowContext = applicationContext
 264  
                 .getWindowContext(UrumaConstants.WORKBENCH_WINDOW_CONTEXT_ID);
 265  0
         return ContextFactory.createPartContext(windowContext, id);
 266  
     }
 267  
 
 268  
     protected void prepareSelectionProvider(final PartContext context) {
 269  0
         List<WidgetHandle> viewers = context.getWidgetHandles(Viewer.class);
 270  0
         if (viewers.size() == 1) {
 271  0
             Viewer viewer = viewers.get(0).<Viewer> getCastWidget();
 272  0
             getSite().setSelectionProvider(viewer);
 273  
         }
 274  0
     }
 275  
 
 276  
     protected void setupSelectionListeners() {
 277  0
         if (partAction == null) {
 278  0
             return;
 279  
         }
 280  
 
 281  0
         List<Method> listenerMethods = AnnotationUtil.getAnnotatedMethods(
 282  
                 partAction.getClass(), SelectionListener.class);
 283  
 
 284  0
         for (Method method : listenerMethods) {
 285  0
             if (Modifier.isPublic(method.getModifiers())) {
 286  0
                 SelectionListener anno = method
 287  
                         .getAnnotation(SelectionListener.class);
 288  0
                 boolean nullSelection = anno.nullSelection();
 289  0
                 Class<?>[] paramTypes = method.getParameterTypes();
 290  0
                 if (paramTypes.length <= 1) {
 291  0
                     SingleParamTypeMethodBinding methodBinding = new SingleParamTypeMethodBinding(
 292  
                             partAction, method);
 293  
 
 294  
                     GenericSelectionListener listener;
 295  0
                     if (nullSelection) {
 296  0
                         listener = new NullGenericSelectionListener(
 297  
                                 partContext, methodBinding);
 298  
                     } else {
 299  0
                         listener = new GenericSelectionListener(partContext,
 300  
                                 methodBinding);
 301  
                     }
 302  
 
 303  0
                     String partId = anno.partId();
 304  
 
 305  0
                     if (StringUtil.isEmpty(partId)) {
 306  0
                         getSite().getPage().addSelectionListener(listener);
 307  
                     } else {
 308  0
                         partId = UrumaServiceUtil.getService().createRcpId(
 309  
                                 partId);
 310  0
                         getSite().getPage().addSelectionListener(partId,
 311  
                                 listener);
 312  
                     }
 313  
 
 314  0
                     logger.log(
 315  
                             UrumaMessageCodes.ISELECTION_LISTENER_REGISTERED,
 316  
                             getViewSite().getId(), methodBinding, partId);
 317  0
                     listeners.add(listener);
 318  
                 }
 319  0
             }
 320  
         }
 321  0
     }
 322  
 
 323  
     protected void registerContextMenu() {
 324  0
         List<WidgetHandle> handles = partContext
 325  
                 .getWidgetHandles(TreeViewer.class);
 326  0
         for (WidgetHandle handle : handles) {
 327  0
             UIComponent uiComponent = handle.getUiComponent();
 328  0
             if (uiComponent instanceof UIHasMenuCompositeComponent) {
 329  0
                 TreeViewer treeViewer = handle.<TreeViewer> getCastWidget();
 330  
 
 331  0
                 MenuManager menuMgr = new MenuManager();
 332  0
                 GroupMarker groupMarker = new GroupMarker(
 333  
                         IWorkbenchActionConstants.MB_ADDITIONS);
 334  0
                 menuMgr.add(groupMarker);
 335  0
                 getSite().registerContextMenu(menuMgr, treeViewer);
 336  
 
 337  0
                 Control control = treeViewer.getControl();
 338  0
                 Menu menu = menuMgr.createContextMenu(control);
 339  0
                 control.setMenu(menu);
 340  
             }
 341  0
         }
 342  0
     }
 343  
 
 344  
     /*
 345  
      * @see org.seasar.uruma.rcp.ui.UrumaViewPart#getId()
 346  
      */
 347  
     public String getId() {
 348  0
         return this.componentId;
 349  
     }
 350  
 
 351  
     /*
 352  
      * @see org.seasar.uruma.rcp.ui.UrumaViewPart#getRcpId()
 353  
      */
 354  
     public String getRcpId() {
 355  0
         return getSite().getId();
 356  
     }
 357  
 
 358  
     /*
 359  
      * @see org.seasar.uruma.rcp.ui.UrumaViewPart#getSecondaryId()
 360  
      */
 361  
     public String getSecondaryId() {
 362  0
         return this.secondaryId;
 363  
     }
 364  
 
 365  
     /*
 366  
      * @see org.eclipse.ui.part.ViewPart#setPartName(java.lang.String)
 367  
      */
 368  
     @Override
 369  
     public void setPartName(final String name) {
 370  0
         super.setPartName(name);
 371  0
     }
 372  
 }