1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.internal.filter.output

File DocumentInstanceOutputFilterStream.java

 

Coverage histogram

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

Code metrics

28
64
11
1
286
193
34
0.53
5.82
11
3.09

Classes

Class Line # Actions
DocumentInstanceOutputFilterStream 56 64 0% 34 27
0.737864173.8%
 

Contributing tests

This file is covered by 10 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.DocumentReferenceResolver;
43    import org.xwiki.model.reference.EntityReference;
44    import org.xwiki.model.reference.EntityReferenceResolver;
45   
46    import com.xpn.xwiki.XWikiContext;
47    import com.xpn.xwiki.doc.XWikiDocument;
48   
49    /**
50    * @version $Id: f13fce6ee4abe2dfbe028435b41eca971b79c767 $
51    * @since 6.2M1
52    */
53    @Component
54    @Named(DocumentInstanceOutputFilterStreamFactory.ROLEHINT)
55    @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
 
56    public class DocumentInstanceOutputFilterStream extends AbstractBeanOutputFilterStream<DocumentInstanceOutputProperties>
57    implements WikiDocumentFilter
58    {
59    private static final TranslationMarker LOG_DOCUMENT_CREATED =
60    new TranslationMarker("filter.instance.log.document.created", WikiDocumentFilter.LOG_DOCUMENT_CREATED);
61   
62    private static final TranslationMarker LOG_DOCUMENT_UPDATED =
63    new TranslationMarker("filter.instance.log.document.updated", WikiDocumentFilter.LOG_DOCUMENT_UPDATED);
64   
65    private static final TranslationMarker LOG_DOCUMENT_FAILSAVE =
66    new TranslationMarker("filter.instance.log.document.failsave", WikiDocumentFilter.LOG_DOCUMENT_ERROR);
67   
68    @Inject
69    private FilterDescriptorManager filterManager;
70   
71    @Inject
72    @Named("current")
73    private DocumentReferenceResolver<EntityReference> entityResolver;
74   
75    @Inject
76    @Named("relative")
77    private EntityReferenceResolver<String> relativeResolver;
78   
79    @Inject
80    private Provider<XWikiContext> xcontextProvider;
81   
82    @Inject
83    @Named("context")
84    private Provider<ComponentManager> componentManagerProvider;
85   
86    @Inject
87    private EntityOutputFilterStream<XWikiDocument> documentListener;
88   
89    @Inject
90    private Logger logger;
91   
92    private boolean documentDeleted;
93   
94    private FilterEventParameters currentLocaleParameters;
95   
96    private FilterEventParameters currentRevisionParameters;
97   
 
98  0 toggle private XWikiDocumentOutputFilterStream getXWikiDocumentOutputFilterStream()
99    {
100  0 return (XWikiDocumentOutputFilterStream) this.documentListener;
101    }
102   
 
103  14 toggle @Override
104    protected Object createFilter() throws FilterException
105    {
106  14 return this.filterManager.createCompositeFilter(this.documentListener.getFilter(), this);
107    }
108   
 
109  0 toggle @Override
110    public void close() throws IOException
111    {
112    // Nothing to close
113    }
114   
 
115  14 toggle @Override
116    public void setProperties(DocumentInstanceOutputProperties properties) throws FilterException
117    {
118  14 super.setProperties(properties);
119   
120  14 this.documentListener.setProperties(properties);
121    }
122   
123    // Events
124   
 
125  17 toggle @Override
126    public void beginWikiDocument(String name, FilterEventParameters parameters) throws FilterException
127    {
128  17 this.documentDeleted = false;
129   
130  17 this.currentLocaleParameters = parameters;
131  17 this.currentRevisionParameters = parameters;
132    }
133   
 
134  17 toggle @Override
135    public void endWikiDocument(String name, FilterEventParameters parameters) throws FilterException
136    {
137  17 maybeSaveDocument();
138   
139    // Reset
140  17 this.currentRevisionParameters = null;
141  17 this.currentLocaleParameters = null;
142    }
143   
 
144  15 toggle @Override
145    public void beginWikiDocumentLocale(Locale locale, FilterEventParameters parameters) throws FilterException
146    {
147  15 this.currentLocaleParameters = parameters;
148  15 this.currentRevisionParameters = parameters;
149    }
150   
 
151  15 toggle @Override
152    public void endWikiDocumentLocale(Locale locale, FilterEventParameters parameters) throws FilterException
153    {
154  15 maybeSaveDocument();
155   
156    // Reset
157  15 this.currentRevisionParameters = null;
158  15 this.currentLocaleParameters = null;
159    }
160   
 
161  15 toggle @Override
162    public void beginWikiDocumentRevision(String version, FilterEventParameters parameters) throws FilterException
163    {
164  15 this.currentRevisionParameters = parameters;
165    }
166   
 
167  15 toggle @Override
168    public void endWikiDocumentRevision(String version, FilterEventParameters parameters) throws FilterException
169    {
170  15 maybeSaveDocument();
171   
172    // Reset
173  15 this.currentRevisionParameters = null;
174    }
175   
 
176  47 toggle private void maybeSaveDocument() throws FilterException
177    {
178  47 XWikiDocument inputDocument = this.documentListener.getEntity();
179  47 this.documentListener.setEntity(null);
180   
181  47 if (this.currentRevisionParameters == null) {
182  30 return;
183    }
184   
185  17 XWikiContext xcontext = this.xcontextProvider.get();
186   
187  17 try {
188  17 XWikiDocument document =
189    xcontext.getWiki().getDocument(inputDocument.getDocumentReferenceWithLocale(), xcontext);
190   
191  17 boolean isNew = document.isNew();
192   
193  17 if (document.isNew()) {
194  17 document = inputDocument;
195    } else {
196  0 if (this.properties.isPreviousDeleted() && !this.documentDeleted) {
197    // Put previous version in recycle bin
198  0 if (xcontext.getWiki().hasRecycleBin(xcontext)) {
199  0 xcontext.getWiki().getRecycleBinStore().saveToRecycleBin(document, xcontext.getUser(),
200    new Date(), xcontext, true);
201    }
202   
203    // Make sure to not generate DocumentDeletedEvent since from listener point of view it's not
204  0 xcontext.getWiki().getStore().deleteXWikiDoc(document, xcontext);
205   
206  0 this.documentDeleted = true;
207  0 document = inputDocument;
208    } else {
209    // Safer to clone for thread safety and in case the save fail
210  0 document = document.clone();
211   
212  0 document.loadAttachmentsContent(xcontext);
213  0 document.apply(inputDocument);
214    }
215    }
216   
217  17 document.setMinorEdit(inputDocument.isMinorEdit());
218   
219    // Author
220   
221  17 if (this.properties.isAuthorPreserved()
222    && this.currentRevisionParameters.containsKey(WikiDocumentFilter.PARAMETER_REVISION_AUTHOR)) {
223  9 document.setAuthorReference(inputDocument.getAuthorReference());
224  8 } else if (this.properties.isAuthorSet()) {
225  0 document.setAuthorReference(this.properties.getAuthor());
226    } else {
227  8 document.setAuthorReference(xcontext.getUserReference());
228    }
229   
230    // Content author
231   
232  17 if (this.properties.isAuthorPreserved()
233    && this.currentRevisionParameters.containsKey(WikiDocumentFilter.PARAMETER_CONTENT_AUTHOR)) {
234  9 document.setContentAuthorReference(inputDocument.getContentAuthorReference());
235    } else {
236  8 document.setContentAuthorReference(document.getAuthorReference());
237    }
238   
239    // Creator
240   
241  17 if (document.isNew() && !this.properties.isAuthorPreserved()
242    || !this.currentLocaleParameters.containsKey(WikiDocumentFilter.PARAMETER_CREATION_AUTHOR)) {
243  8 document.setCreatorReference(document.getAuthorReference());
244    }
245   
246    // Save history
247  17 if (document.isNew() && document.getDocumentArchive() != null) {
248    // we need to force the saving the document archive
249  1 if (document.getDocumentArchive() != null) {
250  1 xcontext.getWiki().getVersioningStore().saveXWikiDocArchive(document.getDocumentArchive(xcontext),
251    true, xcontext);
252    }
253    }
254   
255    // Don't preserve version or history if we don't delete the previous document
256  17 if (document.isNew() && (this.properties.isAuthorPreserved() || this.properties.isVersionPreserved())) {
257    // Make sure version is set
258  15 document.setVersion(document.getVersion());
259   
260  15 document.setMetaDataDirty(false);
261  15 document.setContentDirty(false);
262   
263  15 xcontext.getWiki().saveDocument(document, document.getComment(), document.isMinorEdit(), xcontext);
264    } else {
265  2 xcontext.getWiki().saveDocument(document, this.properties.getSaveComment(), xcontext);
266    }
267   
268  17 if (this.properties.isVerbose()) {
269  4 if (isNew) {
270  4 this.logger.info(LOG_DOCUMENT_CREATED, "Created document [{}]",
271    document.getDocumentReferenceWithLocale());
272    } else {
273  0 this.logger.info(LOG_DOCUMENT_UPDATED, "Updated document [{}]",
274    document.getDocumentReferenceWithLocale());
275    }
276    }
277    } catch (Exception e) {
278  0 this.logger.error(LOG_DOCUMENT_FAILSAVE, "Failed to save document [{}]",
279    inputDocument.getDocumentReferenceWithLocale(), e);
280   
281  0 if (this.properties.isStoppedWhenSaveFail()) {
282  0 throw new FilterException("Failed to save document", e);
283    }
284    }
285    }
286    }