Skip to content
This repository has been archived by the owner on Jun 26, 2021. It is now read-only.

attribute serialization #58

Closed
lex-em opened this issue Jul 15, 2015 · 12 comments
Closed

attribute serialization #58

lex-em opened this issue Jul 15, 2015 · 12 comments

Comments

@lex-em
Copy link

lex-em commented Jul 15, 2015

Hi,

I have a problen with json serialization of ecore model. I'm trying to create .uml and .json (with emfjson) files like this:

ResourceSet umlResourceSet;

    @Before
    public void prepare(){
        umlResourceSet = new ResourceSetImpl();
        umlResourceSet.setURIConverter(URIConverter.INSTANCE);
        umlResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("json", new JsonResourceFactoryCit());
        umlResourceSet.getPackageRegistry().put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
        UMLResourcesUtil.init(umlResourceSet);
    }

    @Test
    public void test(){
        List<EObject> eObjects = new ArrayList<>();
        List<String> useCaseNames = Arrays.asList("Кредитовый перевод",
                "Инициирование кредитового перевода", "Коммерческий платеж",
                "Налоговый платеж", "Валютный платеж", "Межбанковский перевод", "Уведомление кредитора");
        List<String> actorNames = Arrays.asList("Дебитор", "Банк дебитора", "Банк-посредник",
                "Кредитор", "Банк кредитора");
        Map<String, UseCase> useCaseList = new HashMap<>();
        useCaseNames.stream().forEach(n -> {
            UseCase uc = UMLFactory.eINSTANCE.createUseCase();
            uc.setName(n);
            useCaseList.put(n, uc);
        });
        org.eclipse.uml2.uml.Package p = UMLFactoryImpl.init().createPackage();
        eObjects.add(p);
        Resource primitiveLib = umlResourceSet.getResource(URI.createURI(UMLResource.UML_PRIMITIVE_TYPES_LIBRARY_URI), true);
        Package primitiveLibPackage = (Package) EcoreUtil.getObjectByType(primitiveLib.getContents(), UMLPackage.Literals.PACKAGE);
        p.createPackageImport(primitiveLibPackage);
        p.setName("NPModel");
        Resource profileLib = umlResourceSet.getResource(URI.createURI("model/ISO20022Profile.profile.uml"), true);
        Package isoP = (Package) EcoreUtil.getObjectByType(profileLib.getContents(), UMLPackage.Literals.PACKAGE);
        p.applyProfile(isoP.containingProfile());
        actorNames.stream().forEach(n -> p.createPackagedElement(n, UMLFactoryImpl.getPackage().getActor()));
        isoP.containingProfile().getOwnedStereotypes().stream()
                .filter(s -> s.getName().contains("BusinessRole")).findFirst().ifPresent(st -> {
            NamedElement el = p.getPackagedElement("Банк дебитора");
            eObjects.add(el.applyStereotype(st));
        });
        useCaseList.forEach((n, uc) -> p.getPackagedElements().add(uc));
        Resource resource = umlResourceSet.createResource(URI.createURI("test.uml"));
        resource.getContents().addAll(eObjects);
        try {
            resource.save(null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Resource resourceJSON = umlResourceSet.createResource(URI.createURI("test.json"));
        resourceJSON.getContents().addAll(eObjects);
        try {
            resourceJSON.save(null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Created .uml is right:

<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ISO20022Profile="http:///schemas/ISO20022Profile/_Z1baoCR_EeW-eZ1ZLTAX7g/50" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http:///schemas/ISO20022Profile/_Z1baoCR_EeW-eZ1ZLTAX7g/50 model/ISO20022Profile.profile.uml#_Z1fsECR_EeW-eZ1ZLTAX7g">
  <uml:Package xmi:id="_eJYk0CquEeWRmPUlcrfDwQ" name="NPModel">
    <packageImport xmi:id="_eJYk0SquEeWRmPUlcrfDwQ">
      <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
    </packageImport>
    <packagedElement xmi:type="uml:Actor" xmi:id="_eJYk0iquEeWRmPUlcrfDwQ" name="Дебитор"/>
    <packagedElement xmi:type="uml:Actor" xmi:id="_eJYk0yquEeWRmPUlcrfDwQ" name="Банк дебитора"/>
    <packagedElement xmi:type="uml:Actor" xmi:id="_eJYk1CquEeWRmPUlcrfDwQ" name="Банк-посредник"/>
    <packagedElement xmi:type="uml:Actor" xmi:id="_eJYk1SquEeWRmPUlcrfDwQ" name="Кредитор"/>
    <packagedElement xmi:type="uml:Actor" xmi:id="_eJYk1iquEeWRmPUlcrfDwQ" name="Банк кредитора"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJYk1yquEeWRmPUlcrfDwQ" name="Инициирование кредитового перевода"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJYk2CquEeWRmPUlcrfDwQ" name="Межбанковский перевод"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJYk2SquEeWRmPUlcrfDwQ" name="Коммерческий платеж"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJZL4CquEeWRmPUlcrfDwQ" name="Уведомление кредитора"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJZL4SquEeWRmPUlcrfDwQ" name="Кредитовый перевод"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJZL4iquEeWRmPUlcrfDwQ" name="Налоговый платеж"/>
    <packagedElement xmi:type="uml:UseCase" xmi:id="_eJZL4yquEeWRmPUlcrfDwQ" name="Валютный платеж"/>
    <profileApplication xmi:id="_eJZL5CquEeWRmPUlcrfDwQ">
      <eAnnotations xmi:id="_eJZL5SquEeWRmPUlcrfDwQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
        <references xmi:type="ecore:EPackage" href="model/ISO20022Profile.profile.uml#_Z1fsECR_EeW-eZ1ZLTAX7g"/>
      </eAnnotations>
      <appliedProfile href="model/ISO20022Profile.profile.uml#_rspygA6UEeWHY4KRRC3kUQ"/>
    </profileApplication>
  </uml:Package>
  <ISO20022Profile:BusinessRole xmi:id="_eJZL5iquEeWRmPUlcrfDwQ" base_NamedElement="_eJYk0yquEeWRmPUlcrfDwQ" base_Actor="_eJYk0yquEeWRmPUlcrfDwQ"/>
</xmi:XMI>

But .json is not, there no attributes (in this case "name" attribute):

[
  {
    "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//Package",
    "_id": "_ezM94CquEeWRmPUlcrfDwQ",
    "packageImport": [
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//PackageImport",
        "_id": "_ezM94SquEeWRmPUlcrfDwQ",
        "visibility": "public",
        "importedPackage": {
          "$ref": "pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"
        },
        "importingNamespace": {
          "$ref": "_ezM94CquEeWRmPUlcrfDwQ"
        }
      }
    ],
    "packagedElement": [
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//Actor",
        "_id": "_ezM94iquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//Actor",
        "_id": "_ezM94yquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//Actor",
        "_id": "_ezM95CquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//Actor",
        "_id": "_ezM95SquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//Actor",
        "_id": "_ezM95iquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM95yquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM96CquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM96SquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM96iquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM96yquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM97CquEeWRmPUlcrfDwQ"
      },
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//UseCase",
        "_id": "_ezM97SquEeWRmPUlcrfDwQ"
      }
    ],
    "profileApplication": [
      {
        "eClass": "http://www.eclipse.org/uml2/5.0.0/UML#//ProfileApplication",
        "_id": "_ezM97iquEeWRmPUlcrfDwQ",
        "eAnnotations": [
          {
            "eClass": "http://www.eclipse.org/emf/2002/Ecore#//EAnnotation",
            "_id": "_ezM97yquEeWRmPUlcrfDwQ",
            "source": "http://www.eclipse.org/uml2/2.0.0/UML",
            "references": [
              {
                "$ref": "model/ISO20022Profile.profile.uml#_Z1fsECR_EeW-eZ1ZLTAX7g"
              }
            ]
          }
        ],
        "appliedProfile": {
          "$ref": "model/ISO20022Profile.profile.uml#_rspygA6UEeWHY4KRRC3kUQ"
        },
        "applyingPackage": {
          "$ref": "_ezM94CquEeWRmPUlcrfDwQ"
        }
      }
    ]
  },
  {
    "eClass": "model/ISO20022Profile.profile.uml#_Z1hhpyR_EeW-eZ1ZLTAX7g",
    "_id": "_ezNk8CquEeWRmPUlcrfDwQ",
    "registrationStatus": "PROVISIONALLY_REGISTERED ",
    "base_NamedElement": {
      "$ref": "_ezM94yquEeWRmPUlcrfDwQ"
    },
    "base_Actor": {
      "$ref": "_ezM94yquEeWRmPUlcrfDwQ"
    }
  }
]

What happen? What I should do?

@lex-em
Copy link
Author

lex-em commented Jul 15, 2015

Library version is 0.10.0
In 0.11.0 "_id" attribute do not serialized too.

@lex-em
Copy link
Author

lex-em commented Jul 15, 2015

Attributes filtered in org.emfjson.jackson.streaming.StreamWriter.generate() on line 151, here calls org.emfjson.common.EObjects.isCandidate():

    public static boolean isCandidate(EObject object, EAttribute attribute) {
        return (object.eIsSet(attribute) || attribute.getEType() instanceof EEnum) && 
                !attribute.isDerived() && 
                !attribute.isTransient() && 
                !attribute.isUnsettable();
    }

For some needed attributes object.eIsSet(attribute) is false or !attribute.isUnsettable() is false.

Why this filter needs?

@ghillairet
Copy link
Member

Checking that isUnsettable in that method is a mistake, will be remove in next version, see #59
To get ids in 0.11, explicitly set the option like this:

Map<String, Object> options = new HashMap<>();
options.put(EMFJs.OPTION_USE_ID, true);

resource.save(options);

@lex-em
Copy link
Author

lex-em commented Jul 16, 2015

Yes, but it realy don't work until Resource implementation, that also implenets UuidResource interface, do not return true in UuidResource.useUUIDs().

I think it realy needed to use custom JsonResourceFactory with custom JsonResource that overrided useUUIDs(). For this aim need to set custom JsonResourceFactory to EObjectDeserializer and ResourceDeserializer.

It works for me, if needed I can do a pull request.

@ghillairet
Copy link
Member

That's the correct behavior, the default id serializer will serialize the fragment of the object's URI only if the option USE_ID is true. For the fragment to be a UUID you need to have a Resource implementation that supports UUID generation (like XMIResource, JsonResource) and overwrite the method useUUIDs() to return true.

Since 0.11 you can also use custom serializers for ids, see cdo sample.

@lex-em
Copy link
Author

lex-em commented Jul 16, 2015

Yes, but what you think about custom JsonResourceFactory in EObjectDeserializer and ResourceDeserializer?

@ghillairet
Copy link
Member

What are you thinking about? Not sure I understand the need to use a ResourceFactory in those deserializers.

@lex-em
Copy link
Author

lex-em commented Jul 17, 2015

How I can configure deserializer with custom JsonResource?

@lex-em
Copy link
Author

lex-em commented Jul 17, 2015

For this purpose I realize ResourceFactory and expect my custom JsonResource, but I get a standart JsonResource

@ghillairet
Copy link
Member

What are you trying to achieve? If you want to use a custom resource implementation you need to specify it through the resourceSet.

@lex-em
Copy link
Author

lex-em commented Jul 22, 2015

Yes, but your deserializer creates only yours JsonResource

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants