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

File DashboardMacro.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

12
49
6
1
282
140
16
0.33
8.17
6
2.67

Classes

Class Line # Actions
DashboardMacro 58 49 0% 16 17
0.7462686374.6%
 

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.Collections;
23    import java.util.HashMap;
24    import java.util.List;
25    import java.util.Map;
26   
27    import javax.inject.Inject;
28    import javax.inject.Named;
29    import javax.inject.Singleton;
30   
31    import org.apache.commons.lang3.StringUtils;
32    import org.slf4j.Logger;
33    import org.xwiki.component.annotation.Component;
34    import org.xwiki.component.manager.ComponentLookupException;
35    import org.xwiki.component.manager.ComponentManager;
36    import org.xwiki.rendering.block.Block;
37    import org.xwiki.rendering.block.GroupBlock;
38    import org.xwiki.rendering.internal.macro.script.NestedScriptMacroEnabled;
39    import org.xwiki.rendering.macro.AbstractMacro;
40    import org.xwiki.rendering.macro.MacroExecutionException;
41    import org.xwiki.rendering.macro.dashboard.DashboardMacroParameters;
42    import org.xwiki.rendering.macro.dashboard.DashboardRenderer;
43    import org.xwiki.rendering.macro.dashboard.Gadget;
44    import org.xwiki.rendering.macro.dashboard.GadgetRenderer;
45    import org.xwiki.rendering.macro.dashboard.GadgetSource;
46    import org.xwiki.rendering.transformation.MacroTransformationContext;
47    import org.xwiki.skinx.SkinExtension;
48   
49    /**
50    * The dashboard macro, to display other macros as gadgets in a dashboard, using a container to include its contents.
51    *
52    * @version $Id: fd97779dc9d8bc864c9111b44c0a268090d7cd18 $
53    * @since 2.5M2
54    */
55    @Component
56    @Named(DashboardMacro.MACRO_NAME)
57    @Singleton
 
