001/*
002 *  Copyright 2011 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.repository;
017
018import java.util.List;
019
020import javax.jcr.Node;
021import javax.jcr.PathNotFoundException;
022import javax.jcr.RepositoryException;
023
024import org.ametys.plugins.repository.AmetysObject;
025import org.ametys.plugins.repository.AmetysObjectIterable;
026import org.ametys.plugins.repository.AmetysRepositoryException;
027import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
028import org.ametys.plugins.repository.RepositoryConstants;
029import org.ametys.plugins.survey.repository.SurveyRule.RuleType;
030
031/**
032 * {@link AmetysObject} for storing survey
033 */
034public class SurveyPage extends AbstractSurveyElement<SurveyPageFactory>
035{
036    /** Constants for title metadata. */
037    private static final String __PROPERTY_LABEL = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":label";
038    /** Constants for title metadata. */
039    private static final String __PROPERTY_TITLE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":title";
040    /** Constants for description metadata. */
041    private static final String __PROPERTY_DESC = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":description";
042    /** Constants for rules metadata. */
043    private static final String __PROPERTY_RULE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":rule";
044    private static final String __PROPERTY_RULE_TYPE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":rule";
045    private static final String __PROPERTY_RULE_PAGE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":page";
046    
047    /**
048     * Creates a {@link SurveyPage}.
049     * @param node the node backing this {@link AmetysObject}.
050     * @param parentPath the parent path in the Ametys hierarchy.
051     * @param factory the {@link SurveyFactory} which creates the AmetysObject.
052     */
053    public SurveyPage(Node node, String parentPath, SurveyPageFactory factory)
054    {
055        super(node, parentPath, factory);
056    }
057
058    /**
059     * Retrieves the title.
060     * @return the title.
061     * @throws AmetysRepositoryException if an error occurs.
062     */
063    public String getTitle() throws AmetysRepositoryException
064    {
065        try
066        {
067            return getNode().getProperty(__PROPERTY_TITLE).getString();
068        }
069        catch (PathNotFoundException e)
070        {
071            return null;
072        }
073        catch (RepositoryException e)
074        {
075            throw new AmetysRepositoryException("Unable to get title property", e);
076        }
077    }
078    
079    /**
080     * Set the title.
081     * @param title the title.
082     * @throws AmetysRepositoryException if an error occurs.
083     */
084    public void setTitle(String title) throws AmetysRepositoryException
085    {
086        try
087        {
088            getNode().setProperty(__PROPERTY_TITLE, title);
089        }
090        catch (RepositoryException e)
091        {
092            throw new AmetysRepositoryException("Unable to set title property", e);
093        }
094    }
095    
096    /**
097     * Retrieves the survey name.
098     * @return the the survey name.
099     * @throws AmetysRepositoryException if an error occurs.
100     */
101    public String getLabel() throws AmetysRepositoryException
102    {
103        try
104        {
105            return getNode().getProperty(__PROPERTY_LABEL).getString();
106        }
107        catch (PathNotFoundException e)
108        {
109            return null;
110        }
111        catch (RepositoryException e)
112        {
113            throw new AmetysRepositoryException("Unable to get label property", e);
114        }
115    }
116    
117    /**
118     * Set the survey name.
119     * @param name the survey name.
120     * @throws AmetysRepositoryException if an error occurs.
121     */
122    public void setLabel(String name) throws AmetysRepositoryException
123    {
124        try
125        {
126            getNode().setProperty(__PROPERTY_LABEL, name);
127        }
128        catch (RepositoryException e)
129        {
130            throw new AmetysRepositoryException("Unable to set label property", e);
131        }
132    }
133    
134    /**
135     * Retrieves the description.
136     * @return the description.
137     * @throws AmetysRepositoryException if an error occurs.
138     */
139    public String getDescription() throws AmetysRepositoryException
140    {
141        try
142        {
143            return getNode().getProperty(__PROPERTY_DESC).getString();
144        }
145        catch (PathNotFoundException e)
146        {
147            return null;
148        }
149        catch (RepositoryException e)
150        {
151            throw new AmetysRepositoryException("Unable to get description property", e);
152        }
153    }
154    
155    /**
156     * Set the description.
157     * @param description the description.
158     * @throws AmetysRepositoryException if an error occurs.
159     */
160    public void setDescription(String description) throws AmetysRepositoryException
161    {
162        try
163        {
164            getNode().setProperty(__PROPERTY_DESC, description);
165        }
166        catch (RepositoryException e)
167        {
168            throw new AmetysRepositoryException("Unable to set description property", e);
169        }
170    }
171    
172    /**
173     * Set the rule for branching
174     * @param ruleType the rule type
175     * @param page the page to jump or skip. Can be null.
176     * @throws AmetysRepositoryException if an error occurs.
177     */
178    public void setRule (RuleType ruleType, String page) throws AmetysRepositoryException
179    {
180        try
181        {
182            if (!getNode().hasNode(__PROPERTY_RULE))
183            {
184                getNode().addNode(__PROPERTY_RULE, "ametys:survey-rule");
185            }
186            
187            
188            Node ruleNode = getNode().getNode(__PROPERTY_RULE);
189            
190            ruleNode.setProperty(__PROPERTY_RULE_TYPE, ruleType.name());
191            if (ruleType == RuleType.JUMP || ruleType == RuleType.SKIP)
192            {
193                ruleNode.setProperty(__PROPERTY_RULE_PAGE, page);
194            }
195        }
196        catch (RepositoryException e)
197        {
198            throw new AmetysRepositoryException("Unable to add rule", e);
199        }
200    }
201    
202    /**
203     * Delete the rule
204     * @throws AmetysRepositoryException  if an error occurs.
205     */
206    public void deleteRule () throws AmetysRepositoryException
207    {
208        try
209        {
210            if (getNode().hasNode(__PROPERTY_RULE))
211            {
212                getNode().getNode(__PROPERTY_RULE).remove();
213            }
214        }
215        catch (RepositoryException e)
216        {
217            throw new AmetysRepositoryException("Unable to delete rule", e);
218        }
219    }
220    
221    /**
222     * Determines if the page has a rule
223     * @return true if the page has a rule
224     * @throws AmetysRepositoryException if an error occurs.
225     */
226    public boolean hasRule () throws AmetysRepositoryException
227    {
228        try
229        {
230            return getNode().hasNode(__PROPERTY_RULE);
231        }
232        catch (RepositoryException e)
233        {
234            throw new AmetysRepositoryException("Unable to get rule property", e);
235        }
236    }
237    
238    /**
239     * Get rule
240     * @return the rules
241     * @throws AmetysRepositoryException if an error occurs.
242     */
243    public SurveyRule getRule () throws AmetysRepositoryException
244    {
245        try
246        {
247            if (getNode().hasNode(__PROPERTY_RULE))
248            {
249                Node node = getNode().getNode(__PROPERTY_RULE);
250                RuleType type = RuleType.valueOf(node.getProperty(__PROPERTY_RULE_TYPE).getString());
251                String page = null;
252                if (node.hasProperty(__PROPERTY_RULE_PAGE))
253                {
254                    page = node.getProperty(__PROPERTY_RULE_PAGE).getString();
255                }
256                
257                return new SurveyRule(type, page);
258            }
259            
260            return null;
261        }
262        catch (RepositoryException e)
263        {
264            throw new AmetysRepositoryException("Unable to get rule property", e);
265        }
266    }
267    
268    /**
269     * Get the Survey to which this page belongs.
270     * @return the Survey to which this page belongs.
271     * @throws AmetysRepositoryException if an error occurs when retrieving the survey of a page
272     */
273    public Survey getSurvey() throws AmetysRepositoryException
274    {
275        return getParent();
276    }
277    
278    /**
279     * Determines if question exists
280     * @param name The question name
281     * @return &lt;code&gt;true&lt;/code&gt; true if the question exists
282     * @throws AmetysRepositoryException if an error occurs when looking for a survey question
283     */
284    public boolean hasQuestion (String name) throws AmetysRepositoryException
285    {
286        return hasChild(name);
287    }
288    
289    /**
290     * Get a question.
291     * @param name the question name.
292     * @return the question.
293     * @throws AmetysRepositoryException if an error occurs when retrieving a question of a survey
294     */
295    public SurveyQuestion getQuestion(String name) throws AmetysRepositoryException
296    {
297        return getChild(name);
298    }
299    
300    /**
301     * Get the page's questions.
302     * @return the page's questions.
303     * @throws AmetysRepositoryException if an error occurs when retrieving all the questions of a survey
304     */
305    public AmetysObjectIterable<SurveyQuestion> getQuestions() throws AmetysRepositoryException
306    {
307        return getChildren();
308    }
309    
310    @Override
311    public SurveyPage copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException
312    {
313        SurveyPage page = parent.createChild(name, "ametys:survey-page");
314        page.setTitle(getTitle());
315        page.setLabel(getLabel());
316        
317        String description = getDescription();
318        if (description != null)
319        {
320            page.setDescription(description);
321        }
322        
323        copyPictureTo(page);
324        
325        SurveyRule rule = getRule();
326        if (rule != null)
327        {
328            page.setRule(getRule().getType(), getRule().getPage());
329        }
330        
331        Survey parentSurvey = page.getSurvey();
332        for (SurveyQuestion question : getQuestions())
333        {
334            question.copyTo(page, parentSurvey.findUniqueQuestionName(question.getName()));
335        }
336        
337        return page;
338    }
339    
340    @Override
341    public SurveyPage copyTo(ModifiableTraversableAmetysObject parent, String name, List<String> restrictTo) throws AmetysRepositoryException
342    {
343        return copyTo(parent, name);
344    }
345}