blob: 41f56618da8f27cf60fe8073db04b04d6f576928 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* 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:
* Pierre Allard,
* Regent L'Archeveque - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*******************************************************************************/
package org.eclipse.apogy.core.ui.composites;
import org.eclipse.apogy.core.ApogySystemApiAdapter;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFacade;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorPackage;
import org.eclipse.apogy.core.invocator.Context;
import org.eclipse.apogy.core.invocator.Environment;
import org.eclipse.apogy.core.invocator.InvocatorSession;
import org.eclipse.apogy.core.invocator.TypeApiAdapter;
import org.eclipse.apogy.core.invocator.VariableFeatureReference;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
public abstract class ApogySystemApiAdapterBasedComposite extends Composite {
private VariableFeatureReference variableFeatureReference;
private ApogySystemApiAdapter apogySystemApiAdapter;
private Adapter variableFeatureReferenceAdapter;
private ApiInstanceAdapter instancesAdapter;
public ApogySystemApiAdapterBasedComposite(Composite parent, int style) {
super(parent, style);
getInstanceAdapter().registerToAll();
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
// Unregister adapter.
getInstanceAdapter().unregisterFromAll();
}
});
}
public VariableFeatureReference getVariableFeatureReference() {
return this.variableFeatureReference;
}
public void setVariableFeatureReference(VariableFeatureReference newVariableFeatureReference) {
if (this.variableFeatureReference != null) {
this.variableFeatureReference.eAdapters().remove(getVariableFeatureReferenceAdapter());
}
this.variableFeatureReference = newVariableFeatureReference;
if (newVariableFeatureReference != null) {
newVariableFeatureReference.eAdapters().add(getVariableFeatureReferenceAdapter());
}
ApogySystemApiAdapter oldApogySystemApiAdapter = this.apogySystemApiAdapter;
// Attempts to resolve the ApogySystemApiAdapter associated with the new
// variable.
this.apogySystemApiAdapter = resolveApogySystemApiAdapter(newVariableFeatureReference);
// Notify of the change of the ApogySystemApiAdapter.
apogySystemApiAdapterChanged(oldApogySystemApiAdapter, this.apogySystemApiAdapter);
}
/**
* Return the ApogySystemApiAdapter associated with the variable.
*
* @return The ApogySystemApiAdapter, can be null.
*/
public ApogySystemApiAdapter getApogySystemApiAdapter() {
return this.apogySystemApiAdapter;
}
public ApogySystemApiAdapter resolveApogySystemApiAdapter(VariableFeatureReference variableFeatureReference) {
ApogySystemApiAdapter apogySystemApiAdapter = null;
if (variableFeatureReference != null && variableFeatureReference.getVariable() != null) {
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession() != null) {
// Attempts to resolve the ApogySystem associated with the variable.
TypeApiAdapter typeApiAdapter = ApogyCoreInvocatorFacade.INSTANCE
.getTypeApiAdapter(variableFeatureReference);
if (typeApiAdapter instanceof ApogySystemApiAdapter) {
apogySystemApiAdapter = (ApogySystemApiAdapter) typeApiAdapter;
}
}
}
return apogySystemApiAdapter;
}
/**
* Method called whenever the apogySystemApiAdapter associated with the variable
* changes.
*
* @param apogySystemApiAdapter The new ApogySystemApiAdapter associated with
* the variable.
*/
abstract protected void apogySystemApiAdapterChanged(final ApogySystemApiAdapter oldApogySystemApiAdapter,
final ApogySystemApiAdapter newApogySystemApiAdapter);
private Adapter getVariableFeatureReferenceAdapter() {
if (this.variableFeatureReferenceAdapter == null) {
this.variableFeatureReferenceAdapter = new EContentAdapter() {
@Override
public void notifyChanged(Notification msg) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
ApogySystemApiAdapter oldApogySystemApiAdapter = getApogySystemApiAdapter();
ApogySystemApiAdapterBasedComposite.this.apogySystemApiAdapter = resolveApogySystemApiAdapter(
ApogySystemApiAdapterBasedComposite.this.variableFeatureReference);
apogySystemApiAdapterChanged(oldApogySystemApiAdapter,
ApogySystemApiAdapterBasedComposite.this.apogySystemApiAdapter);
}
});
super.notifyChanged(msg);
}
};
}
return this.variableFeatureReferenceAdapter;
}
/**
* Return the adapter used to monitor changes on the instantiation of the
* variables.
*
* @return The adapter, never null.
*/
private ApiInstanceAdapter getInstanceAdapter() {
if (this.instancesAdapter == null) {
this.instancesAdapter = new ApiInstanceAdapter();
}
return this.instancesAdapter;
}
class ApiInstanceAdapter extends AdapterImpl {
private InvocatorSession invocatorSession;
private Environment environment;
private Context context;
public void registerToAll() {
// Register adapter to listen for variable instantiation.
ApogyCoreInvocatorFacade.INSTANCE.eAdapters().add(this);
// Register to active session.
registerToInvocatorSession(ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession());
}
public void unregisterFromAll() {
if (this.invocatorSession != null)
this.invocatorSession.eAdapters().remove(this);
if (this.environment != null)
this.environment.eAdapters().remove(this);
if (this.context != null)
this.context.eAdapters().remove(this);
// Unregister from Facade.
ApogyCoreInvocatorFacade.INSTANCE.eAdapters().remove(this);
}
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof ApogyCoreInvocatorFacade) {
int featureID = msg.getFeatureID(ApogyCoreInvocatorFacade.class);
switch (featureID) {
case ApogyCoreInvocatorPackage.APOGY_CORE_INVOCATOR_FACADE__INIT_VARIABLE_INSTANCES_DATE:
// Updates ApogySystemApiAdapter.
updateApogySystemApiAdapter();
break;
// If the Active Invocator Session changes.
case ApogyCoreInvocatorPackage.APOGY_CORE_INVOCATOR_FACADE__ACTIVE_INVOCATOR_SESSION:
unregisterFromInvocatorSession((InvocatorSession) msg.getOldValue());
registerToInvocatorSession((InvocatorSession) msg.getNewValue());
// Updates ApogySystemApiAdapter.
updateApogySystemApiAdapter();
break;
default:
break;
}
} else if (msg.getNotifier() instanceof InvocatorSession) {
int featureID = msg.getFeatureID(InvocatorSession.class);
switch (featureID) {
case ApogyCoreInvocatorPackage.INVOCATOR_SESSION__ENVIRONMENT:
unregisterFromEnvironment((Environment) msg.getOldValue());
registerToEnvironment((Environment) msg.getNewValue());
// Updates ApogySystemApiAdapter.
updateApogySystemApiAdapter();
break;
default:
break;
}
} else if (msg.getNotifier() instanceof Environment) {
int featureID = msg.getFeatureID(Environment.class);
switch (featureID) {
case ApogyCoreInvocatorPackage.ENVIRONMENT__ACTIVE_CONTEXT:
unregisterFromContext((Context) msg.getOldValue());
registerToContext((Context) msg.getNewValue());
// Updates ApogySystemApiAdapter.
updateApogySystemApiAdapter();
break;
default:
break;
}
} else if (msg.getNotifier() instanceof Context) {
int featureID = msg.getFeatureID(Context.class);
switch (featureID) {
case ApogyCoreInvocatorPackage.CONTEXT__INSTANCES_DISPOSAL_DATE:
// Updates ApogySystemApiAdapter.
updateApogySystemApiAdapter();
break;
default:
break;
}
}
}
private void registerToInvocatorSession(InvocatorSession invocatorSession) {
if (invocatorSession != null) {
invocatorSession.eAdapters().add(this);
registerToEnvironment(invocatorSession.getEnvironment());
}
this.invocatorSession = null;
}
private void unregisterFromInvocatorSession(InvocatorSession invocatorSession) {
if (invocatorSession != null) {
invocatorSession.eAdapters().remove(this);
unregisterFromEnvironment(invocatorSession.getEnvironment());
}
this.invocatorSession = invocatorSession;
}
private void registerToEnvironment(Environment environment) {
if (environment != null) {
environment.eAdapters().add(this);
if (environment.getActiveContext() != null) {
environment.getActiveContext().eAdapters().add(this);
}
}
this.environment = environment;
}
private void unregisterFromEnvironment(Environment environment) {
if (environment != null) {
environment.eAdapters().remove(this);
if (environment.getActiveContext() != null) {
environment.getActiveContext().eAdapters().remove(this);
}
}
this.environment = null;
}
private void registerToContext(Context context) {
if (context != null) {
context.eAdapters().add(this);
}
this.context = context;
}
private void unregisterFromContext(Context context) {
if (context != null) {
context.eAdapters().remove(this);
}
this.context = null;
}
private void updateApogySystemApiAdapter() {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
ApogySystemApiAdapter oldApogySystemApiAdapter = getApogySystemApiAdapter();
ApogySystemApiAdapterBasedComposite.this.apogySystemApiAdapter = resolveApogySystemApiAdapter(
ApogySystemApiAdapterBasedComposite.this.variableFeatureReference);
apogySystemApiAdapterChanged(oldApogySystemApiAdapter,
ApogySystemApiAdapterBasedComposite.this.apogySystemApiAdapter);
}
});
}
}
}