blob: f0b60a9b7b96a5f6ca3e221bc7cab5452d1492d4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009. 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.e4.ui.workbench.swt.internal;
import java.io.IOException;
import org.eclipse.core.commands.contexts.ContextManager;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IContextConstants;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.contexts.RunAndTrack;
import org.eclipse.e4.core.internal.services.EclipseAdapter;
import org.eclipse.e4.core.services.adapter.Adapter;
import org.eclipse.e4.core.services.contributions.IContributionFactory;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.internal.services.ActiveContextsFunction;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MContribution;
import org.eclipse.e4.ui.model.application.ui.MContext;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.e4.ui.services.IStylingEngine;
import org.eclipse.e4.ui.workbench.swt.Activator;
import org.eclipse.e4.workbench.modeling.EPartService;
import org.eclipse.e4.workbench.ui.IExceptionHandler;
import org.eclipse.e4.workbench.ui.IModelResourceHandler;
import org.eclipse.e4.workbench.ui.internal.ActiveChildLookupFunction;
import org.eclipse.e4.workbench.ui.internal.ActivePartLookupFunction;
import org.eclipse.e4.workbench.ui.internal.E4Workbench;
import org.eclipse.e4.workbench.ui.internal.ExceptionHandler;
import org.eclipse.e4.workbench.ui.internal.ReflectionContributionFactory;
import org.eclipse.e4.workbench.ui.internal.ResourceHandler;
import org.eclipse.e4.workbench.ui.internal.WorkbenchLogger;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
*
*/
public class E4Application implements IApplication {
private String[] args;
private IModelResourceHandler handler;
private Display display = null;
public Display getApplicationDisplay() {
if (display == null) {
display = Display.getDefault();
}
return display;
}
public Object start(IApplicationContext applicationContext)
throws Exception {
Display display = getApplicationDisplay();
E4Workbench workbench = createE4Workbench(applicationContext);
// Create and run the UI (if any)
workbench.createAndRunUI(workbench.getApplication());
// Save the model into the targetURI
saveModel();
workbench.close();
return 0;
}
public void saveModel() {
try {
handler.save();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public E4Workbench createE4Workbench(IApplicationContext applicationContext) {
args = (String[]) applicationContext.getArguments().get(
IApplicationContext.APPLICATION_ARGS);
IEclipseContext appContext = createDefaultContext();
appContext.set(IApplicationContext.class, applicationContext);
// Get the factory to create DI instances with
IContributionFactory factory = (IContributionFactory) appContext
.get(IContributionFactory.class.getName());
// Install the life-cycle manager for this session if there's one
// defined
String lifeCycleURI = getArgValue(E4Workbench.LIFE_CYCLE_URI_ARG,
applicationContext);
Object lcManager = null;
if (lifeCycleURI != null) {
lcManager = factory.create(lifeCycleURI, appContext);
if (lcManager != null) {
// Let the manager manipulate the appContext if desired
factory.call(lcManager, null, "postContextCreate", appContext,
null);
}
}
// Create the app model and its context
MApplication appModel = loadApplicationModel(applicationContext,
appContext);
appModel.setContext(appContext);
// for compatibility layer: set the application in the OSGi service
// context (see Workbench#getInstance())
if (!E4Workbench.getServiceContext().containsKey(
MApplication.class.getName())) {
// first one wins.
E4Workbench.getServiceContext().set(MApplication.class.getName(),
appModel);
}
// Set the app's context after adding itself
appContext.set(MApplication.class.getName(), appModel);
// let the life cycle manager add to the model
if (lcManager != null) {
factory.call(lcManager, null, "processAdditions", appContext, null);
factory.call(lcManager, null, "processRemovals", appContext, null);
}
// Create the addons
for (MContribution addon : appModel.getAddons()) {
Object obj = factory.create(addon.getContributionURI(), appContext);
addon.setObject(obj);
}
// Parse out parameters from both the command line and/or the product
// definition (if any) and put them in the context
String xmiURI = getArgValue(E4Workbench.XMI_URI_ARG, applicationContext);
appContext.set(E4Workbench.XMI_URI_ARG, xmiURI);
String cssURI = getArgValue(E4Workbench.CSS_URI_ARG, applicationContext);
appContext.set(E4Workbench.CSS_URI_ARG, cssURI);
String cssResourcesURI = getArgValue(E4Workbench.CSS_RESOURCE_URI_ARG,
applicationContext);
appContext.set(E4Workbench.CSS_RESOURCE_URI_ARG, cssResourcesURI);
// This is a default arg, if missing we use the default rendering engine
String presentationURI = getArgValue(E4Workbench.PRESENTATION_URI_ARG,
applicationContext);
if (presentationURI == null) {
presentationURI = PartRenderingEngine.engineURI;
}
appContext.set(E4Workbench.PRESENTATION_URI_ARG, presentationURI);
// Instantiate the Workbench (which is responsible for
// 'running' the UI (if any)...
E4Workbench workbench = new E4Workbench(appModel, appContext);
return workbench;
}
private MApplication loadApplicationModel(IApplicationContext appContext,
IEclipseContext eclipseContext) {
MApplication theApp = null;
Location instanceLocation = Activator.getDefault()
.getInstanceLocation();
String appModelPath = getArgValue(E4Workbench.XMI_URI_ARG, appContext);
Assert.isNotNull(appModelPath, E4Workbench.XMI_URI_ARG
+ " argument missing"); //$NON-NLS-1$
final URI initialWorkbenchDefinitionInstance = URI
.createPlatformPluginURI(appModelPath, true);
boolean saveAndRestore;
String value = getArgValue(E4Workbench.SAVE_AND_RESTORE, appContext);
saveAndRestore = value == null || Boolean.getBoolean(value);
eclipseContext.set(E4Workbench.SAVE_AND_RESTORE,
Boolean.valueOf(saveAndRestore));
eclipseContext.set(E4Workbench.INITIAL_WORKBENCH_MODEL_URI,
initialWorkbenchDefinitionInstance);
eclipseContext.set(E4Workbench.INSTANCE_LOCATION, instanceLocation);
String resourceHandler = getArgValue(
E4Workbench.MODEL_RESOURCE_HANDLER, appContext);
if (resourceHandler == null) {
resourceHandler = "platform:/plugin/org.eclipse.e4.ui.workbench/"
+ ResourceHandler.class.getName();
}
IContributionFactory factory = eclipseContext
.get(IContributionFactory.class);
handler = (IModelResourceHandler) factory.create(resourceHandler,
eclipseContext);
Resource resource = handler.loadMostRecentModel();
theApp = (MApplication) resource.getContents().get(0);
return theApp;
}
private String getArgValue(String argName, IApplicationContext appContext) {
// Is it in the arg list ?
if (argName == null || argName.length() == 0)
return null;
for (int i = 0; i < args.length; i += 2) {
if (argName.equals(args[i]))
return args[i + 1];
}
return appContext.getBrandingProperty(argName);
}
public void stop() {
}
public static IEclipseContext createDefaultContext() {
// FROM: WorkbenchApplication
// parent of the global workbench context is an OSGi service
// context that can provide OSGi services
IEclipseContext serviceContext = E4Workbench.getServiceContext();
final IEclipseContext appContext = serviceContext
.createChild("WorkbenchContext"); //$NON-NLS-1$
// FROM: Workbench#createWorkbenchContext
IExtensionRegistry registry = RegistryFactory.getRegistry();
ExceptionHandler exceptionHandler = new ExceptionHandler();
ReflectionContributionFactory contributionFactory = new ReflectionContributionFactory(
registry);
appContext.set(IContributionFactory.class.getName(),
contributionFactory);
appContext
.set(Logger.class.getName(), ContextInjectionFactory.make(
WorkbenchLogger.class, appContext));
appContext.set(Adapter.class.getName(),
ContextInjectionFactory.make(EclipseAdapter.class, appContext));
// setup for commands and handlers
appContext.set(ContextManager.class.getName(), new ContextManager());
// FROM: Workbench#createWorkbenchContext
appContext.set(IServiceConstants.ACTIVE_CONTEXTS,
new ActiveContextsFunction());
appContext.set(IServiceConstants.ACTIVE_PART,
new ActivePartLookupFunction());
appContext.runAndTrack(new RunAndTrack() {
public boolean changed(IEclipseContext context) {
Object o = appContext.get(IServiceConstants.ACTIVE_PART);
if (o instanceof MPart) {
appContext.set(IServiceConstants.ACTIVE_PART_ID,
((MPart) o).getElementId());
}
return true;
}
/*
* For debugging purposes only
*/
@Override
public String toString() {
return IServiceConstants.ACTIVE_PART_ID;
}
});
appContext.set(EPartService.PART_SERVICE_ROOT, new ContextFunction() {
@Override
public Object compute(IEclipseContext context) {
MContext perceivedRoot = (MContext) context.get(MWindow.class
.getName());
if (perceivedRoot == null) {
perceivedRoot = (MContext) context.get(MApplication.class
.getName());
if (perceivedRoot == null) {
return null;
}
}
IEclipseContext current = perceivedRoot.getContext();
if (current == null) {
return null;
}
IEclipseContext next = (IEclipseContext) current
.getLocal(IContextConstants.ACTIVE_CHILD);
while (next != null) {
current = next;
next = (IEclipseContext) current
.getLocal(IContextConstants.ACTIVE_CHILD);
}
Object object = current.get(MPerspective.class.getName());
if (object == null) {
// we need to consider detached windows
MUIElement window = (MUIElement) current.get(MWindow.class
.getName());
if (window == null)
return null;
MElementContainer<?> parent = window.getParent();
while (parent != null && !(parent instanceof MApplication)) {
window = parent;
parent = parent.getParent();
}
return window;
}
return object;
}
});
// EHandlerService comes from a ContextFunction
// EContextService comes from a ContextFunction
appContext.set(IExceptionHandler.class.getName(), exceptionHandler);
appContext.set(IExtensionRegistry.class.getName(), registry);
// appContext.set(IServiceConstants.SELECTION,
// new ActiveChildOutputFunction(IServiceConstants.SELECTION));
// appContext.set(IServiceConstants.INPUT, new ContextFunction() {
// public Object compute(IEclipseContext context, Object[] arguments) {
// Class adapterType = null;
// if (arguments.length > 0 && arguments[0] instanceof Class) {
// adapterType = (Class) arguments[0];
// }
// Object newInput = null;
// Object newValue = context.get(IServiceConstants.SELECTION);
// if (adapterType == null || adapterType.isInstance(newValue)) {
// newInput = newValue;
// } else if (newValue != null && adapterType != null) {
// IAdapterManager adapters = (IAdapterManager) appContext
// .get(IAdapterManager.class.getName());
// if (adapters != null) {
// Object adapted = adapters.loadAdapter(newValue,
// adapterType.getName());
// if (adapted != null) {
// newInput = adapted;
// }
// }
// }
// return newInput;
// }
// });
appContext.set(IServiceConstants.ACTIVE_SHELL,
new ActiveChildLookupFunction(IServiceConstants.ACTIVE_SHELL,
E4Workbench.LOCAL_ACTIVE_SHELL));
// FROM: Workbench#initializeNullStyling
appContext.set(IStylingEngine.SERVICE_NAME, new IStylingEngine() {
public void setClassname(Object widget, String classname) {
}
public void setId(Object widget, String id) {
}
public void style(Object widget) {
}
});
// FROM: Workbench constructor
// workbenchContext.set(Workbench.class.getName(), this);
// workbenchContext.set(IWorkbench.class.getName(), this);
appContext.set(IExtensionRegistry.class.getName(), registry);
appContext.set(IContributionFactory.class.getName(),
contributionFactory);
appContext.set(IEclipseContext.class.getName(), appContext);
appContext.set(IShellProvider.class.getName(), new IShellProvider() {
public Shell getShell() {
return null;
}
});
return appContext;
}
}