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

File DefaultMacroContentParser.java

 

Coverage histogram

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

Code metrics

22
40
5
1
190
115
20
0.5
8
5
4

Classes

Class Line # Actions
DefaultMacroContentParser 59 40 0% 20 7
0.895522489.6%
 

Contributing tests

This file is covered by 93 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;
21   
22    import java.io.StringReader;
23    import java.util.ArrayList;
24    import java.util.Collections;
25    import java.util.List;
26   
27    import javax.inject.Inject;
28    import javax.inject.Singleton;
29   
30    import org.apache.commons.lang3.StringUtils;
31    import org.xwiki.component.annotation.Component;
32    import org.xwiki.component.manager.ComponentLookupException;
33    import org.xwiki.component.manager.ComponentManager;
34    import org.xwiki.rendering.block.Block;
35    import org.xwiki.rendering.block.Block.Axes;
36    import org.xwiki.rendering.block.MacroBlock;
37    import org.xwiki.rendering.block.MetaDataBlock;
38    import org.xwiki.rendering.block.XDOM;
39    import org.xwiki.rendering.block.match.MetadataBlockMatcher;
40    import org.xwiki.rendering.internal.transformation.MutableRenderingContext;
41    import org.xwiki.rendering.listener.MetaData;
42    import org.xwiki.rendering.macro.MacroContentParser;
43    import org.xwiki.rendering.macro.MacroExecutionException;
44    import org.xwiki.rendering.parser.Parser;
45    import org.xwiki.rendering.syntax.Syntax;
46    import org.xwiki.rendering.transformation.MacroTransformationContext;
47    import org.xwiki.rendering.transformation.RenderingContext;
48    import org.xwiki.rendering.transformation.TransformationContext;
49    import org.xwiki.rendering.util.ParserUtils;
50   
51    /**
52    * Default implementation for {@link org.xwiki.rendering.macro.MacroContentParser}.
53    *
54    * @version $Id: 690860cfe3abf964c871b69ddce3e9e6104daf84 $
55    * @since 3.0M1
56    */
57    @Component
58    @Singleton
 
59    public class DefaultMacroContentParser implements MacroContentParser
60    {
61    /**
62    * Used to look up the syntax parser to use for parsing the content.
63    */
64    @Inject
65    private ComponentManager componentManager;
66   
67    /**
68    * Used to update rendering context during content transformation.
69    */
70    @Inject
71    private RenderingContext renderingContext;
72   
73    /**
74    * Utility to remove the top level paragraph.
75    */
76    private ParserUtils parserUtils = new ParserUtils();
77   
 
78  8282 toggle @Override
79    public XDOM parse(String content, MacroTransformationContext macroContext, boolean transform, boolean inline)
80    throws MacroExecutionException
81    {
82  8282 return parse(content, macroContext, transform, null, inline);
83    }
84   
 
85  8282 toggle @Override
86    public XDOM parse(String content, MacroTransformationContext macroContext, boolean transform, MetaData metadata,
87    boolean inline) throws MacroExecutionException
88    {
89    // If the content is empty return an empty list
90  8283 if (StringUtils.isEmpty(content)) {
91  393 return new XDOM(Collections.<Block>emptyList(), metadata != null ? metadata : MetaData.EMPTY);
92    }
93   
94  7890 Syntax syntax = getCurrentSyntax(macroContext);
95   
96    // If there's no syntax specified in the Transformation throw an error
97  7889 if (syntax == null) {
98  0 throw new MacroExecutionException("Invalid Transformation: missing Syntax");
99    }
100   
101  7889 try {
102  7889 XDOM result = getSyntaxParser(syntax).parse(new StringReader(content));
103   
104  7890 if (metadata != null) {
105  1 result.getMetaData().addMetaData(metadata);
106    }
107   
108  7890 if (transform && macroContext.getTransformation() != null) {
109  14 TransformationContext txContext = new TransformationContext(result, syntax);
110  14 txContext.setId(macroContext.getId());
111  14 try {
112  14 ((MutableRenderingContext) this.renderingContext).transformInContext(
113    macroContext.getTransformation(), txContext, result);
114    } catch (Exception e) {
115  0 throw new MacroExecutionException("Failed to perform transformation", e);
116    }
117    }
118   
119  7890 if (inline) {
120  146 result = convertToInline(result);
121    }
122   
123  7888 return result;
124    } catch (Exception e) {
125  0 throw new MacroExecutionException("Failed to parse content [" + content + "]", e);
126    }
127    }
128   
129    /**
130    * @param xdom the {@link XDOM} to convert
131    * @return an inline version of the passed {@link XDOM}
132    */
 
133  146 toggle private XDOM convertToInline(XDOM xdom)
134    {
135  146 List<Block> blocks = new ArrayList<Block>(xdom.getChildren());
136   
137    // TODO: use inline parser instead
138  146 if (!blocks.isEmpty()) {
139  146 this.parserUtils.removeTopLevelParagraph(blocks);
140   
141    // Make sure included macro is inline when script macro itself is inline
142  146 Block block = blocks.get(0);
143  146 if (block instanceof MacroBlock) {
144  34 MacroBlock macro = (MacroBlock) block;
145  34 if (!macro.isInline()) {
146  33 blocks.set(0, new MacroBlock(macro.getId(), macro.getParameters(), macro.getContent(), true));
147    }
148    }
149   
150  146 xdom.setChildren(blocks);
151    }
152   
153  146 return xdom;
154    }
155   
156    /**
157    * Get the parser for the current syntax.
158    *
159    * @param syntax the current syntax of the title content
160    * @return the parser for the current syntax
161    * @throws org.xwiki.rendering.macro.MacroExecutionException Failed to find source parser.
162    */
 
163  7890 toggle private Parser getSyntaxParser(Syntax syntax) throws MacroExecutionException
164    {
165  7890 try {
166  7890 return this.componentManager.getInstance(Parser.class, syntax.toIdString());
167    } catch (ComponentLookupException e) {
168  0 throw new MacroExecutionException("Failed to find source parser for syntax [" + syntax + "]", e);
169    }
170    }
171   
 
172  7889 toggle @Override
173    public Syntax getCurrentSyntax(MacroTransformationContext context)
174    {
175  7889 Syntax currentSyntax = context.getSyntax();
176   
177  7890 MacroBlock currentMacroBlock = context.getCurrentMacroBlock();
178   
179  7890 if (currentMacroBlock != null) {
180  7880 MetaDataBlock metaDataBlock =
181    currentMacroBlock.getFirstBlock(new MetadataBlockMatcher(MetaData.SYNTAX), Axes.ANCESTOR_OR_SELF);
182   
183  7880 if (metaDataBlock != null) {
184  7866 currentSyntax = (Syntax) metaDataBlock.getMetaData().getMetaData(MetaData.SYNTAX);
185    }
186    }
187   
188  7890 return currentSyntax;
189    }
190    }