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