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.polls.lar;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.lar.PortletDataContext;
28  import com.liferay.portal.kernel.lar.PortletDataException;
29  import com.liferay.portal.kernel.lar.PortletDataHandler;
30  import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
31  import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
32  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
33  import com.liferay.portal.kernel.util.CalendarFactoryUtil;
34  import com.liferay.portal.util.DocumentUtil;
35  import com.liferay.portlet.polls.DuplicateVoteException;
36  import com.liferay.portlet.polls.NoSuchChoiceException;
37  import com.liferay.portlet.polls.NoSuchQuestionException;
38  import com.liferay.portlet.polls.model.PollsChoice;
39  import com.liferay.portlet.polls.model.PollsQuestion;
40  import com.liferay.portlet.polls.model.PollsVote;
41  import com.liferay.portlet.polls.service.PollsChoiceLocalServiceUtil;
42  import com.liferay.portlet.polls.service.PollsQuestionLocalServiceUtil;
43  import com.liferay.portlet.polls.service.PollsVoteLocalServiceUtil;
44  import com.liferay.portlet.polls.service.persistence.PollsChoiceFinderUtil;
45  import com.liferay.portlet.polls.service.persistence.PollsChoiceUtil;
46  import com.liferay.portlet.polls.service.persistence.PollsQuestionUtil;
47  import com.liferay.portlet.polls.service.persistence.PollsVoteUtil;
48  import com.liferay.util.MapUtil;
49  
50  import com.thoughtworks.xstream.XStream;
51  
52  import java.util.ArrayList;
53  import java.util.Calendar;
54  import java.util.Date;
55  import java.util.Iterator;
56  import java.util.List;
57  import java.util.Map;
58  
59  import javax.portlet.PortletPreferences;
60  
61  import org.apache.commons.logging.Log;
62  import org.apache.commons.logging.LogFactory;
63  
64  import org.dom4j.Document;
65  import org.dom4j.DocumentHelper;
66  import org.dom4j.Element;
67  
68  /**
69   * <a href="PollsPortletDataHandlerImpl.java.html"><b><i>View Source</i></b></a>
70   *
71   * @author Bruno Farache
72   *
73   */
74  public class PollsPortletDataHandlerImpl implements PortletDataHandler {
75  
76      public PortletPreferences deleteData(
77              PortletDataContext context, String portletId,
78              PortletPreferences prefs)
79          throws PortletDataException {
80  
81          try {
82  
83              // Questions
84  
85              if (!context.addPrimaryKey(
86                      PollsPortletDataHandlerImpl.class, "deleteData")) {
87  
88                  PollsQuestionLocalServiceUtil.deleteQuestions(
89                      context.getGroupId());
90              }
91  
92              return null;
93          }
94          catch (Exception e) {
95              throw new PortletDataException(e);
96          }
97      }
98  
99      public String exportData(
100             PortletDataContext context, String portletId,
101             PortletPreferences prefs)
102         throws PortletDataException {
103 
104         try {
105             XStream xStream = new XStream();
106 
107             Document doc = DocumentHelper.createDocument();
108 
109             Element root = doc.addElement("polls-data");
110 
111             root.addAttribute("group-id", String.valueOf(context.getGroupId()));
112 
113             // Questions
114 
115             List questions = PollsQuestionUtil.findByGroupId(
116                 context.getGroupId());
117 
118             List choices = new ArrayList();
119 
120             List votes = new ArrayList();
121 
122             Iterator itr = questions.iterator();
123 
124             while (itr.hasNext()) {
125                 PollsQuestion question = (PollsQuestion)itr.next();
126 
127                 if (context.addPrimaryKey(
128                         PollsQuestion.class, question.getPrimaryKeyObj())) {
129 
130                     itr.remove();
131                 }
132                 else {
133                     List questionChoices = PollsChoiceUtil.findByQuestionId(
134                         question.getQuestionId());
135 
136                     choices.addAll(questionChoices);
137 
138                     if (context.getBooleanParameter(_NAMESPACE, "votes")) {
139                         question.setUserUuid(question.getUserUuid());
140 
141                         List questionVotes = PollsVoteUtil.findByQuestionId(
142                             question.getQuestionId());
143 
144                         votes.addAll(questionVotes);
145                     }
146                 }
147             }
148 
149             String xml = xStream.toXML(questions);
150 
151             Element el = root.addElement("poll-questions");
152 
153             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
154 
155             el.content().add(tempDoc.getRootElement().createCopy());
156 
157             // Choices
158 
159             itr = choices.iterator();
160 
161             while (itr.hasNext()) {
162                 PollsChoice choice = (PollsChoice)itr.next();
163 
164                 if (context.addPrimaryKey(
165                         PollsChoice.class, choice.getPrimaryKeyObj())) {
166 
167                     itr.remove();
168                 }
169             }
170 
171             xml = xStream.toXML(choices);
172 
173             el = root.addElement("poll-choices");
174 
175             tempDoc = DocumentUtil.readDocumentFromXML(xml);
176 
177             el.content().add(tempDoc.getRootElement().createCopy());
178 
179             // Votes
180 
181             itr = votes.iterator();
182 
183             while (itr.hasNext()) {
184                 PollsVote vote = (PollsVote)itr.next();
185 
186                 if (context.addPrimaryKey(
187                         PollsVote.class, vote.getPrimaryKeyObj())) {
188 
189                     itr.remove();
190                 }
191                 else {
192                     vote.setUserUuid(vote.getUserUuid());
193                 }
194             }
195 
196             xml = xStream.toXML(votes);
197 
198             el = root.addElement("poll-votes");
199 
200             tempDoc = DocumentUtil.readDocumentFromXML(xml);
201 
202             el.content().add(tempDoc.getRootElement().createCopy());
203 
204             return doc.asXML();
205         }
206         catch (Exception e) {
207             throw new PortletDataException(e);
208         }
209     }
210 
211     public PortletDataHandlerControl[] getExportControls()
212         throws PortletDataException {
213 
214         return new PortletDataHandlerControl[] {_questions, _votes};
215     }
216 
217     public PortletDataHandlerControl[] getImportControls()
218         throws PortletDataException {
219 
220         return new PortletDataHandlerControl[] {_questions, _votes};
221     }
222 
223     public PortletPreferences importData(
224             PortletDataContext context, String portletId,
225             PortletPreferences prefs, String data)
226         throws PortletDataException {
227 
228         try {
229             XStream xStream = new XStream();
230 
231             Document doc = DocumentUtil.readDocumentFromXML(data);
232 
233             Element root = doc.getRootElement();
234 
235             // Questions
236 
237             Element el = root.element("poll-questions").element("list");
238 
239             Document tempDoc = DocumentHelper.createDocument();
240 
241             tempDoc.content().add(el.createCopy());
242 
243             Map questionPKs = context.getNewPrimaryKeysMap(PollsQuestion.class);
244 
245             List questions = (List)xStream.fromXML(tempDoc.asXML());
246 
247             Iterator itr = questions.iterator();
248 
249             while (itr.hasNext()) {
250                 PollsQuestion question = (PollsQuestion)itr.next();
251 
252                 importQuestion(context, questionPKs, question);
253             }
254 
255             // Choices
256 
257             el = root.element("poll-choices").element("list");
258 
259             tempDoc = DocumentHelper.createDocument();
260 
261             tempDoc.content().add(el.createCopy());
262 
263             Map choicePKs = context.getNewPrimaryKeysMap(PollsChoice.class);
264 
265             List choices = (List)xStream.fromXML(tempDoc.asXML());
266 
267             itr = choices.iterator();
268 
269             while (itr.hasNext()) {
270                 PollsChoice choice = (PollsChoice)itr.next();
271 
272                 importChoice(context, questionPKs, choicePKs, choice);
273             }
274 
275             // Votes
276 
277             if (context.getBooleanParameter(_NAMESPACE, "votes")) {
278                 el = root.element("poll-votes").element("list");
279 
280                 tempDoc = DocumentHelper.createDocument();
281 
282                 tempDoc.content().add(el.createCopy());
283 
284                 List votes = (List)xStream.fromXML(tempDoc.asXML());
285 
286                 itr = votes.iterator();
287 
288                 while (itr.hasNext()) {
289                     PollsVote vote = (PollsVote)itr.next();
290 
291                     importVote(context, questionPKs, choicePKs, vote);
292                 }
293             }
294 
295             return null;
296         }
297         catch (Exception e) {
298             throw new PortletDataException(e);
299         }
300     }
301 
302     public boolean isPublishToLiveByDefault() {
303         return false;
304     }
305 
306     protected void importChoice(
307             PortletDataContext context, Map questionPKs, Map choicePKs,
308             PollsChoice choice)
309         throws Exception {
310 
311         long questionId = MapUtil.getLong(
312             questionPKs, choice.getQuestionId(), choice.getQuestionId());
313 
314         PollsChoice existingChoice = null;
315 
316         try {
317             PollsQuestionUtil.findByPrimaryKey(questionId);
318 
319             if (context.getDataStrategy().equals(
320                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
321 
322                 try {
323                     existingChoice = PollsChoiceFinderUtil.findByUuid_G(
324                         choice.getUuid(), context.getGroupId());
325 
326                     existingChoice = PollsChoiceLocalServiceUtil.updateChoice(
327                         existingChoice.getChoiceId(), questionId,
328                         choice.getName(), choice.getDescription());
329                 }
330                 catch (NoSuchChoiceException nsce) {
331                     existingChoice = PollsChoiceLocalServiceUtil.addChoice(
332                         choice.getUuid(), questionId, choice.getName(),
333                         choice.getDescription());
334                 }
335             }
336             else {
337                 existingChoice = PollsChoiceLocalServiceUtil.addChoice(
338                     questionId, choice.getName(), choice.getDescription());
339             }
340 
341             choicePKs.put(
342                 choice.getPrimaryKeyObj(), existingChoice.getPrimaryKeyObj());
343         }
344         catch (NoSuchQuestionException nsqe) {
345             _log.error(
346                 "Could not find the question for choice " +
347                     choice.getChoiceId());
348         }
349     }
350 
351     protected void importQuestion(
352             PortletDataContext context, Map questionPKs, PollsQuestion question)
353         throws SystemException, PortalException {
354 
355         long userId = context.getUserId(question.getUserUuid());
356         long plid = context.getPlid();
357 
358         Date expirationDate = question.getExpirationDate();
359 
360         int expirationMonth = 0;
361         int expirationDay = 0;
362         int expirationYear = 0;
363         int expirationHour = 0;
364         int expirationMinute = 0;
365         boolean neverExpire = true;
366 
367         if (expirationDate != null) {
368             Calendar expirationCal = CalendarFactoryUtil.getCalendar();
369 
370             expirationCal.setTime(expirationDate);
371 
372             expirationMonth = expirationCal.get(Calendar.MONTH);
373             expirationDay = expirationCal.get(Calendar.DATE);
374             expirationYear = expirationCal.get(Calendar.YEAR);
375             expirationHour = expirationCal.get(Calendar.HOUR);
376             expirationMinute = expirationCal.get(Calendar.MINUTE);
377             neverExpire = false;
378 
379             if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
380                 expirationHour += 12;
381             }
382         }
383 
384         boolean addCommunityPermissions = true;
385         boolean addGuestPermissions = true;
386 
387         PollsQuestion existingQuestion = null;
388 
389         if (context.getDataStrategy().equals(
390                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
391             existingQuestion =  PollsQuestionUtil.fetchByUUID_G(
392                 question.getUuid(), context.getGroupId());
393 
394             if (existingQuestion == null) {
395                 existingQuestion = PollsQuestionLocalServiceUtil.addQuestion(
396                     question.getUuid(), userId, plid, question.getTitle(),
397                     question.getDescription(), expirationMonth, expirationDay,
398                     expirationYear, expirationHour, expirationMinute,
399                     neverExpire, addCommunityPermissions, addGuestPermissions);
400             }
401             else {
402                 existingQuestion = PollsQuestionLocalServiceUtil.updateQuestion(
403                     userId, existingQuestion.getQuestionId(),
404                     question.getTitle(), question.getDescription(),
405                     expirationMonth, expirationDay, expirationYear,
406                     expirationHour, expirationMinute, neverExpire);
407             }
408         }
409         else {
410             existingQuestion = PollsQuestionLocalServiceUtil.addQuestion(
411                 userId, plid, question.getTitle(), question.getDescription(),
412                 expirationMonth, expirationDay, expirationYear, expirationHour,
413                 expirationMinute, neverExpire, addCommunityPermissions,
414                 addGuestPermissions);
415         }
416 
417         questionPKs.put(
418             question.getPrimaryKeyObj(), existingQuestion.getPrimaryKeyObj());
419     }
420 
421     protected void importVote(
422             PortletDataContext context, Map questionPKs, Map choicePKs,
423             PollsVote vote)
424         throws Exception {
425 
426         long userId = context.getUserId(vote.getUserUuid());
427         long questionId = MapUtil.getLong(
428             questionPKs, vote.getQuestionId(), vote.getQuestionId());
429         long choiceId = MapUtil.getLong(
430             choicePKs, vote.getChoiceId(), vote.getChoiceId());
431 
432         try {
433             PollsQuestionUtil.findByPrimaryKey(questionId);
434             PollsChoiceUtil.findByPrimaryKey(choiceId);
435 
436             PollsVoteLocalServiceUtil.addVote(
437                 userId, questionId, choiceId);
438         }
439         catch (DuplicateVoteException dve) {
440         }
441         catch (NoSuchQuestionException nsqe) {
442             _log.error(
443                 "Could not find the question for vote " + vote.getVoteId());
444         }
445         catch (NoSuchChoiceException nsve) {
446             _log.error(
447                 "Could not find the choice for vote " + vote.getVoteId());
448         }
449     }
450 
451     private static final String _NAMESPACE = "polls";
452 
453     private static final PortletDataHandlerBoolean _questions =
454         new PortletDataHandlerBoolean(_NAMESPACE, "questions", true, true);
455 
456     private static final PortletDataHandlerBoolean _votes =
457         new PortletDataHandlerBoolean(_NAMESPACE, "votes");
458 
459     private static Log _log =
460         LogFactory.getLog(PollsPortletDataHandlerImpl.class);
461 
462 }