1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.macro.dashboard

File EditableGadgetRenderer.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

10
36
4
1
177
94
10
0.28
9
4
2.5

Classes

Class Line # Actions
EditableGadgetRenderer 55 36 0% 10 5
0.990%
 

Contributing tests

This file is covered by 2 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.internal.macro.dashboard;
21   
22    import java.util.List;
23   
24    import javax.inject.Inject;
25    import javax.inject.Named;
26    import javax.inject.Singleton;
27   
28    import org.apache.commons.lang3.StringUtils;
29    import org.slf4j.Logger;
30    import org.xwiki.component.annotation.Component;
31    import org.xwiki.component.manager.ComponentLookupException;
32    import org.xwiki.component.manager.ComponentManager;
33    import org.xwiki.rendering.block.Block;
34    import org.xwiki.rendering.block.GroupBlock;
35    import org.xwiki.rendering.block.MacroBlock;
36    import org.xwiki.rendering.block.RawBlock;
37    import org.xwiki.rendering.block.WordBlock;
38    import org.xwiki.rendering.macro.dashboard.Gadget;
39    import org.xwiki.rendering.renderer.BlockRenderer;
40    import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
41    import org.xwiki.rendering.renderer.printer.WikiPrinter;
42    import org.xwiki.rendering.syntax.Syntax;
43    import org.xwiki.rendering.transformation.RenderingContext;
44   
45    /**
46    * Editable gadget renderer, that renders the gadget as in view mode, but with additional metadata that allows editing
47    * the gadget parameters.
48    *
49    * @version $Id: 82299b49933b4f55959335efe92441b6f011ffd9 $
50    * @since 3.0rc1
51    */
52    @Component
53    @Named("edit")
54    @Singleton
 
55    public class EditableGadgetRenderer extends DefaultGadgetRenderer
56    {
57    /**
58    * The identifier of the metadata block for this dashboard (class parameter of the generated XDOM container that
59    * holds the rest of the metadata).
60    */
61    protected static final String METADATA = "metadata";
62   
63    private static final String ANNOTATED_SYNTAXES_PREFIX = "annotated";
64   
65    /**
66    * The macro content renderer, to render the macro as annotated XHTML to be editable.
67    */
68    @Inject
69    @Named("annotatedxhtml/1.0")
70    protected BlockRenderer defaultGadgetContentRenderer;
71   
72    @Inject
73    protected ComponentManager componentManager;
74   
75    @Inject
76    protected RenderingContext renderingContext;
77   
78    @Inject
79    protected Logger logger;
80   
81    /**
82    * @return the renderer corresponding to the "annotated" version of the current target syntax
83    */
 
84  1 toggle protected BlockRenderer getGadgetContentRenderer()
85    {
86    // Get the current syntax
87  1 Syntax currentTargetSyntax = renderingContext.getTargetSyntax();
88  1 if (currentTargetSyntax == null) {
89    // (it should never happen actually)
90  0 return defaultGadgetContentRenderer;
91    }
92   
93    // Get the annotated syntax corresponding to the current target syntax
94  1 String annotatedTargetSyntax = currentTargetSyntax.toIdString();
95  1 if (!StringUtils.startsWith(annotatedTargetSyntax, ANNOTATED_SYNTAXES_PREFIX)) {
96  1 annotatedTargetSyntax = ANNOTATED_SYNTAXES_PREFIX + annotatedTargetSyntax;
97    }
98   
99  1 try {
100  1 return componentManager.getInstance(BlockRenderer.class, annotatedTargetSyntax);
101    } catch (ComponentLookupException e) {
102  1 logger.warn("Failed to load the syntax [{}].", annotatedTargetSyntax);
103    // Failback to the default renderer
104  1 return defaultGadgetContentRenderer;
105    }
106    }
107   
108    /**
109    * @param gadgetContentRenderer the renderer used to render the gadget
110    * @return the syntax to set to the raw block according to the given renderer
111    */
 
112  1 toggle protected Syntax getRawBlockSyntax(BlockRenderer gadgetContentRenderer)
113    {
114    // If there is a BlockRenderer corresponding to the "annotated" version of the current
115    // RenderingContext#getTargetSyntax(), then we return the current target syntax.
116    //
117    // On the opposite, if we have fallbacked to the defaultGadgetContentRenderer (see getGadgetContentRenderer()),
118    // we have to use the syntax corresponding to that renderer: XHTML 1.0.
119    //
120  1 return gadgetContentRenderer != defaultGadgetContentRenderer
121    ? renderingContext.getTargetSyntax() : Syntax.XHTML_1_0;
122    }
123   
124    /**
125    * @param gadget the gadget to decorate
126    * @return the block containing the metadata that will allow clients to edit this gadget
127    */
 
128  2 toggle protected Block getGadgetEditMetadata(Gadget gadget)
129    {
130  2 GroupBlock metadataBlock = new GroupBlock();
131  2 metadataBlock.setParameter(CLASS, METADATA);
132   
133    // look at the content of the gadget and store whether it's a macro or not
134  2 boolean isMacro = gadget.getContent().size() == 1 && gadget.getContent().get(0) instanceof MacroBlock;
135  2 GroupBlock isMacroBlock = new GroupBlock();
136  2 isMacroBlock.setParameter(CLASS, "isMacro");
137  2 isMacroBlock.addChild(new WordBlock(Boolean.toString(isMacro)));
138   
139  2 metadataBlock.addChild(isMacroBlock);
140   
141  2 if (isMacro) {
142    // render the annotated macro call in the page, to be able to edit it. Only the macro call comments will be
143    // rendered, since transformations are not ran, so there is no content in the macro. But annotation is
144    // enough.
145  1 GroupBlock renderedContentBlock = new GroupBlock();
146  1 renderedContentBlock.setParameter(CLASS, "content");
147  1 WikiPrinter printer = new DefaultWikiPrinter();
148  1 BlockRenderer gadgetContentRenderer = getGadgetContentRenderer();
149  1 gadgetContentRenderer.render(gadget.getContent(), printer);
150  1 RawBlock rawBlock = new RawBlock(printer.toString(), getRawBlockSyntax(gadgetContentRenderer));
151  1 renderedContentBlock.addChild(rawBlock);
152   
153    // render the title in the page as well, to be edited as source
154  1 GroupBlock gadgetTitleBlock = new GroupBlock();
155  1 gadgetTitleBlock.setParameter(CLASS, "title");
156    // even if it's not a word, it's fine since it will be rendered in one piece
157  1 gadgetTitleBlock.addChild(new WordBlock(gadget.getTitleSource()));
158   
159  1 metadataBlock.addChild(renderedContentBlock);
160  1 metadataBlock.addChild(gadgetTitleBlock);
161    }
162   
163  2 return metadataBlock;
164    }
165   
 
166  2 toggle @Override
167    public List<Block> decorateGadget(Gadget gadget)
168    {
169  2 List<Block> viewBlock = super.decorateGadget(gadget);
170   
171  2 if (viewBlock.size() > 0) {
172  2 viewBlock.get(0).addChild(getGadgetEditMetadata(gadget));
173    }
174   
175  2 return viewBlock;
176    }
177    }