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.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 import com.liferay.util.MapUtil;
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 import org.apache.commons.logging.Log;
64 import org.apache.commons.logging.LogFactory;
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(node.getNodeId());
206
207 for (WikiPage page : nodePages) {
208 exportPage(context, nodesEl, pagesEl, page);
209 }
210 }
211
212 protected void exportNode(
213 PortletDataContext context, Element nodesEl, long nodeId)
214 throws PortalException, SystemException {
215
216 if (!context.hasDateRange()) {
217 return;
218 }
219
220 WikiNode node = WikiNodeUtil.findByPrimaryKey(nodeId);
221
222 String path = getNodePath(context, node);
223
224 if (!context.isPathNotProcessed(path)) {
225 return;
226 }
227
228 Element nodeEl = nodesEl.addElement("node");
229
230 nodeEl.addAttribute("path", path);
231
232 node.setUserUuid(node.getUserUuid());
233
234 context.addZipEntry(path, node);
235 }
236
237 protected void exportPage(
238 PortletDataContext context, Element nodesEl, Element pagesEl,
239 WikiPage page)
240 throws PortalException, SystemException {
241
242 if (!context.isWithinDateRange(page.getModifiedDate())) {
243 return;
244 }
245
246 String path = getPagePath(context, page);
247
248 if (context.isPathNotProcessed(path)) {
249 Element pageEl = pagesEl.addElement("page");
250
251 pageEl.addAttribute("path", path);
252
253 page.setUserUuid(page.getUserUuid());
254
255 if (context.getBooleanParameter(_NAMESPACE, "comments")) {
256 context.addComments(WikiPage.class, page.getResourcePrimKey());
257 }
258
259 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
260 context.addTagsEntries(
261 WikiPage.class, page.getResourcePrimKey());
262 }
263
264 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
265 page.isHead()) {
266
267 for (String attachment : page.getAttachmentsFiles()) {
268 int pos = attachment.lastIndexOf(StringPool.SLASH);
269
270 String name = attachment.substring(pos + 1);
271 String binPath = getPageAttachementBinPath(
272 context, page, name);
273
274 Element attachmentEl = pageEl.addElement("attachment");
275
276 attachmentEl.addAttribute("name", name);
277 attachmentEl.addAttribute("bin-path", binPath);
278
279 try {
280 byte[] bytes = DLServiceUtil.getFile(
281 context.getCompanyId(), CompanyConstants.SYSTEM,
282 attachment);
283
284 context.addZipEntry(binPath, bytes);
285 }
286 catch (RemoteException re) {
287 }
288 }
289
290 page.setAttachmentsDir(page.getAttachmentsDir());
291 }
292
293 context.addZipEntry(path, page);
294 }
295
296 exportNode(context, nodesEl, page.getNodeId());
297 }
298
299 protected void importNode(
300 PortletDataContext context, Map<Long, Long> nodePKs, WikiNode node)
301 throws Exception {
302
303 long userId = context.getUserId(node.getUserUuid());
304 long plid = context.getPlid();
305
306 boolean addCommunityPermissions = true;
307 boolean addGuestPermissions = true;
308
309 WikiNode existingNode = null;
310
311 if (context.getDataStrategy().equals(
312 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
313
314 existingNode = WikiNodeUtil.fetchByUUID_G(
315 node.getUuid(), context.getGroupId());
316
317 String nodeName = PropsUtil.get(PropsKeys.WIKI_INITIAL_NODE_NAME);
318
319 if (existingNode == null && node.getName().equals(nodeName)) {
320 try {
321 WikiNodeUtil.removeByG_N(
322 context.getGroupId(), node.getName());
323 }
324 catch (NoSuchNodeException nsne) {
325 }
326 }
327
328 if (existingNode == null) {
329 existingNode = WikiNodeLocalServiceUtil.addNode(
330 node.getUuid(), userId, plid, node.getName(),
331 node.getDescription(), addCommunityPermissions,
332 addGuestPermissions);
333 }
334 else {
335 existingNode = WikiNodeLocalServiceUtil.updateNode(
336 existingNode.getNodeId(), node.getName(),
337 node.getDescription());
338 }
339 }
340 else {
341 String nodeName = PropsUtil.get(PropsKeys.WIKI_INITIAL_NODE_NAME);
342
343 if (node.getName().equals(nodeName)) {
344 try {
345 WikiNodeUtil.removeByG_N(
346 context.getGroupId(), node.getName());
347 }
348 catch (NoSuchNodeException nsne) {
349 }
350 }
351
352 existingNode = WikiNodeLocalServiceUtil.addNode(
353 userId, plid, node.getName(), node.getDescription(),
354 addCommunityPermissions, addGuestPermissions);
355 }
356
357 nodePKs.put(node.getNodeId(), existingNode.getNodeId());
358 }
359
360 protected void importPage(
361 PortletDataContext context, Map<Long, Long> nodePKs, Element pageEl,
362 WikiPage page)
363 throws Exception {
364
365 long userId = context.getUserId(page.getUserUuid());
366 long nodeId = MapUtil.getLong(
367 nodePKs, page.getNodeId(), page.getNodeId());
368
369 String[] tagsEntries = null;
370
371 if (context.getBooleanParameter(_NAMESPACE, "tags")) {
372 tagsEntries = context.getTagsEntries(
373 WikiPage.class, page.getResourcePrimKey());
374 }
375
376 PortletPreferences prefs = null;
377
378 ThemeDisplay themeDisplay = null;
379
380 WikiPage existingPage = null;
381
382 try {
383 WikiNodeUtil.findByPrimaryKey(nodeId);
384
385 if (context.getDataStrategy().equals(
386 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
387
388 try {
389 existingPage = WikiPageFinderUtil.findByUuid_G(
390 page.getUuid(), context.getGroupId());
391
392 existingPage = WikiPageLocalServiceUtil.updatePage(
393 userId, nodeId, existingPage.getTitle(), 0,
394 page.getContent(), page.getSummary(), true,
395 page.getFormat(), page.getParentTitle(),
396 page.getRedirectTitle(), tagsEntries, prefs,
397 themeDisplay);
398 }
399 catch (NoSuchPageException nspe) {
400 existingPage = WikiPageLocalServiceUtil.addPage(
401 page.getUuid(), userId, nodeId, page.getTitle(),
402 page.getVersion(), page.getContent(), page.getSummary(),
403 true, page.getFormat(), page.getHead(),
404 page.getParentTitle(), page.getRedirectTitle(),
405 tagsEntries, prefs, themeDisplay);
406 }
407 }
408 else {
409 existingPage = WikiPageLocalServiceUtil.addPage(
410 null, userId, nodeId, page.getTitle(), page.getVersion(),
411 page.getContent(), page.getSummary(), true,
412 page.getFormat(), page.getHead(), page.getParentTitle(),
413 page.getRedirectTitle(), tagsEntries, prefs, themeDisplay);
414 }
415
416 if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
417 page.isHead()) {
418
419 List<Element> attachmentEls = pageEl.elements("attachment");
420
421 List<ObjectValuePair<String, byte[]>> files =
422 new ArrayList<ObjectValuePair<String, byte[]>>();
423
424 for (Element attachmentEl : attachmentEls) {
425 String name = attachmentEl.attributeValue("name");
426 String binPath = attachmentEl.attributeValue("bin-path");
427
428 byte[] bytes = context.getZipEntryAsByteArray(binPath);
429
430 files.add(new ObjectValuePair<String, byte[]>(name, bytes));
431 }
432
433 if (files.size() > 0) {
434 WikiPageLocalServiceUtil.addPageAttachments(
435 nodeId, page.getTitle(), files);
436 }
437 }
438
439 if (context.getBooleanParameter(_NAMESPACE, "comments")) {
440 context.importComments(
441 WikiPage.class, page.getResourcePrimKey(),
442 existingPage.getResourcePrimKey(), context.getGroupId());
443 }
444
445 if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
446 context.importRatingsEntries(
447 WikiPage.class, page.getResourcePrimKey(),
448 existingPage.getResourcePrimKey());
449 }
450 }
451 catch (NoSuchNodeException nsne) {
452 _log.error("Could not find the node for page " + page.getPageId());
453 }
454 }
455
456 protected String getNodePath(PortletDataContext context, WikiNode node) {
457 StringBuilder sb = new StringBuilder();
458
459 sb.append(context.getPortletPath(PortletKeys.WIKI));
460 sb.append("/nodes/");
461 sb.append(node.getNodeId());
462 sb.append(".xml");
463
464 return sb.toString();
465 }
466
467 protected String getPageAttachementBinPath(
468 PortletDataContext context, WikiPage page, String attachment) {
469
470 StringBuilder sb = new StringBuilder();
471
472 sb.append(context.getPortletPath(PortletKeys.WIKI));
473 sb.append("/bin/");
474 sb.append(page.getPageId());
475 sb.append(StringPool.SLASH);
476 sb.append(attachment);
477
478 return sb.toString();
479 }
480
481 protected String getPagePath(PortletDataContext context, WikiPage page) {
482 StringBuilder sb = new StringBuilder();
483
484 sb.append(context.getPortletPath(PortletKeys.WIKI));
485 sb.append("/pages/");
486 sb.append(page.getPageId());
487 sb.append(".xml");
488
489 return sb.toString();
490 }
491
492 private static final String _NAMESPACE = "wiki";
493
494 private static final PortletDataHandlerBoolean _nodesAndPages =
495 new PortletDataHandlerBoolean(
496 _NAMESPACE, "wikis-and-pages", true, true);
497
498 private static final PortletDataHandlerBoolean _attachments =
499 new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
500
501 private static final PortletDataHandlerBoolean _comments =
502 new PortletDataHandlerBoolean(_NAMESPACE, "comments");
503
504 private static final PortletDataHandlerBoolean _tags =
505 new PortletDataHandlerBoolean(_NAMESPACE, "tags");
506
507 private static Log _log =
508 LogFactory.getLog(WikiPortletDataHandlerImpl.class);
509
510 }