001
014
015 package com.liferay.portlet.polls.lar;
016
017 import com.liferay.portal.kernel.lar.BasePortletDataHandler;
018 import com.liferay.portal.kernel.lar.PortletDataContext;
019 import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
020 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
021 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
022 import com.liferay.portal.kernel.util.MapUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.xml.Document;
025 import com.liferay.portal.kernel.xml.Element;
026 import com.liferay.portal.kernel.xml.SAXReaderUtil;
027 import com.liferay.portal.service.ServiceContext;
028 import com.liferay.portal.util.PortletKeys;
029 import com.liferay.portlet.polls.DuplicateVoteException;
030 import com.liferay.portlet.polls.model.PollsChoice;
031 import com.liferay.portlet.polls.model.PollsQuestion;
032 import com.liferay.portlet.polls.model.PollsVote;
033 import com.liferay.portlet.polls.service.PollsChoiceLocalServiceUtil;
034 import com.liferay.portlet.polls.service.PollsQuestionLocalServiceUtil;
035 import com.liferay.portlet.polls.service.PollsVoteLocalServiceUtil;
036 import com.liferay.portlet.polls.service.persistence.PollsChoiceFinderUtil;
037 import com.liferay.portlet.polls.service.persistence.PollsChoiceUtil;
038 import com.liferay.portlet.polls.service.persistence.PollsQuestionUtil;
039 import com.liferay.portlet.polls.service.persistence.PollsVoteUtil;
040
041 import java.util.Calendar;
042 import java.util.Date;
043 import java.util.List;
044 import java.util.Map;
045
046 import javax.portlet.PortletPreferences;
047
048
052 public class PollsPortletDataHandlerImpl extends BasePortletDataHandler {
053
054 @Override
055 public PortletDataHandlerControl[] getExportControls() {
056 return new PortletDataHandlerControl[] {_questions, _votes};
057 }
058
059 @Override
060 public PortletDataHandlerControl[] getImportControls() {
061 return new PortletDataHandlerControl[] {_questions, _votes};
062 }
063
064 @Override
065 public boolean isAlwaysExportable() {
066 return _ALWAYS_EXPORTABLE;
067 }
068
069 @Override
070 public boolean isDataLocalized() {
071 return _DATA_LOCALIZED;
072 }
073
074 protected static void exportChoice(
075 PortletDataContext portletDataContext, Element questionsElement,
076 PollsChoice choice)
077 throws Exception {
078
079 String path = getChoicePath(portletDataContext, choice);
080
081 if (!portletDataContext.isPathNotProcessed(path)) {
082 return;
083 }
084
085 Element choiceElement = questionsElement.addElement("choice");
086
087 portletDataContext.addClassedModel(
088 choiceElement, path, choice, _NAMESPACE);
089 }
090
091 protected static void exportQuestion(
092 PortletDataContext portletDataContext, Element questionsElement,
093 Element choicesElement, Element votesElement,
094 PollsQuestion question)
095 throws Exception {
096
097 if (!portletDataContext.isWithinDateRange(question.getModifiedDate())) {
098 return;
099 }
100
101 String path = getQuestionPath(portletDataContext, question);
102
103 if (!portletDataContext.isPathNotProcessed(path)) {
104 return;
105 }
106
107 Element questionElement = questionsElement.addElement("question");
108
109 List<PollsChoice> choices = PollsChoiceUtil.findByQuestionId(
110 question.getQuestionId());
111
112 for (PollsChoice choice : choices) {
113 exportChoice(portletDataContext, choicesElement, choice);
114 }
115
116 if (portletDataContext.getBooleanParameter(_NAMESPACE, "votes")) {
117 List<PollsVote> votes = PollsVoteUtil.findByQuestionId(
118 question.getQuestionId());
119
120 for (PollsVote vote : votes) {
121 exportVote(portletDataContext, votesElement, vote);
122 }
123 }
124
125 portletDataContext.addClassedModel(
126 questionElement, path, question, _NAMESPACE);
127 }
128
129 protected static void exportVote(
130 PortletDataContext portletDataContext, Element questionsElement,
131 PollsVote vote)
132 throws Exception {
133
134 String path = getVotePath(portletDataContext, vote);
135
136 if (!portletDataContext.isPathNotProcessed(path)) {
137 return;
138 }
139
140 Element voteElement = questionsElement.addElement("vote");
141
142 portletDataContext.addClassedModel(voteElement, path, vote, _NAMESPACE);
143 }
144
145 protected static String getChoicePath(
146 PortletDataContext portletDataContext, PollsChoice choice) {
147
148 StringBundler sb = new StringBundler(6);
149
150 sb.append(portletDataContext.getPortletPath(PortletKeys.POLLS));
151 sb.append("/questions/");
152 sb.append(choice.getQuestionId());
153 sb.append("/choices/");
154 sb.append(choice.getChoiceId());
155 sb.append(".xml");
156
157 return sb.toString();
158 }
159
160 protected static String getQuestionPath(
161 PortletDataContext portletDataContext, PollsQuestion question) {
162
163 StringBundler sb = new StringBundler(4);
164
165 sb.append(portletDataContext.getPortletPath(PortletKeys.POLLS));
166 sb.append("/questions/");
167 sb.append(question.getQuestionId());
168 sb.append(".xml");
169
170 return sb.toString();
171 }
172
173 protected static String getVotePath(
174 PortletDataContext portletDataContext, PollsVote vote) {
175
176 StringBundler sb = new StringBundler(6);
177
178 sb.append(portletDataContext.getPortletPath(PortletKeys.POLLS));
179 sb.append("/questions/");
180 sb.append(vote.getQuestionId());
181 sb.append("/votes/");
182 sb.append(vote.getVoteId());
183 sb.append(".xml");
184
185 return sb.toString();
186 }
187
188 protected static void importChoice(
189 PortletDataContext portletDataContext, PollsChoice choice)
190 throws Exception {
191
192 Map<Long, Long> questionIds =
193 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
194 PollsQuestion.class);
195
196 long questionId = MapUtil.getLong(
197 questionIds, choice.getQuestionId(), choice.getQuestionId());
198
199 PollsChoice importedChoice = null;
200
201 if (portletDataContext.isDataStrategyMirror()) {
202 PollsChoice existingChoice = PollsChoiceFinderUtil.fetchByUUID_G(
203 choice.getUuid(), portletDataContext.getScopeGroupId());
204
205 if (existingChoice == null) {
206 ServiceContext serviceContext = new ServiceContext();
207
208 serviceContext.setUuid(choice.getUuid());
209
210 importedChoice = PollsChoiceLocalServiceUtil.addChoice(
211 questionId, choice.getName(), choice.getDescription(),
212 serviceContext);
213 }
214 else {
215 importedChoice = PollsChoiceLocalServiceUtil.updateChoice(
216 existingChoice.getChoiceId(), questionId, choice.getName(),
217 choice.getDescription());
218 }
219 }
220 else {
221 importedChoice = PollsChoiceLocalServiceUtil.addChoice(
222 questionId, choice.getName(), choice.getDescription(),
223 new ServiceContext());
224 }
225
226 portletDataContext.importClassedModel(
227 choice, importedChoice, _NAMESPACE);
228 }
229
230 protected static void importQuestion(
231 PortletDataContext portletDataContext, Element questionElement,
232 PollsQuestion question)
233 throws Exception {
234
235 long userId = portletDataContext.getUserId(question.getUserUuid());
236
237 Date expirationDate = question.getExpirationDate();
238
239 int expirationMonth = 0;
240 int expirationDay = 0;
241 int expirationYear = 0;
242 int expirationHour = 0;
243 int expirationMinute = 0;
244 boolean neverExpire = true;
245
246 if (expirationDate != null) {
247 Calendar expirationCal = CalendarFactoryUtil.getCalendar();
248
249 expirationCal.setTime(expirationDate);
250
251 expirationMonth = expirationCal.get(Calendar.MONTH);
252 expirationDay = expirationCal.get(Calendar.DATE);
253 expirationYear = expirationCal.get(Calendar.YEAR);
254 expirationHour = expirationCal.get(Calendar.HOUR);
255 expirationMinute = expirationCal.get(Calendar.MINUTE);
256 neverExpire = false;
257
258 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
259 expirationHour += 12;
260 }
261 }
262
263 ServiceContext serviceContext = portletDataContext.createServiceContext(
264 questionElement, question, _NAMESPACE);
265
266 PollsQuestion importedQuestion = null;
267
268 if (portletDataContext.isDataStrategyMirror()) {
269 PollsQuestion existingQuestion = PollsQuestionUtil.fetchByUUID_G(
270 question.getUuid(), portletDataContext.getScopeGroupId());
271
272 if (existingQuestion == null) {
273 serviceContext.setUuid(question.getUuid());
274
275 importedQuestion = PollsQuestionLocalServiceUtil.addQuestion(
276 userId, question.getTitleMap(),
277 question.getDescriptionMap(), expirationMonth,
278 expirationDay, expirationYear, expirationHour,
279 expirationMinute, neverExpire, null, serviceContext);
280 }
281 else {
282 importedQuestion = PollsQuestionLocalServiceUtil.updateQuestion(
283 userId, existingQuestion.getQuestionId(),
284 question.getTitleMap(), question.getDescriptionMap(),
285 expirationMonth, expirationDay, expirationYear,
286 expirationHour, expirationMinute, neverExpire, null,
287 serviceContext);
288 }
289 }
290 else {
291 importedQuestion = PollsQuestionLocalServiceUtil.addQuestion(
292 userId, question.getTitleMap(), question.getDescriptionMap(),
293 expirationMonth, expirationDay, expirationYear, expirationHour,
294 expirationMinute, neverExpire, null, serviceContext);
295 }
296
297 portletDataContext.importClassedModel(
298 question, importedQuestion, _NAMESPACE);
299 }
300
301 protected static void importVote(
302 PortletDataContext portletDataContext, PollsVote vote)
303 throws Exception {
304
305 Map<Long, Long> questionIds =
306 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
307 PollsQuestion.class);
308
309 long questionId = MapUtil.getLong(
310 questionIds, vote.getQuestionId(), vote.getQuestionId());
311
312 Map<Long, Long> choiceIds =
313 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
314 PollsChoice.class);
315
316 long choiceId = MapUtil.getLong(
317 choiceIds, vote.getChoiceId(), vote.getChoiceId());
318
319 ServiceContext serviceContext = new ServiceContext();
320
321 serviceContext.setCreateDate(vote.getVoteDate());
322
323 try {
324 PollsVoteLocalServiceUtil.addVote(
325 vote.getUserId(), questionId, choiceId, serviceContext);
326 }
327 catch (DuplicateVoteException dve) {
328 }
329 }
330
331 @Override
332 protected PortletPreferences doDeleteData(
333 PortletDataContext portletDataContext, String portletId,
334 PortletPreferences portletPreferences)
335 throws Exception {
336
337 if (!portletDataContext.addPrimaryKey(
338 PollsPortletDataHandlerImpl.class, "deleteData")) {
339
340 PollsQuestionLocalServiceUtil.deleteQuestions(
341 portletDataContext.getScopeGroupId());
342 }
343
344 return null;
345 }
346
347 @Override
348 protected String doExportData(
349 PortletDataContext portletDataContext, String portletId,
350 PortletPreferences portletPreferences)
351 throws Exception {
352
353 portletDataContext.addPermissions(
354 "com.liferay.portlet.polls", portletDataContext.getScopeGroupId());
355
356 Document document = SAXReaderUtil.createDocument();
357
358 Element rootElement = document.addElement("polls-data");
359
360 rootElement.addAttribute(
361 "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
362
363 Element questionsElement = rootElement.addElement("questions");
364 Element choicesElement = rootElement.addElement("choices");
365 Element votesElement = rootElement.addElement("votes");
366
367 List<PollsQuestion> questions = PollsQuestionUtil.findByGroupId(
368 portletDataContext.getScopeGroupId());
369
370 for (PollsQuestion question : questions) {
371 exportQuestion(
372 portletDataContext, questionsElement, choicesElement,
373 votesElement, question);
374 }
375
376 return document.formattedString();
377 }
378
379 @Override
380 protected PortletPreferences doImportData(
381 PortletDataContext portletDataContext, String portletId,
382 PortletPreferences portletPreferences, String data)
383 throws Exception {
384
385 portletDataContext.importPermissions(
386 "com.liferay.portlet.polls", portletDataContext.getSourceGroupId(),
387 portletDataContext.getScopeGroupId());
388
389 Document document = SAXReaderUtil.read(data);
390
391 Element rootElement = document.getRootElement();
392
393 Element questionsElement = rootElement.element("questions");
394
395 for (Element questionElement : questionsElement.elements("question")) {
396 String path = questionElement.attributeValue("path");
397
398 if (!portletDataContext.isPathNotProcessed(path)) {
399 continue;
400 }
401
402 PollsQuestion question =
403 (PollsQuestion)portletDataContext.getZipEntryAsObject(path);
404
405 importQuestion(portletDataContext, questionElement, question);
406 }
407
408 Element choicesElement = rootElement.element("choices");
409
410 for (Element choiceElement : choicesElement.elements("choice")) {
411 String path = choiceElement.attributeValue("path");
412
413 if (!portletDataContext.isPathNotProcessed(path)) {
414 continue;
415 }
416
417 PollsChoice choice =
418 (PollsChoice)portletDataContext.getZipEntryAsObject(path);
419
420 importChoice(portletDataContext, choice);
421 }
422
423 if (portletDataContext.getBooleanParameter(_NAMESPACE, "votes")) {
424 Element votesElement = rootElement.element("votes");
425
426 for (Element voteElement : votesElement.elements("vote")) {
427 String path = voteElement.attributeValue("path");
428
429 if (!portletDataContext.isPathNotProcessed(path)) {
430 continue;
431 }
432
433 PollsVote vote =
434 (PollsVote)portletDataContext.getZipEntryAsObject(path);
435
436 importVote(portletDataContext, vote);
437 }
438 }
439
440 return null;
441 }
442
443 private static final boolean _ALWAYS_EXPORTABLE = true;
444
445 private static final boolean _DATA_LOCALIZED = true;
446
447 private static final String _NAMESPACE = "polls";
448
449 private static PortletDataHandlerBoolean _questions =
450 new PortletDataHandlerBoolean(_NAMESPACE, "questions", true, true);
451 private static PortletDataHandlerBoolean _votes =
452 new PortletDataHandlerBoolean(_NAMESPACE, "votes");
453
454 }