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