Community
Participate
Working Groups
Build Identifier: 20100617-1415 Texo 0.1.0-201008031709 If you have an enum in your ecore, the classifier id's in the generated model package are not correct and you will end up with the following exception: Caused by: java.lang.ClassCastException: org.eclipse.emf.ecore.impl.EEnumImpl cannot be cast to org.eclipse.emf.ecore.EClass at de.sim.texo.model.common.person.PersonModelPackage.getContactEClass(PersonModelPackage.java:787) at de.sim.texo.model.common.person.PersonModelPackage.initialize(PersonModelPackage.java:405) at de.sim.texo.model.common.person.PersonModelPackage.<clinit>(PersonModelPackage.java:376) ... 31 more Reproducible: Always
Created attachment 179011 [details] Sample ecore
Created attachment 179012 [details] Sample Annotionsmodel
As workaround you can debug into the getEPackage method of the generated package and find the right index for the certain classes/enums and change their CLASSIFIER_ID's by hand in the generated code.
Hi Mark, Both attachments seem to be empty when I download them, can you email them directly to me: mtaal@elver.org gr. Martin
Hi, Forget my request, I can download them. gr. Martin
Hi Mark, I reacted in the newsgroup for completeness: Hi Mark, I checked the annotations model and there are some strange in there. For example the Address eclass annotation has this eattribute: qualifiedClassName="texo.test.Address" however, the Person eclass has an ereference annotation for address with this eattribute: type="test.Address" This is the reason that there are compile errors in the generated code for the Person, as it refers to a type which does not get generated. It is best to have a quite empty annotationsmodel (so only annotate what you want to change, the rest is automatically generated). So to solve this I would remove all the ereference annotations. To be sure, did you manually change the annotations model? The reason that the ContactType enum is generated in a separate package is because its annotation has this eattribute set: qualifiedClassName="test.ContactType" so therefore it ends up in the test package and not in the texo.test package. gr. Martin
Hi Mark, Which Eclipse/EMF version are you using? I tried it on EMF 2.6/Eclipse 3.6. gr. Martin
(In reply to comment #7) > Hi Mark, > Which Eclipse/EMF version are you using? I tried it on EMF 2.6/Eclipse 3.6. > > gr. Martin Hi Martin, I investigated a little bit. In my opinion, without looking in the code I would say, the CLASSIFIER ID's that are generated in the ModelPackage are the position of the eclassifier-tag in the ecore file. I verified that using an ecore with 12 classes and enums. The generated numbers reflect exactly the position number of the eclassifier tag in the ecore xml file. Enums and eclasses are mixed in the order. The order is given by the ecore-file. The order in the ModelPackage#getEPackage- eClassifiers starts with eclasses after that the enums are listed. The order of all eclasses are the same as before and the order of the enums is the same, but eclasses and enums are not mixed: Example: Ecore Order 0 Person class 1 TitleType enum 2 GenderType enum 3 Address class 4 Geolocation class 5 AddressList class 6 PersonList class 7 Contact class 8 ContactType enum 9 ContactContextType enum 10 ContactList class 11 MaritalStatusType enum ModelPackage eClassifier order: 0 Person class (ecore index 0) 1 Address class (ecore index 3) 2 Geolocation class (ecore index 4) 3 AddressList class (ecore index 5) 4 PersonList class (ecore index 6) 5 Contact class (ecore index 7) 6 ContactList class (ecore index 10) 7 TitleType enum (ecore index 1) 8 GenerType enum (ecore index 2) 9 ContactType (ecore index 8) 10 ContactContextType (ecore index 9) 11 MaritalStatusType (ecore index 11) I think something like this could happened while creating the model code (Pseudocode): List<EEnum> enums = new LinkedList<EEnum>(); List<EClass> eclasses = new LinkedList<EClass>(); Map<String,Short) classifierIdMap = new HashMap<String,Integer>(); ECLassifier[] ecoreClassifiers = ecorePackage.getAllEClassifiers(); for (int i = 0; i < ecoreClassifiers.length; i++) { EClassifier ec = ecoreClassifiers[i]; String eclassConst = null; if (ec instanceof EClass) { eclasses.add((EClass)ec); } if (ec instanceof EEnum) { enums.add((Enum)ec); } classifierIdMap.put(ec.getName(), i); } List<EClassifier> modelClassifiers = new ArrayList... modelClassifiers.addAll(eclasses); modelClassifiers.addAll(enums); return modelClassifiers; Regards, Mark
Hi Mark, I am not sure, this is the piece of template which creates the content of the ModelPackage: «FOREACH this.EDataTypeModelGenAnnotations AS eClassifierAnnotation-» public static final int «toUpperCase(eClassifierAnnotation.name)»_CLASSIFIER_ID = «eClassifierAnnotation.EClassifier.classifierID»; «ENDFOREACH» «FOREACH this.EClassModelGenAnnotations AS eClassAnnotation-» public static final int «toUpperCase(eClassAnnotation.name)»_CLASSIFIER_ID = «eClassAnnotation.EClass.classifierID»; so afaics, the classifier id in the generated code is exactly the same as the classifierid created/used by EMF. Can you try the following in some testcode: for (EClassifier eClassifier : ePackage.getEClassifiers()) { System.err.println(eClassifier.getName() + " --> " eClassifier.getClassifierID()); } where ePackage is your ePackage. Can you attach the generated ModelPackage java file to this bugzilla? gr. Martin
Created attachment 179074 [details] My ecore
Created attachment 179075 [details] My ModelPackage
(In reply to comment #9) > so afaics, the classifier id in the generated code is exactly the same as the > classifierid created/used by EMF. Its seems to be like that > > Can you try the following in some testcode: > for (EClassifier eClassifier : ePackage.getEClassifiers()) { > System.err.println(eClassifier.getName() + " --> " > eClassifier.getClassifierID()); > } > where ePackage is your ePackage. Here is the result: Person --> 0 Address --> 1 GeoLocation --> 2 AddressList --> 3 PersonList --> 4 Contact --> 5 ContactList --> 6 TitleType --> 7 GenderType --> 8 ContactType --> 9 ContactContextType --> 10 MaritalStatusType --> 11 My currently working configuration is: Person --> 0 Address --> 3 GeoLocation --> 4 AddressList --> 5 PersonList --> 6 Contact --> 7 ContactList --> 10 TitleType --> 1 GenderType --> 2 ContactType --> 8 ContactContextType --> 9 MaritalStatusType --> 11 Regards, Mark
Hi Mark, A quick scan of the ModelPackage shows no collision in classifier ids, or am I maybe overlooking something? Does this ModelPackage work correctly? gr. Martin
(In reply to comment #13) > Hi Mark, > A quick scan of the ModelPackage shows no collision in classifier ids, or am I > maybe overlooking something? > Does this ModelPackage work correctly? > > gr. Martin Hi Martin, the CLASSIFIER_ID constants are used as index to access the classifiers list in the epackage of the model package. The problem is the sort order doesn't match to the generated classifier id's anymore. The sort order in the epackage.getEClassifier list is: eClassifier --> index Person --> 0 Address --> 1 GeoLocation --> 2 AddressList --> 3 PersonList --> 4 Contact --> 5 ContactList --> 6 TitleType --> 7 GenderType --> 8 ContactType --> 9 ContactContextType --> 10 MaritalStatusType --> 11 But the CLASSIFIER_ID's have another sort order. If you would load parse the XML of the ecore you wouldn't get this order: Person --> 0 ModelPackage.getEClassifier(PERSON_CLASS_ID) matches Person TitleType --> 1 ModelPackage.getEClassifier(TITLETYPE_CLASS_ID) matches Address GenderType --> 2 ModelPackage.getEClassifier(GENDERTYPE_CLASS_ID) matches GeoLocation and so on. This is the order the CLASSIFIER_ID in the model package are generated from. This mismatch causes the error. There are no double ID's. The classifier id reflect the order od the eClassifier tags from the ecore-file. The eClassifiers in the ePAckage.getEClassifier are ordered: first classes then enums. I have to take a deeper look into it. Regards, Mark
(In reply to comment #13) > Hi Mark, > A quick scan of the ModelPackage shows no collision in classifier ids, or am I > maybe overlooking something? > Does this ModelPackage work correctly? At me, the attached ModelPackage doesn't work. I changed the CLASSIFIER_ID's by hand, after getting the right order from the eClassifier list with debugging. Mark
Okay, I finally understand what you mean... Can you generate once more an incorrect ModelPackage and then zip up the whole generated javapackage (with the sources) and attach it to this bugzilla? The ecore model attached now, is that the one used to generate the source code, or is the one copied into the source tree? I would need both. gr. Martin
Maybe it is this: in the annotations model in the epackage annotation there is an attribute ecorefilecontent. This contains the ecore model which is written out to the ecore file in the generated source package. As it is already set it is not overwritten in subsequent generation actions. This means that you have an old model there. The sources are however generated on the basis of the ecore file on which you do right-click. In the latest build of Texo this attribute is not serialized anymore. Can you try to remove this attribute and regenerate the sources? My feeling is that this is the issue... gr. Martin
Hi Martin, I can make the problem reproducable. If you have just an ecore a 1. I created an empty EMF project 2. Create an ecore as an mix of classes and enums in the order like this: - class AClass - enum AEnum - class BClass - enum BEnum 3. Add Texo nature to this project 4. Create the texo model code without an annotationsmodel 5. Test creating the model package: Everything works here now. No error here 6. Create a genmodel from the ecore 7. I just modified the base package attribute in the genmodel 8. Create the model code 9. Add the texo dependency to the plugin again 10. Delete the old model code 11. Generate the model code again 12. Test creating the model code fails now. I tested this with the latest texo 0.1.0-201009161717. In my opinion the problem has something to do with the extension: <extension point="org.eclipse.emf.ecore.generated_package"> <package class="emf.test.TestPackage" genModel="model/test.genmodel" uri="http://test"> </package> </extension> And the model generation in texo. Before I created the genmodel, everything was fine, but this package wasn't registered. After generating the model code the extension was added and texo generates wrong classifier id's in the model package. I attached my sample project as zip. Regards, Mark
Created attachment 179240 [details] Sample plugin that demonstrates the problem
The Problem lies in the org.eclipse.emf.texo.utils.ModelUtils#readEPackagesFromFile If the package is already registered, nothing will be done in this method. Thats the case, if you have the package registered via org.eclipse.emf.ecore.generated_package-extension. If you get the ePackage now from ModelPackage#getEPackage the field ePackage is null and the method gets the ePackage via ModelUtils#getEPackage(getNsURI()). The eClassifier field has after this example the sort order: EClass AClass EClass BClass EClass BEnum (my mistake, i defined BEnum as ECLass and not as ENum) EENum AEnum Now delete the plugin.xml and with it the extension generated_package!. What happens now, is the ModelUtils#readEPackagesFromFile reads the ecore file and gets an package from it, which will be registered with the corresponding registry. The eClassifier field here has a different sort order: EClass AClass EENum AEnum EClass BClass EClass BEnum (my mistake, i defined BEnum as ECLass and not as ENum) I hope this information helps. Regards, Mark
Hi Mark, Okay clear so this happens when you have both EMF generated code and the plugin.xml and then also generate Texo code. I need to think of a solution for this. Texo will always check the package registry for the epackage, it is kind of difficult to do this differently as Texo should not read an epackage if it is already present in the registry. I am keeping this bugzilla open for now. Thanks for your detailed analysis! gr. Martin
Hi Martin, thought about this problem. Maybe I am wrong but there are two use cases generate the model code: 1. you have just an ecore and no generated EMF code from the genmodel 2. you have ecore and genmodel and the package that is registered in the plugin xml For case 1 there are no problems. But, for case two, the model code has to be based on the registered packages. I just looked in the org.eclipse.emf.texo.eclipse.popup.actions.GenerateCode class. In line 49 GeneratorUtils#readEPackages((final List<java.net.URI> uris, EPackage.Registry registry) will be called, that delegates to GeneratorUtils#readEPackagesUsingEMFURI(final List<URI> uris, EPackage.Registry registry). If I understand the code right, the ecore file is loaded and the packages are registered. Maybe a solution is, to look in the ePackage registry first, to check, if there is an already existing package. I created an patch, to show what I mean. But I never tested the patch because, I couldn't get a build from the sources. Regards, Mark
Created attachment 194252 [details] Patch for GeneratorUtils (never tested!!!!)
Created attachment 194255 [details] Better Patch for GeneratorUtils (never tested!!!!) Please ignore patch on attachment 194252 [details].
Hi Mark, Thanks for the patch, I made some changes in a different way which should also solve this. Can you try the latest build of Texo? gr. Martin
Hi Martin, a first quick test with version 0.1.0.v201104282119 didn't succeed. I will check it. Regards, Mark
Hi again, the sample plugin, from the bug attachment, doen't work too. Ragards, Mark
Okay I made a new solution, the eclassifiers are now sorted before generating the modelcode, the sorting is the same as in the genmodel generated code. Closing the issue, please re-open if it is still not solved...
I just ran into this same problem Mark ran into --- ClassCastException --- using Texo version org.eclipse.emf.texo_0.9.0.v201611141242: Caused by: java.lang.ClassCastException: org.eclipse.emf.ecore.impl.EDataTypeImpl cannot be cast to org.eclipse.emf.ecore.EEnum at com.humanfactor.rw.model.entity.factory.RegattaModelPackage.getCapturedResultsVersionEEnum(RegattaModelPackage.java:14092) at com.humanfactor.rw.model.entity.factory.RegattaModelPackage.initialize(RegattaModelPackage.java:6191) at com.humanfactor.rw.model.entity.factory.RegattaModelPackage.<clinit>(RegattaModelPackage.java:5971) ... 2 more Like Mark, I found that the feature IDs in the Texo-generated ModelPackage were out of sync with the EMF-generated EPackage. I traced the cause down to the fact that Texo generates the ModelPackage feature IDs from the .ecore file, while EMF generates them using its .genmodel file. When the ordering of the EClasses, EEnums and EDataTypes differ between these two, the integer assignments in the ModelPackage and EPackage are out of sync. The genmodel auto-sorts the EClasses and features from the .ecore file into groups (EClasses, EDataTypes, EEnums, etc). In my case the .ecore file was interspersed randomly with EClasses, EDataTypes and EEnums and EMF sorted them nicely in the genmodel file. The ordering of the elements determines how the integer IDs are assigned. My workaround is to manually sort/order the .ecore file to match the genmodel. When I do this, The Texo-generate ModelPackage assigns the IDs just as EMF does and the ClassCastException disappears. Martin, in your previous fix you apparently solved the EClass, EEnum sorting problem that Mark found, but not EDataType sorting. Perhaps there are other feature types that need to to be sorted too, but I don't use them. Another approach would be to read the .genmodel file and use its ordering instead of the .ecore file. That would be resilient to changes in how EMF decides to sore the genmodel file in the future.