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