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

File DocumentTableBlockDataSource.java

 

Coverage histogram

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

Code metrics

26
51
6
1
247
147
21
0.41
8.5
6
3.5

Classes

Class Line # Actions
DocumentTableBlockDataSource 60 51 0% 21 8
0.9036144690.4%
 

Contributing tests

This file is covered by 4 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.chart.source.table;
21   
22    import java.util.List;
23   
24    import javax.inject.Inject;
25    import javax.inject.Named;
26   
27    import org.slf4j.Logger;
28    import org.xwiki.bridge.DocumentAccessBridge;
29    import org.xwiki.bridge.DocumentModelBridge;
30    import org.xwiki.component.annotation.Component;
31    import org.xwiki.component.annotation.InstantiationStrategy;
32    import org.xwiki.display.internal.DocumentDisplayer;
33    import org.xwiki.display.internal.DocumentDisplayerParameters;
34    import org.xwiki.model.reference.DocumentReference;
35    import org.xwiki.model.reference.DocumentReferenceResolver;
36    import org.xwiki.rendering.block.Block;
37    import org.xwiki.rendering.block.MacroBlock;
38    import org.xwiki.rendering.block.MetaDataBlock;
39    import org.xwiki.rendering.block.TableBlock;
40    import org.xwiki.rendering.block.XDOM;
41    import org.xwiki.rendering.block.match.ClassBlockMatcher;
42    import org.xwiki.rendering.block.match.MetadataBlockMatcher;
43    import org.xwiki.rendering.listener.MetaData;
44    import org.xwiki.rendering.macro.MacroExecutionException;
45    import org.xwiki.rendering.transformation.MacroTransformationContext;
46    import org.xwiki.security.authorization.AuthorizationManager;
47    import org.xwiki.security.authorization.Right;
48   
49    import static org.xwiki.component.descriptor.ComponentInstantiationStrategy.PER_LOOKUP;
50   
51    /**
52    * A data source that allows building charts from {@link XDOM} sources.
53    *
54    * @version $Id: e7023430a9c9824e557eaa3f100958fe8d7ac4e5 $
55    * @since 4.2M1
56    */
57    @Component
58    @Named("xdom")
59    @InstantiationStrategy(PER_LOOKUP)
 
