1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package com.xpn.xwiki.internal.filter.output

File XWikiDocumentOutputFilterStream.java

 

Coverage histogram

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

Code metrics

42
125
23
1
450
321
49
0.39
5.43
23
2.13

Classes

Class Line # Actions
XWikiDocumentOutputFilterStream 70 125 0% 49 9
0.952631695.3%
 

Contributing tests

This file is covered by 46 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 com.xpn.xwiki.internal.filter.output;
21   
22    import java.io.InputStream;
23    import java.util.ArrayList;
24    import java.util.Date;
25    import java.util.List;
26    import java.util.Locale;
27   
28    import javax.inject.Inject;
29    import javax.inject.Named;
30    import javax.inject.Provider;
31   
32    import org.apache.commons.lang3.math.NumberUtils;
33    import org.xwiki.component.annotation.Component;
34    import org.xwiki.component.annotation.InstantiationStrategy;
35    import org.xwiki.component.descriptor.ComponentInstantiationStrategy;
36    import org.xwiki.component.manager.ComponentLookupException;
37    import org.xwiki.component.manager.ComponentManager;
38    import org.xwiki.component.phase.Initializable;
39    import org.xwiki.component.phase.InitializationException;
40    import org.xwiki.filter.FilterDescriptorManager;
41    import org.xwiki.filter.FilterEventParameters;
42    import org.xwiki.filter.FilterException;
43    import org.xwiki.filter.event.model.WikiDocumentFilter;
44    import org.xwiki.filter.event.xwiki.XWikiWikiDocumentFilter;
45    import org.xwiki.localization.LocalizationContext;
46    import org.xwiki.model.reference.DocumentReference;
47    import org.xwiki.model.reference.EntityReference;
48    import org.xwiki.rendering.internal.transformation.MutableRenderingContext;
49    import org.xwiki.rendering.listener.WrappingListener;
50    import org.xwiki.rendering.renderer.PrintRendererFactory;
51    import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
52    import org.xwiki.rendering.syntax.Syntax;
53    import org.xwiki.rendering.transformation.RenderingContext;
54   
55    import com.xpn.xwiki.XWikiContext;
56    import com.xpn.xwiki.XWikiException;
57    import com.xpn.xwiki.doc.XWikiAttachment;
58    import com.xpn.xwiki.doc.XWikiDocument;
59    import com.xpn.xwiki.internal.filter.XWikiDocumentFilter;
60    import com.xpn.xwiki.internal.filter.XWikiDocumentFilterCollection;
61    import com.xpn.xwiki.objects.BaseObject;
62    import com.xpn.xwiki.objects.classes.BaseClass;
63   
64    /**
65    * @version $Id: c9111fe3f7205cb38495b5a5372e92a2d22b696a $
66    * @since 6.2M1
67    */
68    @Component
69    @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
 
