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

File ImportAction.java

 

Coverage histogram

../../../../img/srcFileCovDistChart6.png
72% of files have more coverage

Code metrics

60
143
8
1
376
284
41
0.29
17.88
8
5.12

Classes

Class Line # Actions
ImportAction 79 143 0% 41 90
0.5734597457.3%
 

Contributing tests

No tests hitting this source file were found.

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.web;
21   
22    import java.io.IOException;
23    import java.io.InputStream;
24    import java.lang.reflect.Type;
25    import java.util.List;
26    import java.util.UUID;
27   
28    import org.apache.commons.lang3.StringUtils;
29    import org.apache.tika.mime.MediaType;
30    import org.slf4j.Logger;
31    import org.slf4j.LoggerFactory;
32    import org.slf4j.Marker;
33    import org.xwiki.filter.FilterException;
34    import org.xwiki.filter.event.model.WikiDocumentFilter;
35    import org.xwiki.filter.input.BeanInputFilterStream;
36    import org.xwiki.filter.input.BeanInputFilterStreamFactory;
37    import org.xwiki.filter.input.DefaultInputStreamInputSource;
38    import org.xwiki.filter.input.InputFilterStreamFactory;
39    import org.xwiki.filter.instance.output.DocumentInstanceOutputProperties;
40    import org.xwiki.filter.instance.output.InstanceOutputProperties;
41    import org.xwiki.filter.output.BeanOutputFilterStream;
42    import org.xwiki.filter.output.BeanOutputFilterStreamFactory;
43    import org.xwiki.filter.output.OutputFilterStreamFactory;
44    import org.xwiki.filter.type.FilterStreamType;
45    import org.xwiki.filter.xar.input.XARInputProperties;
46    import org.xwiki.localization.LocaleUtils;
47    import org.xwiki.logging.LogLevel;
48    import org.xwiki.logging.LogQueue;
49    import org.xwiki.logging.LoggerManager;
50    import org.xwiki.logging.event.LogEvent;
51    import org.xwiki.logging.event.LoggerListener;
52    import org.xwiki.model.EntityType;
53    import org.xwiki.model.reference.EntityReference;
54    import org.xwiki.model.reference.EntityReferenceResolver;
55    import org.xwiki.model.reference.EntityReferenceSerializer;
56    import org.xwiki.model.reference.EntityReferenceSet;
57    import org.xwiki.model.reference.LocalDocumentReference;
58    import org.xwiki.observation.ObservationManager;
59    import org.xwiki.xar.XarException;
60    import org.xwiki.xar.XarPackage;
61   
62    import com.xpn.xwiki.XWikiContext;
63    import com.xpn.xwiki.XWikiException;
64    import com.xpn.xwiki.doc.XWikiAttachment;
65    import com.xpn.xwiki.doc.XWikiDocument;
66    import com.xpn.xwiki.internal.event.XARImportedEvent;
67    import com.xpn.xwiki.internal.event.XARImportingEvent;
68    import com.xpn.xwiki.plugin.packaging.DocumentInfo;
69    import com.xpn.xwiki.plugin.packaging.DocumentInfoAPI;
70    import com.xpn.xwiki.plugin.packaging.Package;
71    import com.xpn.xwiki.plugin.packaging.PackageAPI;
72    import com.xpn.xwiki.util.Util;
73   
74    /**
75    * XWiki Action responsible for importing XAR archives.
76    *
77    * @version $Id: 772fe9ee3efcfad58414a27ebd02c1c48f68438e $
78    */
 
