2017-08-04 244 views
0

我有以下从aem/cq5中的jcr查询返回的无序列表。 enter image description here从JCR查询搜索结果构建页面树

正如你所看到的,有些页面是其他页面的父页面。 我试图通过比较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(); 
} 

} 

任何帮助表示赞赏。

+0

你只想返回共同父母?我不明白你想解决的问题... –

+0

@florian salihovic我需要显式缩进这些路径基于路径子,父母关系的结构/树结构。 – Sri

回答

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<[email protected]>" 
*/ 
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<[email protected]>" 
*/ 
@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) ; 
    } 
} 

您可以使用此为基础来解决您的问题。