60    public class DocumentTableBlockDataSource extends AbstractTableBlockDataSource
61    {
62    /**
63    * Identifies which xdom to process.
64    */
65    private static final String DOCUMENT_PARAM = "document";
66   
67    /**
68    * Identifies the table on the xdom.
69    */
70    private static final String TABLE_PARAM = "table";
71   
72    /**
73    * The document name of the document holding the table. If null then the data source is located in the current
74    * document.
75    */
76    private DocumentReference documentReference;
77   
78    /**
79    * The id of the table holding the data.
80    */
81    private String tableId;
82   
83    /**
84    * A logger.
85    */
86    @Inject
87    private Logger logger;
88   
89    /**
90    * {@link DocumentDisplayer} used for rendering the document contents.
91    */
92    @Inject
93    private DocumentDisplayer documentDisplayer;
94   
95    /**
96    * {@link DocumentAccessBridge} component.
97    */
98    @Inject
99    private DocumentAccessBridge docBridge;
100   
101    /**
102    * A document reference resolver.
103    */
104    @Inject
105    private DocumentReferenceResolver<String> documentReferenceResolver;
106   
107    /**
108    * The authorization manager.
109    */
110    @Inject
111    private AuthorizationManager authorizationManager;
112   
 
113  10 toggle @Override
114    protected TableBlock getTableBlock(String macroContent, MacroTransformationContext context)
115    throws MacroExecutionException
116    {
117  10 XDOM xdom = computeXDOM(context);
118   
119    // Find the correct table block.
120  10 List<TableBlock> tableBlocks = xdom.getBlocks(new ClassBlockMatcher(TableBlock.class), Block.Axes.DESCENDANT);
121  10 TableBlock result = null;
122  10 this.logger.debug("Table id is [{}], there are [{}] tables in the document [{}]",
123    new Object[]{this.tableId, tableBlocks.size(), this.documentReference});
124  10 if (null != tableId) {
125  1 for (TableBlock tableBlock : tableBlocks) {
126  2 String id = tableBlock.getParameter("id");
127  2 if (null != id && id.equals(this.tableId)) {
128  1 result = tableBlock;
129  1 break;
130    }
131    }
132    } else {
133  9 result = (tableBlocks.size() > 0) ? tableBlocks.get(0) : null;
134    }
135   
136  10 if (null == result) {
137  0 throw new MacroExecutionException("Unable to find a matching data table.");
138    }
139   
140  10 return result;
141    }
142   
143    /**
144    * Get the XDOM for the data source.
145    *
146    * @param context the Macro context from which we can get the XDOM if the source is in the current content
147    * @return the XDOM in which the data source is located
148    * @throws MacroExecutionException in case of an error getting the XDOM
149    */
 
150  10 toggle private XDOM computeXDOM(MacroTransformationContext context) throws MacroExecutionException
151    {
152  10 XDOM xdom;
153   
154    // Parse the document content into an XDOM. If the reference is to the current document then we should not
155    // Parse the content again since 1) that's unnecessary since we can hold of the XDOM from the Transformation
156    // Context and 2) it's going to cause a cycle...
157  10 if (isDefinedChartSourceTheCurrentDocument(context.getCurrentMacroBlock())) {
158  2 xdom = context.getXDOM();
159    } else {
160  8 try {
161  8 DocumentModelBridge document = this.docBridge.getDocument(this.documentReference);
162  8 DocumentDisplayerParameters parameters = new DocumentDisplayerParameters();
163  8 parameters.setContentTranslated(true);
164  8 parameters.setTargetSyntax(context.getTransformationContext().getTargetSyntax());
165  8 xdom = this.documentDisplayer.display(document, parameters);
166    } catch (Exception e) {
167  0 throw new MacroExecutionException(String.format("Error getting Chart table from document [%s]",
168    this.documentReference, e));
169    }
170    }
171  10 return xdom;
172    }
173   
174    /**
175    * @param currentMacroBlock the current macro block being rendered
176    * @return true if the chart macro takes its source in the current document or false otherwise
177    */
 
178  11 toggle protected boolean isDefinedChartSourceTheCurrentDocument(MacroBlock currentMacroBlock)
179    {
180  11 boolean result;
181  11 if (this.documentReference == null) {
182  2 result = true;
183    } else {
184  9 String sourceReference = extractSourceContentReference(currentMacroBlock);
185  9 if (this.documentReferenceResolver.resolve(sourceReference,
186    this.docBridge.getCurrentDocumentReference()).equals(this.documentReference))
187    {
188  1 result = true;
189    } else {
190  8 result = false;
191    }
192    }
193   
194  11 return result;
195    }
196   
 
197  82 toggle @Override
198    protected boolean setParameter(String key, String value) throws MacroExecutionException
199    {
200  82 if (DOCUMENT_PARAM.equals(key)) {
201  9 this.documentReference
202    = this.documentReferenceResolver.resolve(value, docBridge.getCurrentDocumentReference());
203  9 return true;
204    }
205   
206  73 if (TABLE_PARAM.equals(key)) {
207  1 this.tableId = value;
208  1 return true;
209    }
210   
211  72 return super.setParameter(key, value);
212    }
213   
 
214  10 toggle @Override
215    protected void validateParameters() throws MacroExecutionException
216    {
217  10 super.validateParameters();
218   
219  10 if (this.documentReference != null) {
220  8 if (!authorizationManager.hasAccess(Right.VIEW, this.docBridge.getCurrentUserReference(),
221    this.documentReference))
222    {
223  0 throw new MacroExecutionException("You do not have permission to view the document.");
224    }
225   
226  8 if (!this.docBridge.exists(this.documentReference)) {
227  0 throw new MacroExecutionException(
228    String.format("Document [%s] does not exist.", this.documentReference));
229    }
230    }
231    }
232   
233    /**
234    * @param source the blocks from where to try to extract the source content
235    * @return the source content reference or null if none is found
236    */
 
237  9 toggle private String extractSourceContentReference(Block source)
238    {
239  9 String contentSource = null;
240  9 MetaDataBlock metaDataBlock =
241    source.getFirstBlock(new MetadataBlockMatcher(MetaData.SOURCE), Block.Axes.ANCESTOR);
242  9 if (metaDataBlock != null) {
243  8 contentSource = (String) metaDataBlock.getMetaData().getMetaData(MetaData.SOURCE);
244    }
245  9 return contentSource;
246    }
247    }