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