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