blob: 7ad4df447f497e854ace45f76b2369ed2eedeb0a [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:
* Mathieu Larose (Savoir-faire Linux) - Initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.core.programs.javascript;
import java.lang.reflect.Method;
import org.eclipse.apogy.common.emf.AbstractFeatureListNode;
import org.eclipse.apogy.common.emf.ApogyCommonEMFFacade;
import org.eclipse.apogy.common.emf.ApogyCommonEMFFactory;
import org.eclipse.apogy.common.emf.ListFeatureNode;
import org.eclipse.apogy.core.invocator.ApogyCoreInvocatorFacade;
import org.eclipse.apogy.core.invocator.VariableFeatureReference;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
/**
* Proxy for an EObject obtained through a {@link EReference}
*
*/
public class ReferenceProxy extends ScriptableObject {
private static final long serialVersionUID = 1L;
private VariableFeatureReference variableFeatureReference;
private JavaScriptProgram program;
public ReferenceProxy() {
// Rhino requires an empty constructor
}
/**
*
* @param variableFeatureReference {@link VariableFeaturerReference}
* representing the EObject wrapped by this
* classs
* @param program JavaScriptProgram being executed
* @throws NoSuchMethodException
* @throws SecurityException
*/
public ReferenceProxy(VariableFeatureReference variableFeatureReference, JavaScriptProgram program)
throws NoSuchMethodException, SecurityException {
this.variableFeatureReference = variableFeatureReference;
this.program = program;
init();
}
private void init() throws NoSuchMethodException, SecurityException {
EObject instance = ApogyCoreInvocatorFacade.INSTANCE.getInstance(this.variableFeatureReference);
for (EOperation op : ApogyCommonEMFFacade.INSTANCE.getAllAvailableEOperations(instance.eClass())) {
defineProperty(op.getName(), new OperationCallInvoker(this.program, this.variableFeatureReference, op), 0);
}
for (EStructuralFeature structuralFeature : instance.eClass().getEAllStructuralFeatures()) {
if (structuralFeature instanceof EReference) {
ReferenceGetter referenceGetter = new ReferenceGetter(structuralFeature);
Method getter = ReferenceGetter.class.getDeclaredMethod("get", new Class[] { Scriptable.class });
defineProperty(structuralFeature.getName(), referenceGetter, getter, null, 0);
} else if (structuralFeature instanceof EAttribute) {
AttributeGetter attributeGetter = new AttributeGetter(this.variableFeatureReference, structuralFeature);
Method getter = AttributeGetter.class.getDeclaredMethod("get", new Class[] { Scriptable.class });
defineProperty(structuralFeature.getName(), attributeGetter, getter, null, 0);
}
}
}
@Override
public String getClassName() {
return "ReferenceProxy";
}
/**
* Gets a reference of the EObject wrapped by {@link ReferenceProxy}
*
*/
private class ReferenceGetter {
private final EStructuralFeature feature;
public ReferenceGetter(EStructuralFeature feature) {
this.feature = feature;
}
/**
* Returns the reference (represented by this class) of the EObject (represented
* by {@ReferenceProxy})
*
* @param self The JavaScript object
* @return the attribute
*/
@SuppressWarnings("unused")
public Object get(Scriptable self) throws NoSuchMethodException, SecurityException {
VariableFeatureReference subVariableFeatureReference = VariableFeatureReferenceUtil
.clone(ReferenceProxy.this.variableFeatureReference);
AbstractFeatureListNode leaf = ApogyCommonEMFFacade.INSTANCE
.getLeaf(subVariableFeatureReference.getFeatureRoot());
ListFeatureNode node = ApogyCommonEMFFactory.eINSTANCE.createListFeatureNode();
node.setStructuralFeature(this.feature); // Example:
// (rover.centerCamera.)fov
leaf.setChild(node);
Scriptable object = new ReferenceProxy(subVariableFeatureReference, ReferenceProxy.this.program);
object.setParentScope(ReferenceProxy.this);
return object;
}
}
}