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.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 importedNode = null;
111
112 if (context.getDataStrategy().equals(
113 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
114
115 WikiNode 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 importedNode = WikiNodeLocalServiceUtil.addNode(
131 node.getUuid(), userId, node.getName(),
132 node.getDescription(), serviceContext);
133 }
134 else {
135 importedNode = 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 importedNode = WikiNodeLocalServiceUtil.addNode(
153 userId, node.getName(), node.getDescription(), serviceContext);
154 }
155
156 nodePKs.put(node.getNodeId(), importedNode.getNodeId());
157
158 context.importPermissions(
159 WikiNode.class, node.getNodeId(), importedNode.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 long[] assetCategoryIds = null;
172 String[] assetTagNames = null;
173
174 if (context.getBooleanParameter(_NAMESPACE, "categories")) {
175 assetCategoryIds = context.getAssetCategoryIds(
176 WikiPage.class, page.getResourcePrimKey());
177 }
178
179 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
180 assetTagNames = context.getAssetTagNames(
181 WikiPage.class, page.getResourcePrimKey());
182 }
183
184 ServiceContext serviceContext = new ServiceContext();
185
186 serviceContext.setAddCommunityPermissions(true);
187 serviceContext.setAddGuestPermissions(true);
188 serviceContext.setAssetCategoryIds(assetCategoryIds);
189 serviceContext.setAssetTagNames(assetTagNames);
190 serviceContext.setCreateDate(page.getCreateDate());
191 serviceContext.setModifiedDate(page.getModifiedDate());
192
193 WikiPage importedPage = null;
194
195 try {
196 WikiNodeUtil.findByPrimaryKey(nodeId);
197
198 if (context.getDataStrategy().equals(
199 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
200
201 WikiPage existingPage = WikiPageUtil.fetchByUUID_G(
202 page.getUuid(), context.getGroupId());
203
204 if (existingPage == null) {
205 try {
206 existingPage = WikiPageLocalServiceUtil.getPage(
207 nodeId, page.getTitle());
208 }
209 catch (NoSuchPageException nspe) {
210 }
211 }
212
213 if (existingPage == null) {
214 importedPage = WikiPageLocalServiceUtil.addPage(
215 page.getUuid(), userId, nodeId, page.getTitle(),
216 page.getVersion(), page.getContent(), page.getSummary(),
217 true, page.getFormat(), page.getHead(),
218 page.getParentTitle(), page.getRedirectTitle(),
219 serviceContext);
220 }
221 else {
222 importedPage = WikiPageLocalServiceUtil.updatePage(
223 userId, nodeId, existingPage.getTitle(), 0,
224 page.getContent(), page.getSummary(), true,
225 page.getFormat(), page.getParentTitle(),
226 page.getRedirectTitle(), serviceContext);
227 }
228 }
229 else {
230 importedPage = WikiPageLocalServiceUtil.addPage(
231 null, userId, nodeId, page.getTitle(), page.getVersion(),
232 page.getContent(), page.getSummary(), true,
233 page.getFormat(), page.getHead(), page.getParentTitle(),
234 page.getRedirectTitle(), serviceContext);
235 }
236
237 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
238 page.isHead()) {
239
240 List<Element> attachmentEls = pageEl.elements("attachment");
241
242 List<ObjectValuePair<String, byte[]>> files =
243 new ArrayList<ObjectValuePair<String, byte[]>>();
244
245 for (Element attachmentEl : attachmentEls) {
246 String name = attachmentEl.attributeValue("name");
247 String binPath = attachmentEl.attributeValue("bin-path");
248
249 byte[] bytes = context.getZipEntryAsByteArray(binPath);
250
251 files.add(new ObjectValuePair<String, byte[]>(name, bytes));
252 }
253
254 if (files.size() > 0) {
255 WikiPageLocalServiceUtil.addPageAttachments(
256 nodeId, page.getTitle(), files);
257 }
258 }
259
260 context.importPermissions(
261 WikiPage.class, page.getResourcePrimKey(),
262 importedPage.getResourcePrimKey());
263
264 if (context.getBooleanParameter(_NAMESPACE, "comments") &&
265 page.isHead()) {
266
267 context.importComments(
268 WikiPage.class, page.getResourcePrimKey(),
269 importedPage.getResourcePrimKey(), context.getGroupId());
270 }
271
272 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
273 context.importRatingsEntries(
274 WikiPage.class, page.getResourcePrimKey(),
275 importedPage.getResourcePrimKey());
276 }
277 }
278 catch (NoSuchNodeException nsne) {
279 _log.error("Could not find the node for page " + page.getPageId());
280 }
281 }
282
283 public PortletPreferences deleteData(
284 PortletDataContext context, String portletId,
285 PortletPreferences preferences)
286 throws PortletDataException {
287
288 try {
289 if (!context.addPrimaryKey(
290 WikiPortletDataHandlerImpl.class, "deleteData")) {
291
292 WikiNodeLocalServiceUtil.deleteNodes(context.getGroupId());
293 }
294
295 return null;
296 }
297 catch (Exception e) {
298 throw new PortletDataException(e);
299 }
300 }
301
302 public String exportData(
303 PortletDataContext context, String portletId,
304 PortletPreferences preferences)
305 throws PortletDataException {
306
307 try {
308 context.addPermissions(
309 "com.liferay.portlet.wiki", context.getGroupId());
310
311 Document doc = SAXReaderUtil.createDocument();
312
313 Element root = doc.addElement("wiki-data");
314
315 root.addAttribute("group-id", String.valueOf(context.getGroupId()));
316
317 Element nodesEl = root.addElement("nodes");
318 Element pagesEl = root.addElement("pages");
319
320 List<WikiNode> nodes = WikiNodeUtil.findByGroupId(
321 context.getGroupId());
322
323 for (WikiNode node : nodes) {
324 exportNode(context, nodesEl, pagesEl, node);
325 }
326
327 return doc.formattedString();
328 }
329 catch (Exception e) {
330 throw new PortletDataException(e);
331 }
332 }
333
334 public PortletDataHandlerControl[] getExportControls() {
335 return new PortletDataHandlerControl[] {
336 _nodesAndPages, _attachments, _categories, _comments, _tags
337 };
338 }
339
340 public PortletDataHandlerControl[] getImportControls() {
341 return new PortletDataHandlerControl[] {
342 _nodesAndPages, _attachments, _categories, _comments, _tags
343 };
344 }
345
346 public PortletPreferences importData(
347 PortletDataContext context, String portletId,
348 PortletPreferences preferences, String data)
349 throws PortletDataException {
350
351 try {
352 context.importPermissions(
353 "com.liferay.portlet.wiki", context.getSourceGroupId(),
354 context.getGroupId());
355
356 Document doc = SAXReaderUtil.read(data);
357
358 Element root = doc.getRootElement();
359
360 List<Element> nodeEls = root.element("nodes").elements("node");
361
362 Map<Long, Long> nodePKs =
363 (Map<Long, Long>)context.getNewPrimaryKeysMap(WikiNode.class);
364
365 for (Element nodeEl : nodeEls) {
366 String path = nodeEl.attributeValue("path");
367
368 if (!context.isPathNotProcessed(path)) {
369 continue;
370 }
371
372 WikiNode node = (WikiNode)context.getZipEntryAsObject(path);
373
374 importNode(context, nodePKs, node);
375 }
376
377 List<Element> pageEls = root.element("pages").elements("page");
378
379 for (Element pageEl : pageEls) {
380 String path = pageEl.attributeValue("path");
381
382 if (!context.isPathNotProcessed(path)) {
383 continue;
384 }
385
386 WikiPage page = (WikiPage)context.getZipEntryAsObject(path);
387
388 importPage(context, nodePKs, pageEl, page);
389 }
390
391 return null;
392 }
393 catch (Exception e) {
394 throw new PortletDataException(e);
395 }
396 }
397
398 protected static void exportNode(
399 PortletDataContext context, Element nodesEl, long nodeId)
400 throws PortalException, SystemException {
401
402 if (!context.hasDateRange()) {
403 return;
404 }
405
406 WikiNode node = WikiNodeUtil.findByPrimaryKey(nodeId);
407
408 String path = getNodePath(context, node);
409
410 if (!context.isPathNotProcessed(path)) {
411 return;
412 }
413
414 Element nodeEl = nodesEl.addElement("node");
415
416 nodeEl.addAttribute("path", path);
417
418 node.setUserUuid(node.getUserUuid());
419
420 context.addPermissions(WikiNode.class, node.getNodeId());
421
422 context.addZipEntry(path, node);
423 }
424
425 protected static void exportPage(
426 PortletDataContext context, Element nodesEl, Element pagesEl,
427 WikiPage page)
428 throws PortalException, SystemException {
429
430 if (!context.isWithinDateRange(page.getModifiedDate())) {
431 return;
432 }
433
434 String path = getPagePath(context, page);
435
436 if (context.isPathNotProcessed(path)) {
437 Element pageEl = pagesEl.addElement("page");
438
439 pageEl.addAttribute("path", path);
440
441 page.setUserUuid(page.getUserUuid());
442
443 context.addPermissions(WikiPage.class, page.getResourcePrimKey());
444
445 if (context.getBooleanParameter(_NAMESPACE, "categories")) {
446 context.addAssetCategories(
447 WikiPage.class, page.getResourcePrimKey());
448 }
449
450 if (context.getBooleanParameter(_NAMESPACE, "comments")) {
451 context.addComments(WikiPage.class, page.getResourcePrimKey());
452 }
453
454 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
455 context.addAssetTags(WikiPage.class, page.getResourcePrimKey());
456 }
457
458 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
459 page.isHead()) {
460
461 for (String attachment : page.getAttachmentsFiles()) {
462 int pos = attachment.lastIndexOf(StringPool.SLASH);
463
464 String name = attachment.substring(pos + 1);
465 String binPath = getPageAttachementBinPath(
466 context, page, name);
467
468 Element attachmentEl = pageEl.addElement("attachment");
469
470 attachmentEl.addAttribute("name", name);
471 attachmentEl.addAttribute("bin-path", binPath);
472
473 byte[] bytes = DLServiceUtil.getFile(
474 context.getCompanyId(), CompanyConstants.SYSTEM,
475 attachment);
476
477 context.addZipEntry(binPath, bytes);
478 }
479
480 page.setAttachmentsDir(page.getAttachmentsDir());
481 }
482
483 context.addZipEntry(path, page);
484 }
485
486 exportNode(context, nodesEl, page.getNodeId());
487 }
488
489 protected static String getNodePath(
490 PortletDataContext context, WikiNode node) {
491
492 StringBundler sb = new StringBundler(4);
493
494 sb.append(context.getPortletPath(PortletKeys.WIKI));
495 sb.append("/nodes/");
496 sb.append(node.getNodeId());
497 sb.append(".xml");
498
499 return sb.toString();
500 }
501
502 protected static String getPageAttachementBinPath(
503 PortletDataContext context, WikiPage page, String attachment) {
504
505 StringBundler sb = new StringBundler(5);
506
507 sb.append(context.getPortletPath(PortletKeys.WIKI));
508 sb.append("/bin/");
509 sb.append(page.getPageId());
510 sb.append(StringPool.SLASH);
511 sb.append(attachment);
512
513 return sb.toString();
514 }
515
516 protected static String getPagePath(
517 PortletDataContext context, WikiPage page) {
518
519 StringBundler sb = new StringBundler(4);
520
521 sb.append(context.getPortletPath(PortletKeys.WIKI));
522 sb.append("/pages/");
523 sb.append(page.getPageId());
524 sb.append(".xml");
525
526 return sb.toString();
527 }
528
529 private static final String _NAMESPACE = "wiki";
530
531 private static final PortletDataHandlerBoolean _nodesAndPages =
532 new PortletDataHandlerBoolean(
533 _NAMESPACE, "wikis-and-pages", true, true);
534
535 private static final PortletDataHandlerBoolean _attachments =
536 new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
537
538 private static final PortletDataHandlerBoolean _categories =
539 new PortletDataHandlerBoolean(_NAMESPACE, "categories");
540
541 private static final PortletDataHandlerBoolean _comments =
542 new PortletDataHandlerBoolean(_NAMESPACE, "comments");
543
544 private static final PortletDataHandlerBoolean _tags =
545 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
546
547 private static Log _log = LogFactoryUtil.getLog(
548 WikiPortletDataHandlerImpl.class);
549
550 }