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

File WikiUIExtensionParameters.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

8
35
3
1
184
90
14
0.4
11.67
3
4.67

Classes

Class Line # Actions
WikiUIExtensionParameters 45 35 0% 14 2
0.9565217595.7%
 

Contributing tests

This file is covered by 7 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.uiextension.internal;
21   
22    import java.io.StringWriter;
23    import java.util.HashMap;
24    import java.util.Map;
25   
26    import org.apache.velocity.VelocityContext;
27    import org.slf4j.Logger;
28    import org.slf4j.LoggerFactory;
29    import org.xwiki.component.manager.ComponentLookupException;
30    import org.xwiki.component.manager.ComponentManager;
31    import org.xwiki.component.wiki.WikiComponentException;
32    import org.xwiki.context.Execution;
33    import org.xwiki.model.EntityType;
34    import org.xwiki.model.ModelContext;
35    import org.xwiki.velocity.VelocityEngine;
36    import org.xwiki.velocity.VelocityManager;
37    import org.xwiki.velocity.XWikiVelocityException;
38   
39    /**
40    * Wiki UI Extension parameter manager.
41    *
42    * @version $Id: 331cb774672d60e2334543ac98c802164a0896d2 $
43    * @since 5.0M1
44    */
 
45    public class WikiUIExtensionParameters
46    {
47    /**
48    * The logger to log.
49    */
50    private static final Logger LOGGER = LoggerFactory.getLogger(WikiUIExtensionParameters.class);
51   
52    private String id;
53   
54    /**
55    * @see #WikiUIExtensionParameters(String, org.xwiki.component.manager.ComponentManager)
56    */
57    private Map<String, String> parameters;
58   
59    /**
60    * Parameters are evaluated through the velocity engine, to improve performance this variable is used as a cache,
61    * it's emptied for each new request (because of the dynamic vars like: language, user, etc), or if the context
62    * database has changed.
63    */
64    private Map<String, String> evaluatedParameters;
65   
66    /**
67    * HashCode of the previous execution context during the last parameters evaluation.
68    */
69    private int previousContextId;
70   
71    /**
72    * Context database during the last parameters evaluation.
73    */
74    private String previousWiki;
75   
76    /**
77    * @see #WikiUIExtensionParameters(String, org.xwiki.component.manager.ComponentManager)
78    */
79    private VelocityManager velocityManager;
80   
81    /**
82    * Model context.
83    */
84    private ModelContext modelContext;
85   
86    /**
87    * The execution context.
88    */
89    private Execution execution;
90   
91    /**
92    * Default constructor.
93    *
94    * @param id the unique identifier of this set of parameters, mostly used to isolate parameters value execution
95    * @param rawParameters raw parameters, their values can contain velocity directives
96    * @param cm the XWiki component manager
97    * @throws WikiComponentException if some required components can't be found in the Component Manager
98    */
 
99  134 toggle public WikiUIExtensionParameters(String id, String rawParameters, ComponentManager cm)
100    throws WikiComponentException
101    {
102  134 this.id = id;
103  134 this.parameters = parseParameters(rawParameters);
104   
105  134 try {
106  134 this.execution = cm.getInstance(Execution.class);
107  134 this.velocityManager = cm.getInstance(VelocityManager.class);
108  134 this.modelContext = cm.getInstance(ModelContext.class);
109    } catch (ComponentLookupException e) {
110  0 throw new WikiComponentException(
111    "Failed to get an instance for a component role required by Wiki Components.", e);
112    }
113    }
114   
115    /**
116    * Parse the parameters provided by the extension.
117    * The parameters are provided in a LargeString property of the extension object. In the future it would be better
118    * to have a Map<String, String> XClass property.
119    *
120    * @param rawParameters the string to parse
121    * @return a map of parameters
122    */
 
123  134 toggle private Map<String, String> parseParameters(String rawParameters)
124    {
125  134 Map<String, String> result = new HashMap<String, String>();
126  134 for (String line : rawParameters.split("[\\r\\n]+")) {
127  315 String[] pair = line.split("=", 2);
128  315 if (pair.length == 2 && !"".equals(pair[0]) && !"".equals(pair[1])) {
129  290 result.put(pair[0], pair[1]);
130    }
131    }
132   
133  134 return result;
134    }
135   
136    /**
137    * @return the parameters, after their values have been evaluated by the XWiki Velocity Engine.
138    */
 
139  2973 toggle public Map<String, String> get()
140    {
141  2973 boolean isCacheValid = false;
142   
143    // Even though the parameters are dynamic, we cache a rendered version of them in order to improve performance.
144    // This cache has a short lifespan, it gets discarded for each new request, or if the database has been switched
145    // during a request.
146  2971 int currentContextId = this.execution.getContext().hashCode();
147  2973 String currentWiki = modelContext.getCurrentEntityReference().extractReference(EntityType.WIKI).getName();
148  2973 if (currentContextId == this.previousContextId
149    && currentWiki.equals(previousWiki) && this.evaluatedParameters != null) {
150  1798 isCacheValid = true;
151    }
152   
153  2972 if (!isCacheValid) {
154  1175 this.evaluatedParameters = new HashMap<String, String>();
155   
156  1174 if (this.parameters.size() > 0) {
157  1071 try {
158  1072 VelocityEngine velocityEngine = this.velocityManager.getVelocityEngine();
159  1072 VelocityContext velocityContext = this.velocityManager.getVelocityContext();
160   
161  1072 for (Map.Entry<String, String> entry : this.parameters.entrySet()) {
162  2046 StringWriter writer = new StringWriter();
163  2047 try {
164  2046 String namespace = this.id + ':' + entry.getKey();
165  2046 velocityEngine.evaluate(new VelocityContext(velocityContext), writer, namespace,
166    entry.getValue());
167  2046 this.evaluatedParameters.put(entry.getKey(), writer.toString());
168    } catch (XWikiVelocityException e) {
169  1 LOGGER.warn(String.format(
170    "Failed to evaluate UI extension data value, key [%s], value [%s]. Reason: [%s]",
171    entry.getKey(), entry.getValue(), e.getMessage()));
172    }
173    }
174    } catch (XWikiVelocityException ex) {
175  0 LOGGER.warn(String.format("Failed to get velocity engine. Reason: [%s]", ex.getMessage()));
176    }
177  1072 this.previousContextId = currentContextId;
178  1072 this.previousWiki = currentWiki;
179    }
180    }
181   
182  2973 return this.evaluatedParameters;
183    }
184    }