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<PollsQuestion> questions = PollsQuestionUtil.findByGroupId(
116                 context.getGroupId());
117 
118             List<PollsChoice> choices = new ArrayList<PollsChoice>();
119 
120             List<PollsVote> votes = new ArrayList<PollsVote>();
121 
122             Iterator<PollsQuestion> questionsItr = questions.iterator();
123 
124             while (questionsItr.hasNext()) {
125                 PollsQuestion question = questionsItr.next();
126 
127                 if (context.addPrimaryKey(
128                         PollsQuestion.class, question.getPrimaryKeyObj())) {
129 
130                     questionsItr.remove();
131                 }
132                 else {
133                     List<PollsChoice> questionChoices =
134                         PollsChoiceUtil.findByQuestionId(
135                             question.getQuestionId());
136 
137                     choices.addAll(questionChoices);
138 
139                     if (context.getBooleanParameter(_NAMESPACE, "votes")) {
140                         question.setUserUuid(question.getUserUuid());
141 
142                         List<PollsVote> questionVotes =
143                             PollsVoteUtil.findByQuestionId(
144                                 question.getQuestionId());
145 
146                         votes.addAll(questionVotes);
147                     }
148                 }
149             }
150 
151             String xml = xStream.toXML(questions);
152 
153             Element el = root.addElement("poll-questions");
154 
155             Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
156 
157             el.content().add(tempDoc.getRootElement().createCopy());
158 
159             // Choices
160 
161             Iterator<PollsChoice> choicesItr = choices.iterator();
162 
163             while (choicesItr.hasNext()) {
164                 PollsChoice choice = choicesItr.next();
165 
166                 if (context.addPrimaryKey(
167                         PollsChoice.class, choice.getPrimaryKeyObj())) {
168 
169                     choicesItr.remove();
170                 }
171             }
172 
173             xml = xStream.toXML(choices);
174 
175             el = root.addElement("poll-choices");
176 
177             tempDoc = DocumentUtil.readDocumentFromXML(xml);
178 
179             el.content().add(tempDoc.getRootElement().createCopy());
180 
181             // Votes
182 
183             Iterator<PollsVote> votesItr = votes.iterator();
184 
185             while (votesItr.hasNext()) {
186                 PollsVote vote = votesItr.next();
187 
188                 if (context.addPrimaryKey(
189                         PollsVote.class, vote.getPrimaryKeyObj())) {
190 
191                     votesItr.remove();
192                 }
193                 else {
194                     vote.setUserUuid(vote.getUserUuid());
195                 }
196             }
197 
198             xml = xStream.toXML(votes);
199 
200             el = root.addElement("poll-votes");
201 
202             tempDoc = DocumentUtil.readDocumentFromXML(xml);
203 
204             el.content().add(tempDoc.getRootElement().createCopy());
205 
206             return doc.asXML();
207         }
208         catch (Exception e) {
209             throw new PortletDataException(e);
210         }
211     }
212 
213     public PortletDataHandlerControl[] getExportControls()
214         throws PortletDataException {
215 
216         return new PortletDataHandlerControl[] {_questions, _votes};
217     }
218 
219     public PortletDataHandlerControl[] getImportControls()
220         throws PortletDataException {
221 
222         return new PortletDataHandlerControl[] {_questions, _votes};
223     }
224 
225     public PortletPreferences importData(
226             PortletDataContext context, String portletId,
227             PortletPreferences prefs, String data)
228         throws PortletDataException {
229 
230         try {
231             XStream xStream = new XStream();
232 
233             Document doc = DocumentUtil.readDocumentFromXML(data);
234 
235             Element root = doc.getRootElement();
236 
237             // Questions
238 
239             Element el = root.element("poll-questions").element("list");
240 
241             Document tempDoc = DocumentHelper.createDocument();
242 
243             tempDoc.content().add(el.createCopy());
244 
245             Map<Long, Long> questionPKs = context.getNewPrimaryKeysMap(
246                 PollsQuestion.class);
247 
248             List<PollsQuestion> questions =
249                 (List<PollsQuestion>)xStream.fromXML(tempDoc.asXML());
250 
251             for (PollsQuestion question : questions) {
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<Long, Long> choicePKs = context.getNewPrimaryKeysMap(
264                 PollsChoice.class);
265 
266             List<PollsChoice> choices = (List<PollsChoice>)xStream.fromXML(
267                 tempDoc.asXML());
268 
269             for (PollsChoice choice : choices) {
270                 importChoice(context, questionPKs, choicePKs, choice);
271             }
272 
273             // Votes
274 
275             if (context.getBooleanParameter(_NAMESPACE, "votes")) {
276                 el = root.element("poll-votes").element("list");
277 
278                 tempDoc = DocumentHelper.createDocument();
279 
280                 tempDoc.content().add(el.createCopy());
281 
282                 List<PollsVote> votes = (List<PollsVote>)xStream.fromXML(
283                     tempDoc.asXML());
284 
285                 for (PollsVote vote : votes) {
286                     importVote(context, questionPKs, choicePKs, vote);
287                 }
288             }
289 
290             return null;
291         }
292         catch (Exception e) {
293             throw new PortletDataException(e);
294         }
295     }
296 
297     public boolean isPublishToLiveByDefault() {
298         return false;
299     }
300 
301     protected void importChoice(
302             PortletDataContext context, Map<Long, Long> questionPKs,
303             Map<Long, Long> choicePKs, PollsChoice choice)
304         throws Exception {
305 
306         long questionId = MapUtil.getLong(
307             questionPKs, choice.getQuestionId(), choice.getQuestionId());
308 
309         PollsChoice existingChoice = null;
310 
311         try {
312             PollsQuestionUtil.findByPrimaryKey(questionId);
313 
314             if (context.getDataStrategy().equals(
315                     PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
316 
317                 try {
318                     existingChoice = PollsChoiceFinderUtil.findByUuid_G(
319                         choice.getUuid(), context.getGroupId());
320 
321                     existingChoice = PollsChoiceLocalServiceUtil.updateChoice(
322                         existingChoice.getChoiceId(), questionId,
323                         choice.getName(), choice.getDescription());
324                 }
325                 catch (NoSuchChoiceException nsce) {
326                     existingChoice = PollsChoiceLocalServiceUtil.addChoice(
327                         choice.getUuid(), questionId, choice.getName(),
328                         choice.getDescription());
329                 }
330             }
331             else {
332                 existingChoice = PollsChoiceLocalServiceUtil.addChoice(
333                     questionId, choice.getName(), choice.getDescription());
334             }
335 
336             choicePKs.put(choice.getChoiceId(), existingChoice.getChoiceId());
337         }
338         catch (NoSuchQuestionException nsqe) {
339             _log.error(
340                 "Could not find the question for choice " +
341                     choice.getChoiceId());
342         }
343     }
344 
345     protected void importQuestion(
346             PortletDataContext context, Map<Long, Long> questionPKs,
347             PollsQuestion question)
348         throws SystemException, PortalException {
349 
350         long userId = context.getUserId(question.getUserUuid());
351         long plid = context.getPlid();
352 
353         Date expirationDate = question.getExpirationDate();
354 
355         int expirationMonth = 0;
356         int expirationDay = 0;
357         int expirationYear = 0;
358         int expirationHour = 0;
359         int expirationMinute = 0;
360         boolean neverExpire = true;
361 
362         if (expirationDate != null) {
363             Calendar expirationCal = CalendarFactoryUtil.getCalendar();
364 
365             expirationCal.setTime(expirationDate);
366 
367             expirationMonth = expirationCal.get(Calendar.MONTH);
368             expirationDay = expirationCal.get(Calendar.DATE);
369             expirationYear = expirationCal.get(Calendar.YEAR);
370             expirationHour = expirationCal.get(Calendar.HOUR);
371             expirationMinute = expirationCal.get(Calendar.MINUTE);
372             neverExpire = false;
373 
374             if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
375                 expirationHour += 12;
376             }
377         }
378 
379         boolean addCommunityPermissions = true;
380         boolean addGuestPermissions = true;
381 
382         PollsQuestion existingQuestion = null;
383 
384         if (context.getDataStrategy().equals(
385                 PortletDataHandlerKeys.DATA_STRATEGY_MIRROR)) {
386             existingQuestion =  PollsQuestionUtil.fetchByUUID_G(
387                 question.getUuid(), context.getGroupId());
388 
389             if (existingQuestion == null) {
390                 existingQuestion = PollsQuestionLocalServiceUtil.addQuestion(
391                     question.getUuid(), userId, plid, question.getTitle(),
392                     question.getDescription(), expirationMonth, expirationDay,
393                     expirationYear, expirationHour, expirationMinute,
394                     neverExpire, addCommunityPermissions, addGuestPermissions);
395             }
396             else {
397                 existingQuestion = PollsQuestionLocalServiceUtil.updateQuestion(
398                     userId, existingQuestion.getQuestionId(),
399                     question.getTitle(), question.getDescription(),
400                     expirationMonth, expirationDay, expirationYear,
401                     expirationHour, expirationMinute, neverExpire);
402             }
403         }
404         else {
405             existingQuestion = PollsQuestionLocalServiceUtil.addQuestion(
406                 userId, plid, question.getTitle(), question.getDescription(),
407                 expirationMonth, expirationDay, expirationYear, expirationHour,
408                 expirationMinute, neverExpire, addCommunityPermissions,
409                 addGuestPermissions);
410         }
411 
412         questionPKs.put(
413             question.getQuestionId(), existingQuestion.getQuestionId());
414     }
415 
416     protected void importVote(
417             PortletDataContext context, Map<Long, Long> questionPKs,
418             Map<Long, Long> choicePKs, PollsVote vote)
419         throws Exception {
420 
421         long userId = context.getUserId(vote.getUserUuid());
422         long questionId = MapUtil.getLong(
423             questionPKs, vote.getQuestionId(), vote.getQuestionId());
424         long choiceId = MapUtil.getLong(
425             choicePKs, vote.getChoiceId(), vote.getChoiceId());
426 
427         try {
428             PollsQuestionUtil.findByPrimaryKey(questionId);
429             PollsChoiceUtil.findByPrimaryKey(choiceId);
430 
431             PollsVoteLocalServiceUtil.addVote(
432                 userId, questionId, choiceId);
433         }
434         catch (DuplicateVoteException dve) {
435         }
436         catch (NoSuchQuestionException nsqe) {
437             _log.error(
438                 "Could not find the question for vote " + vote.getVoteId());
439         }
440         catch (NoSuchChoiceException nsve) {
441             _log.error(
442                 "Could not find the choice for vote " + vote.getVoteId());
443         }
444     }
445 
446     private static final String _NAMESPACE = "polls";
447 
448     private static final PortletDataHandlerBoolean _questions =
449         new PortletDataHandlerBoolean(_NAMESPACE, "questions", true, true);
450 
451     private static final PortletDataHandlerBoolean _votes =
452         new PortletDataHandlerBoolean(_NAMESPACE, "votes");
453 
454     private static Log _log =
455         LogFactory.getLog(PollsPortletDataHandlerImpl.class);
456 
457 }