001
014
015 package com.liferay.portlet.wiki.lar;
016
017 import com.liferay.documentlibrary.service.DLServiceUtil;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
020 import com.liferay.portal.kernel.lar.PortletDataContext;
021 import com.liferay.portal.kernel.lar.PortletDataException;
022 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
023 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
024 import com.liferay.portal.kernel.util.CharPool;
025 import com.liferay.portal.kernel.util.MapUtil;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.workflow.WorkflowConstants;
030 import com.liferay.portal.kernel.xml.Document;
031 import com.liferay.portal.kernel.xml.Element;
032 import com.liferay.portal.kernel.xml.SAXReaderUtil;
033 import com.liferay.portal.model.CompanyConstants;
034 import com.liferay.portal.service.ServiceContext;
035 import com.liferay.portal.util.PortletKeys;
036 import com.liferay.portal.util.PropsUtil;
037 import com.liferay.portlet.wiki.NoSuchNodeException;
038 import com.liferay.portlet.wiki.NoSuchPageException;
039 import com.liferay.portlet.wiki.model.WikiNode;
040 import com.liferay.portlet.wiki.model.WikiPage;
041 import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
042 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
043 import com.liferay.portlet.wiki.service.persistence.WikiNodeUtil;
044 import com.liferay.portlet.wiki.service.persistence.WikiPageUtil;
045 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
046 import com.liferay.portlet.wiki.util.WikiCacheUtil;
047 import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
048
049 import java.io.InputStream;
050
051 import java.util.List;
052 import java.util.Map;
053
054 import javax.portlet.PortletPreferences;
055
056
062 public class WikiPortletDataHandlerImpl extends BasePortletDataHandler {
063
064 public static void exportNode(
065 PortletDataContext context, Element nodesElement,
066 Element pagesElement, WikiNode node)
067 throws Exception {
068
069 if (context.isWithinDateRange(node.getModifiedDate())) {
070 String path = getNodePath(context, node);
071
072 if (context.isPathNotProcessed(path)) {
073 Element nodeElement = nodesElement.addElement("node");
074
075 nodeElement.addAttribute("path", path);
076
077 node.setUserUuid(node.getUserUuid());
078
079 context.addPermissions(WikiNode.class, node.getNodeId());
080
081 context.addZipEntry(path, node);
082 }
083 }
084
085 List<WikiPage> pages = WikiPageUtil.findByN_S(
086 node.getNodeId(), WorkflowConstants.STATUS_APPROVED,
087 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
088 new PageVersionComparator(true));
089
090 for (WikiPage page : pages) {
091 exportPage(context, nodesElement, pagesElement, page);
092 }
093 }
094
095 public static void importNode(PortletDataContext context, WikiNode node)
096 throws Exception {
097
098 long userId = context.getUserId(node.getUserUuid());
099
100 ServiceContext serviceContext = new ServiceContext();
101
102 serviceContext.setAddCommunityPermissions(true);
103 serviceContext.setAddGuestPermissions(true);
104 serviceContext.setCreateDate(node.getCreateDate());
105 serviceContext.setModifiedDate(node.getModifiedDate());
106 serviceContext.setScopeGroupId(context.getScopeGroupId());
107
108 WikiNode importedNode = null;
109
110 if (context.isDataStrategyMirror()) {
111 WikiNode existingNode = WikiNodeUtil.fetchByUUID_G(
112 node.getUuid(), context.getScopeGroupId());
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.getScopeGroupId(), node.getName());
120 }
121 catch (NoSuchNodeException nsne) {
122 }
123 }
124
125 if (existingNode == null) {
126 serviceContext.setUuid(node.getUuid());
127
128 importedNode = WikiNodeLocalServiceUtil.addNode(
129 userId, node.getName(), node.getDescription(),
130 serviceContext);
131 }
132 else {
133 importedNode = WikiNodeLocalServiceUtil.updateNode(
134 existingNode.getNodeId(), node.getName(),
135 node.getDescription(), serviceContext);
136 }
137 }
138 else {
139 String nodeName = PropsUtil.get(PropsKeys.WIKI_INITIAL_NODE_NAME);
140
141 if (node.getName().equals(nodeName)) {
142 try {
143 WikiNodeUtil.removeByG_N(
144 context.getScopeGroupId(), node.getName());
145 }
146 catch (NoSuchNodeException nsne) {
147 }
148 }
149
150 importedNode = WikiNodeLocalServiceUtil.addNode(
151 userId, node.getName(), node.getDescription(), serviceContext);
152 }
153
154 Map<Long, Long> nodePKs =
155 (Map<Long, Long>)context.getNewPrimaryKeysMap(WikiNode.class);
156
157 nodePKs.put(node.getNodeId(), importedNode.getNodeId());
158
159 context.importPermissions(
160 WikiNode.class, node.getNodeId(), importedNode.getNodeId());
161 }
162
163 public static void importPage(
164 PortletDataContext context, Element pageElement, WikiPage page)
165 throws Exception {
166
167 long userId = context.getUserId(page.getUserUuid());
168
169 Map<Long, Long> nodePKs =
170 (Map<Long, Long>)context.getNewPrimaryKeysMap(WikiNode.class);
171
172 long nodeId = MapUtil.getLong(
173 nodePKs, page.getNodeId(), page.getNodeId());
174
175 long[] assetCategoryIds = null;
176 String[] assetTagNames = null;
177
178 if (context.getBooleanParameter(_NAMESPACE, "categories") &&
179 page.isHead()) {
180
181 assetCategoryIds = context.getAssetCategoryIds(
182 WikiPage.class, page.getResourcePrimKey());
183 }
184
185 if (context.getBooleanParameter(_NAMESPACE, "tags") &&
186 page.isHead()) {
187
188 assetTagNames = context.getAssetTagNames(
189 WikiPage.class, page.getResourcePrimKey());
190 }
191
192 ServiceContext serviceContext = new ServiceContext();
193
194 serviceContext.setAddCommunityPermissions(true);
195 serviceContext.setAddGuestPermissions(true);
196 serviceContext.setAssetCategoryIds(assetCategoryIds);
197 serviceContext.setAssetTagNames(assetTagNames);
198 serviceContext.setCreateDate(page.getCreateDate());
199 serviceContext.setModifiedDate(page.getModifiedDate());
200
201 if (page.getStatus() != WorkflowConstants.STATUS_APPROVED) {
202 serviceContext.setWorkflowAction(
203 WorkflowConstants.ACTION_SAVE_DRAFT);
204 }
205
206 WikiPage importedPage = null;
207
208 if (context.isDataStrategyMirror()) {
209 WikiPage existingPage = WikiPageUtil.fetchByUUID_G(
210 page.getUuid(), context.getScopeGroupId());
211
212 if (existingPage == null) {
213 try {
214 existingPage = WikiPageLocalServiceUtil.getPage(
215 nodeId, page.getTitle());
216 }
217 catch (NoSuchPageException nspe) {
218 }
219 }
220
221 if (existingPage == null) {
222 serviceContext.setUuid(page.getUuid());
223
224 importedPage = WikiPageLocalServiceUtil.addPage(
225 userId, nodeId, page.getTitle(), page.getVersion(),
226 page.getContent(), page.getSummary(), true,
227 page.getFormat(), page.getHead(), page.getParentTitle(),
228 page.getRedirectTitle(), serviceContext);
229 }
230 else {
231 importedPage = WikiPageLocalServiceUtil.updatePage(
232 userId, nodeId, existingPage.getTitle(), 0,
233 page.getContent(), page.getSummary(), true,
234 page.getFormat(), page.getParentTitle(),
235 page.getRedirectTitle(), serviceContext);
236 }
237 }
238 else {
239 importedPage = WikiPageLocalServiceUtil.addPage(
240 userId, nodeId, page.getTitle(), page.getVersion(),
241 page.getContent(), page.getSummary(), true, page.getFormat(),
242 page.getHead(), page.getParentTitle(), page.getRedirectTitle(),
243 serviceContext);
244 }
245
246 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
247 page.isHead()) {
248
249 for (Element attachmentElement :
250 pageElement.elements("attachment")) {
251
252 String name = attachmentElement.attributeValue("name");
253 String binPath = attachmentElement.attributeValue("bin-path");
254
255 InputStream inputStream = context.getZipEntryAsInputStream(
256 binPath);
257
258 WikiPageLocalServiceUtil.addPageAttachment(
259 importedPage.getCompanyId(),
260 importedPage.getAttachmentsDir(),
261 importedPage.getModifiedDate(), name, inputStream);
262 }
263 }
264
265 if (page.isHead()) {
266 context.importPermissions(
267 WikiPage.class, page.getResourcePrimKey(),
268 importedPage.getResourcePrimKey());
269 }
270
271 if (context.getBooleanParameter(_NAMESPACE, "comments") &&
272 page.isHead()) {
273
274 context.importComments(
275 WikiPage.class, page.getResourcePrimKey(),
276 importedPage.getResourcePrimKey(), context.getScopeGroupId());
277 }
278
279 if (context.getBooleanParameter(_NAMESPACE, "ratings") &&
280 page.isHead()) {
281
282 context.importRatingsEntries(
283 WikiPage.class, page.getResourcePrimKey(),
284 importedPage.getResourcePrimKey());
285 }
286 }
287
288 public PortletDataHandlerControl[] getExportControls() {
289 return new PortletDataHandlerControl[] {
290 _nodesAndPages, _attachments, _categories, _comments, _ratings,
291 _tags
292 };
293 }
294
295 public PortletDataHandlerControl[] getImportControls() {
296 return new PortletDataHandlerControl[] {
297 _nodesAndPages, _attachments, _categories, _comments, _ratings,
298 _tags
299 };
300 }
301
302 public PortletPreferences importData(
303 PortletDataContext context, String portletId,
304 PortletPreferences preferences, String data)
305 throws PortletDataException {
306
307 WikiCacheThreadLocal.setClearCache(false);
308
309 try {
310 return super.importData(context, portletId, preferences, data);
311 }
312 finally {
313 WikiCacheThreadLocal.setClearCache(true);
314 }
315 }
316
317 protected static void exportNode(
318 PortletDataContext context, Element nodesElement, long nodeId)
319 throws Exception {
320
321 if (!context.hasDateRange()) {
322 return;
323 }
324
325 WikiNode node = WikiNodeUtil.findByPrimaryKey(nodeId);
326
327 String path = getNodePath(context, node);
328
329 if (!context.isPathNotProcessed(path)) {
330 return;
331 }
332
333 Element nodeElement = nodesElement.addElement("node");
334
335 nodeElement.addAttribute("path", path);
336
337 node.setUserUuid(node.getUserUuid());
338
339 context.addPermissions(WikiNode.class, node.getNodeId());
340
341 context.addZipEntry(path, node);
342 }
343
344 protected static void exportPage(
345 PortletDataContext context, Element nodesElement,
346 Element pagesElement, WikiPage page)
347 throws Exception {
348
349 if (!context.isWithinDateRange(page.getModifiedDate())) {
350 return;
351 }
352
353 String path = getPagePath(context, page);
354
355 if (context.isPathNotProcessed(path)) {
356 Element pageElement = pagesElement.addElement("page");
357
358 pageElement.addAttribute("path", path);
359
360 page.setUserUuid(page.getUserUuid());
361
362 context.addPermissions(WikiPage.class, page.getResourcePrimKey());
363
364 if (context.getBooleanParameter(_NAMESPACE, "categories") &&
365 page.isHead()) {
366
367 context.addAssetCategories(
368 WikiPage.class, page.getResourcePrimKey());
369 }
370
371 if (context.getBooleanParameter(_NAMESPACE, "comments") &&
372 page.isHead()) {
373
374 context.addComments(WikiPage.class, page.getResourcePrimKey());
375 }
376
377 if (context.getBooleanParameter(_NAMESPACE, "ratings") &&
378 page.isHead()) {
379
380 context.addRatingsEntries(
381 WikiPage.class, page.getResourcePrimKey());
382 }
383
384 if (context.getBooleanParameter(_NAMESPACE, "tags") &&
385 page.isHead()) {
386
387 context.addAssetTags(WikiPage.class, page.getResourcePrimKey());
388 }
389
390 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
391 page.isHead()) {
392
393 for (String attachment : page.getAttachmentsFiles()) {
394 int pos = attachment.lastIndexOf(CharPool.SLASH);
395
396 String name = attachment.substring(pos + 1);
397 String binPath = getPageAttachementBinPath(
398 context, page, name);
399
400 Element attachmentEl = pageElement.addElement("attachment");
401
402 attachmentEl.addAttribute("name", name);
403 attachmentEl.addAttribute("bin-path", binPath);
404
405 byte[] bytes = DLServiceUtil.getFile(
406 context.getCompanyId(), CompanyConstants.SYSTEM,
407 attachment);
408
409 context.addZipEntry(binPath, bytes);
410 }
411
412 page.setAttachmentsDir(page.getAttachmentsDir());
413 }
414
415 context.addZipEntry(path, page);
416 }
417
418 exportNode(context, nodesElement, page.getNodeId());
419 }
420
421 protected static String getNodePath(
422 PortletDataContext context, WikiNode node) {
423
424 StringBundler sb = new StringBundler(4);
425
426 sb.append(context.getPortletPath(PortletKeys.WIKI));
427 sb.append("/nodes/");
428 sb.append(node.getNodeId());
429 sb.append(".xml");
430
431 return sb.toString();
432 }
433
434 protected static String getPageAttachementBinPath(
435 PortletDataContext context, WikiPage page, String attachment) {
436
437 StringBundler sb = new StringBundler(5);
438
439 sb.append(context.getPortletPath(PortletKeys.WIKI));
440 sb.append("/bin/");
441 sb.append(page.getPageId());
442 sb.append(StringPool.SLASH);
443 sb.append(attachment);
444
445 return sb.toString();
446 }
447
448 protected static String getPagePath(
449 PortletDataContext context, WikiPage page) {
450
451 StringBundler sb = new StringBundler(4);
452
453 sb.append(context.getPortletPath(PortletKeys.WIKI));
454 sb.append("/pages/");
455 sb.append(page.getPageId());
456 sb.append(".xml");
457
458 return sb.toString();
459 }
460
461 protected PortletPreferences doDeleteData(
462 PortletDataContext context, String portletId,
463 PortletPreferences preferences)
464 throws Exception {
465
466 if (!context.addPrimaryKey(
467 WikiPortletDataHandlerImpl.class, "deleteData")) {
468
469 WikiNodeLocalServiceUtil.deleteNodes(context.getScopeGroupId());
470 }
471
472 return null;
473 }
474
475 protected String doExportData(
476 PortletDataContext context, String portletId,
477 PortletPreferences preferences)
478 throws Exception {
479
480 context.addPermissions(
481 "com.liferay.portlet.wiki", context.getScopeGroupId());
482
483 Document document = SAXReaderUtil.createDocument();
484
485 Element rootElement = document.addElement("wiki-data");
486
487 rootElement.addAttribute(
488 "group-id", String.valueOf(context.getScopeGroupId()));
489
490 Element nodesElement = rootElement.addElement("nodes");
491 Element pagesElement = rootElement.addElement("pages");
492
493 List<WikiNode> nodes = WikiNodeUtil.findByGroupId(
494 context.getScopeGroupId());
495
496 for (WikiNode node : nodes) {
497 exportNode(context, nodesElement, pagesElement, node);
498 }
499
500 return document.formattedString();
501 }
502
503 protected PortletPreferences doImportData(
504 PortletDataContext context, String portletId,
505 PortletPreferences preferences, String data)
506 throws Exception {
507
508 context.importPermissions(
509 "com.liferay.portlet.wiki", context.getSourceGroupId(),
510 context.getScopeGroupId());
511
512 Document document = SAXReaderUtil.read(data);
513
514 Element rootElement = document.getRootElement();
515
516 Element nodesElement = rootElement.element("nodes");
517
518 for (Element nodeElement : nodesElement.elements("node")) {
519 String path = nodeElement.attributeValue("path");
520
521 if (!context.isPathNotProcessed(path)) {
522 continue;
523 }
524
525 WikiNode node = (WikiNode)context.getZipEntryAsObject(path);
526
527 importNode(context, node);
528 }
529
530 Element pagesElement = rootElement.element("pages");
531
532 for (Element pageElement : pagesElement.elements("page")) {
533 String path = pageElement.attributeValue("path");
534
535 if (!context.isPathNotProcessed(path)) {
536 continue;
537 }
538
539 WikiPage page = (WikiPage)context.getZipEntryAsObject(path);
540
541 importPage(context, pageElement, page);
542 }
543
544 Map<Long, Long> nodePKs =
545 (Map<Long, Long>)context.getNewPrimaryKeysMap(WikiNode.class);
546
547 for (long nodeId : nodePKs.values()) {
548 WikiCacheUtil.clearCache(nodeId);
549 }
550
551 return null;
552 }
553
554 private static final String _NAMESPACE = "wiki";
555
556 private static PortletDataHandlerBoolean _attachments =
557 new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
558
559 private static PortletDataHandlerBoolean _categories =
560 new PortletDataHandlerBoolean(_NAMESPACE, "categories");
561
562 private static PortletDataHandlerBoolean _comments =
563 new PortletDataHandlerBoolean(_NAMESPACE, "comments");
564
565 private static PortletDataHandlerBoolean _nodesAndPages =
566 new PortletDataHandlerBoolean(
567 _NAMESPACE, "wikis-and-pages", true, true);
568
569 private static PortletDataHandlerBoolean _ratings =
570 new PortletDataHandlerBoolean(_NAMESPACE, "ratings");
571
572 private static PortletDataHandlerBoolean _tags =
573 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
574
575 }