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