1
14
15 package com.liferay.portlet.wiki.lar;
16
17 import com.liferay.documentlibrary.service.DLServiceUtil;
18 import com.liferay.portal.kernel.dao.orm.QueryUtil;
19 import com.liferay.portal.kernel.exception.PortalException;
20 import com.liferay.portal.kernel.exception.SystemException;
21 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
22 import com.liferay.portal.kernel.lar.PortletDataContext;
23 import com.liferay.portal.kernel.lar.PortletDataException;
24 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
25 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
26 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
27 import com.liferay.portal.kernel.log.Log;
28 import com.liferay.portal.kernel.log.LogFactoryUtil;
29 import com.liferay.portal.kernel.util.MapUtil;
30 import com.liferay.portal.kernel.util.PropsKeys;
31 import com.liferay.portal.kernel.util.StringBundler;
32 import com.liferay.portal.kernel.util.StringPool;
33 import com.liferay.portal.kernel.workflow.WorkflowConstants;
34 import com.liferay.portal.kernel.xml.Document;
35 import com.liferay.portal.kernel.xml.Element;
36 import com.liferay.portal.kernel.xml.SAXReaderUtil;
37 import com.liferay.portal.model.CompanyConstants;
38 import com.liferay.portal.service.ServiceContext;
39 import com.liferay.portal.util.PortletKeys;
40 import com.liferay.portal.util.PropsUtil;
41 import com.liferay.portlet.wiki.NoSuchNodeException;
42 import com.liferay.portlet.wiki.NoSuchPageException;
43 import com.liferay.portlet.wiki.model.WikiNode;
44 import com.liferay.portlet.wiki.model.WikiPage;
45 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
46 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
47 import com.liferay.portlet.wiki.service.persistence.WikiNodeUtil;
48 import com.liferay.portlet.wiki.service.persistence.WikiPageUtil;
49 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
50 import com.liferay.portlet.wiki.util.WikiCacheUtil;
51 import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
52
53 import java.io.InputStream;
54
55 import java.util.List;
56 import java.util.Map;
57
58 import javax.portlet.PortletPreferences;
59
60
68 public class WikiPortletDataHandlerImpl extends BasePortletDataHandler {
69
70 public static void exportNode(
71 PortletDataContext context, Element nodesEl, Element pagesEl,
72 WikiNode node)
73 throws PortalException, SystemException {
74
75 if (context.isWithinDateRange(node.getModifiedDate())) {
76 String path = getNodePath(context, node);
77
78 if (context.isPathNotProcessed(path)) {
79 Element nodeEl = nodesEl.addElement("node");
80
81 nodeEl.addAttribute("path", path);
82
83 node.setUserUuid(node.getUserUuid());
84
85 context.addPermissions(WikiNode.class, node.getNodeId());
86
87 context.addZipEntry(path, node);
88 }
89 }
90
91 List<WikiPage> nodePages = WikiPageUtil.findByN_S(
92 node.getNodeId(), WorkflowConstants.STATUS_APPROVED,
93 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
94 new PageVersionComparator(true));
95
96 for (WikiPage page : nodePages) {
97 exportPage(context, nodesEl, pagesEl, page);
98 }
99 }
100
101 public static void importNode(
102 PortletDataContext context, Map<Long, Long> nodePKs, WikiNode node)
103 throws Exception {
104
105 long userId = context.getUserId(node.getUserUuid());
106
107 ServiceContext serviceContext = new ServiceContext();
108
109 serviceContext.setAddCommunityPermissions(true);
110 serviceContext.setAddGuestPermissions(true);
111 serviceContext.setCreateDate(node.getCreateDate());
112 serviceContext.setModifiedDate(node.getModifiedDate());
113 serviceContext.setScopeGroupId(context.getGroupId());
114
115 WikiNode importedNode = null;
116
117 if (context.getDataStrategy().equals(
118 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
119
120 WikiNode existingNode = WikiNodeUtil.fetchByUUID_G(
121 node.getUuid(), context.getGroupId());
122
123 String nodeName = PropsUtil.get(PropsKeys.WIKI_INITIAL_NODE_NAME);
124
125 if ((existingNode == null) && node.getName().equals(nodeName)) {
126 try {
127 WikiNodeUtil.removeByG_N(
128 context.getGroupId(), node.getName());
129 }
130 catch (NoSuchNodeException nsne) {
131 }
132 }
133
134 if (existingNode == null) {
135 importedNode = WikiNodeLocalServiceUtil.addNode(
136 node.getUuid(), userId, node.getName(),
137 node.getDescription(), serviceContext);
138 }
139 else {
140 importedNode = WikiNodeLocalServiceUtil.updateNode(
141 existingNode.getNodeId(), node.getName(),
142 node.getDescription(), serviceContext);
143 }
144 }
145 else {
146 String nodeName = PropsUtil.get(PropsKeys.WIKI_INITIAL_NODE_NAME);
147
148 if (node.getName().equals(nodeName)) {
149 try {
150 WikiNodeUtil.removeByG_N(
151 context.getGroupId(), node.getName());
152 }
153 catch (NoSuchNodeException nsne) {
154 }
155 }
156
157 importedNode = WikiNodeLocalServiceUtil.addNode(
158 userId, node.getName(), node.getDescription(), serviceContext);
159 }
160
161 nodePKs.put(node.getNodeId(), importedNode.getNodeId());
162
163 context.importPermissions(
164 WikiNode.class, node.getNodeId(), importedNode.getNodeId());
165 }
166
167 public static void importPage(
168 PortletDataContext context, Map<Long, Long> nodePKs, Element pageEl,
169 WikiPage page)
170 throws Exception {
171
172 long userId = context.getUserId(page.getUserUuid());
173 long nodeId = MapUtil.getLong(
174 nodePKs, page.getNodeId(), page.getNodeId());
175
176 long[] assetCategoryIds = null;
177 String[] assetTagNames = null;
178
179 if (context.getBooleanParameter(_NAMESPACE, "categories") &&
180 page.isHead()) {
181
182 assetCategoryIds = context.getAssetCategoryIds(
183 WikiPage.class, page.getResourcePrimKey());
184 }
185
186 if (context.getBooleanParameter(_NAMESPACE, "tags") &&
187 page.isHead()) {
188
189 assetTagNames = context.getAssetTagNames(
190 WikiPage.class, page.getResourcePrimKey());
191 }
192
193 ServiceContext serviceContext = new ServiceContext();
194
195 serviceContext.setAddCommunityPermissions(true);
196 serviceContext.setAddGuestPermissions(true);
197 serviceContext.setAssetCategoryIds(assetCategoryIds);
198 serviceContext.setAssetTagNames(assetTagNames);
199 serviceContext.setCreateDate(page.getCreateDate());
200 serviceContext.setModifiedDate(page.getModifiedDate());
201
202 if (page.getStatus() != WorkflowConstants.STATUS_APPROVED) {
203 serviceContext.setWorkflowAction(
204 WorkflowConstants.ACTION_SAVE_DRAFT);
205 }
206
207 WikiPage importedPage = null;
208
209 try {
210 WikiNodeUtil.findByPrimaryKey(nodeId);
211
212 if (context.getDataStrategy().equals(
213 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
214
215 WikiPage existingPage = WikiPageUtil.fetchByUUID_G(
216 page.getUuid(), context.getGroupId());
217
218 if (existingPage == null) {
219 try {
220 existingPage = WikiPageLocalServiceUtil.getPage(
221 nodeId, page.getTitle());
222 }
223 catch (NoSuchPageException nspe) {
224 }
225 }
226
227 if (existingPage == null) {
228 importedPage = WikiPageLocalServiceUtil.addPage(
229 page.getUuid(), userId, nodeId, page.getTitle(),
230 page.getVersion(), page.getContent(), page.getSummary(),
231 true, page.getFormat(), page.getHead(),
232 page.getParentTitle(), page.getRedirectTitle(),
233 serviceContext);
234 }
235 else {
236 importedPage = WikiPageLocalServiceUtil.updatePage(
237 userId, nodeId, existingPage.getTitle(), 0,
238 page.getContent(), page.getSummary(), true,
239 page.getFormat(), page.getParentTitle(),
240 page.getRedirectTitle(), serviceContext);
241 }
242 }
243 else {
244 importedPage = WikiPageLocalServiceUtil.addPage(
245 null, userId, nodeId, page.getTitle(), page.getVersion(),
246 page.getContent(), page.getSummary(), true,
247 page.getFormat(), page.getHead(), page.getParentTitle(),
248 page.getRedirectTitle(), serviceContext);
249 }
250
251 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
252 page.isHead()) {
253
254 List<Element> attachmentEls = pageEl.elements("attachment");
255
256 for (Element attachmentEl : attachmentEls) {
257 String name = attachmentEl.attributeValue("name");
258 String binPath = attachmentEl.attributeValue("bin-path");
259
260 InputStream inputStream = context.getZipEntryAsInputStream(
261 binPath);
262
263 WikiPageLocalServiceUtil.addPageAttachment(
264 importedPage.getCompanyId(),
265 importedPage.getAttachmentsDir(),
266 importedPage.getModifiedDate(), name, inputStream);
267 }
268 }
269
270 if (page.isHead()) {
271 context.importPermissions(
272 WikiPage.class, page.getResourcePrimKey(),
273 importedPage.getResourcePrimKey());
274 }
275
276 if (context.getBooleanParameter(_NAMESPACE, "comments") &&
277 page.isHead()) {
278
279 context.importComments(
280 WikiPage.class, page.getResourcePrimKey(),
281 importedPage.getResourcePrimKey(), context.getGroupId());
282 }
283
284 if (context.getBooleanParameter(_NAMESPACE, "ratings") &&
285 page.isHead()) {
286
287 context.importRatingsEntries(
288 WikiPage.class, page.getResourcePrimKey(),
289 importedPage.getResourcePrimKey());
290 }
291 }
292 catch (NoSuchNodeException nsne) {
293 _log.error("Could not find the node for page " + page.getPageId());
294 }
295 }
296
297 public PortletPreferences deleteData(
298 PortletDataContext context, String portletId,
299 PortletPreferences preferences)
300 throws PortletDataException {
301
302 try {
303 if (!context.addPrimaryKey(
304 WikiPortletDataHandlerImpl.class, "deleteData")) {
305
306 WikiNodeLocalServiceUtil.deleteNodes(context.getGroupId());
307 }
308
309 return null;
310 }
311 catch (Exception e) {
312 throw new PortletDataException(e);
313 }
314 }
315
316 public String exportData(
317 PortletDataContext context, String portletId,
318 PortletPreferences preferences)
319 throws PortletDataException {
320
321 try {
322 context.addPermissions(
323 "com.liferay.portlet.wiki", context.getGroupId());
324
325 Document doc = SAXReaderUtil.createDocument();
326
327 Element root = doc.addElement("wiki-data");
328
329 root.addAttribute("group-id", String.valueOf(context.getGroupId()));
330
331 Element nodesEl = root.addElement("nodes");
332 Element pagesEl = root.addElement("pages");
333
334 List<WikiNode> nodes = WikiNodeUtil.findByGroupId(
335 context.getGroupId());
336
337 for (WikiNode node : nodes) {
338 exportNode(context, nodesEl, pagesEl, node);
339 }
340
341 return doc.formattedString();
342 }
343 catch (Exception e) {
344 throw new PortletDataException(e);
345 }
346 }
347
348 public PortletDataHandlerControl[] getExportControls() {
349 return new PortletDataHandlerControl[] {
350 _nodesAndPages, _attachments, _categories, _comments, _ratings,
351 _tags
352 };
353 }
354
355 public PortletDataHandlerControl[] getImportControls() {
356 return new PortletDataHandlerControl[] {
357 _nodesAndPages, _attachments, _categories, _comments, _ratings,
358 _tags
359 };
360 }
361
362 public PortletPreferences importData(
363 PortletDataContext context, String portletId,
364 PortletPreferences preferences, String data)
365 throws PortletDataException {
366
367 WikiCacheThreadLocal.setClearCache(false);
368
369 try {
370 context.importPermissions(
371 "com.liferay.portlet.wiki", context.getSourceGroupId(),
372 context.getGroupId());
373
374 Document doc = SAXReaderUtil.read(data);
375
376 Element root = doc.getRootElement();
377
378 List<Element> nodeEls = root.element("nodes").elements("node");
379
380 Map<Long, Long> nodePKs =
381 (Map<Long, Long>)context.getNewPrimaryKeysMap(WikiNode.class);
382
383 for (Element nodeEl : nodeEls) {
384 String path = nodeEl.attributeValue("path");
385
386 if (!context.isPathNotProcessed(path)) {
387 continue;
388 }
389
390 WikiNode node = (WikiNode)context.getZipEntryAsObject(path);
391
392 importNode(context, nodePKs, node);
393 }
394
395 List<Element> pageEls = root.element("pages").elements("page");
396
397 for (Element pageEl : pageEls) {
398 String path = pageEl.attributeValue("path");
399
400 if (!context.isPathNotProcessed(path)) {
401 continue;
402 }
403
404 WikiPage page = (WikiPage)context.getZipEntryAsObject(path);
405
406 importPage(context, nodePKs, pageEl, page);
407 }
408
409 for (long nodeId : nodePKs.values()) {
410 WikiCacheUtil.clearCache(nodeId);
411 }
412
413 return null;
414 }
415 catch (Exception e) {
416 throw new PortletDataException(e);
417 }
418 finally {
419 WikiCacheThreadLocal.setClearCache(true);
420 }
421 }
422
423 protected static void exportNode(
424 PortletDataContext context, Element nodesEl, long nodeId)
425 throws PortalException, SystemException {
426
427 if (!context.hasDateRange()) {
428 return;
429 }
430
431 WikiNode node = WikiNodeUtil.findByPrimaryKey(nodeId);
432
433 String path = getNodePath(context, node);
434
435 if (!context.isPathNotProcessed(path)) {
436 return;
437 }
438
439 Element nodeEl = nodesEl.addElement("node");
440
441 nodeEl.addAttribute("path", path);
442
443 node.setUserUuid(node.getUserUuid());
444
445 context.addPermissions(WikiNode.class, node.getNodeId());
446
447 context.addZipEntry(path, node);
448 }
449
450 protected static void exportPage(
451 PortletDataContext context, Element nodesEl, Element pagesEl,
452 WikiPage page)
453 throws PortalException, SystemException {
454
455 if (!context.isWithinDateRange(page.getModifiedDate())) {
456 return;
457 }
458
459 String path = getPagePath(context, page);
460
461 if (context.isPathNotProcessed(path)) {
462 Element pageEl = pagesEl.addElement("page");
463
464 pageEl.addAttribute("path", path);
465
466 page.setUserUuid(page.getUserUuid());
467
468 context.addPermissions(WikiPage.class, page.getResourcePrimKey());
469
470 if (context.getBooleanParameter(_NAMESPACE, "categories") &&
471 page.isHead()) {
472
473 context.addAssetCategories(
474 WikiPage.class, page.getResourcePrimKey());
475 }
476
477 if (context.getBooleanParameter(_NAMESPACE, "comments") &&
478 page.isHead()) {
479
480 context.addComments(WikiPage.class, page.getResourcePrimKey());
481 }
482
483 if (context.getBooleanParameter(_NAMESPACE, "ratings") &&
484 page.isHead()) {
485
486 context.addRatingsEntries(
487 WikiPage.class, page.getResourcePrimKey());
488 }
489
490 if (context.getBooleanParameter(_NAMESPACE, "tags") &&
491 page.isHead()) {
492
493 context.addAssetTags(WikiPage.class, page.getResourcePrimKey());
494 }
495
496 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
497 page.isHead()) {
498
499 for (String attachment : page.getAttachmentsFiles()) {
500 int pos = attachment.lastIndexOf(StringPool.SLASH);
501
502 String name = attachment.substring(pos + 1);
503 String binPath = getPageAttachementBinPath(
504 context, page, name);
505
506 Element attachmentEl = pageEl.addElement("attachment");
507
508 attachmentEl.addAttribute("name", name);
509 attachmentEl.addAttribute("bin-path", binPath);
510
511 byte[] bytes = DLServiceUtil.getFile(
512 context.getCompanyId(), CompanyConstants.SYSTEM,
513 attachment);
514
515 context.addZipEntry(binPath, bytes);
516 }
517
518 page.setAttachmentsDir(page.getAttachmentsDir());
519 }
520
521 context.addZipEntry(path, page);
522 }
523
524 exportNode(context, nodesEl, page.getNodeId());
525 }
526
527 protected static String getNodePath(
528 PortletDataContext context, WikiNode node) {
529
530 StringBundler sb = new StringBundler(4);
531
532 sb.append(context.getPortletPath(PortletKeys.WIKI));
533 sb.append("/nodes/");
534 sb.append(node.getNodeId());
535 sb.append(".xml");
536
537 return sb.toString();
538 }
539
540 protected static String getPageAttachementBinPath(
541 PortletDataContext context, WikiPage page, String attachment) {
542
543 StringBundler sb = new StringBundler(5);
544
545 sb.append(context.getPortletPath(PortletKeys.WIKI));
546 sb.append("/bin/");
547 sb.append(page.getPageId());
548 sb.append(StringPool.SLASH);
549 sb.append(attachment);
550
551 return sb.toString();
552 }
553
554 protected static String getPagePath(
555 PortletDataContext context, WikiPage page) {
556
557 StringBundler sb = new StringBundler(4);
558
559 sb.append(context.getPortletPath(PortletKeys.WIKI));
560 sb.append("/pages/");
561 sb.append(page.getPageId());
562 sb.append(".xml");
563
564 return sb.toString();
565 }
566
567 private static final String _NAMESPACE = "wiki";
568
569 private static Log _log = LogFactoryUtil.getLog(
570 WikiPortletDataHandlerImpl.class);
571
572 private static PortletDataHandlerBoolean _attachments =
573 new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
574
575 private static PortletDataHandlerBoolean _categories =
576 new PortletDataHandlerBoolean(_NAMESPACE, "categories");
577
578 private static PortletDataHandlerBoolean _comments =
579 new PortletDataHandlerBoolean(_NAMESPACE, "comments");
580
581 private static PortletDataHandlerBoolean _nodesAndPages =
582 new PortletDataHandlerBoolean(
583 _NAMESPACE, "wikis-and-pages", true, true);
584
585 private static PortletDataHandlerBoolean _ratings =
586 new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
587
588 private static PortletDataHandlerBoolean _tags =
589 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
590
591 }