Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » XML Binding to EMF ( Inline element AnyType)
XML Binding to EMF [message #1751144] Wed, 04 January 2017 22:30 Go to next message
Ioan Salau is currently offline Ioan SalauFriend
Messages: 69
Registered: July 2009
Location: Toronto
Member

I am trying to create an .ecore file based on maven pom.xsd in order to generate maven pom.xml using M2M tools (QVTo). The issue I currently encounter is around properties. Basically, pom allows to specify user defined properties as:

....
<properties>
<name1.version>2.3.7</name1.version>
<name2.version>2.3.7</name2.version>
.....
</properties>
....

Obviously, the name of property will not be defined in XSD as POM allows you to define any property with random name at design time.

XSD Fragment for this:

<xs:element minOccurs="0" name="properties">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>

And corresponding .ecore generated based on this pom.xsd will create an EClass "PropertiesType" with an EAttribute "any" as EFeatureMapEntry / ExtendedMetaData: kind="elementWildcard", wildcards="##any", name=":0", processing="skip".

To add a new property, I have defined an operation named addInlineProperty(String name, String value) with following implementation:

-- code starts --

public void addInlineProperty(String name, String value) {
final ExtendedMetaData extendedMetaData =
new BasicExtendedMetaData( this.eResource().getResourceSet().getPackageRegistry() );
EStructuralFeature feature = extendedMetaData.demandFeature(mpom4Package.eNS_URI, name, true);


EClass propertyClass = feature. getEContainingClass();
EObject propertyObject = EcoreUtil.create(propertyClass);
FeatureMapUtil.addText(((XMLTypeDocumentRoot)propertyObject).getMixed(),value);



getAny().add(feature, propertyObject);
}

This will all the new property with the name of my choice but the property element gets an @xsi:type attribute as follows:

<?xml version="1.0" encoding="UTF-8"?>
<mpom4:project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mpom4="http://maven.apache.org/myPOM/4.0.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<mpom4:properties>
<mpom4:xyz xsi:type="mpom4">122</mpom4:xyz>
</mpom4:properties>
</mpom4:project>

@xsi:type value is the same as the NS_PREFIX of the EPackage I used to demand an EStructuralFeature which is not correct. I would like to either set the proper xsi:type to xsd:string or find a way to ignore at all xsi:type during serialization. I really appreciate any tips. Thanks, Ioan

Re: XML Binding to EMF [message #1751157 is a reply to message #1751144] Thu, 05 January 2017 07:00 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Instead of creating an object of the feature's eContainingClass (which is a document root and should never sensibly, in XML terms, be used anywhere except as the single root object of a resource) use XMLTypeFactory.eINSTANCE.createAnyType() to create the what's effectively equivalent to a DOM Node. That AnyType instance has a getMixed method into which you can add the content value and it can be added to the getAny() of the target.

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: XML Binding to EMF [message #1751161 is a reply to message #1751157] Thu, 05 January 2017 07:43 Go to previous messageGo to next message
Ioan Salau is currently offline Ioan SalauFriend
Messages: 69
Registered: July 2009
Location: Toronto
Member

Ed Merks wrote on Thu, 05 January 2017 02:00
Instead of creating an object of the feature's eContainingClass (which is a document root and should never sensibly, in XML terms, be used anywhere except as the single root object of a resource) use XMLTypeFactory.eINSTANCE.createAnyType() to create the what's effectively equivalent to a DOM Node. That AnyType instance has a getMixed method into which you can add the content value and it can be added to the getAny() of the target.


Thanks Ed fro your quick answer. I have tried this as well and I am getting xsi:type="xsd" instead of xsi:type="mpom4". Still not the result I was looking for as I need "xsd:string" or even better a way of skipping xsi:type serialization.

......
public void addInlineProperty(String name, String value) {
final ExtendedMetaData extendedMetaData =
new BasicExtendedMetaData( this.eResource().getResourceSet().getPackageRegistry() );
EStructuralFeature feature = extendedMetaData.demandFeature(mpom4Package.eNS_URI, name, true);
AnyType inlineElement = XMLTypeFactory.eINSTANCE.createAnyType();
FeatureMapUtil.addText(inlineElement.getMixed(),value);

getAny().add(feature, inlineElement);
}
.......
Re: XML Binding to EMF [message #1751175 is a reply to message #1751161] Thu, 05 January 2017 11:49 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Which resource factory is being used to create the resource being serialized? The generated factory? Have you tried reading in a correct serialization and looking at how this case is represented?

My guess is that you're not using the right options (as set in the generated factory) for serialization. You can set a breakpoint in org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElement(EObject, EStructuralFeature) and look at what happens here:
    boolean shouldSaveType = 
      saveTypeInfo ? 
        xmlTypeInfo.shouldSaveType(eClass, eType, f) : 
        eClass != eType && 
         (eClass != anyType || 
            extendedMetaData == null || 
            eType != EcorePackage.Literals.EOBJECT || 
            extendedMetaData.getFeatureKind(f) == ExtendedMetaData.UNSPECIFIED_FEATURE);


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: XML Binding to EMF [message #1751211 is a reply to message #1751175] Thu, 05 January 2017 16:50 Go to previous messageGo to next message
Ioan Salau is currently offline Ioan SalauFriend
Messages: 69
Registered: July 2009
Location: Toronto
Member

I am using QVTo to create a pom instance, so I guess QVTo uses generated factory. This is just a dummy .qvto file to reproduce the issue:

modeltype mpom4 "strict" uses mpom4('http://maven.apache.org/myPOM/4.0.0');
	
transformation toMPOM4(out pomOUT:mpom4);

main() {
	var docRoot : DocumentRoot := ''.map toPOM();
	docRoot.project.properties.addInlineProperty("abc","1.0");	
}

mapping String::toPOM() : DocumentRoot {
	project := object Model {
		properties := object PropertiesType {
					
		};
	};
};


I tried to change generated EMF source code:

  public class PomResourceImpl extends XMLResourceImpl {


with

public class PomResourceImpl extends GenericXMLResourceImpl {


I still get the same result when I execute the above .qvto transformation. What I noticed, when I used this POM embedded to a different model, xsi:type gets generated with a proper value i.e. "mpom4:DocumentRoot" when I use getContainingClass option. However, my preferred option will be to have no xsi:type at all. From XSD validation perspective, an xsi:type is not necessary when we have in XSD an any type. I guess EMF default behaviour is to save the xsi:type, so when this file is loaded later on, it will help creating proper EMF EObject. I will follow your recommendation to troubleshoot further the default behaviour. Many thanks Ed. All the best and Happy New Year:)
Re: XML Binding to EMF [message #1751217 is a reply to message #1751211] Thu, 05 January 2017 18:27 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Do you see that for your schema-based model there is a generated resource factory? That is where the necessary options are set; changing the base class for your resource implementation isn't likely to help, and if your factory isn't used in the first place, it will of course have no impact. You should ensure that your factory is the one being used to create the resource. And note, that given the file extension is "xml", it's unlikely that you can just globally register your factory against that extension without conflict.

Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:[Xcore] EcorePackage version issue (in Xtext validator)
Next Topic:[Xcore] instanceof / typeof / casting problem when working with dynamic Instances
Goto Forum:
  


Current Time: Fri Apr 19 03:22:56 GMT 2024

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

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

Back to the top