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