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