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