/plugin/src/main/java/net/customware/confluence/plugin/toc/TOCMacro.java
Java | 179 lines | 115 code | 23 blank | 41 comment | 3 complexity | b9657fe521a8a7f044ba3d809c7f7bcc MD5 | raw file
Possible License(s): BSD-3-Clause
- /*
- * Copyright (c) 2007, CustomWare Asia Pacific
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of "CustomWare Asia Pacific" nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- package net.customware.confluence.plugin.toc;
- import com.atlassian.confluence.content.render.xhtml.ConversionContext;
- import com.atlassian.confluence.content.render.xhtml.HtmlToXmlConverter;
- import com.atlassian.confluence.content.render.xhtml.Streamable;
- import com.atlassian.confluence.content.render.xhtml.Streamables;
- import com.atlassian.confluence.core.ContentEntityObject;
- import com.atlassian.confluence.languages.LocaleManager;
- import com.atlassian.confluence.macro.MacroExecutionException;
- import com.atlassian.confluence.macro.StreamableMacro;
- import com.atlassian.confluence.renderer.template.TemplateRenderer;
- import com.atlassian.confluence.setup.settings.SettingsManager;
- import com.atlassian.confluence.util.i18n.I18NBeanFactory;
- import com.atlassian.confluence.xhtml.api.XhtmlContent;
- import com.atlassian.event.api.EventPublisher;
- import com.atlassian.renderer.v2.RenderMode;
- import com.atlassian.webresource.api.assembler.PageBuilderService;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import java.io.IOException;
- import java.io.Writer;
- import java.util.Map;
- import static com.atlassian.confluence.macro.Macro.BodyType.NONE;
- import static com.atlassian.renderer.v2.RenderMode.NO_RENDER;
- import static org.apache.commons.lang3.StringUtils.EMPTY;
- /**
- * Creates a table of contents based on the contents of the page.
- * For normal page display, this delegates to a javascript-based implementation
- */
- public class TOCMacro extends AbstractTOCMacro implements StreamableMacro {
- private static final Logger log = LoggerFactory.getLogger(TOCMacro.class);
- private static final String SOY_TEMPLATES_MODULE_NAME = PLUGIN_KEY + ":server-soy-templates";
- private static final String CLIENT_IMPL_CONTAINER_TEMPLATE = "Confluence.Plugins.TableOfContents.Server.clientSideTocContainer.soy";
- private final XhtmlContent xhtmlContent;
- private final PageBuilderService pageBuilderService;
- private final TemplateRenderer templateRenderer;
- private final EventPublisher eventPublisher;
- public TOCMacro(
- StaxDocumentOutlineCreator staxDocumentOutlineCreator,
- XhtmlContent xhtmlContent,
- HtmlToXmlConverter htmlToXmlConverter,
- SettingsManager settingsManager,
- LocaleManager localeManager,
- I18NBeanFactory i18nBeanFactory,
- PageBuilderService pageBuilderService,
- TemplateRenderer templateRenderer, final EventPublisher eventPublisher) {
- super(staxDocumentOutlineCreator, htmlToXmlConverter,
- settingsManager, localeManager, i18nBeanFactory, pageBuilderService);
- this.xhtmlContent = xhtmlContent;
- this.pageBuilderService = pageBuilderService;
- this.templateRenderer = templateRenderer;
- this.eventPublisher = eventPublisher;
- }
- /**
- * The main entry point to the macro. Decides which implementation (client or server) to go with.
- */
- @Override
- public Streamable executeToStream(final Map<String, String> macroParameters, final Streamable macroBody, final ConversionContext context)
- throws MacroExecutionException {
- final TocMacroImplementationType implementationType = TocMacroImplementationType.selectImplementation(context);
- eventPublisher.publish(implementationType.createEvent());
- switch (implementationType) {
- case SERVER:
- return renderServerSideImplementation(macroParameters, macroBody, context);
- case CLIENT:
- return renderClientSideImplementation(macroParameters);
- default:
- throw new MacroExecutionException("Failed to select TOCMacro implementation");
- }
- }
- private Streamable renderServerSideImplementation(final Map<String, String> macroParameters, final Streamable macroBody, final ConversionContext context)
- throws MacroExecutionException {
- return Streamables.from(execute(macroParameters, Streamables.writeToString(macroBody), context));
- }
- private Streamable renderClientSideImplementation(final Map<String, String> macroParameters) {
- pageBuilderService.assembler().resources().requireContext(CLIENT_IMPL_WEBRESOURCE_CONTEXT);
- final Map<String, Object> templateModel = ClientTocMacroTemplateModel.buildTemplateModel(macroParameters);
- return new Streamable() {
- @Override
- public void writeTo(final Writer writer) throws IOException {
- templateRenderer.renderTo(writer, SOY_TEMPLATES_MODULE_NAME, CLIENT_IMPL_CONTAINER_TEMPLATE, templateModel);
- }
- };
- }
- /**
- * This macro operates on the body of the content entity (e.g. the page) on which the macro is a part of. This
- * method fetches the content body (which should be in XHTML storage-format), renders that to view-format, then
- * returns that to be used as the basis of the TOC generation.
- */
- @Override
- protected String getContent(final Map<String, String> parameters, final String body, final ConversionContext conversionContext) {
- final ContentEntityObject contentEntity = conversionContext.getEntity();
- if (contentEntity == null) {
- log.warn("There was an error converting the preview content to view - content entity object was null.");
- return "";
- }
- try {
- return xhtmlContent.convertStorageToView(contentEntity.getBodyAsString(), conversionContext);
- } catch (Exception ex) {
- log.warn("There was an error converting the content for id " + contentEntity.getId() + " to storage format.", ex);
- return "";
- }
- }
- @Override
- protected String createOutput(Map<String, String> parameters, String body, String toc) {
- // Just return the toc as-is.
- return toc;
- }
- @Override
- protected String getDefaultType() {
- return LIST_TYPE;
- }
- @Override
- protected String getUnprintableHtml(final String body) {
- return EMPTY;
- }
- @Override
- public boolean hasBody() {
- return false;
- }
- @Override
- public BodyType getBodyType() {
- return NONE;
- }
- @Override
- public RenderMode getBodyRenderMode() {
- return NO_RENDER;
- }
- }