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