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