79    public class ImportAction extends XWikiAction
80    {
81    private static final Logger LOGGER = LoggerFactory.getLogger(ImportAction.class);
82   
 
83  11 toggle @Override
84    public String render(XWikiContext context) throws XWikiException
85    {
86  11 String result = null;
87   
88  11 try {
89  11 XWikiRequest request = context.getRequest();
90  11 XWikiResponse response = context.getResponse();
91  11 XWikiDocument doc = context.getDoc();
92  11 String name = request.get("name");
93  11 String action = request.get("action");
94   
95  11 if (!context.getWiki().getRightService().hasWikiAdminRights(context)) {
96  0 context.put("message", "needadminrights");
97  0 return "exception";
98    }
99   
100  11 if (name == null) {
101  6 return "admin";
102    }
103   
104  5 if ("getPackageInfos".equals(action)) {
105  0 getPackageInfos(doc.getAttachment(name), response, context);
106  5 } else if ("import".equals(action)) {
107  5 result = importPackage(doc.getAttachment(name), request, context);
108    }
109    } catch (Exception e) {
110  0 throw new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_EXPORT,
111    "Exception while importing", e);
112    }
113   
114  5 return result;
115    }
116   
 
117  0 toggle private void getPackageInfos(XWikiAttachment packFile, XWikiResponse response, XWikiContext xcontext)
118    throws IOException, XWikiException, XarException
119    {
120  0 String encoding = xcontext.getWiki().getEncoding();
121  0 response.setContentType(MediaType.APPLICATION_XML.toString());
122  0 response.setCharacterEncoding(encoding);
123   
124  0 XarPackage xarPackage = new XarPackage(packFile.getContentInputStream(xcontext));
125   
126  0 xarPackage.write(response.getOutputStream(), encoding);
127    }
128   
 
129  5 toggle private String importPackage(XWikiAttachment packFile, XWikiRequest request, XWikiContext context)
130    throws IOException, XWikiException, FilterException
131    {
132  5 String all = request.get("all");
133  5 if (!"1".equals(all)) {
134  5 if (context.getWiki().ParamAsLong("xwiki.action.import.xar.usefilter", 1) == 0) {
135  0 importPackageOld(packFile, request, context);
136    } else {
137  5 importPackageFilterStream(packFile, request, context);
138    }
139   
140  5 if (!StringUtils.isBlank(request.getParameter("ajax"))) {
141    // If the import is done from an AJAX request we don't want to return a whole HTML page,
142    // instead we return "inline" the list of imported documents,
143    // evaluating imported.vm template.
144  4 return "imported";
145    } else {
146  1 return "admin";
147    }
148    }
149   
150  0 return null;
151    }
152   
 
153  5 toggle private String getLocale(String pageName, XWikiRequest request)
154    {
155  5 return Util.normalizeLanguage(request.get("language_" + pageName));
156    }
157   
 
158  5 toggle private int getAction(String pageName, String language, XWikiRequest request)
159    {
160  5 String actionName = "action_" + pageName;
161  5 if (!StringUtils.isBlank(language)) {
162  0 actionName += ("_" + language);
163    }
164  5 String defaultAction = request.get(actionName);
165  5 int iAction;
166  5 if (StringUtils.isBlank(defaultAction)) {
167  5 iAction = DocumentInfo.ACTION_OVERWRITE;
168    } else {
169  0 try {
170  0 iAction = Integer.parseInt(defaultAction);
171    } catch (Exception e) {
172  0 iAction = DocumentInfo.ACTION_SKIP;
173    }
174    }
175   
176  5 return iAction;
177    }
178   
 
179  5 toggle private String getDocumentReference(String pageEntry)
180    {
181  5 return pageEntry.replaceAll(":[^:]*$", "");
182    }
183   
 
