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