001
014
015 package com.liferay.portlet.wiki.lar;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
019 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
020 import com.liferay.portal.kernel.lar.PortletDataContext;
021 import com.liferay.portal.kernel.lar.PortletDataException;
022 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
023 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
024 import com.liferay.portal.kernel.repository.model.FileEntry;
025 import com.liferay.portal.kernel.util.MapUtil;
026 import com.liferay.portal.kernel.util.MimeTypesUtil;
027 import com.liferay.portal.kernel.util.StreamUtil;
028 import com.liferay.portal.kernel.util.StringBundler;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.workflow.WorkflowConstants;
031 import com.liferay.portal.kernel.xml.Element;
032 import com.liferay.portal.service.ServiceContext;
033 import com.liferay.portal.util.PortletKeys;
034 import com.liferay.portal.util.PropsValues;
035 import com.liferay.portlet.dynamicdatamapping.lar.DDMPortletDataHandler;
036 import com.liferay.portlet.journal.lar.JournalPortletDataHandler;
037 import com.liferay.portlet.wiki.NoSuchNodeException;
038 import com.liferay.portlet.wiki.NoSuchPageException;
039 import com.liferay.portlet.wiki.model.WikiNode;
040 import com.liferay.portlet.wiki.model.WikiPage;
041 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
042 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
043 import com.liferay.portlet.wiki.service.persistence.WikiNodeUtil;
044 import com.liferay.portlet.wiki.service.persistence.WikiPageUtil;
045 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
046 import com.liferay.portlet.wiki.util.WikiCacheUtil;
047 import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
048
049 import java.io.InputStream;
050
051 import java.util.List;
052 import java.util.Map;
053
054 import javax.portlet.PortletPreferences;
055
056
062 public class WikiPortletDataHandler extends BasePortletDataHandler {
063
064 public static final String NAMESPACE = "wiki";
065
066 public static void exportNode(
067 PortletDataContext portletDataContext, Element nodesElement,
068 Element pagesElement, Element dlFileEntryTypesElement,
069 Element dlFoldersElement, Element dlFileEntriesElement,
070 Element dlFileRanksElement, Element dlRepositoriesElement,
071 Element dlRepositoryEntriesElement, WikiNode node)
072 throws Exception {
073
074 if (portletDataContext.isWithinDateRange(node.getModifiedDate())) {
075 String path = getNodePath(portletDataContext, node);
076
077 if (portletDataContext.isPathNotProcessed(path)) {
078 Element nodeElement = nodesElement.addElement("node");
079
080 portletDataContext.addClassedModel(
081 nodeElement, path, node, NAMESPACE);
082 }
083 }
084
085 List<WikiPage> pages = WikiPageUtil.findByN_S(
086 node.getNodeId(), WorkflowConstants.STATUS_APPROVED,
087 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
088 new PageVersionComparator(true));
089
090 for (WikiPage page : pages) {
091 exportPage(
092 portletDataContext, nodesElement, pagesElement,
093 dlFileEntryTypesElement, dlFoldersElement, dlFileEntriesElement,
094 dlFileRanksElement, dlRepositoriesElement,
095 dlRepositoryEntriesElement, page, true);
096 }
097 }
098
099 public static void importNode(
100 PortletDataContext portletDataContext, WikiNode node)
101 throws Exception {
102
103 long userId = portletDataContext.getUserId(node.getUserUuid());
104
105 ServiceContext serviceContext = new ServiceContext();
106
107 serviceContext.setAddGroupPermissions(true);
108 serviceContext.setAddGuestPermissions(true);
109 serviceContext.setCreateDate(node.getCreateDate());
110 serviceContext.setModifiedDate(node.getModifiedDate());
111 serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());
112
113 WikiNode importedNode = null;
114
115 if (portletDataContext.isDataStrategyMirror()) {
116 WikiNode existingNode = WikiNodeUtil.fetchByUUID_G(
117 node.getUuid(), portletDataContext.getScopeGroupId());
118
119 String initialNodeName = PropsValues.WIKI_INITIAL_NODE_NAME;
120
121 if ((existingNode == null) &&
122 initialNodeName.equals(node.getName())) {
123
124 try {
125 WikiNodeUtil.removeByG_N(
126 portletDataContext.getScopeGroupId(), node.getName());
127 }
128 catch (NoSuchNodeException nsne) {
129 }
130 }
131
132 if (existingNode == null) {
133 serviceContext.setUuid(node.getUuid());
134
135 importedNode = WikiNodeLocalServiceUtil.addNode(
136 userId, node.getName(), node.getDescription(),
137 serviceContext);
138 }
139 else {
140 importedNode = WikiNodeLocalServiceUtil.updateNode(
141 existingNode.getNodeId(), node.getName(),
142 node.getDescription(), serviceContext);
143 }
144 }
145 else {
146 String initialNodeName = PropsValues.WIKI_INITIAL_NODE_NAME;
147
148 if (initialNodeName.equals(node.getName())) {
149 try {
150 WikiNodeUtil.removeByG_N(
151 portletDataContext.getScopeGroupId(), node.getName());
152 }
153 catch (NoSuchNodeException nsne) {
154 }
155 }
156
157 String nodeName = getNodeName(
158 portletDataContext, node, node.getName(), 2);
159
160 importedNode = WikiNodeLocalServiceUtil.addNode(
161 userId, nodeName, node.getDescription(), serviceContext);
162 }
163
164 portletDataContext.importClassedModel(node, importedNode, NAMESPACE);
165 }
166
167 public static void importPage(
168 PortletDataContext portletDataContext, Element pageElement,
169 WikiPage page)
170 throws Exception {
171
172 long userId = portletDataContext.getUserId(page.getUserUuid());
173
174 Map<Long, Long> nodeIds =
175 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
176 WikiNode.class);
177
178 long nodeId = MapUtil.getLong(
179 nodeIds, page.getNodeId(), page.getNodeId());
180
181 String content = JournalPortletDataHandler.importReferencedContent(
182 portletDataContext, pageElement, page.getContent());
183
184 page.setContent(content);
185
186 ServiceContext serviceContext = portletDataContext.createServiceContext(
187 pageElement, page, NAMESPACE);
188
189 if (page.getStatus() != WorkflowConstants.STATUS_APPROVED) {
190 serviceContext.setWorkflowAction(
191 WorkflowConstants.ACTION_SAVE_DRAFT);
192 }
193
194 WikiPage importedPage = null;
195
196 WikiPage existingPage = WikiPageUtil.fetchByUUID_G(
197 page.getUuid(), portletDataContext.getScopeGroupId());
198
199 if (existingPage == null) {
200 try {
201 existingPage = WikiPageLocalServiceUtil.getPage(
202 nodeId, page.getTitle());
203 }
204 catch (NoSuchPageException nspe) {
205 }
206 }
207
208 if (existingPage == null) {
209 serviceContext.setUuid(page.getUuid());
210
211 importedPage = WikiPageLocalServiceUtil.addPage(
212 userId, nodeId, page.getTitle(), page.getVersion(),
213 page.getContent(), page.getSummary(), page.isMinorEdit(),
214 page.getFormat(), page.getHead(), page.getParentTitle(),
215 page.getRedirectTitle(), serviceContext);
216 }
217 else {
218 importedPage = WikiPageLocalServiceUtil.updatePage(
219 userId, nodeId, existingPage.getTitle(), 0, page.getContent(),
220 page.getSummary(), page.isMinorEdit(), page.getFormat(),
221 page.getParentTitle(), page.getRedirectTitle(), serviceContext);
222 }
223
224 if (portletDataContext.getBooleanParameter(NAMESPACE, "attachments") &&
225 page.isHead()) {
226
227 for (Element attachmentElement :
228 pageElement.elements("attachment")) {
229
230 String name = attachmentElement.attributeValue("name");
231 String binPath = attachmentElement.attributeValue("bin-path");
232
233 InputStream inputStream = null;
234 String mimeType = null;
235
236 try {
237 inputStream = portletDataContext.getZipEntryAsInputStream(
238 binPath);
239
240 mimeType = MimeTypesUtil.getContentType(inputStream, name);
241 }
242 finally {
243 StreamUtil.cleanUp(inputStream);
244 }
245
246 try {
247 inputStream = portletDataContext.getZipEntryAsInputStream(
248 binPath);
249
250 WikiPageLocalServiceUtil.addPageAttachment(
251 userId, importedPage.getNodeId(),
252 importedPage.getTitle(), name, inputStream, mimeType);
253 }
254 finally {
255 StreamUtil.cleanUp(inputStream);
256 }
257 }
258 }
259
260 portletDataContext.importClassedModel(page, importedPage, NAMESPACE);
261 }
262
263 public WikiPortletDataHandler() {
264 setExportControls(
265 new PortletDataHandlerBoolean(
266 NAMESPACE, "wikis-and-pages", true, true));
267 setExportMetadataControls(
268 new PortletDataHandlerBoolean(
269 NAMESPACE, "wiki-pages", true,
270 new PortletDataHandlerControl[] {
271 new PortletDataHandlerBoolean(NAMESPACE, "attachments"),
272 new PortletDataHandlerBoolean(NAMESPACE, "categories"),
273 new PortletDataHandlerBoolean(NAMESPACE, "comments"),
274 new PortletDataHandlerBoolean(NAMESPACE, "ratings"),
275 new PortletDataHandlerBoolean(NAMESPACE, "tags")
276 }));
277 }
278
279 @Override
280 public PortletPreferences importData(
281 PortletDataContext portletDataContext, String portletId,
282 PortletPreferences portletPreferences, String data)
283 throws PortletDataException {
284
285 WikiCacheThreadLocal.setClearCache(false);
286
287 try {
288 return super.importData(
289 portletDataContext, portletId, portletPreferences, data);
290 }
291 finally {
292 WikiCacheThreadLocal.setClearCache(true);
293 }
294 }
295
296 protected static void exportNode(
297 PortletDataContext portletDataContext, Element nodesElement,
298 long nodeId)
299 throws Exception {
300
301 if (!portletDataContext.hasDateRange()) {
302 return;
303 }
304
305 WikiNode node = WikiNodeUtil.findByPrimaryKey(nodeId);
306
307 String path = getNodePath(portletDataContext, node);
308
309 if (!portletDataContext.isPathNotProcessed(path)) {
310 return;
311 }
312
313 Element nodeElement = nodesElement.addElement("node");
314
315 portletDataContext.addClassedModel(nodeElement, path, node, NAMESPACE);
316 }
317
318 protected static void exportPage(
319 PortletDataContext portletDataContext, Element nodesElement,
320 Element pagesElement, Element dlFileEntryTypesElement,
321 Element dlFoldersElement, Element dlFileEntriesElement,
322 Element dlFileRanksElement, Element dlRepositoriesElement,
323 Element dlRepositoryEntriesElement, WikiPage page,
324 boolean checkDateRange)
325 throws Exception {
326
327 if (!portletDataContext.isWithinDateRange(page.getModifiedDate())) {
328 return;
329 }
330
331 String path = getPagePath(portletDataContext, page);
332
333
334
335
336 page = (WikiPage)page.clone();
337
338 Element pageElement = (Element)pagesElement.selectSingleNode(
339 "
340
341 if (portletDataContext.isPathNotProcessed(path)) {
342 if (pageElement == null) {
343 pageElement = pagesElement.addElement("page");
344 }
345
346 String content = DDMPortletDataHandler.exportReferencedContent(
347 portletDataContext, dlFileEntryTypesElement, dlFoldersElement,
348 dlFileEntriesElement, dlFileRanksElement, dlRepositoriesElement,
349 dlRepositoryEntriesElement, pageElement, page.getContent());
350
351 page.setContent(content);
352
353 String imagePath = getPageImagePath(portletDataContext, page);
354
355 pageElement.addAttribute("image-path", imagePath);
356
357 if (portletDataContext.getBooleanParameter(
358 NAMESPACE, "attachments") &&
359 page.isHead()) {
360
361 int i = 0;
362
363 for (FileEntry fileEntry : page.getAttachmentsFileEntries()) {
364 Element attachmentElement = pageElement.addElement(
365 "attachment");
366
367 attachmentElement.addAttribute(
368 "name", fileEntry.getTitle());
369
370 String binPath = getPageAttachementBinPath(
371 portletDataContext, page, i++);
372
373 attachmentElement.addAttribute("bin-path", binPath);
374
375 portletDataContext.addZipEntry(
376 binPath, fileEntry.getContentStream());
377 }
378
379 long folderId = page.getAttachmentsFolderId();
380
381 if (folderId != 0) {
382 page.setAttachmentsFolderId(folderId);
383 }
384 }
385
386 portletDataContext.addClassedModel(
387 pageElement, path, page, NAMESPACE);
388 }
389
390 exportNode(portletDataContext, nodesElement, page.getNodeId());
391 }
392
393 protected static String getNodeName(
394 PortletDataContext portletDataContext, WikiNode node, String name,
395 int count)
396 throws Exception {
397
398 WikiNode existingNode = WikiNodeUtil.fetchByG_N(
399 portletDataContext.getScopeGroupId(), name);
400
401 if (existingNode == null) {
402 return name;
403 }
404
405 String nodeName = node.getName();
406
407 return getNodeName(
408 portletDataContext, node,
409 nodeName.concat(StringPool.SPACE).concat(String.valueOf(count)),
410 ++count);
411 }
412
413 protected static String getNodePath(
414 PortletDataContext portletDataContext, WikiNode node) {
415
416 StringBundler sb = new StringBundler(4);
417
418 sb.append(
419 ExportImportPathUtil.getPortletPath(
420 portletDataContext, PortletKeys.WIKI));
421 sb.append("/nodes/");
422 sb.append(node.getNodeId());
423 sb.append(".xml");
424
425 return sb.toString();
426 }
427
428 protected static String getPageAttachementBinPath(
429 PortletDataContext portletDataContext, WikiPage page, int count) {
430
431 StringBundler sb = new StringBundler(6);
432
433 sb.append(
434 ExportImportPathUtil.getPortletPath(
435 portletDataContext, PortletKeys.WIKI));
436 sb.append("/bin/");
437 sb.append(page.getPageId());
438 sb.append(StringPool.SLASH);
439 sb.append("attachement");
440 sb.append(count);
441
442 return sb.toString();
443 }
444
445 protected static String getPageImagePath(
446 PortletDataContext portletDataContext, WikiPage page)
447 throws Exception {
448
449 StringBundler sb = new StringBundler(6);
450
451 sb.append(
452 ExportImportPathUtil.getPortletPath(
453 portletDataContext, PortletKeys.WIKI));
454 sb.append("/page/");
455 sb.append(page.getUuid());
456 sb.append(StringPool.SLASH);
457 sb.append(page.getVersion());
458 sb.append(StringPool.SLASH);
459
460 return sb.toString();
461 }
462
463 protected static String getPagePath(
464 PortletDataContext portletDataContext, WikiPage page) {
465
466 StringBundler sb = new StringBundler(4);
467
468 sb.append(
469 ExportImportPathUtil.getPortletPath(
470 portletDataContext, PortletKeys.WIKI));
471 sb.append("/pages/");
472 sb.append(page.getPageId());
473 sb.append(".xml");
474
475 return sb.toString();
476 }
477
478 @Override
479 protected PortletPreferences doDeleteData(
480 PortletDataContext portletDataContext, String portletId,
481 PortletPreferences portletPreferences)
482 throws Exception {
483
484 if (portletDataContext.addPrimaryKey(
485 WikiPortletDataHandler.class, "deleteData")) {
486
487 return portletPreferences;
488 }
489
490 WikiNodeLocalServiceUtil.deleteNodes(
491 portletDataContext.getScopeGroupId());
492
493 return portletPreferences;
494 }
495
496 @Override
497 protected String doExportData(
498 PortletDataContext portletDataContext, String portletId,
499 PortletPreferences portletPreferences)
500 throws Exception {
501
502 portletDataContext.addPermissions(
503 "com.liferay.portlet.wiki", portletDataContext.getScopeGroupId());
504
505 Element rootElement = addExportDataRootElement(portletDataContext);
506
507 rootElement.addAttribute(
508 "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
509
510 Element nodesElement = rootElement.addElement("nodes");
511 Element pagesElement = rootElement.addElement("pages");
512
513 Element dlFileEntryTypesElement = pagesElement.addElement(
514 "dl-file-entry-types");
515 Element dlFoldersElement = pagesElement.addElement("dl-folders");
516 Element dlFileEntriesElement = pagesElement.addElement(
517 "dl-file-entries");
518 Element dlFileRanksElement = pagesElement.addElement("dl-file-ranks");
519 Element dlRepositoriesElement = pagesElement.addElement(
520 "dl-repositories");
521 Element dlRepositoryEntriesElement = pagesElement.addElement(
522 "dl-repository-entries");
523
524 List<WikiNode> nodes = WikiNodeUtil.findByGroupId(
525 portletDataContext.getScopeGroupId());
526
527 for (WikiNode node : nodes) {
528 exportNode(
529 portletDataContext, nodesElement, pagesElement,
530 dlFileEntryTypesElement, dlFoldersElement, dlFileEntriesElement,
531 dlFileRanksElement, dlRepositoriesElement,
532 dlRepositoryEntriesElement, node);
533 }
534
535 return getExportDataRootElementString(rootElement);
536 }
537
538 @Override
539 protected PortletPreferences doImportData(
540 PortletDataContext portletDataContext, String portletId,
541 PortletPreferences portletPreferences, String data)
542 throws Exception {
543
544 portletDataContext.importPermissions(
545 "com.liferay.portlet.wiki", portletDataContext.getSourceGroupId(),
546 portletDataContext.getScopeGroupId());
547
548 Element rootElement = portletDataContext.getImportDataRootElement();
549
550 Element nodesElement = rootElement.element("nodes");
551
552 for (Element nodeElement : nodesElement.elements("node")) {
553 String path = nodeElement.attributeValue("path");
554
555 if (!portletDataContext.isPathNotProcessed(path)) {
556 continue;
557 }
558
559 WikiNode node = (WikiNode)portletDataContext.getZipEntryAsObject(
560 path);
561
562 importNode(portletDataContext, node);
563 }
564
565 Element pagesElement = rootElement.element("pages");
566
567 JournalPortletDataHandler.importReferencedData(
568 portletDataContext, pagesElement);
569
570 for (Element pageElement : pagesElement.elements("page")) {
571 String path = pageElement.attributeValue("path");
572
573 if (!portletDataContext.isPathNotProcessed(path)) {
574 continue;
575 }
576
577 WikiPage page = (WikiPage)portletDataContext.getZipEntryAsObject(
578 path);
579
580 importPage(portletDataContext, pageElement, page);
581 }
582
583 Map<Long, Long> nodeIds =
584 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
585 WikiNode.class);
586
587 for (long nodeId : nodeIds.values()) {
588 WikiCacheUtil.clearCache(nodeId);
589 }
590
591 return null;
592 }
593
594 }