org.seasar.uruma.rcp.ui.GenericViewPart.java Source code

Java tutorial

Introduction

Here is the source code for org.seasar.uruma.rcp.ui.GenericViewPart.java

Source

/*
 * Copyright 2004-2008 the Seasar Foundation and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.seasar.uruma.rcp.ui;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import org.seasar.framework.util.StringUtil;
import org.seasar.uruma.annotation.SelectionListener;
import org.seasar.uruma.binding.method.MethodBindingSupport;
import org.seasar.uruma.binding.method.SingleParamTypeMethodBinding;
import org.seasar.uruma.binding.value.ValueBindingSupport;
import org.seasar.uruma.component.Template;
import org.seasar.uruma.component.UIComponent;
import org.seasar.uruma.component.UIComponentContainer;
import org.seasar.uruma.component.UIHasMenuCompositeComponent;
import org.seasar.uruma.component.rcp.ViewPartComponent;
import org.seasar.uruma.context.ApplicationContext;
import org.seasar.uruma.context.ContextFactory;
import org.seasar.uruma.context.PartContext;
import org.seasar.uruma.context.WidgetHandle;
import org.seasar.uruma.context.WindowContext;
import org.seasar.uruma.core.ComponentUtil;
import org.seasar.uruma.core.TemplateManager;
import org.seasar.uruma.core.UrumaConstants;
import org.seasar.uruma.core.UrumaMessageCodes;
import org.seasar.uruma.exception.RenderException;
import org.seasar.uruma.log.UrumaLogger;
import org.seasar.uruma.rcp.UrumaService;
import org.seasar.uruma.rcp.binding.GenericSelectionListener;
import org.seasar.uruma.rcp.binding.NullGenericSelectionListener;
import org.seasar.uruma.rcp.util.UrumaServiceUtil;
import org.seasar.uruma.rcp.util.ViewPartUtil;
import org.seasar.uruma.util.AnnotationUtil;
import org.seasar.uruma.util.S2ContainerUtil;

/**
 * ? {@link IViewPart} ??<br />
 * <p>
 * ???Uruma ? {@link S2Container} ???????
 * {@link S2Container} (????)????<br />
 * h?Uruma ? {@link S2Container} ???<br />
 *  ?????????????????? DI
 * ????
 * </p>
 * <dl>
 * <dt> {@link IViewPart}</dt>
 * <dd>???? {@link GenericViewPart} ?</dd>
 * <dt> {@link PartContext}</dt>
 * <dd>???? {@link PartContext} </dd>
 * </dt>
 * <p>
 * ??? {@link IViewPart} ????? {@link Viewer} ????????????
 * {@link Viewer} ? {@link ISelectionProvider} ???
 * {@link IWorkbenchPartSite} ????<br />
 * {@link Viewer} ????????<br />
 * </p>
 * 
 * @author y-komori
 */
public class GenericViewPart extends ViewPart implements UrumaViewPart, UrumaMessageCodes {
    private UrumaService service = UrumaServiceUtil.getService();

    private static final UrumaLogger logger = UrumaLogger.getLogger(GenericViewPart.class);

    /**
     * {@link TemplateManager} 
     */
    public TemplateManager templateManager;

    /**
     * {@link ApplicationContext} 
     */
    public ApplicationContext applicationContext;

    private PartContext partContext;

    private ViewPartComponent viewPart;

    private String componentId;

    private String secondaryId;

    private String fullComponentId;

    private Object partAction;

    private List<ISelectionListener> listeners = new ArrayList<ISelectionListener>();

    private S2Container localContainer;

    /*
     * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite,
     *      org.eclipse.ui.IMemento)
     */
    @Override
    public void init(final IViewSite site, final IMemento memento) throws PartInitException {
        super.init(site, memento);
        try {
            initInternal(site, memento);

            logger.log(VIEW_INIT_END, fullComponentId);
        } catch (RuntimeException e) {
            logger.log(VIEW_INIT_FAILED, e, fullComponentId, e.getMessage());
            throw e;
        }
    }

    protected void initInternal(final IViewSite site, final IMemento memento) {
        S2ContainerUtil.injectDependency(this, service.getContainer());

        this.componentId = service.getLocalId(getSite().getId());
        this.secondaryId = site.getSecondaryId();
        this.fullComponentId = ViewPartUtil.createFullId(componentId, secondaryId);

        logger.log(VIEW_INIT_START, fullComponentId);

        Template template = templateManager.getTemplateById(componentId);
        UIComponentContainer root = template.getRootComponent();
        if (root instanceof ViewPartComponent) {
            this.viewPart = (ViewPartComponent) root;

            this.partContext = createPartContext(fullComponentId);

            createLocalContainer();
            setupLocalContainer();

            this.partAction = ComponentUtil.setupPartAction(partContext, componentId, localContainer);

            if (partAction != null) {
                ComponentUtil.setupFormComponent(partContext, componentId);
            }
        } else {
            throw new RenderException(UrumaMessageCodes.REQUIRED_VIEWPART_ERROR,
                    template.getURL().toExternalForm());
        }
    }

    /**
     * {@link GenericViewPart} ???<br />
     */
    public GenericViewPart() {
    }

    @Override
    public void createPartControl(final Composite parent) {
        try {
            createPartControlInternal(parent);
            registerContextMenu();
        } catch (RuntimeException e) {
            logger.log(e);
            throw e;
        }
    }

