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

File DocumentInstanceOutputFilterStream.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart8.png
56% of files have more coverage

Code metrics

24
81
13
1
330
221
28
0.35
6.23
13
2.15

Classes

Class Line # Actions
DocumentInstanceOutputFilterStream 60 81 0% 28 29
0.754237375.4%
 

Contributing tests

This file is covered by 12 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.IOException;
23    import java.util.Date;
24    import java.util.Locale;
25   
26    import javax.inject.Inject;
27    import javax.inject.Named;
28    import javax.inject.Provider;
29   
30    import org.slf4j.Logger;
31    import org.xwiki.component.annotation.Component;
32    import org.xwiki.component.annotation.InstantiationStrategy;
33    import org.xwiki.component.descriptor.ComponentInstantiationStrategy;
34    import org.xwiki.component.manager.ComponentManager;
35    import org.xwiki.filter.FilterDescriptorManager;
36    import org.xwiki.filter.FilterEventParameters;
37    import org.xwiki.filter.FilterException;
38    import org.xwiki.filter.event.model.WikiDocumentFilter;
39    import org.xwiki.filter.instance.output.DocumentInstanceOutputProperties;
40    import org.xwiki.filter.output.AbstractBeanOutputFilterStream;
41    import org.xwiki.logging.marker.TranslationMarker;
42    import org.xwiki.model.reference.DocumentReference;
43    import org.xwiki.model.reference.DocumentReferenceResolver;
44    import org.xwiki.model.reference.EntityReference;
45    import org.xwiki.model.reference.EntityReferenceResolver;
46    import org.xwiki.model.reference.WikiReference;
47   
48    import com.xpn.xwiki.XWikiContext;
49    import com.xpn.xwiki.doc.XWikiAttachment;
50    import com.xpn.xwiki.doc.XWikiDocument;
51    import com.xpn.xwiki.doc.XWikiDocumentArchive;
52   
53    /**
54    * @version $Id: d8437fee0e8152671dc720897c319e5eb1405e87 $
55    * @since 6.2M1
56    */
57    @Component
58    @Named(DocumentInstanceOutputFilterStreamFactory.ROLEHINT)
59    @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
 
