@After
 public void tearDown() throws Exception {
   if (wb != null) {
     wb.close();
   }
   appContext.dispose();
 }
  public void testCreateView() {
    final MWindow window = createWindowWithOneView("Part Name");

    MApplication application = ApplicationFactoryImpl.eINSTANCE.createApplication();
    application.getChildren().add(window);
    application.setContext(appContext);
    appContext.set(MApplication.class.getName(), application);

    wb = new E4Workbench(application, appContext);
    wb.createAndRunUI(window);

    MPartSashContainer container = (MPartSashContainer) window.getChildren().get(0);
    MPartStack stack = (MPartStack) container.getChildren().get(0);
    MPart part = (MPart) stack.getChildren().get(0);

    CTabFolder folder = (CTabFolder) stack.getWidget();
    CTabItem item = folder.getItem(0);
    assertEquals("Part Name", item.getText());

    assertFalse(part.isDirty());

    part.setDirty(true);
    assertEquals("*Part Name", item.getText());

    part.setDirty(false);
    assertEquals("Part Name", item.getText());
  }
 /*
  * (non-Javadoc)
  *
  * @see junit.framework.TestCase#tearDown()
  */
 @Override
 protected void tearDown() throws Exception {
   if (wb != null) {
     wb.close();
   }
   appContext.dispose();
 }
  @Test
  public void testBug310027() {
    MApplication application = ApplicationFactoryImpl.eINSTANCE.createApplication();
    MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
    MPartSashContainer container = BasicFactoryImpl.eINSTANCE.createPartSashContainer();
    MPartStack partStackA = BasicFactoryImpl.eINSTANCE.createPartStack();
    MPartStack partStackB = BasicFactoryImpl.eINSTANCE.createPartStack();
    MPart partA = BasicFactoryImpl.eINSTANCE.createPart();
    MPart partB = BasicFactoryImpl.eINSTANCE.createPart();

    window.setWidth(600);
    window.setHeight(400);

    partStackA.setContainerData("50");
    partStackB.setContainerData("50");

    application.getChildren().add(window);
    application.setSelectedElement(window);

    window.getChildren().add(container);
    window.setSelectedElement(container);

    container.getChildren().add(partStackA);
    container.getChildren().add(partStackB);
    container.setSelectedElement(partStackA);

    partStackA.getChildren().add(partA);
    partStackA.setSelectedElement(partA);
    partStackA.getChildren().add(partB);
    partStackA.setSelectedElement(partB);

    application.setContext(appContext);
    appContext.set(MApplication.class, application);

    wb = new E4Workbench(application, appContext);
    wb.createAndRunUI(window);

    assertEquals("50", partStackA.getContainerData());
    assertEquals("50", partStackB.getContainerData());

    partStackB.setToBeRendered(false);

    while (Display.getDefault().readAndDispatch()) ;

    assertEquals("50", partStackA.getContainerData());
  }
  // TODO This should go into a different bundle
  public static IEclipseContext createDefaultHeadlessContext() {
    IEclipseContext serviceContext = E4Workbench.getServiceContext();

    IExtensionRegistry registry = RegistryFactory.getRegistry();
    ExceptionHandler exceptionHandler = new ExceptionHandler();
    ReflectionContributionFactory contributionFactory = new ReflectionContributionFactory(registry);
    serviceContext.set(IContributionFactory.class, contributionFactory);
    serviceContext.set(IExceptionHandler.class, exceptionHandler);
    serviceContext.set(IExtensionRegistry.class, registry);

    serviceContext.set(
        Adapter.class, ContextInjectionFactory.make(EclipseAdapter.class, serviceContext));

    // No default log provider available
    if (serviceContext.get(ILoggerProvider.class) == null) {
      serviceContext.set(
          ILoggerProvider.class,
          ContextInjectionFactory.make(DefaultLoggerProvider.class, serviceContext));
    }

    return serviceContext;
  }
  public void saveModel() {
    // Save the model into the targetURI
    if (lcManager != null && workbench != null) {
      ContextInjectionFactory.invoke(lcManager, PreSave.class, workbench.getContext(), null);
    }

    try {
      if (!(handler instanceof ResourceHandler)
          || ((ResourceHandler) handler).hasTopLevelWindows()) {
        handler.save();
      } else {
        Logger logger = new WorkbenchLogger(PLUGIN_ID);
        logger.error(
            new Exception(), // log a stack trace for debugging
            "Attempted to save a workbench model that had no top-level windows! " //$NON-NLS-1$
                + "Skipped saving the model to avoid corruption."); //$NON-NLS-1$
      }
    } catch (IOException e) {
      Logger logger = new WorkbenchLogger(PLUGIN_ID);
      logger.error(e, "Error saving the workbench model"); // $NON-NLS-1$
    }
  }
  @Override
  public Object start(IApplicationContext applicationContext) throws Exception {
    // set the display name before the Display is
    // created to ensure the app name is used in any
    // platform menus, etc. See
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329456#c14
    IProduct product = Platform.getProduct();
    if (product != null && product.getName() != null) {
      Display.setAppName(product.getName());
    }
    Display display = getApplicationDisplay();
    Location instanceLocation = null;
    try {
      E4Workbench workbench = createE4Workbench(applicationContext, display);

      instanceLocation = (Location) workbench.getContext().get(E4Workbench.INSTANCE_LOCATION);
      Shell shell = display.getActiveShell();
      if (shell == null) {
        shell = new Shell();
        // place it off so it's not visible
        shell.setLocation(0, 10000);
      }
      if (!checkInstanceLocation(instanceLocation, shell, workbench.getContext())) return EXIT_OK;

      // Create and run the UI (if any)
      workbench.createAndRunUI(workbench.getApplication());

      saveModel();
      workbench.close();

      if (workbench.isRestart()) {
        return EXIT_RESTART;
      }

      return EXIT_OK;
    } finally {
      if (display != null) display.dispose();
      if (instanceLocation != null) instanceLocation.release();
    }
  }
 @Override
 public void stop() {
   if (workbench != null) {
     workbench.close();
   }
 }
  public E4Workbench createE4Workbench(
      IApplicationContext applicationContext, final Display display) {
    args = (String[]) applicationContext.getArguments().get(IApplicationContext.APPLICATION_ARGS);

    IEclipseContext appContext = createDefaultContext();
    appContext.set(Display.class, display);
    appContext.set(Realm.class, DisplayRealm.getRealm(display));
    appContext.set(
        UISynchronize.class,
        new UISynchronize() {

          @Override
          public void syncExec(Runnable runnable) {
            if (display != null && !display.isDisposed()) {
              display.syncExec(runnable);
            }
          }

          @Override
          public void asyncExec(Runnable runnable) {
            if (display != null && !display.isDisposed()) {
              display.asyncExec(runnable);
            }
          }
        });
    appContext.set(IApplicationContext.class, applicationContext);

    // This context will be used by the injector for its
    // extended data suppliers
    ContextInjectionFactory.setDefault(appContext);

    // Get the factory to create DI instances with
    IContributionFactory factory = appContext.get(IContributionFactory.class);

    // Install the life-cycle manager for this session if there's one
    // defined
    Optional<String> lifeCycleURI =
        getArgValue(IWorkbench.LIFE_CYCLE_URI_ARG, applicationContext, false);
    lifeCycleURI.ifPresent(
        lifeCycleURIValue -> {
          lcManager = factory.create(lifeCycleURIValue, appContext);
          if (lcManager != null) {
            // Let the manager manipulate the appContext if desired
            ContextInjectionFactory.invoke(lcManager, PostContextCreate.class, appContext, null);
          }
        });

    Optional<String> forcedPerspectiveId =
        getArgValue(PERSPECTIVE_ARG_NAME, applicationContext, false);
    forcedPerspectiveId.ifPresent(
        forcedPerspectiveIdValue ->
            appContext.set(E4Workbench.FORCED_PERSPECTIVE_ID, forcedPerspectiveIdValue));

    String showLocation = getLocationFromCommandLine();
    if (showLocation != null) {
      appContext.set(E4Workbench.FORCED_SHOW_LOCATION, showLocation);
    }

    // Create the app model and its context
    MApplication appModel = loadApplicationModel(applicationContext, appContext);
    appModel.setContext(appContext);

    boolean isRtl = ((Window.getDefaultOrientation() & SWT.RIGHT_TO_LEFT) != 0);
    appModel.getTransientData().put(E4Workbench.RTL_MODE, isRtl);

    // for compatibility layer: set the application in the OSGi service
    // context (see Workbench#getInstance())
    if (!E4Workbench.getServiceContext().containsKey(MApplication.class)) {
      // first one wins.
      E4Workbench.getServiceContext().set(MApplication.class, appModel);
    }

    // Set the app's context after adding itself
    appContext.set(MApplication.class, appModel);

    // adds basic services to the contexts
    initializeServices(appModel);

    // let the life cycle manager add to the model
    if (lcManager != null) {
      ContextInjectionFactory.invoke(lcManager, ProcessAdditions.class, appContext, null);
      ContextInjectionFactory.invoke(lcManager, ProcessRemovals.class, appContext, null);
    }

    // Create the addons
    IEclipseContext addonStaticContext = EclipseContextFactory.create();
    for (MAddon addon : appModel.getAddons()) {
      addonStaticContext.set(MAddon.class, addon);
      Object obj = factory.create(addon.getContributionURI(), appContext, addonStaticContext);
      addon.setObject(obj);
    }

    // Parse out parameters from both the command line and/or the product
    // definition (if any) and put them in the context
    Optional<String> xmiURI = getArgValue(IWorkbench.XMI_URI_ARG, applicationContext, false);
    xmiURI.ifPresent(
        xmiURIValue -> {
          appContext.set(IWorkbench.XMI_URI_ARG, xmiURIValue);
        });

    setCSSContextVariables(applicationContext, appContext);

    Optional<String> rendererFactoryURI =
        getArgValue(E4Workbench.RENDERER_FACTORY_URI, applicationContext, false);
    rendererFactoryURI.ifPresent(
        rendererFactoryURIValue -> {
          appContext.set(E4Workbench.RENDERER_FACTORY_URI, rendererFactoryURIValue);
        });

    // This is a default arg, if missing we use the default rendering engine
    Optional<String> presentationURI =
        getArgValue(IWorkbench.PRESENTATION_URI_ARG, applicationContext, false);
    appContext.set(
        IWorkbench.PRESENTATION_URI_ARG, presentationURI.orElse(PartRenderingEngine.engineURI));

    // Instantiate the Workbench (which is responsible for
    // 'running' the UI (if any)...
    return workbench = new E4Workbench(appModel, appContext);
  }
  @Before
  public void setUp() throws Exception {
    appContext = E4Application.createDefaultContext();
    appContext.set(E4Workbench.PRESENTATION_URI_ARG, PartRenderingEngine.engineURI);

    ems = appContext.get(EModelService.class);

    window = ems.createModelElement(MWindow.class);
    window.setWidth(500);
    window.setHeight(500);

    MPartSashContainer sash = ems.createModelElement(MPartSashContainer.class);
    window.getChildren().add(sash);
    window.setSelectedElement(sash);

    MPartStack stack = ems.createModelElement(MPartStack.class);
    sash.getChildren().add(stack);
    sash.setSelectedElement(stack);

    part = ems.createModelElement(MPart.class);
    part.setElementId("Part");
    part.setLabel("Part");
    part.setToolbar(ems.createModelElement(MToolBar.class));
    part.setContributionURI(Activator.asURI(PartBackend.class));
    stack.getChildren().add(part);

    toolControl = ems.createModelElement(MToolControl.class);
    toolControl.setElementId("ToolControl");
    toolControl.setContributionURI(Activator.asURI(TextField.class));
    part.getToolbar().getChildren().add(toolControl);

    stack = ems.createModelElement(MPartStack.class);
    sash.getChildren().add(stack);
    sash.setSelectedElement(stack);

    otherPart = ems.createModelElement(MPart.class);
    otherPart.setElementId("OtherPart");
    otherPart.setLabel("OtherPart");
    otherPart.setContributionURI(Activator.asURI(PartBackend.class));
    stack.getChildren().add(otherPart);

    MApplication application = ems.createModelElement(MApplication.class);
    application.getChildren().add(window);
    application.setContext(appContext);
    appContext.set(MApplication.class, application);

    wb = new E4Workbench(application, appContext);
    wb.createAndRunUI(window);

    eps = window.getContext().get(EPartService.class);
    // ensure the parts are populated and the contributions instantiated
    eps.activate(part);
    eps.activate(otherPart);
    processEvents();

    // ensure our model backend objects are created
    assertNotNull(part.getObject());
    assertNotNull(toolControl.getObject());
    assertNotNull(otherPart.getObject());

    assertNotNull(part.getWidget());
    assertNotNull(toolControl.getWidget());
    assertNotNull(otherPart.getWidget());

    // ensure focus is set to otherPart.text1
    eps.activate(otherPart);
    processEvents();
    assertTrue(((PartBackend) otherPart.getObject()).text1.isFocusControl());
  }
  public Object safeCreateGui(
      MUIElement element, Object parentWidget, IEclipseContext parentContext) {
    if (!element.isToBeRendered()) return null;

    if (!renderedElements.contains(element)) renderedElements.add(element);

    // no creates while processing a remove
    if (removeRoot != null) {
      return null;
    }

    Object currentWidget = element.getWidget();
    if (currentWidget != null) {
      if (currentWidget instanceof Control) {
        Control control = (Control) currentWidget;
        // make sure the control is visible
        control.setVisible(true);

        if (parentWidget instanceof Composite) {
          Composite currentParent = control.getParent();
          if (currentParent != parentWidget) {
            // check if the original parent was a tab folder
            if (currentParent instanceof CTabFolder) {
              CTabFolder folder = (CTabFolder) currentParent;
              // if we used to be the tab folder's top right
              // control, unset it
              if (folder.getTopRight() == control) {
                folder.setTopRight(null);
              }
            }

            // the parents are different so we should reparent it
            control.setParent((Composite) parentWidget);
          }
        }
      }

      // Reparent the context (or the kid's context)
      if (element instanceof MContext) {
        IEclipseContext ctxt = ((MContext) element).getContext();
        if (ctxt != null) ctxt.setParent(parentContext);
      } else {
        List<MContext> childContexts =
            modelService.findElements(element, null, MContext.class, null);
        for (MContext c : childContexts) {
          // Ensure that we only reset the context of our direct
          // children
          MUIElement kid = (MUIElement) c;
          MUIElement parent = kid.getParent();
          if (parent == null && kid.getCurSharedRef() != null)
            parent = kid.getCurSharedRef().getParent();
          if (!(element instanceof MPlaceholder) && parent != element) continue;

          if (c.getContext() != null && c.getContext().getParent() != parentContext) {
            c.getContext().setParent(parentContext);
          }
        }
      }

      // Now that we have a widget let the parent (if any) know
      if (element.getParent() instanceof MUIElement) {
        MElementContainer<MUIElement> parentElement = element.getParent();
        AbstractPartRenderer parentRenderer = getRendererFor(parentElement);
        if (parentRenderer != null) parentRenderer.childRendered(parentElement, element);
      }
      return element.getWidget();
    }

    if (element instanceof MContext) {
      MContext ctxt = (MContext) element;
      // Assert.isTrue(ctxt.getContext() == null,
      // "Before rendering Context should be null");
      if (ctxt.getContext() == null) {
        IEclipseContext lclContext = parentContext.createChild(getContextName(element));
        populateModelInterfaces(ctxt, lclContext, element.getClass().getInterfaces());
        ctxt.setContext(lclContext);

        // System.out.println("New Context: " + lclContext.toString()
        // + " parent: " + parentContext.toString());

        // make sure the context knows about these variables that have
        // been defined in the model
        for (String variable : ctxt.getVariables()) {
          lclContext.declareModifiable(variable);
        }

        Map<String, String> props = ctxt.getProperties();
        for (String key : props.keySet()) {
          lclContext.set(key, props.get(key));
        }

        E4Workbench.processHierarchy(element);
      }
    }

    // Create a control appropriate to the part
    Object newWidget = createWidget(element, parentWidget);

    // Remember that we've created the control
    if (newWidget != null) {
      AbstractPartRenderer renderer = getRendererFor(element);

      // Have the renderer hook up any widget specific listeners
      renderer.hookControllerLogic(element);

      // Process its internal structure through the renderer that created
      // it
      if (element instanceof MElementContainer) {
        renderer.processContents((MElementContainer<MUIElement>) element);
      }

      // Allow a final chance to set up
      renderer.postProcess(element);

      // Now that we have a widget let the parent (if any) know
      if (element.getParent() instanceof MUIElement) {
        MElementContainer<MUIElement> parentElement = element.getParent();
        AbstractPartRenderer parentRenderer = getRendererFor(parentElement);
        if (parentRenderer != null) parentRenderer.childRendered(parentElement, element);
      }
    } else {
      // failed to create the widget, dispose its context if necessary
      if (element instanceof MContext) {
        MContext ctxt = (MContext) element;
        IEclipseContext lclContext = ctxt.getContext();
        if (lclContext != null) {
          lclContext.dispose();
          ctxt.setContext(null);
        }
      }
    }

    return newWidget;
  }