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

File ImportAction.java

 

Coverage histogram

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

Code metrics

60
141
8
1
371
280
41
0.29
17.62
8
5.12

Classes

Class Line # Actions
ImportAction 79 141 0% 41 91
0.564593356.5%
 

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: 20a96bb18cc17ecadd4ede87166e586f83c9a5eb $
78    */
 
79    public class ImportAction extends XWikiAction
80    {
81    private static final Logger LOGGER = LoggerFactory.getLogger(ImportAction.class);
82   
 
83  16 toggle @Override
84    public String render(XWikiContext context) throws XWikiException
85    {
86  16 String result = null;
87   
88  16 try {
89  16 XWikiRequest request = context.getRequest();
90  16 XWikiResponse response = context.getResponse();
91  16 XWikiDocument doc = context.getDoc();
92  16 String name = request.get("name");
93  16 String action = request.get("action");
94   
95  16 if (!context.getWiki().getRightService().hasWikiAdminRights(context)) {
96  0 context.put("message", "needadminrights");
97  0 return "exception";
98    }
99   
100  16 if (name == null) {
101  12 return "admin";
102    }
103   
104  4 if ("getPackageInfos".equals(action)) {
105  0 getPackageInfos(doc.getAttachment(name), response, context);
106  4 } else if ("import".equals(action)) {
107  4 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  4 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  4 toggle private String importPackage(XWikiAttachment packFile, XWikiRequest request, XWikiContext context)
130    throws IOException, XWikiException, FilterException
131    {
132  4 String all = request.get("all");
133  4 if (!"1".equals(all)) {
134  4 if (context.getWiki().ParamAsLong("xwiki.action.import.xar.usefilter", 1) == 0) {
135  0 importPackageOld(packFile, request, context);
136    } else {
137  4 importPackageFilterStream(packFile, request, context);
138    }
139   
140  4 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  0 return "admin";
147    }
148    }
149   
150  0 return null;
151    }
152   
 
153  4 toggle private String getLocale(String pageName, XWikiRequest request)
154    {
155  4 return Util.normalizeLanguage(request.get("language_" + pageName));
156    }
157   
 
158  4 toggle private int getAction(String pageName, String language, XWikiRequest request)
159    {
160  4 String actionName = "action_" + pageName;
161  4 if (!StringUtils.isBlank(language)) {
162  0 actionName += ("_" + language);
163    }
164  4 String defaultAction = request.get(actionName);
165  4 int iAction;
166  4 if (StringUtils.isBlank(defaultAction)) {
167  4 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  4 return iAction;
177    }
178   
 
179  4 toggle private String getDocumentReference(String pageEntry)
180    {
181  4 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  4 toggle private void importPackageFilterStream(XWikiAttachment packFile, XWikiRequest request, XWikiContext context)
237    throws IOException, XWikiException, FilterException
238    {
239  4 String[] pages = request.getParameterValues("pages");
240   
241  4 XARInputProperties xarProperties = new XARInputProperties();
242  4 DocumentInstanceOutputProperties instanceProperties = new DocumentInstanceOutputProperties();
243  4 instanceProperties.setSaveComment("Imported from XAR");
244   
245  4 if (pages != null) {
246  4 EntityReferenceSet entities = new EntityReferenceSet();
247   
248  4 EntityReferenceResolver<String> resolver =
249    Utils.getComponent(EntityReferenceResolver.TYPE_STRING, "relative");
250   
251  4 for (String pageEntry : pages) {
252  4 if (StringUtils.isNotEmpty(pageEntry)) {
253  4 String locale = getLocale(pageEntry, request);
254  4 int iAction = getAction(pageEntry, locale, request);
255   
256  4 String documentReference = getDocumentReference(pageEntry);
257  4 if (iAction == DocumentInfo.ACTION_OVERWRITE) {
258  4 entities.includes(new LocalDocumentReference(resolver.resolve(documentReference, EntityType.DOCUMENT),
259    LocaleUtils.toLocale(locale)));
260    }
261    }
262    }
263   
264  4 xarProperties.setEntities(entities);
265    }
266   
267    // Set the appropriate strategy to handle versions
268  4 if (StringUtils.equals(request.getParameter("historyStrategy"), "reset")) {
269  0 instanceProperties.setPreviousDeleted(true);
270  0 instanceProperties.setVersionPreserved(false);
271  0 xarProperties.setWithHistory(false);
272  4 } 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  3 instanceProperties.setPreviousDeleted(false);
278  3 instanceProperties.setVersionPreserved(false);
279  3 xarProperties.setWithHistory(false);
280    }
281   
282    // Set the backup pack option
283  4 if (StringUtils.equals(request.getParameter("importAsBackup"), "true")) {
284  1 instanceProperties.setAuthorPreserved(true);
285    } else {
286  3 instanceProperties.setAuthorPreserved(false);
287    }
288   
289  4 BeanInputFilterStreamFactory<XARInputProperties> xarFilterStreamFactory =
290    Utils.getComponent((Type) InputFilterStreamFactory.class, FilterStreamType.XWIKI_XAR_CURRENT.serialize());
291  4 BeanInputFilterStream<XARInputProperties> xarFilterStream =
292    xarFilterStreamFactory.createInputFilterStream(xarProperties);
293   
294  4 BeanOutputFilterStreamFactory<InstanceOutputProperties> instanceFilterStreamFactory =
295    Utils.getComponent((Type) OutputFilterStreamFactory.class, FilterStreamType.XWIKI_INSTANCE.serialize());
296  4 BeanOutputFilterStream<InstanceOutputProperties> instanceFilterStream =
297    instanceFilterStreamFactory.createOutputFilterStream(instanceProperties);
298   
299    // Notify all the listeners about import
300  4 ObservationManager observation = Utils.getComponent(ObservationManager.class);
301   
302  4 InputStream source = packFile.getContentInputStream(context);
303  4 xarProperties.setSource(new DefaultInputStreamInputSource(source));
304   
305    // Setup log
306  4 xarProperties.setVerbose(true);
307  4 instanceProperties.setVerbose(true);
308  4 instanceProperties.setStoppedWhenSaveFail(false);
309  4 LoggerManager loggerManager = Utils.getComponent(LoggerManager.class);
310  4 LogQueue logger = new LogQueue();
311  4 if (loggerManager != null) {
312    // Isolate log
313  4 loggerManager.pushLogListener(new LoggerListener(UUID.randomUUID().toString(), logger));
314    }
315   
316  4 observation.notify(new XARImportingEvent(), null, context);
317   
318  4 try {
319  4 xarFilterStream.read(instanceFilterStream.getFilter());
320   
321  4 xarFilterStream.close();
322  4 instanceFilterStream.close();
323    } finally {
324  4 if (loggerManager != null) {
325    // Stop isolating log
326  4 loggerManager.popLogListener();
327    }
328   
329    // Print the import log
330  4 if (LOGGER.isDebugEnabled()) {
331  0 logger.log(LOGGER);
332    }
333   
334    // Close the input source
335  4 source.close();
336   
337  4 observation.notify(new XARImportedEvent(), null, context);
338    }
339   
340    // Generate import report
341    // Emulate old packager report (for retro compatibility)
342  4 Package oldImporter = new Package();
343  4 if (logger.containLogsFrom(LogLevel.ERROR)) {
344  0 context.put("install_status", DocumentInfo.INSTALL_ERROR);
345    } else {
346  4 context.put("install_status", DocumentInfo.INSTALL_OK);
347    }
348  4 EntityReferenceSerializer<String> serializer =
349    Utils.getComponent(EntityReferenceSerializer.TYPE_STRING, "local");
350  4 for (LogEvent log : logger) {
351  4 Marker marker = log.getMarker();
352  4 if (marker != null) {
353  4 if (marker.contains(WikiDocumentFilter.LOG_DOCUMENT_CREATED.getName())
354    || marker.contains(WikiDocumentFilter.LOG_DOCUMENT_UPDATED.getName())) {
355  4 oldImporter.getInstalled(context).add(
356    serializer.serialize((EntityReference) log.getArgumentArray()[0]));
357  0 } else if (marker.contains(WikiDocumentFilter.LOG_DOCUMENT_SKIPPED.getName())) {
358  0 oldImporter.getSkipped(context).add(
359    serializer.serialize((EntityReference) log.getArgumentArray()[0]));
360  0 } else if (marker.contains(WikiDocumentFilter.LOG_DOCUMENT_ERROR.getName())) {
361  0 Object entity = log.getArgumentArray()[0];
362  0 if (entity != null) {
363  0 oldImporter.getErrors(context).add(
364  0 entity instanceof EntityReference ? serializer.serialize((EntityReference) log
365    .getArgumentArray()[0]) : entity.toString());
366    }
367    }
368    }
369    }
370    }
371    }