blob: 80f46c4d450099c4d95b5501a6b3767325c035a8 [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,
* Sebastien Gemme - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.core.environment.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import org.eclipse.apogy.common.emf.ApogyCommonEMFFacade;
import org.eclipse.apogy.common.emf.ApogyCommonEMFPackage;
import org.eclipse.apogy.common.emf.CurrentTimeSource;
import org.eclipse.apogy.common.emf.TimeSource;
import org.eclipse.apogy.common.math.ApogyCommonMathFacade;
import org.eclipse.apogy.common.math.Tuple3d;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFacade;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.TransformNode;
import org.eclipse.apogy.core.ApogyCoreFacade;
import org.eclipse.apogy.core.ApogyCorePackage;
import org.eclipse.apogy.core.ApogySystem;
import org.eclipse.apogy.core.ConnectionPoint;
import org.eclipse.apogy.core.ConnectionPointsList;
import org.eclipse.apogy.core.FeatureOfInterest;
import org.eclipse.apogy.core.FeatureOfInterestList;
import org.eclipse.apogy.core.environment.AbstractWorksite;
import org.eclipse.apogy.core.environment.ApogyCoreEnvironmentFacade;
import org.eclipse.apogy.core.environment.ApogyCoreEnvironmentFactory;
import org.eclipse.apogy.core.environment.ApogyCoreEnvironmentPackage;
import org.eclipse.apogy.core.environment.ApogyEnvironment;
import org.eclipse.apogy.core.environment.EquatorialCoordinates;
import org.eclipse.apogy.core.environment.Sky;
import org.eclipse.apogy.core.environment.SkyNode;
import org.eclipse.apogy.core.environment.Star;
import org.eclipse.apogy.core.environment.StarField;
import org.eclipse.apogy.core.environment.Sun;
import org.eclipse.apogy.core.environment.TimeSourcesList;
import org.eclipse.apogy.core.environment.Worksite;
import org.eclipse.apogy.core.environment.WorksitesList;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFacade;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFactory;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorPackage;
import org.eclipse.apogy.core.invocator.Context;
import org.eclipse.apogy.core.invocator.DataProductsList;
import org.eclipse.apogy.core.invocator.DataProductsListsContainer;
import org.eclipse.apogy.core.invocator.Environment;
import org.eclipse.apogy.core.invocator.InvocatorSession;
import org.eclipse.apogy.core.invocator.OperationCallResultsList;
import org.eclipse.apogy.core.invocator.ToolsList;
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.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ApogyCoreEnvironmentFacadeCustomImpl extends ApogyCoreEnvironmentFacadeImpl {
private static final Logger Logger = LoggerFactory.getLogger(ApogyCoreEnvironmentFacadeImpl.class);
private Adapter activeSessionAdapter = null;
private Adapter activeApogyEnvironmentAdapter = null;
private Adapter activeWorksiteAdapter = null;
protected ApogyCoreEnvironmentFacadeCustomImpl() {
super();
ApogyCoreInvocatorFacade.INSTANCE.eAdapters().add(getActiveSessionAdapter());
// Initialize the ActiveApogyEnvironment.
if (ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession() != null) {
updateEnvironment(ApogyCoreInvocatorFacade.INSTANCE.getActiveInvocatorSession().getEnvironment());
}
}
@Override
public void setActiveApogyEnvironment(ApogyEnvironment newActiveApogyEnvironment) {
// Unregister from the previous activeApogyEnvironment if required.
if (getActiveApogyEnvironment() != null) {
getActiveApogyEnvironment().eAdapters().remove(getApogyEnvironmentAdapter());
}
// Register to the new Active Apogy Environment.
if (newActiveApogyEnvironment != null) {
newActiveApogyEnvironment.eAdapters().add(getApogyEnvironmentAdapter());
}
super.setActiveApogyEnvironment(newActiveApogyEnvironment);
}
public InvocatorSession createApogySession() {
return createApogySession(true, true, true, true);
}
public InvocatorSession createApogySession(boolean createEnvironment, boolean createPrograms,
boolean createDataProducts, boolean createTools) {
InvocatorSession session = ApogyCoreInvocatorFactory.eINSTANCE.createInvocatorSession();
Context context = null;
if (createEnvironment) {
ApogyEnvironment environment = ApogyCoreEnvironmentFactory.eINSTANCE.createApogyEnvironment();
environment.setLocalTypesList(ApogyCoreInvocatorFactory.eINSTANCE.createLocalTypesList());
environment.setVariablesList(ApogyCoreInvocatorFactory.eINSTANCE.createVariablesList());
environment.setContextsList(ApogyCoreInvocatorFactory.eINSTANCE.createContextsList());
/** Create a default Context */
context = ApogyCoreInvocatorFactory.eINSTANCE.createContext();
context.setName(ApogyCommonEMFFacade.INSTANCE.getDefaultName(environment.getContextsList(), context,
ApogyCoreInvocatorPackage.Literals.CONTEXTS_LIST__CONTEXTS));
context.setVariableImplementationsList(
ApogyCoreInvocatorFactory.eINSTANCE.createVariableImplementationsList());
environment.getContextsList().getContexts().add(context);
environment.setActiveContext(context);
/** Creates the Worksites List */
WorksitesList worksitesList = ApogyCoreEnvironmentFactory.eINSTANCE.createWorksitesList();
environment.setWorksitesList(worksitesList);
/** Creates the Timesource. */
TimeSourcesList timeSourcesList = ApogyCoreEnvironmentFactory.eINSTANCE.createTimeSourcesList();
/** Fills in the TimeSource List. */
timeSourcesList.getTimeSources().addAll(getAllAvaibleTimeSource());
environment.setTimeSourcesList(timeSourcesList);
/** Sets the environment time source to the CurrentTimeSource. */
environment.setActiveTimeSource(getCurrentTimeSource(timeSourcesList.getTimeSources()));
session.setEnvironment(environment);
}
if (createPrograms) {
session.setProgramsList(ApogyCoreInvocatorFactory.eINSTANCE.createProgramsList());
session.setProgramRuntimesList(ApogyCoreInvocatorFactory.eINSTANCE.createProgramRuntimesList());
}
if (createDataProducts) {
DataProductsListsContainer listsContainer = ApogyCoreInvocatorFactory.eINSTANCE
.createDataProductsListsContainer();
DataProductsList dataProductsList = ApogyCoreInvocatorFactory.eINSTANCE.createDataProductsList();
dataProductsList.setName(ApogyCommonEMFFacade.INSTANCE.getDefaultName(listsContainer, dataProductsList,
ApogyCoreInvocatorPackage.Literals.DATA_PRODUCTS_LISTS_CONTAINER__DATA_PRODUCTS_LIST));
listsContainer.getDataProductsList().add(dataProductsList);
session.setDataProductsListContainer(listsContainer);
OperationCallResultsList operationCallResultsList = ApogyCoreInvocatorFactory.eINSTANCE
.createOperationCallResultsList();
operationCallResultsList
.setName(ApogyCommonEMFFacade.INSTANCE.getDefaultName(dataProductsList, operationCallResultsList,
ApogyCoreInvocatorPackage.Literals.DATA_PRODUCTS_LIST__OPERATION_CALL_RESULTS_LIST));
dataProductsList.setOperationCallResultsList(operationCallResultsList);
if (context != null) {
context.setDataProductsList(dataProductsList);
}
}
if (createTools) {
ToolsList toolsList = ApogyCoreInvocatorFactory.eINSTANCE.createToolsList();
session.setToolsList(toolsList);
}
return session;
}
public StarField createAndInitializeStars() {
StarField starField = ApogyCoreEnvironmentFactory.eINSTANCE.createStarField();
starField.setDescription("Star Field.");
starField.setStarFieldFileName("bright_star_catalog_5.txt");
starField.setNodeId(StarFieldCustomImpl.NODE_ID);
return starField;
}
public SortedSet<Star> sortByMagnitude(List<Star> stars) {
TreeSet<Star> treeSet = new TreeSet<Star>(new StarMagnitudeComparator());
treeSet.addAll(stars);
return treeSet;
}
public Sky createSky() {
Sky sky = ApogyCoreEnvironmentFactory.eINSTANCE.createSky();
return sky;
}
public SkyNode createSkyNode() {
SkyNode skyNode = ApogyCoreEnvironmentFactory.eINSTANCE.createSkyNode();
initializeSkyNode(skyNode);
return skyNode;
}
public void initializeSkyNode(SkyNode skyNode) {
skyNode.setDescription("Sky");
skyNode.setNodeId("SKY");
// Creates the Sun
Sun sun = ApogyCoreEnvironmentFactory.eINSTANCE.createSun();
sun.setDescription("The Sun.");
sun.setNodeId(SunCustomImpl.NODE_ID);
// Creates the Sun transform that attaches it to the sky.
Point3d sunPosition = new Point3d();
TransformNode sunTransformNode = ApogyCommonTopologyFacade.INSTANCE.createTransformNodeXYZ(sunPosition.x,
sunPosition.y, sunPosition.z, 0, 0, 0);
sunTransformNode.setDescription("Transform attaching the Sun to the Sky.");
sunTransformNode.setNodeId("SUN_TRANSFORM");
// Attaches the Sun to the sky.
skyNode.getChildren().add(sunTransformNode);
sunTransformNode.setParent(skyNode); // Should not have to this this
// explicitly.
sunTransformNode.getChildren().add(sun);
// Creates the stars and attached them to the sky.
try {
StarField starField = createAndInitializeStars();
// Creates the StarField transform that attaches it to the sky.
// TODO : Initialize this correctly !
TransformNode starFieldTransformNode = ApogyCommonTopologyFacade.INSTANCE.createTransformNodeXYZ(0, 0, 0, 0,
0, 0);
starFieldTransformNode.setDescription("Transform attaching the Star Field to the Sky.");
starFieldTransformNode.setNodeId("STAR_FIELD_TRANSFORM");
// Attaches the StarField to the sky.
skyNode.getChildren().add(starFieldTransformNode);
starFieldTransformNode.getChildren().add(starField);
} catch (Exception e) {
Logger.error("initializeSkyNode(Sky, SkyNode): Could not initialize the StarField.", e);
}
}
public Star createStar(float magnitude, double rightAscension, double declination) {
Star star = ApogyCoreEnvironmentFactory.eINSTANCE.createStar();
star.setMagnitude((float) magnitude);
EquatorialCoordinates equatorialCoordinates = ApogyCoreEnvironmentFactory.eINSTANCE
.createEquatorialCoordinates();
equatorialCoordinates.setRightAscension(rightAscension);
equatorialCoordinates.setDeclination(declination);
equatorialCoordinates.setRadius(Double.MAX_VALUE);
star.setEquatorialCoordinates(equatorialCoordinates);
return star;
}
public Tuple3d getVector(Node node, ApogySystem targetApogySystem, ConnectionPoint connectionPoint,
Environment environment) {
if (environment instanceof ApogyEnvironment) {
ApogyEnvironment apogyEnvironment = (ApogyEnvironment) environment;
if (apogyEnvironment.getActiveWorksite() instanceof Worksite) {
Matrix4d matrix = ApogyCommonTopologyFacade.INSTANCE.expressInFrame(connectionPoint.getNode(), node);
Vector3d v = new Vector3d();
matrix.get(v);
v.normalize();
return ApogyCommonMathFacade.INSTANCE.createTuple3d(v);
}
}
return null;
}
public Tuple3d getVector(ApogySystem sourceApogySystem, String nodeID, ApogySystem targetApogySystem,
ConnectionPoint connectionPoint, Environment environment) {
EList<Node> nodes = ApogyCommonTopologyFacade.INSTANCE.findNodesByID(nodeID,
sourceApogySystem.getTopologyRoot().getOriginNode());
if (!nodes.isEmpty()) {
Node node = nodes.get(0);
return getVector(node, targetApogySystem, connectionPoint, environment);
} else {
return null;
}
}
public Tuple3d getVector(ApogySystem sourceApogySystem, String nodeID, ApogySystem targetApogySystem,
String connectionPointName, Environment environment) {
EList<Node> nodes = ApogyCommonTopologyFacade.INSTANCE.findNodesByID(nodeID,
sourceApogySystem.getTopologyRoot().getOriginNode());
if (!nodes.isEmpty()) {
Node node = nodes.get(0);
ConnectionPoint connectionPoint = getConnectionPointByName(targetApogySystem.getConnectionPointsList(),
connectionPointName);
if (connectionPoint != null) {
return getVector(node, targetApogySystem, connectionPoint, environment);
} else {
return null;
}
} else {
return null;
}
}
public Tuple3d getVector(ApogySystem sourceApogySystem, String nodeID, String targetSystemfullyQualifiedName,
String connectionPointName, Environment environment) {
ApogySystem targetSystem = ApogyCoreFacade.INSTANCE.getApogySystem(environment, targetSystemfullyQualifiedName);
return getVector(sourceApogySystem, nodeID, targetSystem, connectionPointName, environment);
}
public List<FeatureOfInterest> getAllFeatureOfInterestInActiveSession() {
List<FeatureOfInterest> fois = new ArrayList<FeatureOfInterest>();
List<FeatureOfInterestList> foiLists = getAllFeatureOfInterestListInActiveSession();
for (FeatureOfInterestList list : foiLists) {
fois.addAll(list.getFeaturesOfInterest());
}
return fois;
}
public List<FeatureOfInterestList> getAllFeatureOfInterestListInActiveSession() {
List<FeatureOfInterestList> foiLists = new ArrayList<FeatureOfInterestList>();
ApogyEnvironment apogyEnvironment = getActiveApogyEnvironment();
if (apogyEnvironment != null) {
AbstractWorksite worksite = apogyEnvironment.getActiveWorksite();
if (worksite != null) {
List<EObject> children = ApogyCommonEMFFacade.INSTANCE.getEObjectsByType(worksite,
ApogyCorePackage.Literals.FEATURE_OF_INTEREST_LIST);
for (EObject eObject : children) {
if (eObject instanceof FeatureOfInterestList) {
foiLists.add((FeatureOfInterestList) eObject);
}
}
}
}
return foiLists;
}
private ConnectionPoint getConnectionPointByName(ConnectionPointsList connectionPointsList,
String connectionPointName) {
if (connectionPointsList.getConnectionPoints() != null
&& !connectionPointsList.getConnectionPoints().isEmpty()) {
ConnectionPoint connectionPoint = null;
Iterator<ConnectionPoint> it = connectionPointsList.getConnectionPoints().iterator();
while (it.hasNext() && connectionPoint == null) {
ConnectionPoint next = it.next();
if (next.getName().compareTo(connectionPointName) == 0) {
connectionPoint = next;
}
}
return connectionPoint;
}
return null;
}
public Tuple3d getSunVector(ApogySystem apogySystem, String nodeID) {
EList<Node> nodes = ApogyCommonTopologyFacade.INSTANCE.findNodesByID(nodeID,
apogySystem.getTopologyRoot().getOriginNode());
if (!nodes.isEmpty()) {
Node node = nodes.get(0);
return getSunVector(node);
} else {
return null;
}
}
public Tuple3d getSunVector(Node node) {
Sun sun = getActiveSun();
if (sun != null) {
// TODO : Get the root of the active session. How to do that ?
if (getActiveWorksite() instanceof Worksite) {
Worksite worksite = (Worksite) getActiveWorksite();
Node root = worksite.getWorksiteNode();
if (root != null) {
Matrix4d matrix = ApogyCommonTopologyFacade.INSTANCE.expressInFrame(sun, node);
Vector3d v = new Vector3d();
matrix.get(v);
// Ensure the vector is normalized.
v.normalize();
return ApogyCommonMathFacade.INSTANCE.createTuple3d(v);
}
}
}
return null;
}
private List<TimeSource> getAllAvaibleTimeSource() {
List<TimeSource> timeSources = new ArrayList<TimeSource>();
List<EClass> timeSourceEClass = ApogyCommonEMFFacade.INSTANCE
.getAllSubEClasses(ApogyCommonEMFPackage.Literals.TIME_SOURCE);
for (EClass eClass : timeSourceEClass) {
try {
EObject eObject = EcoreUtil.create(eClass);
if (eObject instanceof TimeSource) {
TimeSource timeSource = (TimeSource) eObject;
timeSource.setName(timeSource.eClass().getName());
timeSources.add(timeSource);
}
} catch (Throwable t) {
Logger.error(t.getMessage(), t);
}
}
return timeSources;
}
private CurrentTimeSource getCurrentTimeSource(Collection<TimeSource> timeSources) {
CurrentTimeSource currentTimeSource = null;
Iterator<TimeSource> it = timeSources.iterator();
while (it.hasNext() && currentTimeSource == null) {
TimeSource timeSource = it.next();
if (timeSource instanceof CurrentTimeSource) {
currentTimeSource = (CurrentTimeSource) timeSource;
}
}
return currentTimeSource;
}
private class StarMagnitudeComparator implements Comparator<Star> {
@Override
public int compare(Star star1, Star star2) {
if (star1.getMagnitude() < star2.getMagnitude()) {
return 1;
} else if (star1.getMagnitude() > star2.getMagnitude()) {
return -1;
} else {
if (star1.getEquatorialCoordinates().getRightAscension() > star2.getEquatorialCoordinates()
.getRightAscension()) {
return 1;
} else if (star1.getEquatorialCoordinates().getRightAscension() < star2.getEquatorialCoordinates()
.getRightAscension()) {
return -1;
} else {
if (star1.getEquatorialCoordinates().getDeclination() > star2.getEquatorialCoordinates()
.getDeclination()) {
return 1;
} else {
return -1;
}
}
}
}
}
/**
* Returns The adapter that listens to the active session and updates the active
* ApogyEnvironment accordingly.
*/
private Adapter getActiveSessionAdapter() {
if (this.activeSessionAdapter == null) {
this.activeSessionAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof ApogyCoreInvocatorFacade) {
int featureID = msg.getFeatureID(ApogyCoreInvocatorFacade.class);
if (featureID == ApogyCoreInvocatorPackage.APOGY_CORE_INVOCATOR_FACADE__ACTIVE_INVOCATOR_SESSION) {
if (msg.getNewValue() instanceof InvocatorSession) {
InvocatorSession invocatorSession = (InvocatorSession) msg.getNewValue();
updateEnvironment(invocatorSession.getEnvironment());
} else {
updateEnvironment(null);
}
}
}
}
};
}
return this.activeSessionAdapter;
}
private void updateEnvironment(Environment environment) {
// Unregister from the previous activeApogyEnvironment if required.
if (getActiveApogyEnvironment() != null) {
getActiveApogyEnvironment().eAdapters().remove(getApogyEnvironmentAdapter());
}
// If the new environment is an ApogyEnvironment.
if (environment instanceof ApogyEnvironment) {
ApogyEnvironment apogyEnvironment = (ApogyEnvironment) environment;
// Sets the new Active Apogy Environment.
setActiveApogyEnvironment(apogyEnvironment);
// Sets the active time source.
setActiveTimeSource(apogyEnvironment.getActiveTimeSource());
// Register to the new Apogy Environment.
apogyEnvironment.eAdapters().add(getApogyEnvironmentAdapter());
// Updates the Worksite
updateActiveWorksite(apogyEnvironment.getActiveWorksite());
} else {
setActiveTimeSource(null);
setActiveApogyEnvironment(null);
}
}
private Adapter getApogyEnvironmentAdapter() {
if (this.activeApogyEnvironmentAdapter == null) {
this.activeApogyEnvironmentAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof ApogyEnvironment) {
int featureID = msg.getFeatureID(ApogyCoreEnvironmentFacade.class);
switch (featureID) {
/**
* The Active worksite has changed, we need to update
* the worksite.
*/
case ApogyCoreEnvironmentPackage.APOGY_ENVIRONMENT__ACTIVE_WORKSITE: {
AbstractWorksite newActiveWorksite = (AbstractWorksite) msg.getNewValue();
updateActiveWorksite(newActiveWorksite);
}
break;
case ApogyCoreEnvironmentPackage.APOGY_ENVIRONMENT__ACTIVE_TIME_SOURCE: {
TimeSource newTimeSource = (TimeSource) msg.getNewValue();
setActiveTimeSource(newTimeSource);
}
break;
default:
break;
}
}
}
};
}
return activeApogyEnvironmentAdapter;
}
/**
* Updates the active worksite.
*
* @param abstractWorksite
* The new value of the active worksite, can be null.
*/
private void updateActiveWorksite(final AbstractWorksite abstractWorksite) {
// Unregister from the previous abstractWorksite if required.
if (getActiveWorksite() != null) {
getActiveWorksite().eAdapters().remove(getWorksiteAdapter());
}
// Updates the active worksite
setActiveWorksite(abstractWorksite);
// Register to the new active worksite if required.
if (getActiveWorksite() != null) {
getActiveWorksite().eAdapters().add(getWorksiteAdapter());
}
// If the new abstractWorksite is Worksite, update the active Sun.
if (abstractWorksite instanceof Worksite) {
Worksite worksite = (Worksite) abstractWorksite;
Sky sky = worksite.getSky();
if (sky != null) {
setActiveSun(sky.getSun());
} else {
setActiveSun(null);
}
} else {
setActiveSun(null);
}
}
/**
* Adapter that listens to a Worksite and updates the active Sun when the
* Sky attribute changes.
*
* @return The adapter.
*/
private Adapter getWorksiteAdapter() {
if (activeWorksiteAdapter == null) {
activeWorksiteAdapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof Worksite) {
int featureID = msg.getFeatureID(Worksite.class);
switch (featureID) {
case ApogyCoreEnvironmentPackage.WORKSITE__SKY: {
if (msg.getNewValue() instanceof Sky) {
Sky newSky = (Sky) msg.getNewValue();
setActiveSun(newSky.getSun());
} else {
setActiveSun(null);
}
}
break;
default:
break;
}
}
}
};
}
return this.activeApogyEnvironmentAdapter;
}
} // ApogyCoreEnvironmentFacadeImpl