Cross References to "surrounding" resource [message #1284514] |
Fri, 04 April 2014 15:13 |
Marcus Höpfner Messages: 56 Registered: February 2014 |
Member |
|
|
Hi,
this is kind of rerefering to my thread http://www.eclipse.org/forums/index.php/t/678768/ but now it becomes more and more clear to me how this should all work (especially with cross references).
There is an existing ecore model called "Query" and there is a form based eclipse editor for Query. FormulaDefinition is part of the Query and is edited in a popup within Query Editor.
For FormulaDefinition I have defined a arithmetic grammar with Xtext. Basically I have used the wizard "Xtext Project From Existing Ecore Models". I choosed the Query ecore and set "FormulaDefinition" as entry rule. Later I changed the grammar according to my needs.
Here is the grammar:
grammar com.sap.bw.qd.formula.QueryFormula with org.eclipse.xtext.common.Terminals
import "platform:/resource/com.sap.bw.qd.model/model/query.ecore"
import "http://www.eclipse.org/emf/2003/XMLType" as type
import "http://www.w3.org/2005/Atom" as atom
import "platform:/resource/com.sap.bw.models/bwcore/bwcore.ecore" as bwcore
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
// TODO: decide whether the operations (from back end) which are not a function should be written
// as prefix (as currently) or better infix with one operand (like in the old query designer)
// TODO: operators used directly as code instead of referencing parser rule, otherwise serialization does not work properly
// refer to http://www.eclipse.org/forums/index.php/m/1273046/#msg_1273046
FormulaDefinition returns FormulaDefinition:
{FormulaDefinition}
formulaToken=FormulaToken?;
FormulaToken returns FormulaToken:
Prio1SignOperation | Prio1Operation ;
Prio1Operation returns FormulaToken: // like +
Prio2Operation ({FormulaInfixOperator.childToken+=current} code=('+' | '-' | 'OR' | 'XOR') childToken+=Prio2Operation)*;
Prio2Operation returns FormulaToken: // like *
Prio3Operation ({FormulaInfixOperator.childToken+=current} code=('%' | '%A' | '%_A' | '*' | '/' | 'AND' | 'DIV' | 'MOD') childToken+=Prio3Operation)*;
Prio3Operation returns FormulaToken: // like ==
InfixOperandIncludeSignOperation ({FormulaInfixOperator.childToken+=current} code=('**' | '<' | '<=' | '<>' | '==' | '>' | '>=')
childToken+=InfixOperandIncludeSignOperation)*;
InfixOperandIncludeSignOperation returns FormulaToken:
InfixOperand | Prio5SignOperation;
InfixOperand returns FormulaToken:
'(' FormulaToken ')' | FormulaMeasure | FormulaConstant | FormulaCell | PrefixOperation1Operand | PrefixOperation2Operands;
Prio1SignOperation returns FormulaToken:
{FormulaSignOperator} code=('+') childToken+=Prio1Operation; // sign operation and prio1operation have the same priority
Prio5SignOperation returns FormulaToken:
{FormulaSignOperator} code=('-') childToken+=InfixOperand;
PrefixOperation returns FormulaOperator:
PrefixOperation1Operand | PrefixOperation2Operands;
PrefixOperation2Operands returns FormulaPrefixOperator:
code=('MAX' | 'MIN') '(' childToken+=FormulaToken ';' childToken+=FormulaToken ')';
PrefixOperation1Operand returns FormulaPrefixOperator:
code=('NOT' | '%CT' | '%GT' | '%RT' | '%XT' | '%YT' | 'ABS' | 'ACOS' | 'ASIN' | 'ATAN' | 'CEIL' | 'COS' | 'COSH' | 'COUNT'
| 'DATE' | 'DELTA' | 'EXP' | 'FIX' | 'FLOOR' | 'FRAC' | 'LEAF' | 'LOG' | 'LOG10' | 'MAX0' | 'MIN0' | 'NDIV0' |
'NODIM' | 'NOERR' | 'SCAL' | 'SIGN' | 'SIN' | 'SINH' | 'SQRT' | 'SUMCT' | 'SUMGT' | 'SUMRT' | 'TAN' | 'TANH' | 'TIME'
| 'TRUNC' | 'VECT') '(' childToken+=FormulaToken ')';
PrefixOperator1Operand returns NumericalOperator:
('NOT' | '%CT' | '%GT' | '%RT' | '%XT' | '%YT' | 'ABS' | 'ACOS' | 'ASIN' | 'ATAN' | 'CEIL' | 'COS' | 'COSH' | 'COUNT'
| 'DATE' | 'DELTA' | 'EXP' | 'FIX' | 'FLOOR' | 'FRAC' | 'LEAF' | 'LOG' | 'LOG10' | 'MAX0' | 'MIN0' | 'NDIV0' |
'NODIM' | 'NOERR' | 'SCAL' | 'SIGN' | 'SIN' | 'SINH' | 'SQRT' | 'SUMCT' | 'SUMGT' | 'SUMRT' | 'TAN' | 'TANH' | 'TIME'
| 'TRUNC' | 'VECT');
PrefixOperator2Operands returns NumericalOperator:
('MAX' | 'MIN');
/* like +5 */
SignOperatorPrio1 returns NumericalOperator:
('+');
SignOperatorPrio5 returns NumericalOperator:
('-');
InfixOperatorPrio1 returns NumericalOperator:
('+' | '-' | 'OR' | 'XOR');
InfixOperatorPrio2 returns NumericalOperator:
('%' | '%A' | '%_A' | '*' | '/' | 'AND' | 'DIV' | 'MOD');
InfixOperatorPrio3 returns NumericalOperator:
('**' | '<' | '<=' | '<>' | '==' | '>' | '>=');
FormulaCell:
id=CELL_ID;
FormulaConstant returns FormulaConstant:
value=FormulaConstantValue;
FormulaMeasure returns FormulaMeasure:
ref=[Member|SELECTION_ID];
/*like "S1(Amount) */
terminal SELECTION_ID returns ecore::EString: // self created to implement value converter
('S') ('0'..'9')* ('(') STRING (')');
/*like "C1(My Cell) */
terminal CELL_ID returns type::String: // self created to implement value converter
('C') ('0'..'9')* ('(') STRING (')');
FormulaConstantValue returns type::Double:
DOUBLE /* TODO: maybe we need value converter for that in order to be country specific about the decimal point*/;
/* this is the parent of formulaDefinition, for some reasons the serializer needs that rule */
MemberFormula returns MemberFormula:
formulaDefinition=FormulaDefinition;
terminal DOUBLE returns ecore::EDouble:
('0'..'9')+ (('.'|',') ('0'..'9')+)?; // double or int
terminal INT returns ecore::EInt:
'deactived since rule DOUBLE covers integers as well';
I'm using xtext's EmbeddedEditor for the formula in the popup.
Here is some coding:
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.xtext.resource.SaveOptions;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceFactory;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.serializer.ISerializer;
import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditor;
import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditorFactory;
import org.eclipse.xtext.ui.editor.embedded.IEditedResourceProvider;
import com.google.inject.Injector;
import com.sap.bw.localization.TextConstants;
@SuppressWarnings("restriction")
public class XtextEObjectEmbeddedEditor {
private EObject eObject;
private Injector injector;
private XtextResource resource;
public XtextEObjectEmbeddedEditor(EObject eObject, Injector injector) {
this.eObject = eObject;
this.injector = injector;
}
public void createEditor(Composite parent) {
EmbeddedEditor e = getEditor(parent);
e.createPartialEditor(TextConstants.EMPTY_STRING, getSerializedFormula(),
TextConstants.EMPTY_STRING, false);
}
private String getSerializedFormula() {
SaveOptions options = SaveOptions.newBuilder().noValidation().getOptions();
ISerializer serializer = injector.getInstance(ISerializer.class);
return serializer.serialize(eObject, options);
}
private EmbeddedEditor getEditor(Composite parent) {
EmbeddedEditorFactory factory = injector.getInstance(EmbeddedEditorFactory.class);
EmbeddedEditor embeddedEditor = factory.newEditor(getResourceProvider()).withParent(parent);
return embeddedEditor;
}
private IEditedResourceProvider getResourceProvider() {
IEditedResourceProvider resourceProvider = new IEditedResourceProvider() {
@Override
public XtextResource createResource() {
return getResource();
}
};
return resourceProvider;
}
private XtextResource getResource() {
URI uri = eObject.eResource().getURI();
XtextResourceFactory resourceFactory = injector.getInstance(XtextResourceFactory.class);
resource = (XtextResource) resourceFactory.createResource(uri);
XtextResourceSet rs = injector.getInstance(XtextResourceSet.class);
rs.setClasspathURIContext(getClass());
rs.getResources().add(resource);
// loading the resource is done by xtext embedded editor
return resource;
}
public EObject getEObject() {
return resource.getContents().get(0);
}
}
The call is more or less
new XtextEObjectEmbeddedEditor(formulaDefinition, QueryFormulaActivator.getInstance().getInjector(QueryFormulaActivator.COM_SAP_BW_QD_FORMULA_QUERYFORMULA)).createEditor(parentComposite);
Now my question:
In the grammar you can see that FormulaMeasure has a reference to Member (which is also part of the query).
How can I get all the Member(s) from the Query? Is it local scoping or is it global scoping (it is actually the same resource, at least when popup is closed and formulaDefinition is set back to Query).
[Updated on: Fri, 04 April 2014 15:13] Report message to a moderator
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.02786 seconds