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