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