1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package org.xwiki.configuration.internal; |
21 |
|
|
22 |
|
import java.util.ArrayList; |
23 |
|
import java.util.Arrays; |
24 |
|
import java.util.Collections; |
25 |
|
import java.util.List; |
26 |
|
import java.util.Set; |
27 |
|
import java.util.regex.Pattern; |
28 |
|
|
29 |
|
import javax.inject.Inject; |
30 |
|
import javax.inject.Provider; |
31 |
|
|
32 |
|
import org.slf4j.Logger; |
33 |
|
import org.xwiki.bridge.event.WikiDeletedEvent; |
34 |
|
import org.xwiki.cache.Cache; |
35 |
|
import org.xwiki.cache.CacheException; |
36 |
|
import org.xwiki.cache.CacheManager; |
37 |
|
import org.xwiki.cache.config.CacheConfiguration; |
38 |
|
import org.xwiki.component.manager.ComponentLifecycleException; |
39 |
|
import org.xwiki.component.phase.Disposable; |
40 |
|
import org.xwiki.component.phase.Initializable; |
41 |
|
import org.xwiki.component.phase.InitializationException; |
42 |
|
import org.xwiki.model.EntityType; |
43 |
|
import org.xwiki.model.reference.DocumentReference; |
44 |
|
import org.xwiki.model.reference.EntityReferenceSerializer; |
45 |
|
import org.xwiki.model.reference.LocalDocumentReference; |
46 |
|
import org.xwiki.model.reference.RegexEntityReference; |
47 |
|
import org.xwiki.model.reference.WikiReference; |
48 |
|
import org.xwiki.observation.EventListener; |
49 |
|
import org.xwiki.observation.ObservationManager; |
50 |
|
import org.xwiki.observation.event.Event; |
51 |
|
import org.xwiki.properties.ConverterManager; |
52 |
|
import org.xwiki.wiki.descriptor.WikiDescriptorManager; |
53 |
|
|
54 |
|
import com.xpn.xwiki.XWikiContext; |
55 |
|
import com.xpn.xwiki.XWikiException; |
56 |
|
import com.xpn.xwiki.doc.XWikiDocument; |
57 |
|
import com.xpn.xwiki.internal.event.XObjectAddedEvent; |
58 |
|
import com.xpn.xwiki.internal.event.XObjectDeletedEvent; |
59 |
|
import com.xpn.xwiki.internal.event.XObjectUpdatedEvent; |
60 |
|
import com.xpn.xwiki.objects.BaseObject; |
61 |
|
import com.xpn.xwiki.objects.BaseProperty; |
62 |
|
|
63 |
|
|
64 |
|
|
65 |
|
|
66 |
|
@version |
67 |
|
@since |
68 |
|
|
|
|
| 95% |
Uncovered Elements: 7 (139) |
Complexity: 49 |
Complexity Density: 0.6 |
|
69 |
|
public abstract class AbstractDocumentConfigurationSource extends AbstractConfigurationSource implements Initializable, |
70 |
|
Disposable |
71 |
|
{ |
72 |
|
|
73 |
|
|
74 |
|
|
75 |
|
|
76 |
|
protected static final String NO_VALUE = "---"; |
77 |
|
|
78 |
|
@Inject |
79 |
|
protected WikiDescriptorManager wikiManager; |
80 |
|
|
81 |
|
@Inject |
82 |
|
protected CacheManager cacheManager; |
83 |
|
|
84 |
|
@Inject |
85 |
|
protected EntityReferenceSerializer<String> referenceSerializer; |
86 |
|
|
87 |
|
@Inject |
88 |
|
protected ObservationManager observation; |
89 |
|
|
90 |
|
@Inject |
91 |
|
protected Provider<XWikiContext> xcontextProvider; |
92 |
|
|
93 |
|
@Inject |
94 |
|
protected ConverterManager converter; |
95 |
|
|
96 |
|
@Inject |
97 |
|
protected Logger logger; |
98 |
|
|
99 |
|
protected Cache<Object> cache; |
100 |
|
|
101 |
|
|
102 |
|
@return |
103 |
|
|
104 |
|
|
105 |
|
protected abstract DocumentReference getDocumentReference(); |
106 |
|
|
107 |
|
|
108 |
|
@return |
109 |
|
|
110 |
|
protected abstract LocalDocumentReference getClassReference(); |
111 |
|
|
112 |
|
|
113 |
|
@return |
114 |
|
|
115 |
|
protected abstract String getCacheId(); |
116 |
|
|
117 |
|
|
118 |
|
@return |
119 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
120 |
39860 |
protected String getCacheKeyPrefix()... |
121 |
|
{ |
122 |
39852 |
return this.referenceSerializer.serialize(getDocumentReference()); |
123 |
|
} |
124 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 0.5 |
|
125 |
322 |
@Override... |
126 |
|
public void initialize() throws InitializationException |
127 |
|
{ |
128 |
|
|
129 |
322 |
try { |
130 |
322 |
this.cache = this.cacheManager.createNewCache(new CacheConfiguration(getCacheId())); |
131 |
|
} catch (CacheException e) { |
132 |
0 |
throw new InitializationException("Failed to initialize cache", e); |
133 |
|
} |
134 |
|
|
135 |
|
|
136 |
322 |
this.observation.addListener(new EventListener() |
137 |
|
{ |
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
138 |
132 |
@Override... |
139 |
|
public void onEvent(Event event, Object source, Object data) |
140 |
|
{ |
141 |
132 |
onCacheCleanup(event, source, data); |
142 |
|
} |
143 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
144 |
2936 |
@Override... |
145 |
|
public String getName() |
146 |
|
{ |
147 |
2936 |
return getCacheId(); |
148 |
|
} |
149 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
150 |
312 |
@Override... |
151 |
|
public List<Event> getEvents() |
152 |
|
{ |
153 |
312 |
return getCacheCleanupEvents(); |
154 |
|
} |
155 |
|
}); |
156 |
|
} |
157 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
158 |
294 |
@Override... |
159 |
|
public void dispose() throws ComponentLifecycleException |
160 |
|
{ |
161 |
294 |
this.observation.removeListener(getCacheId()); |
162 |
|
} |
163 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0.5 |
|
164 |
312 |
protected List<Event> getCacheCleanupEvents()... |
165 |
|
{ |
166 |
312 |
RegexEntityReference classMatcher = |
167 |
|
new RegexEntityReference(Pattern.compile(".*:" + this.referenceSerializer.serialize(getClassReference()) |
168 |
|
+ "\\[\\d*\\]"), EntityType.OBJECT); |
169 |
|
|
170 |
312 |
return Arrays.<Event>asList(new XObjectAddedEvent(classMatcher), new XObjectDeletedEvent(classMatcher), |
171 |
|
new XObjectUpdatedEvent(classMatcher), new WikiDeletedEvent()); |
172 |
|
} |
173 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
174 |
132 |
protected void onCacheCleanup(Event event, Object source, Object data)... |
175 |
|
{ |
176 |
|
|
177 |
132 |
this.cache.removeAll(); |
178 |
|
} |
179 |
|
|
180 |
|
|
181 |
|
@return |
182 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
183 |
13775 |
protected WikiReference getCurrentWikiReference()... |
184 |
|
{ |
185 |
13777 |
return new WikiReference(this.wikiManager.getCurrentWikiId()); |
186 |
|
} |
187 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (7) |
Complexity: 3 |
Complexity Density: 0.6 |
|
188 |
340231 |
@Override... |
189 |
|
public boolean containsKey(String key) |
190 |
|
{ |
191 |
340225 |
XWikiContext xcontext = this.xcontextProvider.get(); |
192 |
|
|
193 |
340217 |
if (xcontext != null && xcontext.getWiki() != null) { |
194 |
261999 |
Object value = getPropertyValue(key, null); |
195 |
262000 |
return value != null; |
196 |
|
} |
197 |
|
|
198 |
78197 |
return false; |
199 |
|
} |
200 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (9) |
Complexity: 3 |
Complexity Density: 0.43 |
|
201 |
1054 |
protected BaseObject getBaseObject() throws XWikiException... |
202 |
|
{ |
203 |
1054 |
DocumentReference documentReference = getFailsafeDocumentReference(); |
204 |
1054 |
LocalDocumentReference classReference = getFailsafeClassReference(); |
205 |
|
|
206 |
1054 |
if (documentReference != null && classReference != null) { |
207 |
709 |
XWikiContext xcontext = this.xcontextProvider.get(); |
208 |
|
|
209 |
709 |
XWikiDocument document = xcontext.getWiki().getDocument(getDocumentReference(), xcontext); |
210 |
|
|
211 |
709 |
return document.getXObject(classReference); |
212 |
|
} |
213 |
|
|
214 |
345 |
return null; |
215 |
|
} |
216 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (16) |
Complexity: 5 |
Complexity Density: 0.62 |
|
217 |
1052 |
protected Object getBaseProperty(String propertyName, boolean text) throws XWikiException... |
218 |
|
{ |
219 |
1052 |
BaseObject baseObject = getBaseObject(); |
220 |
|
|
221 |
1052 |
if (baseObject != null) { |
222 |
319 |
BaseProperty property = (BaseProperty) baseObject.getField(propertyName); |
223 |
|
|
224 |
42 |
Object value = property != null ? (text ? property.toText() : property.getValue()) : null; |
225 |
|
|
226 |
|
|
227 |
|
|
228 |
319 |
if (isEmpty(value)) { |
229 |
297 |
value = null; |
230 |
|
} |
231 |
|
|
232 |
319 |
return value; |
233 |
|
} |
234 |
|
|
235 |
733 |
return null; |
236 |
|
} |
237 |
|
|
|
|
| 95% |
Uncovered Elements: 1 (20) |
Complexity: 6 |
Complexity Density: 0.43 |
|
238 |
15 |
@Override... |
239 |
|
public List<String> getKeys() |
240 |
|
{ |
241 |
15 |
List<String> keys = Collections.emptyList(); |
242 |
|
|
243 |
15 |
XWikiContext xcontext = this.xcontextProvider.get(); |
244 |
|
|
245 |
15 |
if (xcontext != null && xcontext.getWiki() != null) { |
246 |
3 |
BaseObject baseObject; |
247 |
3 |
try { |
248 |
3 |
baseObject = getBaseObject(); |
249 |
|
|
250 |
3 |
if (baseObject != null) { |
251 |
2 |
Set<String> properties = baseObject.getPropertyList(); |
252 |
2 |
keys = new ArrayList<String>(properties.size()); |
253 |
2 |
for (String key : properties) { |
254 |
|
|
255 |
|
|
256 |
5 |
if (containsKey(key)) { |
257 |
3 |
keys.add(key); |
258 |
|
} |
259 |
|
} |
260 |
|
} |
261 |
|
} catch (XWikiException e) { |
262 |
0 |
this.logger.error("Failed to access configuration", e); |
263 |
|
} |
264 |
|
} |
265 |
|
|
266 |
15 |
return keys; |
267 |
|
} |
268 |
|
|
|
|
| 87.5% |
Uncovered Elements: 1 (8) |
Complexity: 3 |
Complexity Density: 0.75 |
|
269 |
529 |
@Override... |
270 |
|
public <T> T getProperty(String key, T defaultValue) |
271 |
|
{ |
272 |
529 |
T result = getPropertyValue(key, defaultValue != null ? (Class<T>) defaultValue.getClass() : null); |
273 |
|
|
274 |
|
|
275 |
|
|
276 |
529 |
if (result == null) { |
277 |
4 |
result = defaultValue; |
278 |
|
} |
279 |
|
|
280 |
529 |
return result; |
281 |
|
} |
282 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (6) |
Complexity: 2 |
Complexity Density: 0.5 |
|
283 |
552051 |
@Override... |
284 |
|
public <T> T getProperty(String key, Class<T> valueClass) |
285 |
|
{ |
286 |
552047 |
T result = getPropertyValue(key, valueClass); |
287 |
|
|
288 |
|
|
289 |
|
|
290 |
552111 |
if (result == null) { |
291 |
551971 |
result = getDefault(valueClass); |
292 |
|
} |
293 |
|
|
294 |
552073 |
return result; |
295 |
|
} |
296 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
297 |
312 |
@Override... |
298 |
|
@SuppressWarnings("unchecked") |
299 |
|
public <T> T getProperty(String key) |
300 |
|
{ |
301 |
312 |
return (T) getPropertyValue(key, null); |
302 |
|
} |
303 |
|
|
|
|
| 92.3% |
Uncovered Elements: 2 (26) |
Complexity: 10 |
Complexity Density: 0.71 |
|
304 |
814870 |
protected <T> T getPropertyValue(String key, Class<T> valueClass)... |
305 |
|
{ |
306 |
814948 |
String cacheKey = getCacheKeyPrefix() + ':' + (valueClass != null ? valueClass.getName() : null) + ':' + key; |
307 |
|
|
308 |
814912 |
Object result = this.cache.get(cacheKey); |
309 |
|
|
310 |
814953 |
if (result == null) { |
311 |
14265 |
XWikiContext xcontext = this.xcontextProvider.get(); |
312 |
|
|
313 |
14264 |
if (xcontext != null && xcontext.getWiki() != null) { |
314 |
14265 |
try { |
315 |
14266 |
result = getBaseProperty(key, valueClass == String.class); |
316 |
|
|
317 |
14266 |
if (valueClass != null && result != null) { |
318 |
36 |
result = this.converter.convert(valueClass, result); |
319 |
|
} |
320 |
|
|
321 |
|
|
322 |
14264 |
this.cache.set(cacheKey, result == null ? Void.TYPE : result); |
323 |
|
} catch (XWikiException e) { |
324 |
0 |
this.logger.error("Failed to access configuration property", e); |
325 |
|
} |
326 |
|
} |
327 |
|
} |
328 |
|
|
329 |
|
|
330 |
814926 |
if (result == Void.TYPE) { |
331 |
798971 |
result = null; |
332 |
|
} |
333 |
|
|
334 |
814939 |
return (T) result; |
335 |
|
} |
336 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
337 |
2 |
@Override... |
338 |
|
public boolean isEmpty() |
339 |
|
{ |
340 |
2 |
return getKeys().isEmpty(); |
341 |
|
} |
342 |
|
|
|
|
| 80% |
Uncovered Elements: 1 (5) |
Complexity: 2 |
Complexity Density: 0.4 |
|
343 |
27282 |
protected DocumentReference getFailsafeDocumentReference()... |
344 |
|
{ |
345 |
27284 |
DocumentReference documentReference; |
346 |
|
|
347 |
27288 |
try { |
348 |
27288 |
documentReference = getDocumentReference(); |
349 |
|
} catch (Exception e) { |
350 |
|
|
351 |
|
|
352 |
0 |
documentReference = null; |
353 |
|
} |
354 |
|
|
355 |
27291 |
return documentReference; |
356 |
|
} |
357 |
|
|
|
|
| 80% |
Uncovered Elements: 1 (5) |
Complexity: 2 |
Complexity Density: 0.4 |
|
358 |
27286 |
protected LocalDocumentReference getFailsafeClassReference()... |
359 |
|
{ |
360 |
27288 |
LocalDocumentReference classReference; |
361 |
|
|
362 |
27288 |
try { |
363 |
27287 |
classReference = getClassReference(); |
364 |
|
} catch (Exception e) { |
365 |
|
|
366 |
|
|
367 |
0 |
classReference = null; |
368 |
|
} |
369 |
|
|
370 |
27286 |
return classReference; |
371 |
|
} |
372 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
373 |
13592 |
protected boolean isEmpty(Object value)... |
374 |
|
{ |
375 |
|
|
376 |
13593 |
return value == null || (value instanceof String && (value.equals("") || value.equals(NO_VALUE))); |
377 |
|
} |
378 |
|
} |