58    public class DashboardMacro extends AbstractMacro<DashboardMacroParameters> implements NestedScriptMacroEnabled
59    {
60    /**
61    * The marker to set as class parameter for the gadget containers in this dashboard, i.e. the elements that can
62    * contain gadgets.
63    */
64    public static final String GADGET_CONTAINER = "gadget-container";
65   
66    /**
67    * The prefix of the id of the gadget containers in this dashboard, i.e. the elements that can contain gadgets. To
68    * be completed by the individual renderers with the container ids.
69    */
70    public static final String GADGET_CONTAINER_PREFIX = "gadgetcontainer_";
71   
72    /**
73    * The identifier of the metadata block for this dashboard (class parameter of the generated XDOM container that
74    * holds the rest of the metadata).
75    */
76    public static final String METADATA = "metadata";
77   
78    /**
79    * The identifier of the edit url metadata.
80    */
81    public static final String EDIT_URL = "editurl";
82   
83    /**
84    * The identifier of the add url metadata.
85    */
86    public static final String ADD_URL = "addurl";
87   
88    /**
89    * The identifier of the remove url metadata.
90    */
91    public static final String REMOVE_URL = "removeurl";
92   
93    /**
94    * The identifier of the source page metadata.
95    */
96    public static final String SOURCE_PAGE = "sourcepage";
97   
98    /**
99    * The identifier of the source space metadata.
100    */
101    public static final String SOURCE_SPACE = "sourcespace";
102   
103    /**
104    * The identifier of the source wiki metadata.
105    */
106    public static final String SOURCE_WIKI = "sourcewiki";
107   
108    /**
109    * The identifier of the source url metadata.
110    */
111    public static final String SOURCE_URL = "sourceurl";
112   
113    /**
114    * The name of this macro.
115    */
116    public static final String MACRO_NAME = "dashboard";
117   
118    /**
119    * The description of this macro.
120    */
121    private static final String DESCRIPTION = "A macro to define a dashboard.";
122   
123    /**
124    * CSS file skin extension, to include the dashboard css.
125    */
126    @Inject
127    @Named("ssfx")
128    private SkinExtension ssfx;
129   
130    /**
131    * JS file skin extension, to include the dashboard.js.
132    */
133    @Inject
134    @Named("jsfx")
135    private SkinExtension jsfx;
136   
137    /**
138    * The component manager, to resolve the dashboard renderer by layout hint.
139    */
140    @Inject
141    private ComponentManager componentManager;
142   
143    /**
144    * The gadget reader providing the list of {@link Gadget}s to render on this dashboard.
145    */
146    @Inject
147    private GadgetSource gadgetSource;
148   
149    /**
150    * The logger to log.
151    */
152    @Inject
153    private Logger logger;
154   
155    /**
156    * Instantiates the dashboard macro, setting the name, description and parameters type.
157    */
 
158  3 toggle public DashboardMacro()
159    {
160  3 super("Dashboard", DESCRIPTION, DashboardMacroParameters.class);
161    }
162   
 
163  3 toggle @Override
164    public List<Block> execute(DashboardMacroParameters parameters, String content, MacroTransformationContext context)
165    throws MacroExecutionException
166    {
167    // get the gadgets from the objects
168  3 List<Gadget> gadgets;
169  3 try {
170  3 gadgets = this.gadgetSource.getGadgets(parameters.getSource(), context);
171    } catch (Exception e) {
172  0 String message = "Could not get the gadgets.";
173    // log and throw further
174  0 this.logger.error(message, e);
175  0 throw new MacroExecutionException(message, e);
176    }
177   
178  3 boolean isInEditMode = this.gadgetSource.isEditing();
179   
180  3 DashboardRenderer renderer =
181  3 getDashboardRenderer(StringUtils.isEmpty(parameters.getLayout()) ? "columns" : parameters.getLayout());
182  3 if (renderer == null) {
183  0 String message = "Could not find dashboard renderer " + parameters.getLayout();
184    // log and throw further
185  0 this.logger.error(message);
186  0 throw new MacroExecutionException(message);
187    }
188   
189  3 GadgetRenderer gadgetRenderer = getGadgetRenderer(isInEditMode);
190   
191    // else, layout
192  3 List<Block> layoutedResult;
193  3 try {
194  3 layoutedResult = renderer.renderGadgets(gadgets, gadgetRenderer, context);
195    } catch (Exception e) {
196  0 String message = "Could not render the gadgets for layout " + parameters.getLayout();
197    // log and throw further
198  0 this.logger.error(message, e);
199  0 throw new MacroExecutionException(message, e);
200    }
201   
202    // include the css and js for this macro. here so that it's included after any dependencies have included their
203    // css, so that it cascades properly
204  3 this.includeResources(isInEditMode);
205   
206    // put everything in a nice toplevel group for this dashboard, to be able to add classes to it
207  3 GroupBlock topLevel = new GroupBlock();
208    // just under the toplevel, above the content, slip in the metadata, for the client code, only if we're in edit
209    // mode
210  3 if (isInEditMode) {
211  2 topLevel.addChildren(this.gadgetSource.getDashboardSourceMetadata(parameters.getSource(), context));
212    }
213  3 topLevel.addChildren(layoutedResult);
214    // add the style attribute of the dashboard macro as a class to the toplevel container
215  3 topLevel.setParameter("class",
216  3 MACRO_NAME + (StringUtils.isEmpty(parameters.getStyle()) ? "" : " " + parameters.getStyle()));
217   
218  3 return Collections.<Block> singletonList(topLevel);
219    }
220   
221    /**
222    * Includes the js and css resources for the dashboard macro.
223    *
224    * @param editMode whether the dashboard is in edit mode or not (js resources need to be loaded only in edit mode)
225    */
 
226  3 toggle protected void includeResources(boolean editMode)
227    {
228  3 Map<String, Object> fxParamsForceSkinAction = new HashMap<String, Object>();
229  3 fxParamsForceSkinAction.put("forceSkinAction", true);
230  3 this.ssfx.use("uicomponents/dashboard/dashboard.css", fxParamsForceSkinAction);
231    // include the js resources, for editing, in edit mode only
232  3 if (editMode) {
233    // include the effects.js and dragdrop.js that are needed by the dashboard js
234  2 this.jsfx.use("js/scriptaculous/effects.js");
235  2 this.jsfx.use("js/scriptaculous/dragdrop.js");
236  2 Map<String, Object> fxParamsNonDeferredForceSkinAction = new HashMap<String, Object>();
237  2 fxParamsNonDeferredForceSkinAction.put("defer", false);
238  2 fxParamsNonDeferredForceSkinAction.putAll(fxParamsForceSkinAction);
239  2 this.jsfx.use("js/xwiki/wysiwyg/xwe/XWikiWysiwyg.js", fxParamsNonDeferredForceSkinAction);
240  2 this.jsfx.use("uicomponents/dashboard/dashboard.js", fxParamsForceSkinAction);
241    }
242    }
243   
244    /**
245    * @param layout the layout style parameter of this dashboard, to find the renderer for
246    * @return the dashboard renderer, according to the style parameter of this dashboard macro
247    */
 
248  3 toggle protected DashboardRenderer getDashboardRenderer(String layout)
249    {
250  3 try {
251  3 return this.componentManager.getInstance(DashboardRenderer.class, layout);
252    } catch (ComponentLookupException e) {
253  0 this.logger.warn("Could not find the Dashboard renderer for layout \"" + layout + "\"");
254  0 return null;
255    }
256    }
257   
258    /**
259    * @param isEditing whether this dashboard is in edit mode or in view mode
260    * @return the gadgets renderer used by this dashboard
261    * @throws MacroExecutionException if the gadget renderer cannot be found
262    */
 
263  3 toggle protected GadgetRenderer getGadgetRenderer(boolean isEditing) throws MacroExecutionException
264    {
265  3 String hint = "default";
266  3 if (isEditing) {
267  2 hint = "edit";
268    }
269  3 try {
270  3 return this.componentManager.getInstance(GadgetRenderer.class, hint);
271    } catch (ComponentLookupException e) {
272  0 throw new MacroExecutionException(String.format("Could not find the Gadgets renderer for hint [%s].",
273    hint), e);
274    }
275    }
276   
 
277  0 toggle @Override
278    public boolean supportsInlineMode()
279    {
280  0 return false;
281    }
282    }