从JCR查询搜索结果构建页面树

时间:2017-08-04 21:10:33

标签: cq5 aem query-builder jcr sling

我在aem / cq5中跟踪了从jcr查询返回的无序路径列表。 enter image description here

正如您所看到的,有些页面是其他页面的父页面。 我试图通过比较childnode.parent.pagepath和Node.pagePath来构建Node-> childNodes关系。

我无法建立关系并完成模型。

以下是我尝试过的代码:

public class SiteMapFooterServiceImpl implements SiteMapFooterService{

 private static final Logger LOG = LoggerFactory.getLogger(SiteMapFooterService.class);

@Override
public Collection<SiteMapNavigation> getSiteMapPages(Page currentPage, ResourceResolver resourceResolver) {

Map<String, SiteMapNavigation> siteMapNavigationItems = new HashMap<String, SiteMapNavigation>();

String rootPath = currentPage.getAbsoluteParent(3).getPath();
SearchResult result = getQueryResult(resourceResolver, rootPath, "includeInSiteMap", "true", "cq:PageContent");

Map<String, Page> siteMapPages = new HashMap<String, Page>();

Map<String, Page> pageMap = new HashMap<String, Page>();

if(result != null) {

  for (Hit hit : result.getHits()) {
    Resource sitePageContent;
    Page sitePage;

    try {
      sitePageContent = hit.getResource();
      sitePage = PageUtility.getPageForResouce(sitePageContent);
      siteMapPages.put(sitePage.getPath(), sitePage);
    } catch (RepositoryException e) {
      LOG.error("Error retrieving paths in getSiteMapPages - SiteMapFooterServiceImpl ", e);
    }
  }

  for(Entry<String, Page>  sitePageEntry : siteMapPages.entrySet()) {
    buildPageTree(siteMapPages.get(sitePageEntry.getKey()), siteMapPages, siteMapNavigationItems, pageMap);
  }
}

return siteMapNavigationItems.values();
}

 private void buildPageTree(Page sitePage, Map<String, Page> siteMapPages, 
  Map<String, SiteMapNavigation> siteMapNavigationItems, Map<String, Page> parentPagesMap) {

Page parentPage = sitePage.getParent();

//if parent exists in the result set - siteMapPages
if(siteMapPages.get(parentPage.getPath()) != null) {

  Page sitePageParent = siteMapPages.get(parentPage.getPath());

    if(parentPagesMap.get(parentPage.getPath()) != null) {

      //get the parent navigation item
      SiteMapNavigation parentNavigationItem = siteMapNavigationItems.get(parentPage.getPath());

      if(parentPagesMap.get(sitePage.getPath()) != null){
        //make this page as child of existing parent
        SiteMapNavigation sitePageNavigationItem = siteMapNavigationItems.get(sitePage.getPath());
        parentNavigationItem.getChildPages().add(sitePageNavigationItem);

        //remove the existent sitepage node from sitemapnavigationitems
        siteMapNavigationItems.remove(sitePage.getPath());
        parentPagesMap.remove(sitePage.getPath());

        //add it to parents list
        parentPagesMap.put(sitePageParent.getPath(), sitePageParent);
      } else {

        //create child
        SiteMapNavigation childNavigation = createSiteMapNavigationItem(sitePage);

        parentNavigationItem.getChildPages().add(childNavigation);

      }

      //add to parent navigation list
     // parentNavigationItem.getChildPages().add(createSiteMapNavigationItem(sitePage));

    } else {
         //create parent
         SiteMapNavigation parentNavigationItem = createSiteMapNavigationItem(sitePageParent);

         //check if sitepage exists as a parent in the pageMap
         if(parentPagesMap.get(sitePage.getPath()) != null){
           //make this page as child of new parent
           SiteMapNavigation sitePageNavigationItem = siteMapNavigationItems.get(sitePage.getPath());
           parentNavigationItem.getChildPages().add(sitePageNavigationItem);

           //remove the existent sitepage node from sitemapnavigationitems
           siteMapNavigationItems.remove(sitePage.getPath());
           parentPagesMap.remove(sitePage.getPath());

           siteMapNavigationItems.put(parentNavigationItem.getRawPath(), parentNavigationItem);
           //add it to parents list
           parentPagesMap.put(sitePageParent.getPath(), sitePageParent);
         } else {

           //create child
           SiteMapNavigation childNavigation = createSiteMapNavigationItem(sitePage);

           parentNavigationItem.getChildPages().add(childNavigation);
           siteMapNavigationItems.put(parentNavigationItem.getRawPath(), parentNavigationItem);
         }

       //add it to parents list
       parentPagesMap.put(sitePageParent.getPath(), sitePageParent);
  }      

} else {
  //if parent NOT exists in the result set - siteMapPages, then add the 
page to siteMapNavigationItems as the first level page
     SiteMapNavigation siteMapNavigation = 
createSiteMapNavigationItem(sitePage);
    siteMapNavigationItems.put(siteMapNavigation.getRawPath(), 
 siteMapNavigation);
    parentPagesMap.put(sitePage.getPath(), sitePage);
 }

 }