    protected void createPartControlInternal(final Composite parent) {
        WidgetHandle parentHandle = ContextFactory.createWidgetHandle(parent);
        parentHandle.setUiComponent(service.getWorkbenchComponent());

        viewPart.preRender(parentHandle, partContext.getWindowContext());
        viewPart.render(parentHandle, partContext);

        prepareSelectionProvider(partContext);

        setupSelectionListeners();

        // PartAction?@Initialize ???
        ComponentUtil.invokeInitMethodOnAction(partAction, partContext);

        // ??????????
        ValueBindingSupport.exportValue(partContext);
        ValueBindingSupport.exportSelection(partContext);

        // // Enable Depending ?
        // WindowContext context = UrumaServiceUtil.getService()
        // .getWorkbenchWindowContext();
        // EnablesDependingListenerSupport.setupEnableDependingListeners(context
        // );

        // Method Binding ?
        MethodBindingSupport.createListeners(partContext);
    }

    /*
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    @Override
    public void setFocus() {
        // Do nothing.
    }

    /*
     * @see org.eclipse.ui.part.WorkbenchPart#dispose()
     */
    @Override
    public void dispose() {
        IWorkbenchPage page = getSite().getPage();
        for (ISelectionListener listener : listeners) {
            page.removeSelectionListener(listener);
        }
        WindowContext windowContext = applicationContext
                .getWindowContext(UrumaConstants.WORKBENCH_WINDOW_CONTEXT_ID);
        windowContext.disposePartContext(partContext.getName());

        super.dispose();
    }

    /**
     *  ViewPart ? {@link S2Container} ????<br />
     */
    protected void createLocalContainer() {
        S2Container container = S2ContainerFactory.create();
        container.include(service.getContainer());
        this.localContainer = container;
    }

    protected void setupLocalContainer() {
        localContainer.register(this);
        localContainer.register(partContext);
    }

    protected PartContext createPartContext(final String id) {
        WindowContext windowContext = applicationContext
                .getWindowContext(UrumaConstants.WORKBENCH_WINDOW_CONTEXT_ID);
        return ContextFactory.createPartContext(windowContext, id);
    }

    protected void prepareSelectionProvider(final PartContext context) {
        List<WidgetHandle> viewers = context.getWidgetHandles(Viewer.class);
        if (viewers.size() == 1) {
            Viewer viewer = viewers.get(0).<Viewer>getCastWidget();
            getSite().setSelectionProvider(viewer);
        }
    }

    protected void setupSelectionListeners() {
        if (partAction == null) {
            return;
        }

        List<Method> listenerMethods = AnnotationUtil.getAnnotatedMethods(partAction.getClass(),
                SelectionListener.class);

        for (Method method : listenerMethods) {
            if (Modifier.isPublic(method.getModifiers())) {
                SelectionListener anno = method.getAnnotation(SelectionListener.class);
                boolean nullSelection = anno.nullSelection();
                Class<?>[] paramTypes = method.getParameterTypes();
                if (paramTypes.length <= 1) {
                    SingleParamTypeMethodBinding methodBinding = new SingleParamTypeMethodBinding(partAction,
                            method);

                    GenericSelectionListener listener;
                    if (nullSelection) {
                        listener = new NullGenericSelectionListener(partContext, methodBinding);
                    } else {
                        listener = new GenericSelectionListener(partContext, methodBinding);
                    }

                    String partId = anno.partId();

                    if (StringUtil.isEmpty(partId)) {
                        getSite().getPage().addSelectionListener(listener);
                    } else {
                        partId = UrumaServiceUtil.getService().createRcpId(partId);
                        getSite().getPage().addSelectionListener(partId, listener);
                    }

                    logger.log(UrumaMessageCodes.ISELECTION_LISTENER_REGISTERED, getViewSite().getId(),
                            methodBinding, partId);
                    listeners.add(listener);
                }
            }
        }
    }

    protected void registerContextMenu() {
        List<WidgetHandle> handles = partContext.getWidgetHandles(TreeViewer.class);
        for (WidgetHandle handle : handles) {
            UIComponent uiComponent = handle.getUiComponent();
            if (uiComponent instanceof UIHasMenuCompositeComponent) {
                TreeViewer treeViewer = handle.<TreeViewer>getCastWidget();

                MenuManager menuMgr = new MenuManager();
                GroupMarker groupMarker = new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS);
                menuMgr.add(groupMarker);
                getSite().registerContextMenu(menuMgr, treeViewer);

                Control control = treeViewer.getControl();
                Menu menu = menuMgr.createContextMenu(control);
                control.setMenu(menu);
            }
        }
    }

    /*
     * @see org.seasar.uruma.rcp.ui.UrumaViewPart#getId()
     */
    public String getId() {
        return this.componentId;
    }

    /*
     * @see org.seasar.uruma.rcp.ui.UrumaViewPart#getRcpId()
     */
    public String getRcpId() {
        return getSite().getId();
    }

    /*
     * @see org.seasar.uruma.rcp.ui.UrumaViewPart#getSecondaryId()
     */
    public String getSecondaryId() {
        return this.secondaryId;
    }

    /*
     * @see org.eclipse.ui.part.ViewPart#setPartName(java.lang.String)
     */
    @Override
    public void setPartName(final String name) {
        super.setPartName(name);
    }
}