Skip to main content

Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Default INT value to 0 not serialized in xmi
Default INT value to 0 not serialized in xmi [message #1861334] Fri, 06 October 2023 12:26 Go to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Hi all,

Maybe this is a topic more related to EMF serialization but as I'm working in a Xtext project, I'm asking here.
I have a grammar with a rule containing an optional element (port_value) of type int:

 '__Node' name=ID '{' 
 ('__PortSelect' '=' port_select=STRING ';')?
 ('__PortNumber' '=' port_value=INT ';')?
 ('__SyncPoint' '=' sync_point=BooleanType ';')?
 ('__Exec' '=' execution=ID ';')?

From this grammar I'm serializing an example file to xmi but my problem is that I'm not seeing the port_value element when its value is 0. Then, when I deserialize the xmi, I can't retrieve the same content as my original file because this field is missing.

This is my example file:
__SubFlow FtDualSupplyVmin_SubFlow {
    __Node FT_DSVmin_Pass {
        __XCoord = (1336,95);
        __InputPosition = 279;
        __TestID = "";
        __EnableExpression = __Expression { __String = "TRUE"; __Type = BOOLEAN; }
        __PortSelect = "0";
        __PortNumber = 0;

And the associated xmi:
<?xml version="1.0" encoding="ASCII"?>
<unaDsl:UnaFile xmi:version="2.0" xmlns:xmi="" xmlns:xsi="" xmlns:unaDsl="">
  <una_elements xsi:type="unaDsl:SubFlow" name="FtDualSupplyVmin_SubFlow">
    <elements xsi:type="unaDsl:Node" name="FT_DSVmin_Pass" port_select="0">
      <coordinates x="1336" y="95"/>
      <input_position position="279"/>
      <testId name=""/>
        <expr expr="TRUE" type="BOOLEAN"/>

In my xtend file where I have the code to serialize my file, I added the option OPTION_KEEP_DEFAULT_CONTENT but no change:
		val Resource xmiResource = resourceSet.createResource(URI.createFileURI(xmiResourcePathName))
		var options = new HashMap<String, Object>();
		options.put(XMIResource.OPTION_KEEP_DEFAULT_CONTENT, Boolean.TRUE);[b]options[/b])

Using the debugger I followed the code execution to find out where this parameter is filtered.
I found in the class org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl, the method saveFeatures() is going through all features and calls shouldSaveFeature().
  protected boolean shouldSaveFeature(EObject o, EStructuralFeature f)
    return o.eIsSet(f) || keepDefaults && f.getDefaultValueLiteral() != null;

keepDefaults is set to true thanks to the option OPTION_KEEP_DEFAULT_CONTENT but the feature getDefaultValueLiteral() method return null.
And the eIsSet() for my rule Node return false because it test the value of the object to its default value which is set to 0 in the generated file.
  protected static final int PORT_VALUE_EDEFAULT = 0;
  public boolean eIsSet(int featureID)
    switch (featureID)
      case UnaDslPackage.NODE__NAME:
        return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
      case UnaDslPackage.NODE__COORDINATES:
        return coordinates != null;
      case UnaDslPackage.NODE__PORTS_CONNECTION:
        return ports_connection != null && !ports_connection.isEmpty();
      case UnaDslPackage.NODE__INPUT_POSITION:
        return input_position != null;
      case UnaDslPackage.NODE__TEST_ID:
        return testId != null;
      case UnaDslPackage.NODE__ENABLE_EXPRESSION:
        return enableExpression != null;
      case UnaDslPackage.NODE__PORT_SELECT:
        return PORT_SELECT_EDEFAULT == null ? port_select != null : !PORT_SELECT_EDEFAULT.equals(port_select);
      case UnaDslPackage.NODE__PORT_VALUE:
        return port_value != PORT_VALUE_EDEFAULT;
      case UnaDslPackage.NODE__SYNC_POINT:
        return SYNC_POINT_EDEFAULT == null ? sync_point != null : !SYNC_POINT_EDEFAULT.equals(sync_point);
      case UnaDslPackage.NODE__EXECUTION:
        return EXECUTION_EDEFAULT == null ? execution != null : !EXECUTION_EDEFAULT.equals(execution);
    return super.eIsSet(featureID);

Is there a way to either change the NodeImpl to avoid having the default value tested ? Or to add a 'DefaultValueLiteral' in the EMF model ?
I hope I'm not mixing everything here, my knowledge on this is only practical, running the debugger to reverse engineer the behavior.
Thanks for any support on that.
Re: Default INT value to 0 not serialized in xmi [message #1861335 is a reply to message #1861334] Fri, 06 October 2023 12:53 Go to previous message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Nevermind, I figured out a solution by changing my grammar.
 '__Node' name=ID '{' 
 ('__PortSelect' '=' port_select=STRING ';')?
 //('__PortNumber' '=' port_value=INT ';')?
 ('__SyncPoint' '=' sync_point=BooleanType ';')?
 ('__Exec' '=' execution=ID ';')?

'__PortNumber' '=' port_number=INT ';'	

Problem solved. Sorry for the disturbance.
Previous Topic:Inefficient Validation
Next Topic:compile error: InternalModelingDslParser: too much static variables
Goto Forum:

Current Time: Sun Jul 14 04:55:57 GMT 2024

Powered by FUDForum. Page generated in 0.03458 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top