70    public class XWikiDocumentOutputFilterStream extends AbstractEntityOutputFilterStream<XWikiDocument>
71    implements Initializable
72    {
73    @Inject
74    private FilterDescriptorManager filterManager;
75   
76    @Inject
77    @Named("context")
78    private Provider<ComponentManager> componentManagerProvider;
79   
80    @Inject
81    private RenderingContext renderingContext;
82   
83    @Inject
84    private LocalizationContext localizationContext;
85   
86    @Inject
87    private EntityOutputFilterStream<XWikiAttachment> attachmentFilter;
88   
89    @Inject
90    private EntityOutputFilterStream<BaseClass> classFilter;
91   
92    @Inject
93    private EntityOutputFilterStream<BaseObject> objectFilter;
94   
95    @Inject
96    private Provider<XWikiContext> xcontextProvider;
97   
98    private WrappingListener contentListener = new WrappingListener();
99   
100    private DefaultWikiPrinter currentWikiPrinter;
101   
102    private Syntax previousTargetSyntax;
103   
104    private Locale currentLocale;
105   
106    private String currentVersion;
107   
108    private FilterEventParameters currentLocaleParameters;
109   
110    private Locale currentDefaultLocale;
111   
 
112  7652 toggle @Override
113    public void initialize() throws InitializationException
114    {
115  7652 initialize(this.attachmentFilter, this.classFilter, this.objectFilter);
116    }
117   
 
118  7652 toggle @Override
119    protected Object createFilter()
120    {
121  7652 List<XWikiDocumentFilter> filters = new ArrayList<>(this.children.size() + 1);
122  7652 for (EntityOutputFilterStream<?> child : this.children) {
123  22956 filters.add((XWikiDocumentFilter) child.getFilter());
124    }
125  7652 filters.add(this);
126   
127  7652 this.filter = new XWikiDocumentFilterCollection(filters)
128    {
 
129  8051 toggle @Override
130    public void beginWikiClass(FilterEventParameters parameters) throws FilterException
131    {
132  8051 if (!objectFilter.isEnabled()) {
133  682 classFilter.enable();
134    }
135   
136  8051 super.beginWikiClass(parameters);
137    }
138   
 
139  8051 toggle @Override
140    public void endWikiClass(FilterEventParameters parameters) throws FilterException
141    {
142  8051 super.endWikiClass(parameters);
143   
144  8051 classFilter.disable();
145    }
146   
 
147  7370 toggle @Override
148    public void beginWikiObject(String name, FilterEventParameters parameters) throws FilterException
149    {
150  7370 objectFilter.enable();
151   
152  7370 super.beginWikiObject(name, parameters);
153    }
154   
 
155  7370 toggle @Override
156    public void endWikiObject(String name, FilterEventParameters parameters) throws FilterException
157    {
158  7370 super.endWikiObject(name, parameters);
159   
160  7370 objectFilter.disable();
161    }
162   
 
163  1032 toggle @Override
164    public void onWikiAttachment(String name, InputStream content, Long size, FilterEventParameters parameters)
165    throws FilterException
166    {
167  1032 attachmentFilter.enable();
168   
169  1032 super.onWikiAttachment(name, content, size, parameters);
170   
171  1032 attachmentFilter.disable();
172    }
173    };
174   
175  7652 if (this.contentListener != null) {
176    // Inject listener for the document content events
177  17 return this.filterManager.createCompositeFilter(this.contentListener, this.filter);
178    } else {
179  7635 return this.filter;
180    }
181    }
182   
 
183  2064 toggle private XWikiAttachmentOutputFilterStream getXWikiAttachmentOutputFilterStream()
184    {
185  2064 return (XWikiAttachmentOutputFilterStream) this.attachmentFilter;
186    }
187   
 
188  31011 toggle private BaseClassOutputFilterStream getBaseClassOutputFilterStream()
189    {
190  31011 return (BaseClassOutputFilterStream) this.classFilter;
191    }
192   
 
193  14740 toggle private BaseObjectOutputFilterStream getBaseObjectOutputFilterStream()
194    {
195  14740 return (BaseObjectOutputFilterStream) this.objectFilter;
196    }
197   
198    /**
199    * Optimization to disable any plumbing to support rendering events. To be used in case we know this kind of event
200    * won't be received or we want to ignore them. Should be called before {@link #getFilter()}.
201    */
 
202  7635 toggle public void disableRenderingEvents()
203    {
204  7635 this.contentListener = null;
205    }
206   
207    // Events
208   
 
209  22960 toggle private EntityReference getDefaultDocumentReference()
210    {
211  22960 if (this.properties != null && this.properties.getDefaultReference() != null) {
212  22899 return this.properties.getDefaultReference();
213    }
214   
215  61 if (this.entity != null) {
216  40 return this.entity.getDocumentReference();
217    }
218   
219  21 return null;
220    }
221   
 
222  22960 toggle private void begin(FilterEventParameters parameters) throws FilterException
223    {
224  22960 DocumentReference documentReference =
225    this.documentEntityResolver.resolve(this.currentEntityReference, getDefaultDocumentReference());
226   
227  22960 if (this.entity == null) {
228  5074 this.entity = new XWikiDocument(documentReference, this.currentLocale);
229    } else {
230  17886 this.entity.setDocumentReference(documentReference);
231  17886 this.entity.setLocale(this.currentLocale);
232    }
233   
234    // Find default author
235  22960 DocumentReference defaultAuthorReference;
236  22960 if (this.properties.isAuthorSet()) {
237  0 defaultAuthorReference = this.properties.getAuthor();
238    } else {
239  22960 XWikiContext xcontext = xcontextProvider.get();
240  22960 defaultAuthorReference = xcontext != null ? xcontext.getUserReference() : null;
241    }
242   
243  22960 this.entity
244    .setCreationDate(getDate(WikiDocumentFilter.PARAMETER_CREATION_DATE, this.currentLocaleParameters, null));
245   
246  22960 this.entity.setCreatorReference(getUserReference(WikiDocumentFilter.PARAMETER_CREATION_AUTHOR,
247    this.currentLocaleParameters, defaultAuthorReference));
248  22960 this.entity.setDefaultLocale(this.currentDefaultLocale);
249   
250  22960 this.entity.setSyntax(getSyntax(WikiDocumentFilter.PARAMETER_SYNTAX, parameters, null));
251   
252  22960 this.entity.setParentReference(getEntityReference(WikiDocumentFilter.PARAMETER_PARENT, parameters, null));
253  22960 this.entity.setCustomClass(getString(WikiDocumentFilter.PARAMETER_CUSTOMCLASS, parameters, null));
254  22960 this.entity.setTitle(getString(WikiDocumentFilter.PARAMETER_TITLE, parameters, null));
255  22960 this.entity.setDefaultTemplate(getString(WikiDocumentFilter.PARAMETER_DEFAULTTEMPLATE, parameters, null));
256  22960 this.entity.setValidationScript(getString(WikiDocumentFilter.PARAMETER_VALIDATIONSCRIPT, parameters, null));
257  22960 this.entity.setHidden(getBoolean(WikiDocumentFilter.PARAMETER_HIDDEN, parameters, false));
258   
259  22960 this.entity.setMinorEdit(getBoolean(WikiDocumentFilter.PARAMETER_REVISION_MINOR, parameters, false));
260   
261  22960 this.entity.setAuthorReference(
262    getUserReference(WikiDocumentFilter.PARAMETER_REVISION_AUTHOR, parameters, defaultAuthorReference));
263  22960 this.entity.setContentAuthorReference(
264    getUserReference(WikiDocumentFilter.PARAMETER_CONTENT_AUTHOR, parameters, defaultAuthorReference));
265   
266  22960 String revisions =
267    getString(XWikiWikiDocumentFilter.PARAMETER_JRCSREVISIONS, this.currentLocaleParameters, null);
268  22960 if (revisions != null) {
269  188 try {
270  188 this.entity.setDocumentArchive(revisions);
271    } catch (XWikiException e) {
272  0 throw new FilterException("Failed to set document archive", e);
273    }
274    }
275   
276  22960 if (this.currentVersion != null && this.properties.isVersionPreserved()) {
277  2593 if (VALID_VERSION.matcher(this.currentVersion).matches()) {
278  2589 this.entity.setVersion(this.currentVersion);
279  4 } else if (NumberUtils.isDigits(this.currentVersion)) {
280  4 this.entity.setVersion(this.currentVersion + ".1");
281    } else {
282    // TODO: log something, probably a warning
283    }
284    }
285   
286  22960 this.entity.setDate(getDate(WikiDocumentFilter.PARAMETER_REVISION_DATE, parameters, new Date()));
287  22960 this.entity.setComment(getString(WikiDocumentFilter.PARAMETER_REVISION_COMMENT, parameters, ""));
288   
289  22960 this.entity.setContentUpdateDate(getDate(WikiDocumentFilter.PARAMETER_CONTENT_DATE, parameters, new Date()));
290   
291    // Content
292   
293  22960 if (this.contentListener != null) {
294    // Remember the current rendering context target syntax
295  55 this.previousTargetSyntax = this.renderingContext.getTargetSyntax();
296    }
297   
298  22960 if (parameters.containsKey(WikiDocumentFilter.PARAMETER_CONTENT)) {
299  7618 this.entity.setContent(getString(WikiDocumentFilter.PARAMETER_CONTENT, parameters, null));
300   
301  7618 if (this.contentListener != null) {
302    // Cancel any existing content listener
303  13 this.currentWikiPrinter = null;
304  13 this.contentListener.setWrappedListener(null);
305    }
306  15342 } else if (this.contentListener != null) {
307  42 if (this.properties != null && this.properties.getDefaultSyntax() != null) {
308  0 this.entity.setSyntax(this.properties.getDefaultSyntax());
309    } else {
310    // Make sure to set the default syntax if none were provided
311  42 this.entity.setSyntax(this.entity.getSyntax());
312    }
313   
314  42 ComponentManager componentManager = this.componentManagerProvider.get();
315   
316  42 String syntaxString = this.entity.getSyntax().toIdString();
317  42 if (componentManager.hasComponent(PrintRendererFactory.class, syntaxString)) {
318  42 PrintRendererFactory rendererFactory;
319  42 try {
320  42 rendererFactory = componentManager.getInstance(PrintRendererFactory.class, syntaxString);
321    } catch (ComponentLookupException e) {
322  0 throw new FilterException(
323    String.format("Failed to find PrintRendererFactory for syntax [%s]", this.entity.getSyntax()),
324    e);
325    }
326   
327  42 this.currentWikiPrinter = new DefaultWikiPrinter();
328  42 ((MutableRenderingContext) this.renderingContext).setTargetSyntax(rendererFactory.getSyntax());
329  42 this.contentListener.setWrappedListener(rendererFactory.createRenderer(this.currentWikiPrinter));
330    }
331    }
332   
333    // Initialize the class
334  22960 getBaseClassOutputFilterStream().setEntity(this.entity.getXClass());
335    }
336   
 
337  22960 toggle private void end(FilterEventParameters parameters)
338    {
339    // Set content
340  22960 if (this.currentWikiPrinter != null) {
341  8 this.entity.setContent(this.currentWikiPrinter.getBuffer().toString());
342   
343  8 this.contentListener.setWrappedListener(null);
344  8 this.currentWikiPrinter = null;
345    }
346   
347  22960 if (this.contentListener != null) {
348    // Reset
349  55 ((MutableRenderingContext) this.renderingContext).setTargetSyntax(this.previousTargetSyntax);
350    }
351    }
352   
 
353  7656 toggle @Override
354    public void beginWikiDocument(String name, FilterEventParameters parameters) throws FilterException
355    {
356  7656 super.beginWikiDocument(name, parameters);
357   
358  7656 if (parameters.containsKey(WikiDocumentFilter.PARAMETER_LOCALE)) {
359  7646 this.currentDefaultLocale = get(Locale.class, WikiDocumentFilter.PARAMETER_LOCALE, parameters, Locale.ROOT);
360    } else {
361  10 this.currentDefaultLocale = this.localizationContext.getCurrentLocale();
362    }
363   
364  7656 this.currentLocale = Locale.ROOT;
365  7656 this.currentLocaleParameters = parameters;
366   
367  7656 begin(parameters);
368    }
369   
 
370  7656 toggle @Override
371    public void endWikiDocument(String name, FilterEventParameters parameters) throws FilterException
372    {
373  7656 end(parameters);
374   
375  7656 super.endWikiDocument(name, parameters);
376   
377    // Reset
378  7656 this.currentLocaleParameters = null;
379  7656 this.currentLocale = null;
380  7656 this.currentDefaultLocale = null;
381    }
382   
 
383  7652 toggle @Override
384    public void beginWikiDocumentLocale(Locale locale, FilterEventParameters parameters) throws FilterException
385    {
386  7652 this.currentLocale = locale;
387  7652 this.currentLocaleParameters = parameters;
388   
389  7652 begin(parameters);
390    }
391   
 
392  7652 toggle @Override
393    public void endWikiDocumentLocale(Locale locale, FilterEventParameters parameters) throws FilterException
394    {
395  7652 end(parameters);
396   
397    // Reset
398  7652 this.currentLocale = null;
399  7652 this.currentLocaleParameters = null;
400    }
401   
 
402  7652 toggle @Override
403    public void beginWikiDocumentRevision(String version, FilterEventParameters parameters) throws FilterException
404    {
405  7652 this.currentVersion = version;
406   
407  7652 begin(parameters);
408    }
409   
 
410  7652 toggle @Override
411    public void endWikiDocumentRevision(String version, FilterEventParameters parameters) throws FilterException
412    {
413  7652 end(parameters);
414   
415    // Reset
416  7652 this.currentVersion = null;
417    }
418   
 
419  8051 toggle @Override
420    public void endWikiClass(FilterEventParameters parameters) throws FilterException
421    {
422  8051 getBaseClassOutputFilterStream().setEntity(null);
423    }
424   
 
425  1032 toggle @Override
426    public void onWikiAttachment(String name, InputStream content, Long size, FilterEventParameters parameters)
427    throws FilterException
428    {
429  1032 this.entity.addAttachment(getXWikiAttachmentOutputFilterStream().getEntity());
430   
431    // Reset attachment
432  1032 getXWikiAttachmentOutputFilterStream().setEntity(null);
433    }
434   
 
435  7370 toggle @Override
436    public void endWikiObject(String name, FilterEventParameters parameters) throws FilterException
437    {
438  7370 super.endWikiObject(name, parameters);
439   
440  7370 BaseObject baseObject = getBaseObjectOutputFilterStream().getEntity();
441   
442  7370 if (baseObject.getNumber() < 0) {
443  1 this.entity.addXObject(baseObject);
444    } else {
445  7369 this.entity.setXObject(baseObject.getNumber(), baseObject);
446    }
447   
448  7370 getBaseObjectOutputFilterStream().setEntity(null);
449    }
450    }