001/*
002 *  Copyright 2015 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.survey.actions;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.jcr.RepositoryException;
024
025import org.apache.avalon.framework.parameters.Parameters;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.cocoon.ProcessingException;
029import org.apache.cocoon.acting.ServiceableAction;
030import org.apache.cocoon.environment.ObjectModelHelper;
031import org.apache.cocoon.environment.Redirector;
032import org.apache.cocoon.environment.Request;
033import org.apache.cocoon.environment.SourceResolver;
034import org.apache.commons.lang.StringUtils;
035
036import org.ametys.core.cocoon.JSonReader;
037import org.ametys.plugins.repository.AmetysObject;
038import org.ametys.plugins.repository.AmetysObjectIterable;
039import org.ametys.plugins.repository.AmetysObjectResolver;
040import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
041import org.ametys.plugins.repository.jcr.JCRAmetysObject;
042import org.ametys.plugins.survey.dao.SurveyDAO;
043import org.ametys.plugins.survey.repository.Survey;
044import org.ametys.plugins.survey.repository.SurveyPage;
045import org.ametys.plugins.survey.repository.SurveyQuestion;
046import org.ametys.web.repository.site.SiteManager;
047
048/**
049 * SAX events for surveys, survey pages and survey questions
050 *
051 */
052public class GetSurveysAction extends ServiceableAction
053{
054    /** The String representing the type of a survey node */
055    protected static final String SURVEY_TYPE = "survey";
056    /** The String representing the type of a survey page node */
057    protected static final String SURVEY_PAGE_TYPE = "page";
058    /** The String representing the type of a survey question node */
059    protected static final String SURVEY_QUESTION_TYPE = "question";
060    
061    /** The Ametys object resolver */
062    protected AmetysObjectResolver _resolver;
063    /** The site manager */
064    protected SiteManager _siteManager;
065    /** The survey DAO */
066    protected SurveyDAO _surveyDAO;
067    
068    @Override
069    public void service(ServiceManager serviceManager) throws ServiceException
070    {
071        super.service(serviceManager);
072        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
073        _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE);
074        _surveyDAO = (SurveyDAO) serviceManager.lookup(SurveyDAO.ROLE);
075    }
076
077    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
078    {
079        @SuppressWarnings("unchecked")
080        Map jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
081        
082        String nodeId = (String) jsParameters.get("node");
083        //String nodeType = (String) jsParameters.get("nodeType");
084        String lang = (String) jsParameters.get("lang");
085        String siteName = (String) jsParameters.get("siteName");
086        
087        boolean surveyOnly = (Boolean) jsParameters.get("surveyOnly");
088        
089        List<Map<String, Object>> nodes = new ArrayList<>();
090        
091        try
092        {
093            if (StringUtils.isEmpty(nodeId) || "survey-root-node".equals(nodeId))
094            {
095                ModifiableTraversableAmetysObject rootNode = getSurveyRootNode(siteName, lang);
096                
097                AmetysObjectIterable<Survey> surveys = rootNode.getChildren();
098                for (Survey survey : surveys)
099                {
100                    nodes.add(surveyToJSON(survey, surveyOnly));
101                }
102            }
103            else if (!surveyOnly)
104            {
105                AmetysObject object = _resolver.resolveById(nodeId);
106                if (object instanceof Survey)
107                {
108                    for (AmetysObject page : ((Survey) object).getPages())
109                    {
110                        nodes.add(surveyPageToJSON((SurveyPage) page));
111                    }
112                }
113                else if (object instanceof SurveyPage)
114                {
115                    for (AmetysObject question : ((SurveyPage) object).getChildren())
116                    {
117                        nodes.add(surveyQuestionToJSON((SurveyQuestion) question));
118                    }
119                }
120            }
121        }
122        catch (RepositoryException e)
123        {
124            throw new ProcessingException("Unable to get surveys", e);
125        }
126        
127        Map<String, Object> result = new HashMap<>();
128        result.put("children", nodes);
129        
130        Request request = ObjectModelHelper.getRequest(objectModel);
131        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
132        
133        return EMPTY_MAP;
134    }
135    
136    /**
137     * Gets survey's properties to JSON format.
138     * @param survey The survey.
139     * @param surveyOnly true to display survey only
140     * @return The survey's properties
141     */
142    protected Map<String, Object> surveyToJSON(Survey survey, boolean surveyOnly)
143    {
144        Map<String, Object> infos = new HashMap<>();
145        
146        infos.put("id", survey.getId());
147        infos.put("type", SURVEY_TYPE);
148        infos.put("name", survey.getName());
149        infos.put("private", _surveyDAO.isPrivate(survey));
150        infos.put("validated", survey.isValidated());
151        infos.put("title", survey.getTitle());
152        infos.put("label", survey.getLabel());
153        infos.put("description", survey.getDescription());
154        infos.put("endingMessage", survey.getEndingMessage());
155        infos.put("hasChildren", !surveyOnly && survey.getPages().size() > 0);
156        
157        return infos;
158    }
159    
160    /**
161     * Gets survey page's properties to JSON format.
162     * @param page The survey page
163     * @return The page's properties
164     */
165    protected Map<String, Object> surveyPageToJSON(SurveyPage page)
166    {
167        Map<String, Object> infos = new HashMap<>();
168        
169        infos.put("id", page.getId());
170        infos.put("type", SURVEY_PAGE_TYPE);
171        infos.put("label", page.getLabel());
172        infos.put("title", page.getTitle());
173        infos.put("description", page.getDescription());
174        infos.put("hasChildren", page.getChildren().getSize() > 0);
175        
176        return infos;
177    }
178    
179    /**
180     * Gets survey question's properties to JSON format.
181     * @param question The survey question
182     * @return The question's properties
183     */
184    protected Map<String, Object> surveyQuestionToJSON(SurveyQuestion question)
185    {
186        Map<String, Object> infos = new HashMap<>();
187        
188        infos.put("id", question.getId());
189        infos.put("type", SURVEY_QUESTION_TYPE);
190        infos.put("name", question.getName());
191        infos.put("questionType", question.getType().name());
192        infos.put("mandatory", question.isMandatory());
193        infos.put("validated", question.getSurvey().isValidated());
194        infos.put("label", question.getLabel());
195        infos.put("title", question.getTitle());
196        infos.put("hasChildren", false);
197        
198        return infos;
199    }
200    
201    /**
202     * Get the root node for surveys
203     * @param siteName the site name
204     * @param lang the language
205     * @return the root node
206     * @throws RepositoryException if an error occurs when manipulating the repository
207     */
208    protected ModifiableTraversableAmetysObject getSurveyRootNode (String siteName, String lang) throws RepositoryException
209    {
210        ModifiableTraversableAmetysObject pluginsNode = _siteManager.getSite(siteName).getRootPlugins();
211        
212        ModifiableTraversableAmetysObject surveyNode = null;
213        if (!pluginsNode.hasChild("survey"))
214        {
215            surveyNode = ((ModifiableTraversableAmetysObject) pluginsNode.createChild("survey", "ametys:unstructured")).createChild("ametys:surveys", "ametys:unstructured");
216        }
217        else
218        {
219            surveyNode = pluginsNode.getChild("survey/ametys:surveys");
220        }
221        
222        if (!surveyNode.hasChild(lang))
223        {
224            surveyNode.createChild(lang, "ametys:unstructured");
225            ((JCRAmetysObject) pluginsNode).getNode().getSession().save();
226        }
227        
228        return pluginsNode.getChild("survey/ametys:surveys/" + lang);
229    }
230}