Raja
Raja

Reputation: 325

Accessing resource data from JCR repo

Using sling resource interface I am trying to get access the data saved as a binary property to my JCR node. Currently I am doing it in the following ways , which is returning me a null value.

Resource dataResource = resourceResolver.getResource("/testNode/A/test.txt");
ValueMap properties = dataResource.adaptTo(ValueMap.class);        

String expected = properties.get("jcr:data").toString(); // null
InputStream content = (InputStream) actualProp.get("jcr:data");  // null 

Can anyone let me know what is missing , or what is the best way to read the jcr:data property , which is present as a binary data. The dataResource is a nt:unstructured one.

the output it shows is :- org.apache.sling.jcr.resource.internal.helper.LazyInputStream@4f4c8085

Upvotes: 4

Views: 12666

Answers (4)

arnor
arnor

Reputation: 41

In AEM, files are often stored as assets. If that is the case, you can adapt the respective resource (the one with dam:Asset as primary type) to an asset and read from the file in the following way:

InputStream inputStream = resource.adaptTo(Asset.class).getOriginal().getStream()

Tuan Dang's method works, but all of the JCR Node methods throw RepositoryException.

Baeldung has a summary on how to convert input stream to a string.

Upvotes: 0

diffa
diffa

Reputation: 2996

You mention that you were using the Sling resource API rather than the JCR API. You can adapt the resource to an InputStream directly from a Resource like so:

Resource dataResource = resourceResolver.getResource("/testNode/A/test.txt/jcr:content");
InputStream is = dataResource.adaptTo(InputStream.class);

As long as the resource is an nt:file or nt:resource, the contents of the jcr:data attribute should be returned as an InputStream.

From there you can read from the InputStream as Tuan suggested in his answer.

You can see an example of this functionality from the following unit test: http://svn.apache.org/repos/asf/sling/whiteboard/fmeschbe/resource/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java

Upvotes: 12

Tuna
Tuna

Reputation: 3005

The below code has worked for me:

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

//skip here

Session session = (Session) resourceResolver.adaptTo(Session.class);
Node root = session.getRootNode();
Node jcrContent = root.getNode("testNode/A/test.txt/jcr:content");

InputStream is = jcrContent.getProperty("jcr:data").getBinary().getStream();

BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while (result != -1) {
    byte b = (byte) result;
    buf.write(b);
    result = bis.read();
}

System.out.println("plain text: " + buf.toString());

Also you can find more information at another post

Upvotes: 1

Jan Kuźniak
Jan Kuźniak

Reputation: 308

If I remember correctly, your path should be more like:

Resource dataResource = resourceResolver.getResource("/testNode/A/test.txt/jcr:content");

I would personally adapt that resource to a JCR Node (javax.jcr.Node) and use JCR API from there (#getProperty(), #getBinary()), but that may be my old school upbringing speaking.

Upvotes: 1

Related Questions