60    public class DocumentInstanceOutputFilterStream extends AbstractBeanOutputFilterStream<DocumentInstanceOutputProperties>
61    implements WikiDocumentFilter
62    {
63    private static final TranslationMarker LOG_DOCUMENT_CREATED =
64    new TranslationMarker("filter.instance.log.document.created", WikiDocumentFilter.LOG_DOCUMENT_CREATED);
65   
66    private static final TranslationMarker LOG_DOCUMENT_UPDATED =
67    new TranslationMarker("filter.instance.log.document.updated", WikiDocumentFilter.LOG_DOCUMENT_UPDATED);
68   
69    private static final TranslationMarker LOG_DOCUMENT_FAILSAVE =
70    new TranslationMarker("filter.instance.log.document.failsave", WikiDocumentFilter.LOG_DOCUMENT_ERROR);
71   
72    @Inject
73    private FilterDescriptorManager filterManager;
74   
75    @Inject
76    @Named("current")
77    private DocumentReferenceResolver<EntityReference> entityResolver;
78   
79    @Inject
80    @Named("relative")
81    private EntityReferenceResolver<String> relativeResolver;
82   
83    @Inject
84    private Provider<XWikiContext> xcontextProvider;
85   
86    @Inject
87    @Named("context")
88    private Provider<ComponentManager> componentManagerProvider;
89   
90    @Inject
91    private EntityOutputFilterStream<XWikiDocument> documentListener;
92   
93    @Inject
94    private Logger logger;
95   
96    private boolean documentDeleted;
97   
98    private FilterEventParameters currentLocaleParameters;
99   
100    private FilterEventParameters currentRevisionParameters;
101   
 
102  0 toggle private XWikiDocumentOutputFilterStream getXWikiDocumentOutputFilterStream()
103    {
104  0 return (XWikiDocumentOutputFilterStream) this.documentListener;
105    }
106   
 
107  17 toggle @Override
108    protected Object createFilter() throws FilterException
109    {
110  17 return this.filterManager.createCompositeFilter(this.documentListener.getFilter(), this);
111    }
112   
 
113  0 toggle @Override
114    public void close() throws IOException
115    {
116    // Nothing to close
117    }
118   
 
119  17 toggle @Override
120    public void setProperties(DocumentInstanceOutputProperties properties) throws FilterException
121    {
122  17 super.setProperties(properties);
123   
124  17 this.documentListener.setProperties(properties);
125    }
126   
127    // Events
128   
 
129  21 toggle @Override
130    public void beginWikiDocument(String name, FilterEventParameters parameters) throws FilterException
131    {
132  21 this.documentDeleted = false;
133   
134  21 this.currentLocaleParameters = parameters;
135  21 this.currentRevisionParameters = parameters;
136    }
137   
 
138  21 toggle @Override
139    public void endWikiDocument(String name, FilterEventParameters parameters) throws FilterException
140    {
141  21 maybeSaveDocument();
142   
143    // Reset
144  21 this.currentRevisionParameters = null;
145  21 this.currentLocaleParameters = null;
146    }
147   
 
148  17 toggle @Override
149    public void beginWikiDocumentLocale(Locale locale, FilterEventParameters parameters) throws FilterException
150    {
151  17 this.currentLocaleParameters = parameters;
152  17 this.currentRevisionParameters = parameters;
153    }
154   
 
155  17 toggle @Override
156    public void endWikiDocumentLocale(Locale locale, FilterEventParameters parameters) throws FilterException
157    {
158  17 maybeSaveDocument();
159   
160    // Reset
161  17 this.currentRevisionParameters = null;
162  17 this.currentLocaleParameters = null;
163    }
164   
 
165  17 toggle @Override
166    public void beginWikiDocumentRevision(String version, FilterEventParameters parameters) throws FilterException
167    {
168  17 this.currentRevisionParameters = parameters;
169    }
170   
 
171  17 toggle @Override
172    public void endWikiDocumentRevision(String version, FilterEventParameters parameters) throws FilterException
173    {
174  17 maybeSaveDocument();
175   
176    // Reset
177  17 this.currentRevisionParameters = null;
178    }
179   
 
180  55 toggle private void maybeSaveDocument() throws FilterException
181    {
182  55 XWikiDocument inputDocument = this.documentListener.getEntity();
183  55 this.documentListener.setEntity(null);
184   
185  55 if (this.currentRevisionParameters == null) {
186  34 return;
187    }
188   
189  21 XWikiContext xcontext = this.xcontextProvider.get();
190   
191  21 try {
192  21 XWikiDocument document =
193    xcontext.getWiki().getDocument(inputDocument.getDocumentReferenceWithLocale(), xcontext);
194   
195  21 if (!this.documentDeleted && !document.isNew() && this.properties.isPreviousDeleted()) {
196  0 XWikiDocument originalDocument = document;
197   
198    // Save current context wiki
199  0 WikiReference currentWiki = xcontext.getWikiReference();
200  0 try {
201    // Make sure the store is executed in the right context
202  0 xcontext.setWikiReference(document.getDocumentReference().getWikiReference());
203   
204    // Put previous version in recycle bin
205  0 if (xcontext.getWiki().hasRecycleBin(xcontext)) {
206  0 xcontext.getWiki().getRecycleBinStore().saveToRecycleBin(document, xcontext.getUser(),
207    new Date(), xcontext, true);
208    }
209   
210    // Make sure to not generate DocumentDeletedEvent since from listener point of view it's not
211  0 xcontext.getWiki().getStore().deleteXWikiDoc(document, xcontext);
212  0 this.documentDeleted = true;
213    } finally {
214    // Restore current context wiki
215  0 xcontext.setWikiReference(currentWiki);
216    }
217   
218  0 document = xcontext.getWiki().getDocument(inputDocument.getDocumentReferenceWithLocale(), xcontext);
219   
220    // Remember deleted document as the actual previous version of the document (to simulate an update
221    // instead of a creation)
222  0 document.setOriginalDocument(originalDocument);
223    } else {
224    // Make sure to remember that the document should not be deleted anymore
225  21 this.documentDeleted = true;
226    }
227   
228    // Remember if it's a creation or an update
229  21 boolean isnew = document.isNew();
230   
231    // Safer to clone for thread safety and in case the save fail
232  21 document = document.clone();
233   
234  21 document.loadAttachmentsContentSafe(xcontext);
235  21 document.apply(inputDocument);
236   
237    // Get the version from the input document
238   
239  21 document.setMinorEdit(inputDocument.isMinorEdit());
240   
241    // Authors
242   
243  21 if (!this.properties.isAuthorPreserved()) {
244  4 if (this.properties.isAuthorSet()) {
245  0 setAuthorReference(document, this.properties.getAuthor());
246    } else {
247  4 setAuthorReference(document, xcontext.getUserReference());
248    }
249  4 document.setContentAuthorReference(document.getAuthorReference());
250  4 if (document.isNew()) {
251  4 document.setCreatorReference(document.getAuthorReference());
252    }
253    } else {
254  17 setAuthors(document, inputDocument);
255    }
256   
257    // Version related information and save
258   
259  21 if (this.properties.isVersionPreserved()) {
260    // Make sure to use metadata coming from the input document
261  17 document.setVersion(inputDocument.getVersion());
262  17 document.setDate(inputDocument.getDate());
263  17 document.setContentUpdateDate(inputDocument.getContentUpdateDate());
264  17 for (XWikiAttachment attachment : document.getAttachmentList()) {
265  7 attachment.setVersion(inputDocument.getAttachment(attachment.getFilename()).getVersion());
266    }
267  17 if (document.isNew()) {
268  17 document.setCreationDate(inputDocument.getCreationDate());
269  17 document.setDocumentArchive(inputDocument.getDocumentArchive());
270    }
271   
272    // Make sure the document won't be modified by the store
273  17 document.setMetaDataDirty(false);
274  17 document.setContentDirty(false);
275   
276  17 xcontext.getWiki().saveDocument(document, inputDocument.getComment(), inputDocument.isMinorEdit(),
277    xcontext);
278    } else {
279    // Forget the input history to let the store do its standard job
280  4 document.setDocumentArchive((XWikiDocumentArchive) null);
281   
282  4 xcontext.getWiki().saveDocument(document, this.properties.getSaveComment(), xcontext);
283    }
284   
285  21 if (this.properties.isVerbose()) {
286  5 if (isnew) {
287  5 this.logger.info(LOG_DOCUMENT_CREATED, "Created document [{}]",
288    document.getDocumentReferenceWithLocale());
289    } else {
290  0 this.logger.info(LOG_DOCUMENT_UPDATED, "Updated document [{}]",
291    document.getDocumentReferenceWithLocale());
292    }
293    }
294    } catch (Exception e) {
295  0 this.logger.error(LOG_DOCUMENT_FAILSAVE, "Failed to save document [{}]",
296    inputDocument.getDocumentReferenceWithLocale(), e);
297   
298  0 if (this.properties.isStoppedWhenSaveFail()) {
299  0 throw new FilterException("Failed to save document", e);
300    }
301    }
302    }
303   
 
304  4 toggle private void setAuthorReference(XWikiDocument document, DocumentReference authorReference)
305    {
306    // Document author
307  4 document.setAuthorReference(authorReference);
308   
309    // Attachments author
310  4 for (XWikiAttachment attachment : document.getAttachmentList()) {
311  1 attachment.setAuthorReference(authorReference);
312    }
313    }
314   
 
315  17 toggle private void setAuthors(XWikiDocument document, XWikiDocument inputDocument)
316    {
317    // Document author
318  17 document.setAuthorReference(inputDocument.getAuthorReference());
319  17 document.setContentAuthorReference(inputDocument.getContentAuthorReference());
320  17 if (document.isNew()) {
321  17 document.setCreatorReference(inputDocument.getCreatorReference());
322    }
323   
324    // Attachments author
325  17 for (XWikiAttachment currentAttachment : document.getAttachmentList()) {
326  7 currentAttachment
327    .setAuthorReference(inputDocument.getAttachment(currentAttachment.getFilename()).getAuthorReference());
328    }
329    }
330    }