-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Extrinsic XMI IDs #62
Comments
Hi, the short answer is that NMF always tries to use index-based identifiers until either this is not possible (because the collection underneath is not ordered) or elements explicitly declare identifiers. In the first case, NMF uses XMI IDs, but I understand that you would probably not want to use unordered collections all over the place just to force NMF to use XMI IDs. I guess this can be easily implemented as a flag in the serializer. Give me a couple of days. Best, Georg |
Thanks you very much Georg! Please let me know if there is anything I can do to assist.
Bill
… On Feb 22, 2021, at 1:33 AM, Georg Hinkel ***@***.***> wrote:
Hi,
the short answer is that NMF always tries to use index-based identifiers until either this is not possible (because the collection underneath is not ordered) or elements explicitly declare identifiers. In the first case, NMF uses XMI IDs, but I understand that you would probably not want to use unordered collections all over the place just to force NMF to use XMI IDs.
I guess this can be easily implemented as a flag in the serializer. Give me a couple of days.
Best,
Georg
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#62 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ALBHV63K4ZF3LEZHO7ITV2LTAH3DPANCNFSM4X7NAHEQ>.
|
c1f29bf should add this functionality, integrated into the model repositories. There is also a test that checks that the ids are on all model elements. The changes should be on Nuget in about 10min. Please reopen, if your problem persists. |
I see the changes on GitHub, but Nuget still showing v2.0.164. Should I be seeing a new version or does it take time to be available through Nuget?
Thanks for working this so quickly Georg!
… On Feb 22, 2021, at 2:09 PM, Georg Hinkel ***@***.***> wrote:
c1f29bf <c1f29bf> should add this functionality, integrated into the model repositories. There is also a test that checks that the ids are on all model elements. The changes should be on Nuget in about 10min. Please reopen, if your problem persists.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#62 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ALBHV62AR3MZM4ONHYDVGQTTAKTXJANCNFSM4X7NAHEQ>.
|
Yeah, I am having problems that Nuget somehow does not accept my API key. The old one was expired but I actually tried several attempts now to assign a new one, unfortunately with little success so far. |
Georg, Also, I see many cases where a reference from one element to another uses a name rather than the XMI:ID. Non-containment references need to use the XMI:ID of the element that is being referenced. I've only started trying to step through the code but am noticing that NMF makes the "name" property an ID by default. Is there a way to turn that off in the generator? Most often a UUID is generated when a new ID is required. Is it possible, for cases when an ID needs to be generated, that a user supplied ID generator is used? That way it can be adapted to whatever might be required. My plan is to continue to step through the serialization code to understand how it works and perhaps offer up some changes if I figure it out on my own. Its somewhat complex and I do worry that I'll break something along the way. Thanks for the support, and again my complements on creating such useful technology! |
The serialization code is actually the oldest part of NMF. I wrote large parts of it in my first and second term in university and then extended the code when necessary. This is also why the base is an XmlSerializer that is actually not really used. The entire serialization started with an idea to implement an XML serializer that was able to cope with circular references and only afterwards I tried to implement XMI as a special case... I guess the easiest option here would be to put a transient extension on the model elements to store the id, much like this is done for types to store their .NET type mapping. Afterwards, you could use this extension to obtain the id in serialization. That way, you have the full flexibility how you generate the id, if not present. |
I'm not sure I understand what you are suggesting and I'm afraid my knowledge of C# isn't nearly as deep as yours. Are you suggesting the use of a Service provider with dependency injection for ID generation? Or type extension where I define an extension method? If the latter, would that extension go on the ModelElement class? Would that require a Serializer and Deserializer that is cognizant of the extension? I'm certainly willing to try to work on an implementation, but a little more detailed advice would be extremely helpful to get me started. Best regards. |
Extensions are essentially the implementation of stereotypes in NMeta. You can see a |
Are you meaning that IDs be added to each element by storing them in the IModelElement Extensions member during deserialization? I looked into doing that by modifying the Set operation on the XmiArtificialIDAttribute and having it not only add the ID to the serialization context, but adding itself to the Extensions on the IModelElement being deserialized. The problem I encounter is that the Serialization project has no knowledge of ModelElements and therefore no access to their extensions. I can't add a reference to the Models project because that creates cycles in the project dependencies. I also looked at a more brute force approach of adding code to the ExplicitIdSerializer to add each Id to the extensions of each element at the conclusion of Deserialization and the doing something similar at the start of serializing, but the Deserialize/Serialize members are not virtual and I wasn't sure you would want to change that. Sorry if I misunderstand your suggestions. Thanks again for any your assistance. |
As said, the serialization code is the oldest in NMF. I eventually introduced extension points just as I needed them because it would have been too much effort to redesign the serialization component and the code had too much merits that I did not want to give up. The easy answer is that the property serialization that is used for the id is a virtual property, so you can just inherit from the BTW, the build currently does not work because somehow AppVeyor fails to push the packages to Nuget.org |
It sounds so easy when you describe it like that! Regarding overriding XmlArtificialIdAttribute I'm not sure how to get existing code to use this. The deserializer, which is initialized during construction of the repository, uses XmiArtificialId.Instance when loading in all of the meta data. I don't see an easy way to override this behavior since loading of the repositories is done in the construction of the MetaRepository and it is not something I can call externally. I can create an instance of the ExplicitIdSerializer using the one created in the repository as parent, but the XmiArtificialIds remain for each type and are employed during deserialization. I can use a class that inherits from XmiArtificialId during serialization because a newly created serializer seems to build the property info as needed. I created an ExplicitIdExtension element to add to model extensions per your original suggestion. The only way I could figure out to add it was to override InitializeAttributeProperties to add the extension whenever is came across a ModelIdAttribute property. This worked in that it added the extension to each element, but it caused other problems. First, the extension is now a child element of each model element, so my tree control that allows the user to browse the model sees these extensions. Second, and even more of a problem, the serializer tries to serialize it and end up with duplicate XMI. I've tried setting the XmlAttributeAttribute = false on the Id property of the extension but this seems to have no effect. I've been unable to find any ways to make the extension "transient" as you suggested in your earlier e-mail. After spending a good number of hours trying to get this to work in a manner consistent with your existing design, I ended up adding dictionaries to the ExplicitIdSerializer that are populated with IDs during deserialization, and then used to restore IDs during serialization with IDs being added for newly created elements. Of course, if one were to use a different serializer than the one used during deserialization, none of the original IDs would be available and new ones would be created for every element. This doesn't seem consistent with what you've been trying to accomplish in the design, but I'm happy to post it if you are interested. Let me know if you have any additional suggestions. |
When resolving an XMI model that uses XMI:ID attributes, NMF successfully resolves references using those IDs. When saving a model, NMF does not use the XMI:ID attribute but rather uses the URL path to the element instead. This causes a problem in round tripping data with other tools that depend on the XMI:ID. Is there a way to set the desired behavior? The goal is to utilize "Extrinsic IDs" as outlined in the EMF modeling guide.
The text was updated successfully, but these errors were encountered: