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