blob: 4c515a9fb462bf18f128cdf3e74d7af5558cd189 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 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.workbench.ui.internal;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.RegistryFactory;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.e4.ui.model.application.MElementContainer;
import org.eclipse.e4.ui.model.application.MModelComponent;
import org.eclipse.e4.ui.model.application.MModelComponents;
import org.eclipse.e4.ui.model.application.MUIElement;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
/**
* Process extensions to E4 model contributed via extensions.
*/
public class ModelExtensionProcessor {
final private static String extensionPointID = "org.eclipse.e4.workbench.model"; //$NON-NLS-1$
/**
* Preferred default parent ID, if none specified
*/
// final private static String preferredID1 = "Horizontal Sash[right]"; //$NON-NLS-1$
/**
* Alternative preferred default parent ID, if none specified
*/
// final private static String preferredID2 = "bottom"; //$NON-NLS-1$
private MApplication e4Window;
/**
* Constructs processor for the model extensions on the MWindow
*
* @param e4Window
*/
public ModelExtensionProcessor(MApplication e4Window) {
this.e4Window = e4Window;
}
private MElementContainer<MUIElement> findDefaultParent(String parentID) {
MApplicationElement defaultElement = null;
// Try the specified ID
if (parentID != null) {
defaultElement = findElementById(e4Window, parentID);
if (defaultElement != null)
return (MElementContainer<MUIElement>) defaultElement;
}
// // Try first preferred ID
// defaultElement = findElementById(e4Window, preferredID1);
// if (defaultElement != null)
// return (MElementContainer<MUIElement>) defaultElement;
//
// // Try second preferred ID - parent of "bottom"
// defaultElement = findPart(e4Window, preferredID2);
// if (defaultElement != null)
// return defaultElement.getParent();
return null;
}
public void addModelExtensions() {
IExtensionRegistry registry = RegistryFactory.getRegistry();
IExtensionPoint extPoint = registry.getExtensionPoint(extensionPointID);
IExtension[] extensions = extPoint.getExtensions();
for (IExtension extension : extensions) {
IConfigurationElement[] ces = extension.getConfigurationElements();
for (IConfigurationElement ce : ces) {
if (!"snippet".equals(ce.getName())) //$NON-NLS-1$
continue;
IContributor contributor = ce.getContributor();
String attrURI = ce.getAttribute("uri"); //$NON-NLS-1$
if (attrURI == null) {
log("Unable to find location for the model extension \"{0}\"", //$NON-NLS-1$
contributor.getName());
continue;
}
URI uri;
String bundleName = contributor.getName();
String path = bundleName + '/' + attrURI;
try {
uri = URI.createPlatformPluginURI(path, false);
} catch (RuntimeException e) {
log("Model extension has invalid location", e); //$NON-NLS-1$
continue;
}
Resource resource;
try {
resource = new ResourceSetImpl().getResource(uri, true);
} catch (RuntimeException e) {
log("Unable to read model extension", e); //$NON-NLS-1$
continue;
}
EList<?> contents = resource.getContents();
if (contents.isEmpty())
continue;
Object extensionRoot = contents.get(0);
if (!(extensionRoot instanceof MModelComponents)) {
log("Unable to create model extension \"{0}\"", //$NON-NLS-1$
contributor.getName());
continue;
}
EList<MModelComponent> snippets = ((MModelComponents) extensionRoot)
.getComponents();
for (MModelComponent snippet : snippets) {
Object parentElement = findDefaultParent(snippet.getParentID());
if (parentElement == null) {
log("Unable to find parent with ID \"{0}\"", //$NON-NLS-1$
snippet.getParentID());
continue;
}
EObject parentObject = ((EObject) parentElement);
Object[] elements = ((EObject) snippet).eContents().toArray();
for (int i = 0; i < elements.length; i++) {
EStructuralFeature sourceFeature = ((EObject) elements[i])
.eContainingFeature();
EStructuralFeature destinationFeature = parentObject.eClass()
.getEStructuralFeature(sourceFeature.getName());
if (destinationFeature == null) {
log("Unable to find feature named \"{0}\"", //$NON-NLS-1$
sourceFeature.getName());
continue;
}
// TBD: 1) isn't it always a list?; 2) is there some utility to do this?
Object oldValue = parentObject.eGet(destinationFeature);
if (oldValue instanceof EList<?>)
((EList) oldValue).add(elements[i]);
else
parentObject.eSet(destinationFeature, elements[i]);
}
}
}
}
}
private void log(String msg, Exception e) {
// IEclipseContext context = e4Window.getContext();
// Logger logger = (Logger) context.get(Logger.class.getName());
// if (logger == null)
e.printStackTrace();
// else
// logger.error(e, msg);
}
private void log(String msg, String arg) {
// IEclipseContext context = e4Window.getContext();
// Logger logger = (Logger) context.get(Logger.class.getName());
// if (logger == null)
System.err.println(msg);
// else
// logger.error(msg, arg);
}
private MApplicationElement findElementById(MApplicationElement element, String id) {
if (id == null || id.length() == 0)
return null;
// is it me?
if (id.equals(element.getId()))
return element;
// Recurse if this is a container
EList<EObject> elements = ((EObject) element).eContents();
for (EObject childElement : elements) {
if (!(childElement instanceof MApplicationElement))
continue;
MApplicationElement result = findElementById((MApplicationElement) childElement, id);
if (result != null)
return result;
}
return null;
}
}