 private SiteMapNavigation createSiteMapNavigationItem(Page 
   pageToProcess) {
SiteMapNavigation siteMapNavigation = new SiteMapNavigation();
siteMapNavigation.setTitle(PageUtility.getTitle(pageToProcess));
siteMapNavigation.setPagePath(pageToProcess.getPath() + ".html");
siteMapNavigation.setRawPath(pageToProcess.getPath());

  return siteMapNavigation;
}

    private SearchResult getQueryResult(ResourceResolver 
  resourceResolver, String contentPath, String property, String 
propertyValue, String nodeType) {

Map<String, String> queryMap = new HashMap<String, String>();

queryMap.put("path", contentPath);
queryMap.put("type", nodeType);
queryMap.put("property", property);
queryMap.put("property.1_value", propertyValue);
queryMap.put("p.limit", "-1");

Session session = resourceResolver.adaptTo(Session.class);
QueryBuilder builder = resourceResolver.adaptTo(QueryBuilder.class);
Query query = builder.createQuery(PredicateGroup.create(queryMap), 
 session);
   return query.getResult();
 }

}

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:0)

为了平整树结构,这应该提供一个很好的基础:

package com.github.floriansalihovic.sling;

import com.day.cq.wcm.api.*;
import org.apache.sling.api.resource.Resource;

import javax.annotation.*;
import java.util.*;

/**
 * Building a map containing the relations from parent.
 *
 * @author "Florian Salihovic<florian.salihovic@me.com>"
 */
public interface PageRelations {

    /**
     * @param pageManager The {@link PageManager}.
     * @param resources   A {@link List} of resources.
     * @return A {@link Map} containing paths as the keys and {@link Set}
     * instances containing the
     */
    default Map<String, Set<String>> build(@Nonnull final PageManager pageManager,
            @Nonnull final List<Resource> resources) {
        final Map<String, Set<String>> acc = new HashMap<>();
        for (final Resource resource : resources) {
            Page page = pageManager.getContainingPage(resource);
            while (null != page) {
                final Page parent = page.getParent();
                if (null != parent) {
                    acc.putIfAbsent(parent.getPath(), new HashSet<>());
                    acc.get(parent.getPath()).add(page.getPath());
                }
                page = page.getParent();
            }
        }
        return acc;
    }
}

它基本上创建了一个包含父页面到子页面路径的地图。

package com.github.floriansalihovic.sling;

import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import org.apache.sling.api.resource.Resource;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

/**
 * @author "Florian Salihovic<florian.salihovic@me.com>"
 */
@RunWith(MockitoJUnitRunner.class)
public class PageRelationsTest implements PageRelations {

    @Mock
    private PageManager pageManager;

    @Test
    public void buildingRelations() throws Throwable {
        final List<Resource> resources = Arrays.asList(
                initializeMocks(Arrays.asList("content", "tenant", "language", "de", "index")).get(0),
                initializeMocks(Arrays.asList("content", "tenant", "language", "en", "index")).get(0));
        final Map<String, Set<String>> result = build(pageManager, resources);
        Assert.assertNotNull(result);
        Assert.assertFalse(result.isEmpty());
        Assert.assertEquals(1, result.get("/content/tenant").size());
        Assert.assertTrue(result.get("/content/tenant").contains("/content/tenant/language"));
        Assert.assertEquals(2, result.get("/content/tenant/language").size());
        Assert.assertTrue(result.get("/content/tenant/language")
                .containsAll(Arrays.asList("/content/tenant/language/de", "/content/tenant/language/en")));
    }

    public List<Resource> initializeMocks(final List<String> list) {
        final Queue<String> segments = Queues.newArrayDeque(list);
        final List<Resource> resources = new ArrayList<>();

        Page currentPage, parentPage = null;
        Resource currentResource, parentResource = null;

        String path = "";
        for (String segment : segments) {
            path += ("/" + segment);

            currentPage = Mockito.mock(Page.class);
            currentResource = Mockito.mock(Resource.class);
            Mockito.when(currentPage.getPath()).thenReturn(path);
            Mockito.when(currentResource.getPath()).thenReturn(path + "/jcr:content");
            Mockito.when(pageManager.getContainingPage(currentResource)).thenReturn(currentPage);
            resources.add(currentResource);

            if (parentPage != null) {
                Mockito.when(currentResource.getParent()).thenReturn(parentResource);
                Mockito.when(currentPage.getParent()).thenReturn(parentPage);
            }
            parentPage = currentPage;
            parentResource = currentResource;
        }
        return Lists.reverse(resources) ;
    }
}

您可以将此作为解决问题的基础。