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.getScopeGroupId());
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.getScopeGroupId());
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.getScopeGroupId());
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.getScopeGroupId());
295 
296             Document doc = SAXReaderUtil.createDocument();
297 
298             Element root = doc.addElement("polls-data");
299 
300             root.addAttribute(
301                 "group-id", String.valueOf(context.getScopeGroupId()));
302 
303             Element questionsEl = root.addElement("questions");
304             Element choicesEl = root.addElement("choices");
305             Element votesEl = root.addElement("votes");
306 
307             List<PollsQuestion> questions = PollsQuestionUtil.findByGroupId(
308                 context.getScopeGroupId());
309 
310             for (PollsQuestion question : questions) {
311                 exportQuestion(
312                     context, questionsEl, choicesEl, votesEl, question);
313             }
314 
315             return doc.formattedString();
316         }
317         catch (Exception e) {
318             throw new PortletDataException(e);
319         }
320     }
321 
322     public PortletDataHandlerControl[] getExportControls() {
323         return new PortletDataHandlerControl[] {_questions, _votes};
324     }
325 
326     public PortletDataHandlerControl[] getImportControls() {
327         return new PortletDataHandlerControl[] {_questions, _votes};
328     }
329 
330     public PortletPreferences importData(
331             PortletDataContext context, String portletId,
332             PortletPreferences preferences, String data)
333         throws PortletDataException {
334 
335         try {
336             context.importPermissions(
337                 "com.liferay.portlet.polls", context.getSourceGroupId(),
338                 context.getScopeGroupId());
339 
340             Document doc = SAXReaderUtil.read(data);
341 
342             Element root = doc.getRootElement();
343 
344             List<Element> questionEls = root.element("questions").elements(
345                 "question");
346 
347             Map<Long, Long> questionPKs =
348                 (Map<Long, Long>)context.getNewPrimaryKeysMap(
349                     PollsQuestion.class);
350 
351             for (Element questionEl : questionEls) {
352                 String path = questionEl.attributeValue("path");
353 
354                 if (!context.isPathNotProcessed(path)) {
355                     continue;
356                 }
357 
358                 PollsQuestion question =
359                     (PollsQuestion)context.getZipEntryAsObject(path);
360 
361                 importQuestion(context, questionPKs, question);
362             }
363 
364             List<Element> choiceEls = root.element("choices").elements(
365                 "choice");
366 
367             Map<Long, Long> choicePKs =
368                 (Map<Long, Long>)context.getNewPrimaryKeysMap(
369                     PollsChoice.class);
370 
371             for (Element choiceEl : choiceEls) {
372                 String path = choiceEl.attributeValue("path");
373 
374                 if (!context.isPathNotProcessed(path)) {
375                     continue;
376                 }
377 
378                 PollsChoice choice = (PollsChoice)context.getZipEntryAsObject(
379                     path);
380 
381                 importChoice(context, questionPKs, choicePKs, choice);
382             }
383 
384             if (context.getBooleanParameter(_NAMESPACE, "votes")) {
385                 List<Element> voteEls = root.element("votes").elements("vote");
386 
387                 for (Element voteEl : voteEls) {
388                     String path = voteEl.attributeValue("path");
389 
390                     if (!context.isPathNotProcessed(path)) {
391                         continue;
392                     }
393 
394                     PollsVote vote = (PollsVote)context.getZipEntryAsObject(
395                         path);
396 
397                     importVote(context, questionPKs, choicePKs, vote);
398                 }
399             }
400 
401             return null;
402         }
403         catch (Exception e) {
404             throw new PortletDataException(e);
405         }
406     }
407 
408     public boolean isAlwaysExportable() {
409         return _ALWAYS_EXPORTABLE;
410     }
411 
412     protected static void exportChoice(
413             PortletDataContext context, Element questionsEl, PollsChoice choice)
414         throws SystemException {
415 
416         String path = getChoicePath(context, choice);
417 
418         if (!context.isPathNotProcessed(path)) {
419             return;
420         }
421 
422         Element choiceEl = questionsEl.addElement("choice");
423 
424         choiceEl.addAttribute("path", path);
425 
426         context.addZipEntry(path, choice);
427     }
428 
429     protected static void exportVote(
430             PortletDataContext context, Element questionsEl, PollsVote vote)
431         throws SystemException {
432 
433         String path = getVotePath(context, vote);
434 
435         if (!context.isPathNotProcessed(path)) {
436             return;
437         }
438 
439         Element voteEl = questionsEl.addElement("vote");
440 
441         voteEl.addAttribute("path", path);
442 
443         context.addZipEntry(path, vote);
444     }
445 
446     protected static String getChoicePath(
447         PortletDataContext context, PollsChoice choice) {
448 
449         StringBundler sb = new StringBundler(6);
450 
451         sb.append(context.getPortletPath(PortletKeys.POLLS));
452         sb.append("/questions/");
453         sb.append(choice.getQuestionId());
454         sb.append("/choices/");
455         sb.append(choice.getChoiceId());
456         sb.append(".xml");
457 
458         return sb.toString();
459     }
460 
461     protected static String getQuestionPath(
462         PortletDataContext context, PollsQuestion question) {
463 
464         StringBundler sb = new StringBundler(4);
465 
466         sb.append(context.getPortletPath(PortletKeys.POLLS));
467         sb.append("/questions/");
468         sb.append(question.getQuestionId());
469         sb.append(".xml");
470 
471         return sb.toString();
472     }
473 
474     protected static String getVotePath(
475         PortletDataContext context, PollsVote vote) {
476 
477         StringBundler sb = new StringBundler(6);
478 
479         sb.append(context.getPortletPath(PortletKeys.POLLS));
480         sb.append("/questions/");
481         sb.append(vote.getQuestionId());
482         sb.append("/votes/");
483         sb.append(vote.getVoteId());
484         sb.append(".xml");
485 
486         return sb.toString();
487     }
488 
489     private static final boolean _ALWAYS_EXPORTABLE = true;
490 
491     private static final String _NAMESPACE = "polls";
492 
493     private static final PortletDataHandlerBoolean _questions =
494         new PortletDataHandlerBoolean(_NAMESPACE, "questions", true, true);
495 
496     private static final PortletDataHandlerBoolean _votes =
497         new PortletDataHandlerBoolean(_NAMESPACE, "votes");
498 
499     private static Log _log = LogFactoryUtil.getLog(
500         PollsPortletDataHandlerImpl.class);
501 
502 }