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