April 1, 2020
Estimated Post Reading Time ~

How to read an external file in CQ

Use Case: You want to read something from external file
Solution: There are multiple ways you can do this I will mentioned two of them here,

1) You can put them under /resources folder under /src/main for example if you want to read a file called "test.txt" then you can put file under /src/resources/<any-sub-foler>/<file-to-read>

Then use following code to read file
InputStream stream = getClass().getResourceAsStream("<file-to-read>");
in above case it would be InputStream stream = getClass().getResourceAsStream("/test.txt");

Good practice is to follow convention, For example if your source code is under /src/main/java/com/test/mytest/Test.java Then your resource should be in location /resource/com/test/myTest/<Your File>

Then you can use something like

InputStream in = Test.class.getResourceAsStream("<Your File>");

2) You can put file in repository (Any repository location is file) and use Node data as stream to read.

then use following code,
InputStream in = node.getNode("jcr:content").getProperty("jcr:data").getStream();

How to Upload File in CRX

File file = new File("/mypath/mydocument.pdf");
FileInputStream is = new FileInputStream(file);
mimeType = "application/octet-stream";
Node node = session.getNode(parentNode);
ValueFactory valueFactory = session.getValueFactory();
Binary contentValue = valueFactory.createBinary(is);
Node fileNode = node.addNode(fileName, "nt:file");
fileNode.addMixin("mix:referenceable");
Node resNode = fileNode.addNode("jcr:content", "nt:resource");
resNode.setProperty("jcr:mimeType", mimeType);
resNode.setProperty("jcr:data", contentValue);
Calendar lastModified = Calendar.getInstance();
lastModified.setTimeInMillis(lastModified.getTimeInMillis());
resNode.setProperty("jcr:lastModified", lastModified);
session.save();
return fileNode.getPath();

Using Sling FSResource Provider (To convert File system resource to jcr resource):


Please see what all different kind of resource provider is present

http://sling.apache.org/documentation/the-sling-engine/resources.html
FS resource provider essentially mapped your file system path with repository path. That mean you can adapt your file system resource to a sling resource object and can do fun stuff with it.

1) More information can be obtained here http://sling.apache.org/documentation/bundles/accessing-filesystem-resources-extensions-fsresource.html

2) FSResource provider is not present OOTB, so you have to first embed this in your project,

in your pom.xml do following (I hope you know how to do this, if not ping me :D),

<embedded>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.fsresource</artifactId>
<target>/apps/<your app>/install</target>
</embedded>

And

<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.fsresource</artifactId>
<version>1.1.3-SNAPSHOT</version>
</dependency>


3) create a osgi config with following setting
Name of file: org.apache.sling.fsprovider.internal.FsResourceProvider-samples.xml

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
provider.roots=“<some repository path, this can be any random path>"
provider.file=“<Absolute path for file in file system>"
provider.checkinterval="1000”/>

4) Then in your code you can do following,

import java.io.File;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service
public class FileSystemFileTest implements FileSystemTest {
private static final Logger LOG = LoggerFactory.getLogger(FileSystemFileTest.class);
@Reference
ResourceResolverFactory resourceResolverFactory;
@Reference
ResourceProvider resourceProvider;
ResourceResolver resourceResolver = null;
@Override
public File getFile() {
try {
resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
Resource resource = resourceResolver.getResource("<some repository path from above>");
File file = resource.adaptTo(File.class);
if(null!=file){
return file;
}
} catch (LoginException e) {
LOG.error(e.getMessage());
}finally{
if(null!=resourceResolver){
resourceResolver.close();
}
}
return null;
}
}


Note that in this case, you need to have a file in your file system. You will essentially use this approach if you want to get a jcr resource view of your file system to do something with it. For example, if your method can only accept the resource object as an argument.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.