Serializer fails (grammar based on existing ecore) [message #1695891] |
Wed, 20 May 2015 03:09  |
Eclipse User |
|
|
|
Hi,
I've created a grammar (for a formula) based on a small part of an existing model (the query) for which we have a form based editor. A small part of the query is the formula for which a xtext popup editor is used. Persistence is done in the query model as xml.
When the popup is opened the formula is serialized. When popup closes formula is parsed back into query model.
After some needed model changes (for cross references) the serializer fails:
java.lang.RuntimeException: Could not serialize EObject via backtracking.
Constraint: null member=[QueryElement|STRING] null
Values: member(1), operandType(1)
Semantic Object: FormulaDefinition.formulaToken->FormulaMemberOperand
Context: FormulaToken
at org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic$ExceptionThrowingAcceptor.accept(ISerializationDiagnostic.java:70)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.createSequence(BacktrackingSemanticSequencer.java:451)
at com.sap.bw.qd.formula.serializer.AbstractQueryFormulaSemanticSequencer.sequence_FormulaMemberOperand(AbstractQueryFormulaSemanticSequencer.java:184)
at com.sap.bw.qd.formula.serializer.AbstractQueryFormulaSemanticSequencer.createSequence(AbstractQueryFormulaSemanticSequencer.java:88)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.acceptEObjectRuleCall(SequenceFeeder.java:299)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.acceptRuleCall(SequenceFeeder.java:325)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.accept(SequenceFeeder.java:222)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.accept(BacktrackingSemanticSequencer.java:407)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.createSequence(BacktrackingSemanticSequencer.java:449)
at com.sap.bw.qd.formula.serializer.AbstractQueryFormulaSemanticSequencer.sequence_FormulaDefinition(AbstractQueryFormulaSemanticSequencer.java:175)
at com.sap.bw.qd.formula.serializer.AbstractQueryFormulaSemanticSequencer.createSequence(AbstractQueryFormulaSemanticSequencer.java:59)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:85)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:108)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:122)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:51)
at com.sap.bw.qd.formula.serialize.UnitTest.test_FD_withOperandType(UnitTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
The reason is the new attribute operandTypein
<xsd:complexType name="FormulaMemberOperand">
<xsd:annotation>
<xsd:documentation xml:lang="en">
wrapper for cross references to QueryElements which can be
</xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="FormulaToken">
<xsd:attribute name="member" type="xsd:IDREF" ecore:reference="QueryElement" use="required" />
------->> <xsd:attribute name="operandType" type="MemberOperandType" use="optional" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
In the grammar there is no handling for operandType:
/*
* Is something like "[0VC_AMT] Amount" or "Amount" (depends on display mode handler)
* and represents a variable or a member (selection, cell, formula)
*/
FormulaMemberOperand returns FormulaMemberOperand:
member=[QueryElement|STRING];
operandType is set in the Linker in afterModelLinked. This information is needed for further processing but it shouldn't matter for the serialization.
For
FormulaDefinition {
cref FormulaToken formulaToken FormulaMemberOperand {
ref QueryElement member ref: MemberSelection@5I3Y6060H25K3T09I2HST0WEN
attr MemberOperandType operandType 'Member'
}
}
serialization fails. I guess it tries to find handling for operandType in the grammar.
My question: Can I force the serializer to ignore the "unknown" (with respect to the grammar) attributes.
On solution would be to write an own serializer and call FormulaMemberOperand.unsetOperandType. But is it the best?
|
|
|
Re: Serializer fails (grammar based on existing ecore) [message #1696046 is a reply to message #1695891] |
Thu, 21 May 2015 07:16   |
Eclipse User |
|
|
|
found a solution:
Before operandType has been introduced in the model a method in Abstract<MyGrammar>SemanticSequencer looked like this:
@SuppressWarnings("restriction")
protected void sequence_FormulaMemberOperand(EObject context, FormulaMemberOperand semanticObject) {
if (errorAcceptor != null) {
if (transientValues.isValueTransient(semanticObject, QueryPackage.Literals.FORMULA_MEMBER_OPERAND__MEMBER) == ValueTransient.YES)
errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject,
QueryPackage.Literals.FORMULA_MEMBER_OPERAND__MEMBER));
}
INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
feeder.accept(grammarAccess.getFormulaMemberOperandAccess().getMemberQueryElementSTRINGTerminalRuleCall_0_1(),
semanticObject.getMember());
feeder.finish();
}
Now it looks like this and this caused the above mentioned error:
/**
* Constraint:
* member=[QueryElement|STRING]
*/
protected void sequence_FormulaMemberOperand(EObject context, FormulaMemberOperand semanticObject) {
genericSequencer.createSequence(context, semanticObject);
}
So I have overwritten the method in <MyGramma>SemanticSequencer and added the original code there and it works again:
@SuppressWarnings("restriction")
@Override
protected void sequence_FormulaMemberOperand(EObject context, FormulaMemberOperand semanticObject) {
if (errorAcceptor != null) {
if (transientValues.isValueTransient(semanticObject, QueryPackage.Literals.FORMULA_MEMBER_OPERAND__MEMBER) == ValueTransient.YES)
errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject,
QueryPackage.Literals.FORMULA_MEMBER_OPERAND__MEMBER));
}
INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
feeder.accept(grammarAccess.getFormulaMemberOperandAccess().getMemberQueryElementSTRINGTerminalRuleCall_0_1(),
semanticObject.getMember());
feeder.finish();
}
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03039 seconds