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