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