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