Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 322094

Summary: Implicity Default for EDouble Not Serialized
Product: [Modeling] EMF Reporter: Ole Ersoy <ole.ersoy>
Component: XML/XMIAssignee: Ed Merks <Ed.Merks>
Status: RESOLVED INVALID QA Contact:
Severity: enhancement    
Priority: P3 CC: ole.ersoy
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:

Description Ole Ersoy CLA 2010-08-08 17:45:41 EDT
Build Identifier: M20090917-0800

I read through a serialized instance of a model and noticed that EMF does not serialize EAttribute instances of type EDouble when the value is set to the default value for EDouble.  It would be nice if it did for the purpose of being able to analyze serialized data.

Reproducible: Always

Steps to Reproduce:
    	EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE;
    	EcorePackage ecorePackage = EcorePackage.eINSTANCE;

    	// Warehouse class
    	EClass warehouseClass = ecoreFactory.createEClass();
    	warehouseClass.setName("Warehouse");

    	// Warehouse name property
    	EAttribute warehouseName = ecoreFactory.createEAttribute();
    	warehouseName.setName("name");
    	warehouseName.setEType(ecorePackage.getEString());
    	warehouseClass.getEStructuralFeatures().add(warehouseName);

    	//Part class
    	EClass partClass = ecoreFactory.createEClass();
    	partClass.setName("Part");

    	//Part class name
    	EAttribute partName = ecoreFactory.createEAttribute();
    	partName.setName("name");
    	partName.setEType(ecorePackage.getEString());
    	partClass.getEStructuralFeatures().add(partName);
    	
    	//Part class price
    	EAttribute partPrice = ecoreFactory.createEAttribute();
    	partPrice.setName("price");
    	partPrice.setEType(ecorePackage.getEDouble());
    	partClass.getEStructuralFeatures().add(partPrice);
    	

    	// Warehouse part reference container 
    	EReference warehouseParts = ecoreFactory.createEReference();
    	warehouseParts.setName("warehouseParts");
    	warehouseParts.setEType(partClass);
    	warehouseParts.setContainment(true);
    	warehouseParts.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
    	warehouseClass.getEStructuralFeatures().add(warehouseParts);

    	//Warehouse package
    	EPackage warehousePackage = ecoreFactory.createEPackage();
    	warehousePackage.setName("warehouse");
    	warehousePackage.setNsPrefix("warehouse");
    	warehousePackage.setNsURI("http:///com.example.warehouse");
    	warehousePackage.getEClassifiers().add(partClass);
    	warehousePackage.getEClassifiers().add(warehouseClass);
    	
    	//Creating an instance reflectively
    	EFactory warehouseFactory = warehousePackage.getEFactoryInstance();

    	EObject warehouse = warehouseFactory.create(warehouseClass);
    	warehouse.eSet(warehouseName, "chicago-warehouse");

    	EObject partInstance = warehouseFactory.create(partClass);
    	partInstance.eSet(partName, "SKU123");
    	partInstance.eSet(partPrice, 0.0);

    	((List)warehouse.eGet(warehouseParts)).add(partInstance);
    	
    	// create resource set and resource 
    	ResourceSet resourceSet = new ResourceSetImpl();

    	// Register XML resource factory
    	resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xml", 
    	new XMLResourceFactoryImpl());

    	Resource resource = resourceSet.createResource(URI.createFileURI("src/test/resources/warehouse.xml"));
    	// add the root object to the resource
    	resource.getContents().add(warehouse);
    	// serialize resource – you can specify also serialization
    	// options which defined on org.eclipse.emf.ecore.xmi.XMIResource
    	resource.save(null);

        assertEquals( partInstance.eGet(partPrice), 0.0 );


Output produced by the code:

<?xml version="1.0" encoding="ASCII"?>
<warehouse:Warehouse xmlns:warehouse="http:///com.mydemandchain.warehouse" name="chicago-warehouse">
  <warehouseParts name="SKU123"/>
</warehouse:Warehouse>

If an analyst were to read the raw xml, it would seem that the warehouseParts element is missing the price attribute all together.
Comment 1 Ed Merks CLA 2010-08-08 21:13:11 EDT
This is working as designed. For any given feature, if eIsSet is false, the value will not be serialized.  

There are options like this might be what you want.

  /**
   * Keep default content ( e.g. default attributes). This applies to saving and converting contents to DOM.
   * By default the default content is discarded.
   * To save the default content, set this option to <code>Boolean.TRUE</code>.
   */
  String OPTION_KEEP_DEFAULT_CONTENT = "KEEP_DEFAULT_CONTENT";

In this case, attributes with explicit defaults in the Ecore model will serialize that default value.  Note that I mean an explicit default; the implicit default zero for all the numeric types will not be serialized unless you explicitly set that value on the EAttribute.

Another alternative is to make the feature unsettable so that the distinction between never have been set and being set to the default value is captured in the model.
Comment 2 Ed Merks CLA 2010-08-08 21:13:44 EDT
So this bug is invalid.