emfjson / emfjson-jackson

JSON Binding for Eclipse Modeling Framework
https://emfjson.github.io
Other
80 stars 23 forks source link

Unable to load resource from json file #48

Closed bonnysinha closed 9 years ago

bonnysinha commented 9 years ago

Hi,

I have an ecore model defined. Later when I try to load an instance from a json file, it fails to do so. Kindly have a look at the model definition and the instance.

Model

{
  "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EPackage",
  "name" : "JNDISamplePackage",
  "nsURI" : "http://com.sample.jndisample",
  "nsPrefix" : "JNDISample",
  "eClassifiers" : [ {
    "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EClass",
    "name" : "Server",
    "eStructuralFeatures" : [ {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "IP_Addr",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EString",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    }, {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "Port_Number",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    }, {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "Mac_Addr",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EString",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    }, {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EReference",
      "name" : "Database",
      "upperBound" : -1,
      "containment" : true,
      "eType" : {
        "$ref" : "//Database",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EClass"
      }
    } ]
  }, {
    "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EClass",
    "name" : "Database",
    "eStructuralFeatures" : [ {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "Database_Name",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EString",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    }, {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "Username",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EString",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    }, {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "Password",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EString",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    }, {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EReference",
      "name" : "Schema",
      "containment" : true,
      "eType" : {
        "$ref" : "//Schema",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EClass"
      }
    } ]
  }, {
    "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EClass",
    "name" : "Schema",
    "eStructuralFeatures" : [ {
      "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
      "name" : "Schema_Name",
      "eType" : {
        "$ref" : "http://www.eclipse.org/emf/2002/Ecore#//EString",
        "eClass" : "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
      }
    } ]
  } ]
}

Instance

[ {
  "IP_Addr" : "SAMPLE_VALUE",
  "Port_Number" : 0,
  "Mac_Addr" : "SAMPLE_VALUE",
  "Database" : [ {
    "Database_Name" : "SAMPLE_VALUE",
    "Username" : "SAMPLE_VALUE",
    "Password" : "SAMPLE_VALUE",
    "Schema" : {
      "Schema_Name" : "SAMPLE_VALUE"
    }
  } ]
}, {
  "Database_Name" : "SAMPLE_VALUE",
  "Username" : "SAMPLE_VALUE",
  "Password" : "SAMPLE_VALUE",
  "Schema" : {
    "Schema_Name" : "SAMPLE_VALUE"
  }
}, {
  "Schema_Name" : "SAMPLE_VALUE"
} ]

Kindly find the steps used to load the instance

  1. I get the corresponding EPackage of model.(ePack)
  2. ResourceSet metaResourceSet = new ResourceSetImpl();
  3. metaResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new JsonResourceFactory());
  4. metaResourceSet.getPackageRegistry().put(ePack.getNsURI(), ePack);
  5. Resource res = metaResourceSet.getResource(URI.createFileURI("/instance.json"),true);
  6. res.getContents().size() is zero.

Hence I cannot use it further.

The same works perfectly in the case of XML(using XMLResourceset and all).

I just started working with emf and am new to it. Kindly help.

ghillairet commented 9 years ago

You can try to add a field eClass for each objects, otherwise emfjson does not know what kind of objects to load.

{
  "eClass": "http://com.sample.jndisample#//Server"
  "IP_Addr" : "SAMPLE_VALUE",
  "Port_Number" : 0
}
bonnysinha commented 9 years ago

Hi Guillaume,

Thanks for the response. Following is the modified instance.

{ "eClass": "http://com.sample.jndisample#//Server" "IP_Addr" : "SAMPLE_VALUE", "Port_Number" : 0, "Mac_Addr" : "SAMPLE_VALUE", "Database" : [ { "eClass": "http://com.sample.jndisample#//Database" "Database_Name" : "SAMPLE_VALUE", "Username" : "SAMPLE_VALUE", "Password" : "SAMPLE_VALUE", "Schema" : { "eClass": "http://com.sample.jndisample#//Schema" "Schema_Name" : "SAMPLE_VALUE" } } ] }

Following are the observations made: a. This new json threw an exception (java.net.UnknownHostException: com.sample.jndisample). Note: I do not have the URI hosted anywhere. b. If I modify the json by removing the URI information as "eClass": "#//Server" and the same for others, I get the exception (java.io.FileNotFoundException: D:\SampleEMFProject (Access is denied)) c. Lastly I tried to modify "STEP-3" as explained in my first post as: metaResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*.json", new JsonResourceFactory()); I got the error as (Cannot create a resource for '/instance.json'; a registered resource factory is needed)

Is there something else I am missing? Kindly help.

Regards, Bonny.

ghillairet commented 9 years ago

Did you register the EPackage before loading the file?

bonnysinha commented 9 years ago

Yes I registered as shown below

ResourceSet metaResourceSet = new ResourceSetImpl(); metaResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(<tried as "" and as ".json">, new JsonResourceFactory()); metaResourceSet.getPackageRegistry().put(ePack.getNsURI(), ePack);

ghillairet commented 9 years ago

This works for me, create a maven project, add emfjson-jackson as dependencies, put the json files in src/main/resources.

package emfj;

import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.emfjson.jackson.resource.JsonResourceFactory;

public class Main {

    public static void main(String[] args) {
        ResourceSet resourceSet = new ResourceSetImpl();
        resourceSet
            .getPackageRegistry()
            .put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);

        resourceSet
            .getResourceFactoryRegistry()
            .getExtensionToFactoryMap()
            .put("json", new JsonResourceFactory());

        Resource resource = resourceSet.getResource(
                URI.createFileURI("src/main/resources/meta.json"), true);

        EPackage ePackage = (EPackage) resource.getContents().get(0);

        resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage);

        Resource resource2 = resourceSet.getResource(
                URI.createFileURI("src/main/resources/model.json"), true);

        EObject server = resource2.getContents().get(0);
        System.out.println(server.eGet(server.eClass().getEStructuralFeature("IP_Addr")));
        System.out.println(server.eGet(server.eClass().getEStructuralFeature("Port_Number")));

        List<EObject> databases = (List<EObject>) server.eGet(server.eClass().getEStructuralFeature("Database"));
        EObject database = databases.get(0);
        System.out.println(database.eGet(database.eClass().getEStructuralFeature("Database_Name")));
    }

}
bonnysinha commented 9 years ago

Hi Guillaume,

I changed my code to the following as I had to get the ecore object from code and not file.

image

And followed the rest of the code as shown above. It worked like a charm. Thanks a lot.

Cheers.