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