1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.extension.xar.internal.handler.packager

File Packager.java

 

Coverage histogram

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

Code metrics

38
100
12
1
363
269
40
0.4
8.33
12
3.33

Classes

Class Line # Actions
Packager 74 100 0% 40 35
0.7666666576.7%
 

Contributing tests

This file is covered by 17 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 org.xwiki.extension.xar.internal.handler.packager;
21   
22    import java.io.File;
23    import java.io.FileInputStream;
24    import java.io.IOException;
25    import java.io.InputStream;
26    import java.util.ArrayList;
27    import java.util.Collection;
28    import java.util.List;
29   
30    import javax.inject.Inject;
31    import javax.inject.Named;
32    import javax.inject.Provider;
33    import javax.inject.Singleton;
34   
35    import org.apache.commons.compress.archivers.ArchiveEntry;
36    import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
37    import org.slf4j.Logger;
38    import org.xwiki.component.annotation.Component;
39    import org.xwiki.component.manager.ComponentLookupException;
40    import org.xwiki.extension.xar.internal.handler.XarExtensionPlan;
41    import org.xwiki.filter.FilterException;
42    import org.xwiki.filter.input.DefaultInputStreamInputSource;
43    import org.xwiki.filter.instance.output.DocumentInstanceOutputProperties;
44    import org.xwiki.filter.xar.input.XARInputProperties;
45    import org.xwiki.logging.marker.BeginTranslationMarker;
46    import org.xwiki.logging.marker.EndTranslationMarker;
47    import org.xwiki.logging.marker.TranslationMarker;
48    import org.xwiki.model.reference.DocumentReference;
49    import org.xwiki.model.reference.DocumentReferenceResolver;
50    import org.xwiki.model.reference.EntityReference;
51    import org.xwiki.model.reference.LocalDocumentReference;
52    import org.xwiki.model.reference.WikiReference;
53    import org.xwiki.observation.ObservationManager;
54    import org.xwiki.xar.XarEntry;
55    import org.xwiki.xar.XarFile;
56    import org.xwiki.xar.internal.model.XarModel;
57   
58    import com.xpn.xwiki.XWikiContext;
59    import com.xpn.xwiki.XWikiException;
60    import com.xpn.xwiki.doc.MandatoryDocumentInitializerManager;
61    import com.xpn.xwiki.doc.XWikiDocument;
62    import com.xpn.xwiki.internal.event.XARImportedEvent;
63    import com.xpn.xwiki.internal.event.XARImportingEvent;
64    import com.xpn.xwiki.internal.filter.XWikiDocumentFilterUtils;
65   
66    /**
67    * Default implementation of {@link Packager}.
68    *
69    * @version $Id: 780bb169c7aa527b0ab4ba7e6d6e1c0a888f6420 $
70    * @since 4.0M1
71    */
72    @Component(roles = Packager.class)
73    @Singleton
 
