001/*
002 *  Copyright 2021 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.forms.question;
017
018import java.util.List;
019import java.util.Map;
020
021import org.xml.sax.ContentHandler;
022import org.xml.sax.SAXException;
023
024import org.ametys.core.ui.ClientSideElement.ScriptFile;
025import org.ametys.plugins.forms.repository.FormEntry;
026import org.ametys.plugins.forms.repository.FormQuestion;
027import org.ametys.runtime.i18n.I18nizableText;
028import org.ametys.runtime.model.Model;
029import org.ametys.runtime.model.ModelItem;
030import org.ametys.runtime.model.View;
031import org.ametys.runtime.model.type.DataContext;
032import org.ametys.runtime.model.type.ElementType;
033
034import com.google.common.collect.Multimap;
035
036/**
037 * Interface for question's types
038 */
039public interface FormQuestionType
040{
041    /** 
042     * Get id of the question type 
043     * @return the id
044     */
045    public String getId();
046    
047    /** 
048     * Get label of question type 
049     * @return the label
050     */
051    public I18nizableText getLabel();
052    
053    /** 
054     * Get description of question type 
055     * @return the description 
056     */
057    public I18nizableText getDescription();
058    
059    /** 
060     * Get display order of the question type 
061     * @return the display order
062     */
063    public Integer getDisplayOrder();
064    
065    /** 
066     * Get icon of question type button 
067     * @return the icon-glyph name 
068     */
069    public String getIconGlyph();
070    
071    /**
072     * Get the scripts to import
073     * @return the list of scripts
074     */
075    public List<ScriptFile> getScripts();
076    
077    /**
078     * Get the category of question type
079     * @return the name of the category in questionTypeButtonMenu
080     */
081    public I18nizableText getCategory();
082    
083    /**
084     * Get the display XSLT file
085     * @return the display XSLT file
086     */
087    public String getDisplayXSLT();
088    
089    /**
090     * Get the form question view
091     * @return a view of question model
092     */
093    public View getView();
094    
095    /**
096     * Get the form question model
097     * @return the form question model
098     */
099    public Model getModel();
100
101    /**
102     * Get the form entry model for the question type
103     * @param question the question
104     * @return the form entry model
105     */
106    public Model getEntryModel(FormQuestion question);
107    
108    /**
109     * Get the storage type of the question type
110     * @param question the question
111     * @return the storage type
112     */
113    public String getStorageType(FormQuestion question);
114    
115    /**
116     * Get the default title depending on type 
117     * @return the default title
118     */
119    public I18nizableText getDefaultTitle();
120    
121    /**
122     * Sax additional informations for the question type
123     * @param contentHandler the content handler
124     * @param question the question
125     * @throws SAXException if a saxing error occurred
126     */
127    public void saxAdditionalInfos(ContentHandler contentHandler, FormQuestion question) throws SAXException;
128
129    /**
130     * Validate values to create or edit the question
131     * @param values the values
132     * @param errors the errors
133     */
134    public void validateQuestionValues(Map<String, Object> values, Map<String, I18nizableText> errors);
135    
136    /**
137     * Validate values to create a form entry
138     * @param question the question
139     * @param values the values
140     * @param errors the errors
141     */
142    public void validateEntryValues(FormQuestion question, Map<String, Object> values, Multimap<String, I18nizableText> errors);
143    
144    /**
145     * Do additional operations to create or edit the question
146     * @param question the question
147     * @param values the values
148     */
149    public void doAdditionalOperations(FormQuestion question, Map<String, Object> values);
150
151    /**
152     * Get field to disable if form is published
153     * @param question the form question
154     * @return the list of field name
155     */
156    public List<String> getFieldToDisableIfFormPublished(FormQuestion question);
157    
158    /**
159     * Sax the entry value depending on the question type
160     * @param contentHandler the content handler
161     * @param question the question getting saxed 
162     * @param entry the entry
163     * @throws SAXException exception while saxing entry
164     */
165    public void saxEntryValue(ContentHandler contentHandler, FormQuestion question, FormEntry entry) throws SAXException;
166    
167    /** 
168     * Say if question needs more configuration to be used
169     * @param question the current question
170     * @return false if question needs more configuration, true by default
171     */
172    public boolean isQuestionConfigured(FormQuestion question);
173    
174    /**
175     * Get the js renderer for the choice list
176     * @param question the question
177     * @return the js renderer
178     */
179    public default String getJSRenderer(FormQuestion question)
180    {
181        return null;
182    }
183
184    /**
185     * Get the js converter for the choice list
186     * @param question the question
187     * @return the js converter
188     */
189    public default String getJSConverter(FormQuestion question)
190    {
191        return null;
192    }
193    
194    /**
195     * Convert the entry value into a JSON object to use client side
196     * @param value the value to convert
197     * @param question the form question
198     * @param entry the form entry
199     * @param modelItem the model item
200     * @return The value as JSON
201     * @throws Exception if an error occurred
202     */
203    public default Object valueToJSONForClient(Object value, FormQuestion question, FormEntry entry, ModelItem modelItem) throws Exception
204    {
205        DataContext context = DataContext.newInstance()
206                .withDataPath(modelItem.getPath())
207                .withObjectId(entry.getId());
208        
209        return ((ElementType) modelItem.getType()).valueToJSONForClient(value, context);
210    }
211    
212    /**
213     * Return <code>true</code> if the type of question is only for display.
214     * @param question the question
215     * @return <code>true</code> if the type of question is only for display.
216     */
217    public default boolean onlyForDisplay(FormQuestion question)
218    {
219        return false;
220    }
221    
222    /**
223     * Return <code>true</code> if the type of question can be answered by user.
224     * @param question the question
225     * @return <code>true</code> if the type of question can be answered by user.
226     */
227    public default boolean canBeAnsweredByUser(FormQuestion question)
228    {
229        return true;
230    }
231}