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