74    public class Packager
75    {
76    private static final BeginTranslationMarker LOG_INSTALLDOCUMENT_BEGIN =
77    new BeginTranslationMarker("extension.xar.log.install.document.begin");
78   
79    private static final EndTranslationMarker LOG_INSTALLDOCUMENT_SUCCESS_END =
80    new EndTranslationMarker("extension.xar.log.install.document.success.end");
81   
82    private static final EndTranslationMarker LOG_INSTALLDOCUMENT_FAILURE_END =
83    new EndTranslationMarker("extension.xar.log.install.document.failure.end");
84   
85    private static final TranslationMarker LOG_DELETEDDOCUMENT =
86    new TranslationMarker("extension.xar.log.delete.document");
87   
88    private static final TranslationMarker LOG_DELETEDDOCUMENT_FAILURE =
89    new TranslationMarker("extension.xar.log.delete.document.failure");
90   
91    @Inject
92    @Named("explicit")
93    private DocumentReferenceResolver<EntityReference> resolver;
94   
95    /**
96    * The logger to log.
97    */
98    @Inject
99    private Logger logger;
100   
101    @Inject
102    private ObservationManager observation;
103   
104    @Inject
105    private Provider<XWikiContext> xcontextProvider;
106   
107    @Inject
108    private DocumentMergeImporter importer;
109   
110    @Inject
111    private MandatoryDocumentInitializerManager initializerManager;
112   
113    @Inject
114    private XWikiDocumentFilterUtils documentImporter;
115   
 
116  60 toggle public void importXAR(String comment, File xarFile, PackageConfiguration configuration)
117    throws IOException, XWikiException, ComponentLookupException, FilterException
118    {
119  60 if (configuration.getWiki() == null) {
120  16 XWikiContext xcontext = this.xcontextProvider.get();
121  16 List<String> wikis = xcontext.getWiki().getVirtualWikisDatabaseNames(xcontext);
122   
123  16 for (String subwiki : wikis) {
124  24 importXARToWiki(comment, xarFile, new WikiReference(subwiki), configuration);
125    }
126    } else {
127  44 importXARToWiki(comment, xarFile, new WikiReference(configuration.getWiki()), configuration);
128    }
129    }
130   
 
131  68 toggle private XarMergeResult importXARToWiki(String comment, File xarFile, WikiReference wikiReference,
132    PackageConfiguration configuration)
133    throws IOException, ComponentLookupException, XWikiException, FilterException
134    {
135  68 FileInputStream fis = new FileInputStream(xarFile);
136  68 try {
137  68 return importXARToWiki(comment, fis, wikiReference, configuration);
138    } finally {
139  68 fis.close();
140    }
141    }
142   
 
143  68 toggle private XarMergeResult importXARToWiki(String comment, InputStream xarInputStream, WikiReference wikiReference,
144    PackageConfiguration configuration)
145    throws IOException, ComponentLookupException, XWikiException, FilterException
146    {
147  68 XarMergeResult mergeResult = new XarMergeResult();
148   
149  68 ZipArchiveInputStream zis = new ZipArchiveInputStream(xarInputStream);
150   
151  68 XWikiContext xcontext = this.xcontextProvider.get();
152   
153  68 String currentWiki = xcontext.getWikiId();
154  68 try {
155  68 xcontext.setWikiId(wikiReference.getName());
156   
157  68 this.observation.notify(new XARImportingEvent(), null, xcontext);
158   
159  517 for (ArchiveEntry entry = zis.getNextEntry(); entry != null; entry = zis.getNextEntry()) {
160  449 if (!entry.isDirectory()) {
161    // Only import what should be imported
162  449 if (!entry.getName().equals(XarModel.PATH_PACKAGE) && (configuration.getEntriesToImport() == null
163    || configuration.getEntriesToImport().contains(entry.getName()))) {
164  362 XarEntryMergeResult entityMergeResult =
165    importDocumentToWiki(comment, wikiReference, zis, configuration);
166  362 if (entityMergeResult != null) {
167  39 mergeResult.addMergeResult(entityMergeResult);
168    }
169    }
170    }
171    }
172    } finally {
173  68 this.observation.notify(new XARImportedEvent(), null, xcontext);
174   
175  68 xcontext.setWikiId(currentWiki);
176    }
177   
178  68 return mergeResult;
179    }
180   
 
181  362 toggle private XarEntryMergeResult importDocumentToWiki(String comment, WikiReference wikiReference,
182    InputStream inputStream, PackageConfiguration configuration)
183    throws XWikiException, FilterException, ComponentLookupException, IOException
184    {
185  362 XWikiContext xcontext = this.xcontextProvider.get();
186   
187  362 XWikiDocument nextDocument;
188  362 try {
189  362 nextDocument = getXWikiDocument(inputStream, wikiReference);
190    } catch (Exception e) {
191  0 this.logger.error("Failed to parse document", e);
192   
193  0 return null;
194    }
195   
196  362 DocumentReference reference = nextDocument.getDocumentReferenceWithLocale();
197  362 XWikiDocument currentDocument = xcontext.getWiki().getDocument(reference, xcontext);
198  362 currentDocument.loadAttachmentsContent(xcontext);
199  362 XWikiDocument previousDocument;
200  362 XarExtensionPlan xarExtensionPlan = configuration.getXarExtensionPlan();
201  362 if (xarExtensionPlan != null) {
202  346 previousDocument = xarExtensionPlan.getPreviousXWikiDocument(reference, this);
203    } else {
204  16 previousDocument = null;
205    }
206   
207  362 if (configuration.isVerbose()) {
208  346 this.logger.info(LOG_INSTALLDOCUMENT_BEGIN, "Installing document [{}]",
209    nextDocument.getDocumentReferenceWithLocale());
210    }
211   
212  362 try {
213  362 XarEntryMergeResult entityMergeResult =
214    this.importer.saveDocument(comment, previousDocument, currentDocument, nextDocument, configuration);
215   
216  362 if (configuration.isVerbose()) {
217  346 this.logger.info(LOG_INSTALLDOCUMENT_SUCCESS_END, "Done installing document [{}]",
218    nextDocument.getDocumentReferenceWithLocale());
219    }
220   
221  362 return entityMergeResult;
222    } catch (Exception e) {
223  0 if (configuration.isVerbose()) {
224  0 this.logger.error(LOG_INSTALLDOCUMENT_FAILURE_END, "Failed to install document [{}]",
225    nextDocument.getDocumentReferenceWithLocale(), e);
226    }
227    }
228   
229  0 return null;
230    }
231   
 
232  0 toggle public void unimportPages(Collection<XarEntry> pages, PackageConfiguration configuration) throws XWikiException
233    {
234  0 if (configuration.getWiki() == null) {
235  0 XWikiContext xcontext = this.xcontextProvider.get();
236  0 List<String> wikis = xcontext.getWiki().getVirtualWikisDatabaseNames(xcontext);
237   
238  0 for (String subwiki : wikis) {
239  0 unimportPagesFromWiki(pages, subwiki, configuration);
240    }
241    } else {
242  0 unimportPagesFromWiki(pages, configuration.getWiki(), configuration);
243    }
244    }
245   
 
246  0 toggle private void unimportPagesFromWiki(Collection<XarEntry> entries, String wiki, PackageConfiguration configuration)
247    {
248  0 WikiReference wikiReference = new WikiReference(wiki);
249   
250  0 for (XarEntry xarEntry : entries) {
251    // Only delete what should be deleted.
252  0 if (configuration.getEntriesToImport() == null
253    || configuration.getEntriesToImport().contains(xarEntry.getEntryName())) {
254  0 DocumentReference documentReference =
255    new DocumentReference(this.resolver.resolve(xarEntry, wikiReference), xarEntry.getLocale());
256   
257  0 if (!configuration.isSkipMandatorytDocuments() || !isMandatoryDocument(documentReference)) {
258  0 deleteDocument(documentReference, configuration);
259    }
260    }
261    }
262    }
263   
 
264  70 toggle public void deleteDocument(DocumentReference documentReference, PackageConfiguration configuration)
265    {
266  70 XWikiContext xcontext = this.xcontextProvider.get();
267   
268  70 try {
269    // Make sure to have an expected context as much as possible
270  70 if (configuration.getUserReference() != null) {
271  70 xcontext.setUserReference(configuration.getUserReference());
272    }
273   
274  70 XWikiDocument document = xcontext.getWiki().getDocument(documentReference, xcontext);
275   
276  70 if (!document.isNew()) {
277  70 xcontext.getWiki().deleteDocument(document, xcontext);
278   
279  70 if (configuration.isVerbose()) {
280  70 this.logger.info(LOG_DELETEDDOCUMENT, "Deleted document [{}]",
281    document.getDocumentReferenceWithLocale());
282    }
283    }
284    } catch (XWikiException e) {
285  0 this.logger.error(LOG_DELETEDDOCUMENT_FAILURE, "Failed to delete document [{}]", documentReference, e);
286    }
287    }
288   
 
289  147 toggle private boolean isMandatoryDocument(DocumentReference documentReference)
290    {
291  147 return this.initializerManager.getMandatoryDocumentInitializer(documentReference) != null;
292    }
293   
 
294  134 toggle public XWikiDocument getXWikiDocument(WikiReference wikiReference, LocalDocumentReference documentReference,
295    XarFile xarFile) throws FilterException, IOException, ComponentLookupException
296    {
297  134 XarEntry realEntry = xarFile.getEntry(documentReference);
298  134 if (realEntry != null) {
299  134 InputStream stream = xarFile.getInputStream(realEntry);
300   
301  134 try {
302  134 return getXWikiDocument(stream, wikiReference);
303    } finally {
304  134 stream.close();
305    }
306    }
307   
308  0 return null;
309    }
310   
 
311  496 toggle public XWikiDocument getXWikiDocument(InputStream source, WikiReference wikiReference)
312    throws FilterException, IOException, ComponentLookupException
313    {
314    // Output
315  496 DocumentInstanceOutputProperties documentProperties = new DocumentInstanceOutputProperties();
316  496 documentProperties.setDefaultReference(wikiReference);
317  496 documentProperties.setVersionPreserved(false);
318   
319    // Input
320  496 XARInputProperties xarProperties = new XARInputProperties();
321  496 xarProperties.setWithHistory(false);
322   
323  496 return this.documentImporter.importDocument(new DefaultInputStreamInputSource(source), xarProperties,
324    documentProperties);
325    }
326   
 
327  22 toggle public List<DocumentReference> getDocumentReferences(Collection<XarEntry> pages, PackageConfiguration configuration)
328    throws XWikiException
329    {
330  22 List<DocumentReference> documents = new ArrayList<DocumentReference>(pages.size());
331   
332  22 if (configuration.getWiki() == null) {
333  2 XWikiContext xcontext = this.xcontextProvider.get();
334  2 List<String> wikis = xcontext.getWiki().getVirtualWikisDatabaseNames(xcontext);
335   
336  2 for (String subwiki : wikis) {
337  4 getDocumentReferencesFromWiki(documents, pages, subwiki, configuration);
338    }
339    } else {
340  20 getDocumentReferencesFromWiki(documents, pages, configuration.getWiki(), configuration);
341    }
342   
343  22 return documents;
344    }
345   
 
346  24 toggle private void getDocumentReferencesFromWiki(List<DocumentReference> documents, Collection<XarEntry> pages,
347    String wiki, PackageConfiguration configuration)
348    {
349  24 WikiReference wikiReference = new WikiReference(wiki);
350   
351  24 for (XarEntry xarEntry : pages) {
352    // Only delete what should be deleted.
353  147 if (configuration.getEntriesToImport() == null
354    || configuration.getEntriesToImport().contains(xarEntry.getEntryName())) {
355  147 DocumentReference documentReference = new DocumentReference(xarEntry, wikiReference);
356   
357  147 if (!configuration.isSkipMandatorytDocuments() || !isMandatoryDocument(documentReference)) {
358  146 documents.add(documentReference);
359    }
360    }
361    }
362    }
363    }