184  0 toggle private void importPackageOld(XWikiAttachment packFile, XWikiRequest request, XWikiContext context)
185    throws IOException, XWikiException
186    {
187  0 PackageAPI importer = ((PackageAPI) context.getWiki().getPluginApi("package", context));
188   
189  0 String[] pages = request.getParameterValues("pages");
190   
191  0 importer.Import(packFile.getContentInputStream(context));
192  0 if (pages != null) {
193    // Skip document by default
194  0 List<DocumentInfoAPI> filelist = importer.getFiles();
195  0 for (DocumentInfoAPI dia : filelist) {
196  0 dia.setAction(DocumentInfo.ACTION_SKIP);
197    }
198   
199    // Indicate with documents to import
200  0 for (String pageEntry : pages) {
201  0 String language = getLocale(pageEntry, request);
202  0 int iAction = getAction(pageEntry, language, request);
203   
204  0 String docName = getDocumentReference(pageEntry);
205  0 if (language == null) {
206  0 importer.setDocumentAction(docName, iAction);
207    } else {
208  0 importer.setDocumentAction(docName, language, iAction);
209    }
210    }
211    }
212   
213    // Set the appropriate strategy to handle versions
214  0 if (StringUtils.equals(request.getParameter("historyStrategy"), "reset")) {
215  0 importer.setPreserveVersion(false);
216  0 importer.setWithVersions(false);
217  0 } else if (StringUtils.equals(request.getParameter("historyStrategy"), "replace")) {
218  0 importer.setPreserveVersion(false);
219  0 importer.setWithVersions(true);
220    } else {
221  0 importer.setPreserveVersion(true);
222  0 importer.setWithVersions(false);
223    }
224   
225    // Set the backup pack option
226  0 if (StringUtils.equals(request.getParameter("importAsBackup"), "true")) {
227  0 importer.setBackupPack(true);
228    } else {
229  0 importer.setBackupPack(false);
230    }
231   
232    // Import files
233  0 importer.install();
234    }
235   
 
