javajsoneclipse-emfeclipse-emf-ecore

Reading JSON-String using EMFJson


I am using EMFJson for serializing EMF Ecore Models. I am able to create a JSON String from an existing model. However, the way back is not working for me. I tried the following two snippets:

First Attempt:

ObjectMapper objectMapper = EMFModule.setupDefaultMapper();
objectMapper.reader().forType(MyClass.class).readValue(string);

Second Attempt:

ObjectMapper objectMapper = EMFModule.setupDefaultMapper();

    ResourceSet resourceSet = new ResourceSetImpl();
    resourceSet.getResourceFactoryRegistry()
                    .getExtensionToFactoryMap()
                    .put("json", new JsonResourceFactory());
try {
    Resource resource = objectMapper
        .reader()
        .withAttribute(EMFContext.Attributes.RESOURCE_SET, resourceSet)
        .withAttribute(EMFContext.Attributes.RESOURCE_URI, null)
        .forType(Resource.class)
        .readValue(string);
    } catch (IOException e1) {
        e1.printStackTrace();
    }

For both attempts I am getting the following exception: java.lang.RuntimeException: Cannot create resource for uri default

I guess that the second approach cannot work at all as I do not know what to provide as RESOURCE_URI. The example here I took as foundation for attempt two reads a file rather than a string. Does somebody have an idea how to make this work? Thanks!


Solution

  • I managed to handle it using the answer given here: Parse XML in string format using EMF

    The method with my changes looks like this:

    private EObject loadEObjectFromString(String model, EPackage ePackage) throws IOException { 
        ResourceSet resourceSet = new ResourceSetImpl();
        resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, new JsonResourceFactory());
    
        resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage);
        Resource resource = resourceSet.createResource(URI.createURI("*.extension"));
        InputStream stream = new ByteArrayInputStream(model.getBytes(StandardCharsets.UTF_8));
        resource.load(stream, null);
    
        return resource.getContents().get(0);
    }
    

    Now I can call it like this:

    EObject test = this.loadEObjectFromString(jsonString, MyPackage.eINSTANCE);