1. Project Clover database Tue Dec 20 2016 21:24:09 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

38
120
23
1
436
311
47
0.39
5.22
23
2.04

Classes

Class Line # Actions
XWikiDocumentOutputFilterStream 69 120 0% 47 8
0.955801195.6%
 

Contributing tests

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