Index: main/plugin-web/src/org/ametys/web/inputdata/SitemapInputData.java =================================================================== --- main/plugin-web/src/org/ametys/web/inputdata/SitemapInputData.java (revision 32090) +++ main/plugin-web/src/org/ametys/web/inputdata/SitemapInputData.java (working copy) @@ -41,8 +41,6 @@ import org.ametys.web.pageaccess.PageAccessInfo; import org.ametys.web.pageaccess.PageAccessManager; import org.ametys.web.pageaccess.RestrictedPagePolicy; -import org.ametys.web.renderingcontext.RenderingContext; -import org.ametys.web.renderingcontext.RenderingContextHandler; import org.ametys.web.repository.page.Page; import org.ametys.web.repository.page.PagesContainer; import org.ametys.web.repository.page.Page.PageType; @@ -76,15 +74,15 @@ protected SiteManager _siteManager; /** Page access manager*/ protected PageAccessManager _accessManager; - /** The rendering context handler. */ - protected RenderingContextHandler _renderingContextHandler; + + private SitemapSaxer _sitemapSaxer; @Override public void service(ServiceManager manager) throws ServiceException { _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); _accessManager = (PageAccessManager) manager.lookup(PageAccessManager.ROLE); - _renderingContextHandler = (RenderingContextHandler) manager.lookup(RenderingContextHandler.ROLE); + _sitemapSaxer = (SitemapSaxer) manager.lookup(SitemapSaxer.ROLE); } @Override @@ -107,8 +105,15 @@ } @Override + public boolean shouldBeCached(Site site, Page page) + { + return true; + } + + @Override public void toSAX(ContentHandler handler) throws SAXException, ProcessingException { + Request request = ContextHelper.getRequest(_context); String siteName = (String) request.getAttribute("site"); @@ -121,26 +126,35 @@ Page page = (Page) request.getAttribute(Page.class.getName()); - try + String login = (String) request.getAttribute(WebConstants.FO_LOGIN); + + if ("1".equals(request.getParameter("mode"))) { - handler.startPrefixMapping(NAMESPACE_PREFIX, NAMESPACE_URI); + _sitemapSaxer.toSAX(handler, site, sitemap, page, login, _initialDepth, _descendantDepth); + } + else + { + try + { + handler.startPrefixMapping(NAMESPACE_PREFIX, NAMESPACE_URI); - AttributesImpl attrs = new AttributesImpl(); - attrs.addCDATAAttribute(NAMESPACE_URI, "site", NAMESPACE_PREFIX + ":site", site.getName()); - attrs.addCDATAAttribute(NAMESPACE_URI, "lang", NAMESPACE_PREFIX + ":lang", sitemap.getName()); + AttributesImpl attrs = new AttributesImpl(); + attrs.addCDATAAttribute(NAMESPACE_URI, "site", NAMESPACE_PREFIX + ":site", site.getName()); + attrs.addCDATAAttribute(NAMESPACE_URI, "lang", NAMESPACE_PREFIX + ":lang", sitemap.getName()); - XMLUtils.startElement(handler, "sitemap", attrs); + XMLUtils.startElement(handler, "sitemap", attrs); - // Process recursively pages - String login = (String) request.getAttribute(WebConstants.FO_LOGIN); - _saxPages(handler, sitemap, page != null ? page.getPathInSitemap() : null, 1, -1, policy, login); + // Process recursively pages + //String login = (String) request.getAttribute(WebConstants.FO_LOGIN); + _saxPages(handler, sitemap, page != null ? page.getPathInSitemap() : null, 1, -1, policy, login); - XMLUtils.endElement(handler, "sitemap"); - handler.endPrefixMapping(NAMESPACE_PREFIX); - } - catch (AmetysRepositoryException e) - { - throw new ProcessingException("Unable to process sitemap", e); + XMLUtils.endElement(handler, "sitemap"); + handler.endPrefixMapping(NAMESPACE_PREFIX); + } + catch (AmetysRepositoryException e) + { + throw new ProcessingException("Unable to process sitemap", e); + } } } @@ -160,15 +174,12 @@ { AmetysObjectIterable pages = composite.getChildrenPages(); - RenderingContext renderingContext = _renderingContextHandler.getRenderingContext(); - boolean inBackOffice = renderingContext == RenderingContext.BACK || renderingContext == RenderingContext.PREVIEW; - for (Page page : pages) { PageAccessInfo info = _accessManager.getAccessInfo(page); boolean accessGranted = _accessManager.hasRight(page, login); - if ((inBackOffice || accessGranted || policy == RestrictedPagePolicy.DISPLAYED) && _processPage(page)) + if ((accessGranted || policy == RestrictedPagePolicy.DISPLAYED) && _processPage(page)) { _saxPage(handler, currentPagePath, currentDepth, descendantDepth, policy, login, page, info); } Index: main/plugin-web/src/org/ametys/web/inputdata/SitemapSaxer.java =================================================================== --- main/plugin-web/src/org/ametys/web/inputdata/SitemapSaxer.java (revision 0) +++ main/plugin-web/src/org/ametys/web/inputdata/SitemapSaxer.java (revision 0) @@ -0,0 +1,230 @@ +package org.ametys.web.inputdata; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.avalon.framework.component.Component; +import org.apache.avalon.framework.context.Context; +import org.apache.avalon.framework.context.ContextException; +import org.apache.avalon.framework.context.Contextualizable; +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.Serviceable; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.xml.AttributesImpl; +import org.apache.cocoon.xml.XMLUtils; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import org.ametys.plugins.repository.AmetysObjectIterable; +import org.ametys.plugins.repository.metadata.CompositeMetadata; +import org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType; +import org.ametys.web.pageaccess.PageAccessInfo; +import org.ametys.web.pageaccess.PageAccessManager; +import org.ametys.web.repository.page.Page; +import org.ametys.web.repository.page.Page.PageType; +import org.ametys.web.repository.site.Site; +import org.ametys.web.repository.site.SiteManager; +import org.ametys.web.repository.sitemap.Sitemap; + +public class SitemapSaxer extends AbstractLogEnabled implements Contextualizable, Serviceable, Component +{ + /** Avalon role. */ + public static final String ROLE = SitemapSaxer.class.getName(); + + /** Prefix for sitemap namespace. */ + public static final String NAMESPACE_PREFIX = "sitemap"; + /** URI for sitemap namespace. */ + public static final String NAMESPACE_URI = "http://www.ametys.org/inputdata/sitemap/3.0"; + + /** Avalon context. */ + protected Context _context; + /** CMS Sites manager */ + protected SiteManager _siteManager; + /** Page access manager*/ + protected PageAccessManager _accessManager; + + private Map>> _bufferedPages = new HashMap>>(); + + @Override + public void service(ServiceManager manager) throws ServiceException + { + _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); + _accessManager = (PageAccessManager) manager.lookup(PageAccessManager.ROLE); + } + + @Override + public void contextualize(Context context) throws ContextException + { + _context = context; + } + + public void toSAX(ContentHandler contentHandler, Site site, Sitemap sitemap, Page currentPage, String login, int initialDepth, int descendantDepth) throws SAXException, ProcessingException + { + String siteName = site.getName(); + String sitemapName = sitemap.getName(); + + Map> sitePages = _bufferedPages.get(siteName); + + if (sitePages == null) + { + sitePages = new HashMap>(); + _bufferedPages.put(siteName, sitePages); + } + + List pages = sitePages.get(sitemapName); + + if (pages == null) + { + pages = _fill(sitemap.getChildrenPages()); + sitePages.put(sitemapName, pages); + } + + contentHandler.startPrefixMapping(NAMESPACE_PREFIX, NAMESPACE_URI); + + AttributesImpl attrs = new AttributesImpl(); + attrs.addCDATAAttribute(NAMESPACE_URI, "site", NAMESPACE_PREFIX + ":site", siteName); + attrs.addCDATAAttribute(NAMESPACE_URI, "lang", NAMESPACE_PREFIX + ":lang", sitemapName); + + XMLUtils.startElement(contentHandler, "sitemap", attrs); + + // Process recursively pages + _saxPages(contentHandler, pages, currentPage, login, initialDepth, descendantDepth, 1, -1); + + XMLUtils.endElement(contentHandler, "sitemap"); + contentHandler.endPrefixMapping(NAMESPACE_PREFIX); + } + + private List _fill(AmetysObjectIterable pages) + { + List result = new ArrayList(); + + for (Page page : pages) + { + BufferedPage bufferedPage = new BufferedPage(); + + bufferedPage.path = page.getPathInSitemap(); + + Map internalAttributes = new HashMap(); + bufferedPage.internalAttributes = internalAttributes; + + String path = page.getPathInSitemap(); + PageType pageType = page.getType(); + internalAttributes.put("id", page.getId()); + internalAttributes.put("name", page.getName()); + internalAttributes.put("title", page.getTitle()); + internalAttributes.put("long-title", page.getLongTitle()); + internalAttributes.put("path", path); + internalAttributes.put("type", page.getType().name()); + + PageAccessInfo info = _accessManager.getAccessInfo(page); + if (info.isRestricted()) + { + internalAttributes.put("restricted", "true"); + } + + // Add a flag if there is data + if (pageType == PageType.CONTAINER) + { + internalAttributes.put("container", "true"); + } + // Add URL if found + else if (pageType == PageType.LINK) + { + internalAttributes.put("link", page.getURL()); + internalAttributes.put("link-type", page.getURLType().name()); + } + + // metadata + Map attributes = new HashMap(); + bufferedPage.attributes = attributes; + + CompositeMetadata metadataHolder = page.getMetadataHolder(); + + for (String metadataName : metadataHolder.getMetadataNames()) + { + MetadataType type = metadataHolder.getType(metadataName); + + // SAX only non composite, non binary, non rich text and non multivalued metadatas + if (type != MetadataType.COMPOSITE && type != MetadataType.BINARY && type != MetadataType.RICHTEXT && !metadataHolder.isMultiple(metadataName)) + { + attributes.put(metadataName, metadataHolder.getString(metadataName)); + } + } + + // tags + for (String tag : page.getTags()) + { + attributes.put("PLUGIN_TAGS_" + tag, "empty"); + } + + bufferedPage.children = _fill(page.getChildrenPages()); + result.add(bufferedPage); + } + + return result; + } + + private void _saxPages(ContentHandler handler, List pages, Page currentPage, String login, int initialDepth, int descendantDepth, int currentDepth, int currentDescendantDepth) throws SAXException + { + for (BufferedPage page : pages) + { + String pagePath = page.path; + + AttributesImpl attrs = new AttributesImpl(); + Map internalAttributes = page.internalAttributes; + + for (String name : internalAttributes.keySet()) + { + attrs.addCDATAAttribute(NAMESPACE_URI, name, NAMESPACE_PREFIX + ':' + name, internalAttributes.get(name)); + } + + Map attributes = page.attributes; + + for (String name : attributes.keySet()) + { + attrs.addCDATAAttribute(name, attributes.get(name)); + } + + String currentPagePath = currentPage != null ? currentPage.getPathInSitemap() : null; + + // If the page belongs to current page's path + boolean isPageCurrent = currentPagePath != null && currentPagePath.equals(pagePath); + boolean inPath = isPageCurrent || (currentPagePath != null && currentPagePath.startsWith(pagePath + "/")); + boolean descendant = pagePath.startsWith(currentPagePath); + + if (inPath) + { + attrs.addCDATAAttribute(NAMESPACE_URI, "in-path", NAMESPACE_PREFIX + ":in-path", "true"); + } + + // If the page is the current page + if (isPageCurrent) + { + attrs.addCDATAAttribute(NAMESPACE_URI, "current", NAMESPACE_PREFIX + ":current", "true"); + } + + XMLUtils.startElement(handler, "page", attrs); + + if (currentDepth < initialDepth || inPath || isPageCurrent || (descendant && currentDescendantDepth < descendantDepth)) + { + int newCurrentDescendantDepth = isPageCurrent ? 1 : (descendant ? currentDescendantDepth + 1 : -1); + + _saxPages(handler, page.children, currentPage, login, initialDepth, descendantDepth, currentDepth + 1, newCurrentDescendantDepth); + } + + XMLUtils.endElement(handler, "page"); + } + } + + class BufferedPage + { + String path; + Map attributes; + Map internalAttributes; + List children; + } +}