| /******************************************************************************* |
| * 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); |
| } |
| }); |
| } |
| } |
| |
| } |