blob: dd85d6a340ae5bd55dd5ecc52764d5a85d22477a [file] [log] [blame]
/**
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Thales Corporate Services S.A.S - initial API and implementation
*/
package org.eclipse.egf.producer.internal.manager;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.egf.common.helper.BundleHelper;
import org.eclipse.egf.common.helper.EMFHelper;
import org.eclipse.egf.core.fcore.IPlatformFcore;
import org.eclipse.egf.core.fcore.IPlatformFcoreProvider;
import org.eclipse.egf.core.helper.BundleSessionHelper;
import org.eclipse.egf.core.l10n.EGFCoreMessages;
import org.eclipse.egf.core.producer.InvocationException;
import org.eclipse.egf.core.producer.context.IProductionContext;
import org.eclipse.egf.core.producer.context.ProductionContext;
import org.eclipse.egf.core.session.ProjectBundleSession;
import org.eclipse.egf.model.fcore.ContractMode;
import org.eclipse.egf.model.fcore.ModelElement;
import org.eclipse.egf.model.fcore.NamedModelElement;
import org.eclipse.egf.model.types.Type;
import org.eclipse.egf.model.types.TypeAbstractClass;
import org.eclipse.egf.model.types.TypeClass;
import org.eclipse.egf.producer.EGFProducerPlugin;
import org.eclipse.egf.producer.l10n.ProducerMessages;
import org.eclipse.egf.producer.manager.IModelElementManager;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
/**
* @author Xavier Maysonnave
*
*/
public abstract class ModelElementManager<P extends ModelElement, T extends ModelElement> implements IModelElementManager<P, T> {
protected static BasicDiagnostic getDiagnostic(ModelElement element, boolean runtime) {
String message = null;
if (element instanceof NamedModelElement) {
NamedModelElement namedElement = (NamedModelElement) element;
if (namedElement.getName() != null && namedElement.getName().trim().length() != 0) {
if (runtime) {
message = NLS.bind(ProducerMessages.RuntimeCanInvoke_Diagnosis_message, namedElement.getName());
} else {
message = NLS.bind(ProducerMessages.CanInvoke_Diagnosis_message, namedElement.getName());
}
}
}
if (message == null) {
if (runtime) {
message = NLS.bind(ProducerMessages.RuntimeCanInvoke_Diagnosis_message, element.eClass().getName());
} else {
message = NLS.bind(ProducerMessages.CanInvoke_Diagnosis_message, element.eClass().getName());
}
}
return new BasicDiagnostic(EGFProducerPlugin.getDefault().getPluginID(), 0, message, new Object[] {
element
});
}
protected static <M extends ModelElement> void populateContext(ProductionContext<?, M> context, Bundle bundle, M key, ContractMode mode, Type type, Object value) throws InvocationException {
// Class
if (type instanceof TypeAbstractClass) {
try {
// Store
String fqcn = (String) value;
TypeAbstractClass abstractClass = (TypeAbstractClass) type;
// TypeClass with null value are simply ignored and as such not exposed in the ProductionContext
if (type instanceof TypeClass && (fqcn == null || fqcn.trim().length() == 0)) {
return;
}
// Do we have an instance value
Object object = abstractClass.getInstance();
// Should we instantiate our String value
if (object == null) {
// Null value is a valid value except for TypeClass
if (fqcn != null && fqcn.trim().length() != 0) {
object = BundleHelper.instantiate(fqcn.trim(), bundle);
if (object == null) {
throw new InvocationException(NLS.bind(EGFCoreMessages.ProjectBundleSession_BundleClassInstantiationFailure, fqcn, bundle.getSymbolicName()));
}
}
}
// Type and object are validated in the ProductionContext while added
if (mode == ContractMode.IN) {
context.addInputData(key, abstractClass.getType(), object, true);
} else if (mode == ContractMode.OUT) {
context.addOutputData(key, abstractClass.getType(), null, true);
} else if (mode == ContractMode.IN_OUT) {
context.addInputData(key, abstractClass.getType(), object, true);
context.addOutputData(key, abstractClass.getType(), object, true);
}
} catch (Throwable t) {
throw new InvocationException(NLS.bind(EGFCoreMessages.ProjectBundleSession_BundleClassInstantiationFailure, value, bundle.getSymbolicName()), t);
}
} else {
// Type and object are validated in the ProductionContext while added
if (mode == ContractMode.IN) {
context.addInputData(key, type.getType(), value, true);
} else if (mode == ContractMode.OUT) {
context.addOutputData(key, type.getType(), null, true);
} else if (mode == ContractMode.IN_OUT) {
context.addInputData(key, type.getType(), value, true);
context.addOutputData(key, type.getType(), value, true);
}
}
}
private P _element;
protected IModelElementManager<?, ?> _parent;
protected IProductionContext<P, T> _productionContext;
private Bundle _bundle;
private ProjectBundleSession _session;
private IPlatformFcore _fcore;
public ModelElementManager(P element) throws InvocationException {
Assert.isNotNull(element);
_element = element;
if (_element.eIsProxy())
throw new InvocationException(NLS.bind(EGFCoreMessages.EObject_is_proxy, EcoreUtil.getURI(_element)));
if (_element.eResource() == null) {
throw new InvocationException( NLS.bind(EGFCoreMessages.EObject_no_Resource, EcoreUtil.getURI(_element)));
}
if (_element.eResource() instanceof IPlatformFcoreProvider) {
_fcore = ((IPlatformFcoreProvider) _element.eResource()).getIPlatformFcore();
}
if (_fcore == null) {
throw new InvocationException(NLS.bind(EGFCoreMessages.Fcore_not_found, EcoreUtil.getURI(_element).trimFragment()));
}
}
public ModelElementManager(Bundle bundle, P element) {
Assert.isNotNull(bundle);
Assert.isNotNull(element);
_bundle = bundle;
_element = element;
}
public ModelElementManager(IModelElementManager<?, ?> parent, P element) throws InvocationException {
Assert.isNotNull(parent);
Assert.isNotNull(element);
_parent = parent;
_element = element;
if (_element.eResource() == null && parent.getBundle() == null) {
throw new InvocationException(NLS.bind(EGFCoreMessages.EObject_no_Bundle, EcoreUtil.getURI(_element)));
}
if (_element.eResource() != null) {
if (_element.eResource() instanceof IPlatformFcoreProvider) {
_fcore = ((IPlatformFcoreProvider) _element.eResource()).getIPlatformFcore();
}
if (_fcore == null) {
throw new InvocationException(NLS.bind(EGFCoreMessages.Fcore_not_found, EcoreUtil.getURI(_element).trimFragment()));
}
}
}
public P getElement() {
return _element;
}
public IProductionContext<P, T> getProductionContext() throws InvocationException {
return getInternalProductionContext();
}
public IModelElementManager<?, ?> getParent() {
return _parent;
}
protected abstract ProductionContext<P, T> getInternalProductionContext() throws InvocationException;
public String getName() {
return EMFHelper.getText(getElement());
}
public Bundle getBundle() throws InvocationException {
// Platform
if (_fcore != null) {
// Runtime or target associated with a runtime bundle
if (_fcore.isRuntime() || _fcore.getBundle() != null) {
return _fcore.getBundle();
}
// Workspace Bundle
if (_fcore.isWorkspace()) {
try {
return BundleSessionHelper.getBundle(getProjectBundleSession(), _fcore);
} catch (Throwable t) {
throw new InvocationException(t);
}
}
// Cannot associate a Bundle to a target platform fcore
throw new InvocationException(NLS.bind(EGFCoreMessages.TargetPlatform_ExtensionPoint_no_bundle, _fcore.getPlatformBundle().getBundleId()));
}
// Memory takes its bundle from its parent
if (getParent() != null) {
return getParent().getBundle();
}
// Parent
return _bundle;
}
public ProjectBundleSession getProjectBundleSession() {
if (getParent() != null) {
return getParent().getProjectBundleSession();
}
if (_session == null) {
_session = new ProjectBundleSession(EGFProducerPlugin.getDefault().getBundle().getBundleContext());
}
return _session;
}
public void setProjectBundleSession(ProjectBundleSession session) {
if (getParent() != null) {
getParent().setProjectBundleSession(session);
} else {
_session = session;
}
}
@SuppressWarnings("unused")
protected BasicDiagnostic checkInputElement(boolean runtime) throws InvocationException {
return getDiagnostic(getElement(), runtime);
}
@SuppressWarnings("unused")
protected BasicDiagnostic checkOutputElement(BasicDiagnostic diagnostic) throws InvocationException {
return diagnostic;
}
public Diagnostic canInvoke() throws InvocationException {
return checkInputElement(false);
}
public abstract void initializeContext() throws InvocationException;
public void dispose() throws InvocationException {
if (_session != null) {
try {
_session.dispose();
} catch (Throwable t) {
throw new InvocationException(t);
}
}
}
}