AEM get parent node from Valuemapvalue filepath in sling model

1.2k views Asked by At

I need to get the parent folder name (String type), once a user provides a filepath in cq dialog. This is my approach:

import lombok.Getter;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.*;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
@Getter
@Model(adaptables = {
    Resource.class,
    SlingHttpServletRequest.class
  },
  defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

public class Test {
  @SlingObject
  private Resource resource;
  @OSGiService
  private ResourceResolver resourceResolver;

  @ValueMapValue
  private String fileUrl;

  @PostConstruct
  public String getData() {
    Resource resource = resourceResolver.getResource(fileUrl);
    Resource parentProps = resource.getParent();
    System.out.println("parent node is =>" + parentProps);
  }
}

Is there a problem? My code builds correctly but does not return anything

2

There are 2 answers

0
Ameesh Trikha On

ResourceResolver is not a OSGI service, its SlingObject

Also you need to make sure that logged-in user making the request have right access setup for the file path

0
Daniel Hernandez On

I suggest you get comfortable debugging code so you can understand exactly what is going on behind the scenes instead of just adding logging statements. Also, not totally sure where System.out.println calls get logged, but you can find logging information in /crx-quickstar/logs/error.log using an slf4j logger. What I do is configure the log level to ERROR on my local instance so that it's easier to find my logging statements

As Ameesh said, you need to use @SlingObject to inject ResourceResolver, although you can just use the annotation @ResourcePath which does all the resource resolution for you:

@Getter
@Model(adaptables = Resource.class,
  defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

public class Test {

  private static final Logger LOG = LoggerFactory.getLogger(Test.class);
  
  @Self
  private Resource resource;

  @ResourcePath(name = "fileUrl")
  private Resource file;

  @PostConstruct
  public String getData() {
    final String path = Optional.ofNullable(file)
                          .map(file -> file.getParent())
                          .map(parent -> parent.getPath())
                          .orElse("resource not found!");
    LOG.error("parent node is: {}", path);
  }
}