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