236  5 toggle private void importPackageFilterStream(XWikiAttachment packFile, XWikiRequest request, XWikiContext context)
237    throws IOException, XWikiException, FilterException
238    {
239  5 String[] pages = request.getParameterValues("pages");
240   
241  5 XARInputProperties xarProperties = new XARInputProperties();
242  5 DocumentInstanceOutputProperties instanceProperties = new DocumentInstanceOutputProperties();
243  5 instanceProperties.setSaveComment("Imported from XAR");
244   
245  5 if (pages != null) {
246  5 EntityReferenceSet entities = new EntityReferenceSet();
247   
248  5 EntityReferenceResolver<String> resolver =
249    Utils.getComponent(EntityReferenceResolver.TYPE_STRING, "relative");
250   
251  5 for (String pageEntry : pages) {
252  5 if (StringUtils.isNotEmpty(pageEntry)) {
253  5 String locale = getLocale(pageEntry, request);
254  5 int iAction = getAction(pageEntry, locale, request);
255   
256  5 String documentReference = getDocumentReference(pageEntry);
257  5 if (iAction == DocumentInfo.ACTION_OVERWRITE) {
258  5 entities.includes(new LocalDocumentReference(resolver.resolve(documentReference, EntityType.DOCUMENT),
259    LocaleUtils.toLocale(locale)));
260    }
261    }
262    }
263   
264  5 xarProperties.setEntities(entities);
265    }
266   
267    // Set the appropriate strategy to handle versions
268  5 if (StringUtils.equals(request.getParameter("historyStrategy"), "reset")) {
269  0 instanceProperties.setPreviousDeleted(true);
270  0 instanceProperties.setVersionPreserved(false);
271  0 xarProperties.setWithHistory(false);
272  5 } else if (StringUtils.equals(request.getParameter("historyStrategy"), "replace")) {
273  1 instanceProperties.setPreviousDeleted(true);
274  1 instanceProperties.setVersionPreserved(true);
275  1 xarProperties.setWithHistory(true);
276    } else {
277  4 instanceProperties.setPreviousDeleted(false);
278  4 instanceProperties.setVersionPreserved(false);
279  4 xarProperties.setWithHistory(false);
280    }
281   
282    // Set the backup pack option
283  5 if (StringUtils.equals(request.getParameter("importAsBackup"), "true")) {
284  1 instanceProperties.setAuthorPreserved(true);
285    } else {
286  4 instanceProperties.setAuthorPreserved(false);
287    }
288   
289  5 BeanInputFilterStreamFactory<XARInputProperties> xarFilterStreamFactory =
290    Utils.getComponent((Type) InputFilterStreamFactory.class, FilterStreamType.XWIKI_XAR_CURRENT.serialize());
291  5 BeanInputFilterStream<XARInputProperties> xarFilterStream =
292    xarFilterStreamFactory.createInputFilterStream(xarProperties);
293   
294  5 BeanOutputFilterStreamFactory<InstanceOutputProperties> instanceFilterStreamFactory =
295    Utils.getComponent((Type) OutputFilterStreamFactory.class, FilterStreamType.XWIKI_INSTANCE.serialize());
296  5 BeanOutputFilterStream<InstanceOutputProperties> instanceFilterStream =
297    instanceFilterStreamFactory.createOutputFilterStream(instanceProperties);
298   
299    // Notify all the listeners about import
300  5 ObservationManager observation = Utils.getComponent(ObservationManager.class);
301   
302  5 InputStream source = packFile.getContentInputStream(context);
303  5 xarProperties.setSource(new DefaultInputStreamInputSource(source));
304   
305    // Setup log
306  5 xarProperties.setVerbose(true);
307  5 instanceProperties.setVerbose(true);
308  5 instanceProperties.setStoppedWhenSaveFail(false);
309  5 LoggerManager loggerManager = Utils.getComponent(LoggerManager.class);
310  5 LogQueue logger = new LogQueue();
311  5 if (loggerManager != null) {
312    // Isolate log
313  5 loggerManager.pushLogListener(new LoggerListener(UUID.randomUUID().toString(), logger));
314    }
315   
316  5 observation.notify(new XARImportingEvent(), null, context);
317   
318  5 try {
319  5 xarFilterStream.read(instanceFilterStream.getFilter());
320   
321  5 xarFilterStream.close();
322  5 instanceFilterStream.close();
323    } finally {
324  5 if (loggerManager != null) {
325    // Stop isolating log
326  5 loggerManager.popLogListener();
327    }
328   
329    // Print the import log
330  5 if (LOGGER.isDebugEnabled()) {
331  0 logger.log(LOGGER);
332    } else {
333    // TODO: remove when the UI show the log properly
334  5 for (LogEvent logEvent : logger.getLogsFrom(LogLevel.ERROR)) {
335  0 logEvent.log(LOGGER);
336    }
337    }
338   
339    // Close the input source
340  5 source.close();
341   
342  5 observation.notify(new XARImportedEvent(), null, context);
343    }
344   
345    // Generate import report
346    // Emulate old packager report (for retro compatibility)
347  5 Package oldImporter = new Package();
348  5 if (logger.containLogsFrom(LogLevel.ERROR)) {
349  0 context.put("install_status", DocumentInfo.INSTALL_ERROR);
350    } else {
351  5 context.put("install_status", DocumentInfo.INSTALL_OK);
352    }
353  5 EntityReferenceSerializer<String> serializer =
354    Utils.getComponent(EntityReferenceSerializer.TYPE_STRING, "local");
355  5 for (LogEvent log : logger) {
356  5 Marker marker = log.getMarker();
357  5 if (marker != null) {
358  5 if (marker.contains(WikiDocumentFilter.LOG_DOCUMENT_CREATED.getName())
359    || marker.contains(WikiDocumentFilter.LOG_DOCUMENT_UPDATED.getName())) {
360  5 oldImporter.getInstalled(context).add(
361    serializer.serialize((EntityReference) log.getArgumentArray()[0]));
362  0 } else if (marker.contains(WikiDocumentFilter.LOG_DOCUMENT_SKIPPED.getName())) {
363  0 oldImporter.getSkipped(context).add(
364    serializer.serialize((EntityReference) log.getArgumentArray()[0]));
365  0 } else if (marker.contains(WikiDocumentFilter.LOG_DOCUMENT_ERROR.getName())) {
366  0 Object entity = log.getArgumentArray()[0];
367  0 if (entity != null) {
368  0 oldImporter.getErrors(context).add(
369  0 entity instanceof EntityReference ? serializer.serialize((EntityReference) log
370    .getArgumentArray()[0]) : entity.toString());
371    }
372    }
373    }
374    }
375    }
376    }