From JCR Node to JSON

Dear experts,

I need you advise.

Objective :
Create a complex document (using compund type) and generate the api-manual with it.

HIPPO CMS can do the following:

  1. Create the complex data structure via the CMS interface (compound type and document type)
  2. Generate the java files via Bean Writer
  3. Generate generic API even for this compund type.

BUT HIPPO CMS cannot generate the api-manual for such complex type.

This is how I did it.

  1. Create a component type call Orang (Person in Malay) and in it nama (name) in cms

  2. Create a document type call OrangDT which content only 1 Orang type in cms

  3. Create a document instance of OrangDT can call it cubaorang (tryPeople in Malay) in cms

  4. Generate all the Java files with Bean Writer in essential

  5. Generate the generic api and also manual api.in essential so that I can get to use this URL
    (http://localhost:8080/site/api-manual/OrangDT/)

  6. In the cms/console you should see something like this YAML format,
    (/content/documents/xxxxxx/cubaorang)

  7. In the orangDTResource.java (created by beanwriter) I added the following

@GET
@Path("/test")
public String test(@Context HttpServletRequest request)throws Exception{
    Session session = null;
    StringBuilder result = new StringBuilder();
    try {
        HippoRepository repository = HippoRepositoryFactory.getHippoRepository("vm://");
        session = repository.login("admin","admin".toCharArray());
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        Query query = queryManager.createQuery("SELECT * FROM xxxxxx:OrangDT WHERE hippostd:stateSummary='live' AND hippostd:state='published'",Query.SQL);
        QueryResult qResult = query.execute();
        NodeIterator ns = qResult.getNodes(); // get the nodes
        while (ns.hasNext()) {
            Node n = ns.nextNode(); // get each node
            // get the properties
            PropertyIterator it = n.getProperties(); // get the properties
            while (it.hasNext()) {
                Property property = it.nextProperty(); // get each property
                String key =  p.getName().trim();
                String value = "";
                if(p.isMultiple()) {
                    Value[] valueArr = p.getValues();
                    int i = 0;
                    for (i=0;i < valueArr.length;i++) {
                        value += valueArr[i].getString();
                    }
                }else {
                    p.getValue().getString().trim();
                }
                result.append (key + ":" + value);
            }
        }
    } catch (Exception e) {e.printStackTrace();
    } finally {session.logout();}
    return result.toString();
}	

Using this logic I was able to generate extract the properties and convert the result into anything I wish for example another JSON or XML or etc…

But I do not think this is the best way.

Is there a way I can take the Node and convert into an OrangDT object so I can extract the Orang object… (for example change from line 12 to have something like this?)

        while (ns.hasNext()) {
            Node n = ns.nextNode(); // get each node
			OrangDT test = (OrangDT) n;
			Orang temp = test.getOrang();
        }

Cheers
Sola Lee

If from your context you can get HstRequestContext then we can use ObjectBeanManager for that purpose

HstRequestContext hstRequestContext = RequestContextProvider.get();
OrangDT orangObject = (OrangDT) hstRequestContext.getObjectBeanManager().getObject(node.getParent()); // We need to get parent as it is the handle node.
1 Like

Dear Thole,

Thank you, I did not think of using HST. I will try and get back to this with the sample code.

Regards
Sola Lee

Dear Thole,

Sorry for the delay in my updates. Yes I found the answer and am here to share with you the codes on how I manage to extract the compound object and document object using HST.

I have yet to study how to do the following:

  1. return that object as REST API (hopefully be able to use POJO)
  2. be able to get the keep object value AFTER closing the session

I will update again once I found out how to do the 1 and 2.

Thank you again ThoLe.

Sharing this to extract the Object (Compund Type) and print them to screen.

	@GET
	@Path("/test")
	public void test(@Context HttpServletRequest request) throws Exception {
		System.out.println("Test");
		HippoRepository repository = HippoRepositoryFactory.getHippoRepository("vm://");
		Session session = repository.login("admin","admin".toCharArray());	
		Node node = session.getRootNode().getNode("content/documents/xxxxxx/cubaorang/cubaorang[3]/xxxxxx:Orang");	
		HstRequestContext context = RequestContextProvider.get();		
		Orang org = (Orang) context.getObjectConverter().getObject(node);
		System.out.println(org.getNama());
		session.logout();		
	}

Sharing this function to extract the Object (Document Type) and print them to screen.

	@GET
	@Path("/test2")
	public void test2(@Context HttpServletRequest request) throws Exception {
		System.out.println("Test");
		HippoRepository repository = HippoRepositoryFactory.getHippoRepository("vm://");
		Session session = repository.login("admin","admin".toCharArray());	
		Node node = session.getRootNode().getNode("content/documents/xxxxxx/cubaorang/cubaorang[3]/xxxxxx:Orang");	
		HstRequestContext context = RequestContextProvider.get();
		OrangDT org = (OrangDT) context.getObjectConverter().getObject(node.getParent());
		System.out.println(org.getOrang().getNama());
		session.logout();
	}

Hi,

Yes, good found of course. (1) and (2) of course possible, enjoy it.

1 Like

After many years I found a better way to do this.

Please add this to your pom.xml

org.apache.sling org.apache.sling.commons.json 2.0.8

In your java codes

   HstRequestContext context = request.getRequestContext();
   HippoDocument bean = (HippoDocument) context.getContentBean();
   // Session session = 
   HippoRepositoryFactory.getHippoRepository("vm://").login(username,password.toCharArray());
   // OR
   Session session = context.getSession();
   result = new JsonJcrNode(node);
   if(node.hasNodes()){
       NodeIterator nodeIterator = node.getNodes();
       while (nodeIterator.hasNext()) {
            Node dirNode = nodeIterator.nextNode();
           System.out.println(dirNode.getName());
       }
   }