1
22
23 package com.liferay.portlet.wiki.lar;
24
25 import com.liferay.documentlibrary.service.DLServiceUtil;
26 import com.liferay.portal.PortalException;
27 import com.liferay.portal.SystemException;
28 import com.liferay.portal.kernel.dao.orm.QueryUtil;
29 import com.liferay.portal.kernel.log.Log;
30 import com.liferay.portal.kernel.log.LogFactoryUtil;
31 import com.liferay.portal.kernel.util.MapUtil;
32 import com.liferay.portal.kernel.util.ObjectValuePair;
33 import com.liferay.portal.kernel.util.PropsKeys;
34 import com.liferay.portal.kernel.util.StringPool;
35 import com.liferay.portal.kernel.xml.Document;
36 import com.liferay.portal.kernel.xml.Element;
37 import com.liferay.portal.kernel.xml.SAXReaderUtil;
38 import com.liferay.portal.lar.BasePortletDataHandler;
39 import com.liferay.portal.lar.PortletDataContext;
40 import com.liferay.portal.lar.PortletDataException;
41 import com.liferay.portal.lar.PortletDataHandlerBoolean;
42 import com.liferay.portal.lar.PortletDataHandlerControl;
43 import com.liferay.portal.lar.PortletDataHandlerKeys;
44 import com.liferay.portal.model.CompanyConstants;
45 import com.liferay.portal.service.ServiceContext;
46 import com.liferay.portal.util.PortletKeys;
47 import com.liferay.portal.util.PropsUtil;
48 import com.liferay.portlet.wiki.NoSuchNodeException;
49 import com.liferay.portlet.wiki.NoSuchPageException;
50 import com.liferay.portlet.wiki.model.WikiNode;
51 import com.liferay.portlet.wiki.model.WikiPage;
52 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
53 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
54 import com.liferay.portlet.wiki.service.persistence.WikiNodeUtil;
55 import com.liferay.portlet.wiki.service.persistence.WikiPageUtil;
56 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
57
58 import java.util.ArrayList;
59 import java.util.List;
60 import java.util.Map;
61
62 import javax.portlet.PortletPreferences;
63
64
71 public class WikiPortletDataHandlerImpl extends BasePortletDataHandler {
72
73 public static void exportNode(
74 PortletDataContext context, Element nodesEl, Element pagesEl,
75 WikiNode node)
76 throws PortalException, SystemException {
77
78 if (context.isWithinDateRange(node.getModifiedDate())) {
79 String path = getNodePath(context, node);
80
81 if (context.isPathNotProcessed(path)) {
82 Element nodeEl = nodesEl.addElement("node");
83
84 nodeEl.addAttribute("path", path);
85
86 node.setUserUuid(node.getUserUuid());
87
88 context.addZipEntry(path, node);
89 }
90 }
91
92 List<WikiPage> nodePages = WikiPageUtil.findByNodeId(
93 node.getNodeId(), QueryUtil.ALL_POS, QueryUtil.ALL_POS,
94 new PageCreateDateComparator(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.setScopeGroupId(context.getGroupId());
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.getGroupId());
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.getGroupId(), 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());
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.getGroupId(), 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
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
191 WikiPage existingPage = null;
192
193 try {
194 WikiNodeUtil.findByPrimaryKey(nodeId);
195
196 if (context.getDataStrategy().equals(
197 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
198
199 try {
200 existingPage = WikiPageUtil.findByUUID_G(
201 page.getUuid(), context.getGroupId());
202 }
203 catch (NoSuchPageException nspe) {
204 }
205
206 if (existingPage == null) {
207 try {
208 existingPage = WikiPageLocalServiceUtil.getPage(
209 nodeId, page.getTitle());
210 }
211 catch (NoSuchPageException nspe) {
212 }
213 }
214
215 if (existingPage != null) {
216 existingPage = WikiPageLocalServiceUtil.updatePage(
217 userId, nodeId, existingPage.getTitle(), 0,
218 page.getContent(), page.getSummary(), true,
219 page.getFormat(), page.getParentTitle(),
220 page.getRedirectTitle(), serviceContext);
221 }
222 else {
223 existingPage = WikiPageLocalServiceUtil.addPage(
224 page.getUuid(), userId, nodeId, page.getTitle(),
225 page.getVersion(), page.getContent(), page.getSummary(),
226 true, page.getFormat(), page.getHead(),
227 page.getParentTitle(), page.getRedirectTitle(),
228 serviceContext);
229 }
230 }
231 else {
232 existingPage = WikiPageLocalServiceUtil.addPage(
233 null, userId, nodeId, page.getTitle(), page.getVersion(),
234 page.getContent(), page.getSummary(), true,
235 page.getFormat(), page.getHead(), page.getParentTitle(),
236 page.getRedirectTitle(), serviceContext);
237 }
238
239 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
240 page.isHead()) {
241
242 List<Element> attachmentEls = pageEl.elements("attachment");
243
244 List<ObjectValuePair<String, byte[]>> files =
245 new ArrayList<ObjectValuePair<String, byte[]>>();
246
247 for (Element attachmentEl : attachmentEls) {
248 String name = attachmentEl.attributeValue("name");
249 String binPath = attachmentEl.attributeValue("bin-path");
250
251 byte[] bytes = context.getZipEntryAsByteArray(binPath);
252
253 files.add(new ObjectValuePair<String, byte[]>(name, bytes));
254 }
255
256 if (files.size() > 0) {
257 WikiPageLocalServiceUtil.addPageAttachments(
258 nodeId, page.getTitle(), files);
259 }
260 }
261
262 if (context.getBooleanParameter(_NAMESPACE, "comments") &&
263 page.isHead()) {
264
265 context.importComments(
266 WikiPage.class, page.getResourcePrimKey(),
267 existingPage.getResourcePrimKey(), context.getGroupId());
268 }
269
270 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
271 context.importRatingsEntries(
272 WikiPage.class, page.getResourcePrimKey(),
273 existingPage.getResourcePrimKey());
274 }
275 }
276 catch (NoSuchNodeException nsne) {
277 _log.error("Could not find the node for page " + page.getPageId());
278 }
279 }
280
281 public PortletPreferences deleteData(
282 PortletDataContext context, String portletId,
283 PortletPreferences preferences)
284 throws PortletDataException {
285
286 try {
287 if (!context.addPrimaryKey(
288 WikiPortletDataHandlerImpl.class, "deleteData")) {
289
290 WikiNodeLocalServiceUtil.deleteNodes(context.getGroupId());
291 }
292
293 return null;
294 }
295 catch (Exception e) {
296 throw new PortletDataException(e);
297 }
298 }
299
300 public String exportData(
301 PortletDataContext context, String portletId,
302 PortletPreferences preferences)
303 throws PortletDataException {
304
305 try {
306 Document doc = SAXReaderUtil.createDocument();
307
308 Element root = doc.addElement("wiki-data");
309
310 root.addAttribute("group-id", String.valueOf(context.getGroupId()));
311
312 Element nodesEl = root.addElement("nodes");
313 Element pagesEl = root.addElement("pages");
314
315 List<WikiNode> nodes = WikiNodeUtil.findByGroupId(
316 context.getGroupId());
317
318 for (WikiNode node : nodes) {
319 exportNode(context, nodesEl, pagesEl, node);
320 }
321
322 return doc.formattedString();
323 }
324 catch (Exception e) {
325 throw new PortletDataException(e);
326 }
327 }
328
329 public PortletDataHandlerControl[] getExportControls() {
330 return new PortletDataHandlerControl[] {
331 _nodesAndPages, _attachments, _categories, _comments, _tags
332 };
333 }
334
335 public PortletDataHandlerControl[] getImportControls() {
336 return new PortletDataHandlerControl[] {
337 _nodesAndPages, _attachments, _categories, _comments, _tags
338 };
339 }
340
341 public PortletPreferences importData(
342 PortletDataContext context, String portletId,
343 PortletPreferences preferences, String data)
344 throws PortletDataException {
345
346 try {
347 Document doc = SAXReaderUtil.read(data);
348
349 Element root = doc.getRootElement();
350
351 List<Element> nodeEls = root.element("nodes").elements("node");
352
353 Map<Long, Long> nodePKs =
354 (Map<Long, Long>)context.getNewPrimaryKeysMap(WikiNode.class);
355
356 for (Element nodeEl : nodeEls) {
357 String path = nodeEl.attributeValue("path");
358
359 if (!context.isPathNotProcessed(path)) {
360 continue;
361 }
362
363 WikiNode node = (WikiNode)context.getZipEntryAsObject(path);
364
365 importNode(context, nodePKs, node);
366 }
367
368 List<Element> pageEls = root.element("pages").elements("page");
369
370 for (Element pageEl : pageEls) {
371 String path = pageEl.attributeValue("path");
372
373 if (!context.isPathNotProcessed(path)) {
374 continue;
375 }
376
377 WikiPage page = (WikiPage)context.getZipEntryAsObject(path);
378
379 importPage(context, nodePKs, pageEl, page);
380 }
381
382 return null;
383 }
384 catch (Exception e) {
385 throw new PortletDataException(e);
386 }
387 }
388
389 protected static void exportNode(
390 PortletDataContext context, Element nodesEl, long nodeId)
391 throws PortalException, SystemException {
392
393 if (!context.hasDateRange()) {
394 return;
395 }
396
397 WikiNode node = WikiNodeUtil.findByPrimaryKey(nodeId);
398
399 String path = getNodePath(context, node);
400
401 if (!context.isPathNotProcessed(path)) {
402 return;
403 }
404
405 Element nodeEl = nodesEl.addElement("node");
406
407 nodeEl.addAttribute("path", path);
408
409 node.setUserUuid(node.getUserUuid());
410
411 context.addZipEntry(path, node);
412 }
413
414 protected static void exportPage(
415 PortletDataContext context, Element nodesEl, Element pagesEl,
416 WikiPage page)
417 throws PortalException, SystemException {
418
419 if (!context.isWithinDateRange(page.getModifiedDate())) {
420 return;
421 }
422
423 String path = getPagePath(context, page);
424
425 if (context.isPathNotProcessed(path)) {
426 Element pageEl = pagesEl.addElement("page");
427
428 pageEl.addAttribute("path", path);
429
430 page.setUserUuid(page.getUserUuid());
431
432 if (context.getBooleanParameter(_NAMESPACE, "categories")) {
433 context.addTagsCategories(
434 WikiPage.class, page.getResourcePrimKey());
435 }
436
437 if (context.getBooleanParameter(_NAMESPACE, "comments")) {
438 context.addComments(WikiPage.class, page.getResourcePrimKey());
439 }
440
441 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
442 context.addTagsEntries(
443 WikiPage.class, page.getResourcePrimKey());
444 }
445
446 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
447 page.isHead()) {
448
449 for (String attachment : page.getAttachmentsFiles()) {
450 int pos = attachment.lastIndexOf(StringPool.SLASH);
451
452 String name = attachment.substring(pos + 1);
453 String binPath = getPageAttachementBinPath(
454 context, page, name);
455
456 Element attachmentEl = pageEl.addElement("attachment");
457
458 attachmentEl.addAttribute("name", name);
459 attachmentEl.addAttribute("bin-path", binPath);
460
461 byte[] bytes = DLServiceUtil.getFile(
462 context.getCompanyId(), CompanyConstants.SYSTEM,
463 attachment);
464
465 context.addZipEntry(binPath, bytes);
466 }
467
468 page.setAttachmentsDir(page.getAttachmentsDir());
469 }
470
471 context.addZipEntry(path, page);
472 }
473
474 exportNode(context, nodesEl, page.getNodeId());
475 }
476
477 protected static String getNodePath(
478 PortletDataContext context, WikiNode node) {
479
480 StringBuilder sb = new StringBuilder();
481
482 sb.append(context.getPortletPath(PortletKeys.WIKI));
483 sb.append("/nodes/");
484 sb.append(node.getNodeId());
485 sb.append(".xml");
486
487 return sb.toString();
488 }
489
490 protected static String getPageAttachementBinPath(
491 PortletDataContext context, WikiPage page, String attachment) {
492
493 StringBuilder sb = new StringBuilder();
494
495 sb.append(context.getPortletPath(PortletKeys.WIKI));
496 sb.append("/bin/");
497 sb.append(page.getPageId());
498 sb.append(StringPool.SLASH);
499 sb.append(attachment);
500
501 return sb.toString();
502 }
503
504 protected static String getPagePath(
505 PortletDataContext context, WikiPage page) {
506
507 StringBuilder sb = new StringBuilder();
508
509 sb.append(context.getPortletPath(PortletKeys.WIKI));
510 sb.append("/pages/");
511 sb.append(page.getPageId());
512 sb.append(".xml");
513
514 return sb.toString();
515 }
516
517 private static final String _NAMESPACE = "wiki";
518
519 private static final PortletDataHandlerBoolean _nodesAndPages =
520 new PortletDataHandlerBoolean(
521 _NAMESPACE, "wikis-and-pages", true, true);
522
523 private static final PortletDataHandlerBoolean _attachments =
524 new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
525
526 private static final PortletDataHandlerBoolean _categories =
527 new PortletDataHandlerBoolean(_NAMESPACE, "categories");
528
529 private static final PortletDataHandlerBoolean _comments =
530 new PortletDataHandlerBoolean(_NAMESPACE, "comments");
531
532 private static final PortletDataHandlerBoolean _tags =
533 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
534
535 private static Log _log =
536 LogFactoryUtil.getLog(WikiPortletDataHandlerImpl.class);
537
538 }