1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.wiki.lar;
24  
25  import com.liferay.documentlibrary.service.DLServiceUtil;
26  import com.liferay.portal.kernel.lar.PortletDataContext;
27  import com.liferay.portal.kernel.lar.PortletDataException;
28  import com.liferay.portal.kernel.lar.PortletDataHandler;
29  import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
30  import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
31  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
32  import com.liferay.portal.kernel.util.ObjectValuePair;
33  import com.liferay.portal.model.CompanyConstants;
34  import com.liferay.portal.theme.ThemeDisplay;
35  import com.liferay.portal.util.DocumentUtil;
36  import com.liferay.portlet.wiki.NoSuchNodeException;
37  import com.liferay.portlet.wiki.NoSuchPageException;
38  import com.liferay.portlet.wiki.model.WikiNode;
39  import com.liferay.portlet.wiki.model.WikiPage;
40  import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
41  import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
42  import com.liferay.portlet.wiki.service.persistence.WikiNodeUtil;
43  import com.liferay.portlet.wiki.service.persistence.WikiPageFinderUtil;
44  import com.liferay.portlet.wiki.service.persistence.WikiPageUtil;
45  import com.liferay.util.MapUtil;
46  
47  import com.thoughtworks.xstream.XStream;
48  
49  import java.util.ArrayList;
50  import java.util.Iterator;
51  import java.util.List;
52  import java.util.Map;
53  
54  import javax.portlet.PortletPreferences;
55  
56  import org.apache.commons.logging.Log;
57  import org.apache.commons.logging.LogFactory;
58  
59  import org.dom4j.Document;
60  import org.dom4j.DocumentHelper;
61  import org.dom4j.Element;
62  
63  /**
64   * <a href="WikiPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
65   *
66   * @author Bruno Farache
67   * @author Jorge Ferrer
68   *
69   */
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  
79              // Nodes
80  
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              XStream xStream = new XStream();
100 
101             Document doc = DocumentHelper.createDocument();
102 
103             Element root = doc.addElement("wiki-data");
104 
105             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
106 
107             // Nodes
108 
109             List<WikiNode> nodes = WikiNodeUtil.findByGroupId(
110                 context.getGroupId());
111 
112             List<WikiPage> pages = new ArrayList<WikiPage>();
113 
114             Iterator<WikiNode> nodesItr = nodes.iterator();
115 
116             while (nodesItr.hasNext()) {
117                 WikiNode node = nodesItr.next();
118 
119                 if (context.addPrimaryKey(
120                         WikiNode.class, node.getPrimaryKeyObj())) {
121 
122                     nodesItr.remove();
123                 }
124                 else {
125                     node.setUserUuid(node.getUserUuid());
126 
127                     List<WikiPage> nodePages = WikiPageUtil.findByNodeId(
128                         node.getNodeId());
129 
130                     pages.addAll(nodePages);
131                 }
132             }
133 
134             String xml = xStream.toXML(nodes);
135 
136             Element el = root.addElement("wiki-nodes");
137 
138             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
139 
140             el.content().add(tempDoc.getRootElement().createCopy());
141 
142             // Pages
143 
144             Iterator<WikiPage> pagesItr = pages.iterator();
145 
146             while (pagesItr.hasNext()) {
147                 WikiPage page = pagesItr.next();
148 
149                 if (context.addPrimaryKey(
150                         WikiPage.class, page.getPrimaryKeyObj())) {
151 
152                     pagesItr.remove();
153                 }
154                 else {
155                     page.setUserUuid(page.getUserUuid());
156 
157                     if (context.getBooleanParameter(_NAMESPACE, "comments")) {
158                         context.addComments(
159                             WikiPage.class,
160                             new Long(page.getResourcePrimKey()));
161                     }
162 
163                     if (context.getBooleanParameter(_NAMESPACE, "tags")) {
164                         context.addTagsEntries(
165                             WikiPage.class,
166                             new Long(page.getResourcePrimKey()));
167                     }
168 
169                     // Attachments
170 
171                     if (context.getBooleanParameter(
172                             _NAMESPACE, "attachments") && page.isHead()) {
173 
174                         String[] attachments = page.getAttachmentsFiles();
175 
176                         for (int i = 0; i < attachments.length; i++) {
177                             String attachment = attachments[i];
178 
179                             byte[] byteArray = DLServiceUtil.getFile(
180                                 context.getCompanyId(), CompanyConstants.SYSTEM,
181                                 attachment);
182 
183                             context.getZipWriter().addEntry(
184                                 attachment, byteArray);
185                         }
186 
187                         page.setAttachmentsDir(page.getAttachmentsDir());
188                     }
189 
190                 }
191             }
192 
193             xml = xStream.toXML(pages);
194 
195             el = root.addElement("wiki-pages");
196 
197             tempDoc = DocumentUtil.readDocumentFromXML(xml);
198 
199             el.content().add(tempDoc.getRootElement().createCopy());
200 
201             return doc.asXML();
202         }
203         catch (Exception e) {
204             throw new PortletDataException(e);
205         }
206     }
207 
208     public PortletDataHandlerControl[] getExportControls()
209         throws PortletDataException {
210 
211         return new PortletDataHandlerControl[] {
212             _nodesAndPages, _attachments, _comments, _tags
213         };
214     }
215 
216     public PortletDataHandlerControl[] getImportControls()
217         throws PortletDataException {
218 
219         return new PortletDataHandlerControl[] {
220             _nodesAndPages, _attachments, _comments, _tags
221         };
222     }
223 
224     public PortletPreferences importData(
225             PortletDataContext context, String portletId,
226             PortletPreferences prefs, String data)
227         throws PortletDataException {
228 
229         try {
230             XStream xStream = new XStream();
231 
232             Document doc = DocumentUtil.readDocumentFromXML(data);
233 
234             Element root = doc.getRootElement();
235 
236             // Nodes
237 
238             Element el = root.element("wiki-nodes").element("list");
239 
240             Document tempDoc = DocumentHelper.createDocument();
241 
242             tempDoc.content().add(el.createCopy());
243 
244             Map<Long, Long> nodePKs = context.getNewPrimaryKeysMap(
245                 WikiNode.class);
246 
247             List<WikiNode> nodes = (List<WikiNode>)xStream.fromXML(
248                 tempDoc.asXML());
249 
250             Iterator<WikiNode> nodesItr = nodes.iterator();
251 
252             while (nodesItr.hasNext()) {
253                 WikiNode node = nodesItr.next();
254 
255                 importNode(context, nodePKs, node);
256             }
257 
258             // Pages
259 
260             el = root.element("wiki-pages").element("list");
261 
262             tempDoc = DocumentHelper.createDocument();
263 
264             tempDoc.content().add(el.createCopy());
265 
266             List<WikiPage> pages = (List<WikiPage>)xStream.fromXML(
267                 tempDoc.asXML());
268 
269             Iterator<WikiPage> pagesItr = pages.iterator();
270 
271             while (pagesItr.hasNext()) {
272                 WikiPage page = pagesItr.next();
273 
274                 importPage(context, nodePKs, page);
275             }
276 
277             return null;
278         }
279         catch (Exception e) {
280             throw new PortletDataException(e);
281         }
282     }
283 
284     public boolean isPublishToLiveByDefault() {
285         return false;
286     }
287 
288     protected void importNode(
289             PortletDataContext context, Map<Long, Long> nodePKs, WikiNode node)
290         throws Exception {
291 
292         long userId = context.getUserId(node.getUserUuid());
293         long plid = context.getPlid();
294 
295         boolean addCommunityPermissions = true;
296         boolean addGuestPermissions = true;
297 
298         WikiNode existingNode = null;
299 
300         if (context.getDataStrategy().equals(
301                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
302 
303             existingNode = WikiNodeUtil.fetchByUUID_G(
304                 node.getUuid(), context.getGroupId());
305 
306             if (existingNode == null) {
307                 existingNode = WikiNodeLocalServiceUtil.addNode(
308                     node.getUuid(), userId, plid, node.getName(),
309                     node.getDescription(), addCommunityPermissions,
310                     addGuestPermissions);
311             }
312             else {
313                 existingNode = WikiNodeLocalServiceUtil.updateNode(
314                     existingNode.getNodeId(), node.getName(),
315                     node.getDescription());
316             }
317         }
318         else {
319             existingNode = WikiNodeLocalServiceUtil.addNode(
320                 userId, plid, node.getName(), node.getDescription(),
321                 addCommunityPermissions, addGuestPermissions);
322         }
323 
324         nodePKs.put(node.getNodeId(), existingNode.getNodeId());
325     }
326 
327     protected void importPage(
328             PortletDataContext context, Map<Long, Long> nodePKs, WikiPage page)
329         throws Exception {
330 
331         long userId = context.getUserId(page.getUserUuid());
332         long nodeId = MapUtil.getLong(
333             nodePKs, page.getNodeId(), page.getNodeId());
334 
335         String[] tagsEntries = null;
336 
337         if (context.getBooleanParameter(_NAMESPACE, "tags")) {
338             tagsEntries = context.getTagsEntries(
339                 WikiPage.class, page.getPrimaryKeyObj());
340         }
341 
342         PortletPreferences prefs = null;
343 
344         ThemeDisplay themeDisplay = null;
345 
346         WikiPage existingPage = null;
347 
348         try {
349             WikiNodeUtil.findByPrimaryKey(nodeId);
350 
351             if (context.getDataStrategy().equals(
352                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
353 
354                 try {
355                     existingPage = WikiPageFinderUtil.findByUuid_G(
356                         page.getUuid(), context.getGroupId());
357 
358                     existingPage = WikiPageLocalServiceUtil.updatePage(
359                         userId, nodeId, existingPage.getTitle(), 0,
360                         page.getContent(), page.getFormat(),
361                         page.getParentTitle(), page.getRedirectTitle(),
362                         tagsEntries, prefs, themeDisplay);
363                 }
364                 catch (NoSuchPageException nspe) {
365                     existingPage = WikiPageLocalServiceUtil.addPage(
366                         page.getUuid(), userId, nodeId, page.getTitle(),
367                         page.getVersion(), page.getContent(), page.getFormat(),
368                         page.getHead(), page.getParentTitle(),
369                         page.getRedirectTitle(), tagsEntries, prefs,
370                         themeDisplay);
371                 }
372             }
373             else {
374                 existingPage = WikiPageLocalServiceUtil.addPage(
375                     null, userId, nodeId, page.getTitle(), page.getVersion(),
376                     page.getContent(), page.getFormat(), page.getHead(),
377                     page.getParentTitle(), page.getRedirectTitle(), tagsEntries,
378                     prefs, themeDisplay);
379             }
380 
381             if (context.getBooleanParameter(_NAMESPACE, "attachments") &&
382                 page.isHead()) {
383 
384                 List<ObjectValuePair<String, byte[]>> files =
385                     context.getZipReader().getFolderEntries().get(
386                         page.getAttachmentsDir() + "/");
387 
388                 if (files != null) {
389                     WikiPageLocalServiceUtil.addPageAttachments(
390                         nodeId, page.getTitle(), files);
391                 }
392             }
393 
394             if (context.getBooleanParameter(_NAMESPACE, "comments")) {
395                 context.importComments(
396                     WikiPage.class, new Long(page.getResourcePrimKey()),
397                     new Long(existingPage.getResourcePrimKey()),
398                     context.getGroupId());
399             }
400 
401             if (context.getBooleanParameter(_NAMESPACE, "ratings")) {
402                 context.importRatingsEntries(
403                     WikiPage.class, new Long(page.getResourcePrimKey()),
404                     new Long(existingPage.getResourcePrimKey()));
405             }
406         }
407         catch (NoSuchNodeException nsne) {
408             _log.error(
409                 "Could not find the node for page " +
410                     page.getPageId());
411         }
412     }
413 
414     private static final String _NAMESPACE = "wiki";
415 
416     private static final PortletDataHandlerBoolean _nodesAndPages =
417         new PortletDataHandlerBoolean(
418             _NAMESPACE, "wikis-and-pages", true, true);
419 
420     private static final PortletDataHandlerBoolean _attachments =
421         new PortletDataHandlerBoolean(_NAMESPACE, "attachments");
422 
423     private static final PortletDataHandlerBoolean _comments =
424         new PortletDataHandlerBoolean(_NAMESPACE, "comments");
425 
426     private static final PortletDataHandlerBoolean _tags =
427         new PortletDataHandlerBoolean(_NAMESPACE, "tags");
428 
429     private static Log _log =
430         LogFactory.getLog(WikiPortletDataHandlerImpl.class);
431 
432 }