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.types; 017 018import java.util.List; 019import java.util.Map; 020 021import org.ametys.plugins.forms.helper.FormElementDefinitionHelper; 022import org.ametys.plugins.forms.question.validators.NumberIntervalFormValidator; 023import org.ametys.plugins.forms.repository.FormQuestion; 024import org.ametys.runtime.config.DisableCondition; 025import org.ametys.runtime.config.DisableCondition.OPERATOR; 026import org.ametys.runtime.config.DisableConditions; 027import org.ametys.runtime.i18n.I18nizableText; 028import org.ametys.runtime.model.ElementDefinition; 029import org.ametys.runtime.model.ModelItem; 030import org.ametys.runtime.model.SimpleViewItemGroup; 031import org.ametys.runtime.model.StaticEnumerator; 032import org.ametys.runtime.model.ViewElement; 033import org.ametys.runtime.model.type.ModelItemTypeConstants; 034 035/** 036 * Class for creating number question type 037 */ 038public class NumberQuestionType extends AbstractFormQuestionType 039{ 040 /** Constant for min attribute */ 041 public static final String ATTRIBUTE_MIN_DOUBLE = "min-double"; 042 043 /** Constant for max attribute */ 044 public static final String ATTRIBUTE_MAX_DOUBLE = "max-double"; 045 046 /** Constant for min attribute */ 047 public static final String ATTRIBUTE_MIN_INT = "min-int"; 048 049 /** Constant for max attribute */ 050 public static final String ATTRIBUTE_MAX_INT = "max-int"; 051 052 /** Constant for number type attribute */ 053 public static final String ATTRIBUTE_NUMBER_TYPE = "number-type"; 054 055 /** Name of double numberTypeStaticEnumerator entry */ 056 public static final String DOUBLE_NUMBER_VALUE = "double"; 057 058 /** Name of integer numberTypeStaticEnumerator entry */ 059 public static final String INTEGER_NUMBER_VALUE = "int"; 060 061 /** Constant for default title */ 062 public static final String DEFAULT_TITLE = "PLUGIN_FORMS_QUESTION_DEFAULT_TITLE_NUMBER"; 063 064 @Override 065 protected SimpleViewItemGroup _getAdvancedTab() 066 { 067 SimpleViewItemGroup advancedFieldset = super._getAdvancedTab(); 068 069 ViewElement numberType = new ViewElement(); 070 numberType.setDefinition((ElementDefinition< ? >) getModel().getModelItem(ATTRIBUTE_NUMBER_TYPE)); 071 advancedFieldset.addViewItem(numberType); 072 073 ViewElement min = new ViewElement(); 074 min.setDefinition((ElementDefinition< ? >) getModel().getModelItem(ATTRIBUTE_MIN_DOUBLE)); 075 advancedFieldset.addViewItem(min); 076 077 ViewElement max = new ViewElement(); 078 max.setDefinition((ElementDefinition< ? >) getModel().getModelItem(ATTRIBUTE_MAX_DOUBLE)); 079 advancedFieldset.addViewItem(max); 080 081 ViewElement minInt = new ViewElement(); 082 minInt.setDefinition((ElementDefinition< ? >) getModel().getModelItem(ATTRIBUTE_MIN_INT)); 083 advancedFieldset.addViewItem(minInt); 084 085 ViewElement maxInt = new ViewElement(); 086 maxInt.setDefinition((ElementDefinition< ? >) getModel().getModelItem(ATTRIBUTE_MAX_INT)); 087 advancedFieldset.addViewItem(maxInt); 088 089 return advancedFieldset; 090 } 091 092 @Override 093 protected List<ModelItem> _getModelItems() 094 { 095 List<ModelItem> modelItems = super._getModelItems(); 096 097 // DOUBLE Conditions 098 DisableConditions doubleDisableConditions = new DisableConditions(); 099 DisableCondition conditionDouble = new DisableCondition(ATTRIBUTE_NUMBER_TYPE, OPERATOR.NEQ, DOUBLE_NUMBER_VALUE); 100 doubleDisableConditions.getConditions().add(conditionDouble); 101 //MIN 102 ElementDefinition minDouble = FormElementDefinitionHelper.getElementDefinition(ATTRIBUTE_MIN_DOUBLE, ModelItemTypeConstants.DOUBLE_TYPE_ID, "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MIN", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MIN_DESC", null); 103 minDouble.setDisableConditions(doubleDisableConditions); 104 modelItems.add(minDouble); 105 106 //MAX 107 ElementDefinition maxDouble = FormElementDefinitionHelper.getElementDefinition(ATTRIBUTE_MAX_DOUBLE, ModelItemTypeConstants.DOUBLE_TYPE_ID, "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MAX", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MAX_DESC", null); 108 maxDouble.setDisableConditions(doubleDisableConditions); 109 modelItems.add(maxDouble); 110 111 // INTEGER Conditions 112 DisableConditions integerDisableConditions = new DisableConditions(); 113 DisableCondition conditionInteger = new DisableCondition(ATTRIBUTE_NUMBER_TYPE, OPERATOR.NEQ, INTEGER_NUMBER_VALUE); 114 integerDisableConditions.getConditions().add(conditionInteger); 115 //MIN 116 ElementDefinition minInt = FormElementDefinitionHelper.getElementDefinition(ATTRIBUTE_MIN_INT, ModelItemTypeConstants.LONG_TYPE_ID, "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MIN", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MIN_DESC", null); 117 minInt.setDisableConditions(integerDisableConditions); 118 modelItems.add(minInt); 119 120 //MAX 121 ElementDefinition maxInt = FormElementDefinitionHelper.getElementDefinition(ATTRIBUTE_MAX_INT, ModelItemTypeConstants.LONG_TYPE_ID, "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MAX", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_MAX_DESC", null); 122 maxInt.setDisableConditions(integerDisableConditions); 123 modelItems.add(maxInt); 124 125 //NUMBER_TYPE 126 ElementDefinition<String> numberType = FormElementDefinitionHelper.getElementDefinition(ATTRIBUTE_NUMBER_TYPE, ModelItemTypeConstants.STRING_TYPE_ID, "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_NUMBER_TYPE", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_NUMBER_TYPE_DESC", null); 127 128 StaticEnumerator<String> numberTypeStaticEnumerator = new StaticEnumerator<>(); 129 numberTypeStaticEnumerator.add(new I18nizableText("plugin.forms", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_TYPE_DOUBLE"), DOUBLE_NUMBER_VALUE); 130 numberTypeStaticEnumerator.add(new I18nizableText("plugin.forms", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_TYPE_INT"), INTEGER_NUMBER_VALUE); 131 numberType.setEnumerator(numberTypeStaticEnumerator); 132 numberType.setDefaultValue(INTEGER_NUMBER_VALUE); 133 modelItems.add(numberType); 134 135 return modelItems; 136 } 137 138 public String getStorageType(FormQuestion question) 139 { 140 String type = question.getValue(ATTRIBUTE_NUMBER_TYPE); 141 return type.equals(DOUBLE_NUMBER_VALUE) ? ModelItemTypeConstants.DOUBLE_TYPE_ID : ModelItemTypeConstants.LONG_TYPE_ID; 142 } 143 144 @Override 145 protected ModelItem _getEntryModelItem(FormQuestion question) 146 { 147 ModelItem item = super._getEntryModelItem(question); 148 if (DOUBLE_NUMBER_VALUE.equals(question.getValue(ATTRIBUTE_NUMBER_TYPE))) 149 { 150 ((ElementDefinition) item).setValidator(new NumberIntervalFormValidator(null, isMandatory(question), question.getValue(ATTRIBUTE_MIN_DOUBLE), question.getValue(ATTRIBUTE_MAX_DOUBLE))); 151 } 152 else 153 { 154 ((ElementDefinition) item).setValidator(new NumberIntervalFormValidator(null, isMandatory(question), question.getValue(ATTRIBUTE_MIN_INT), question.getValue(ATTRIBUTE_MAX_INT))); 155 } 156 return item; 157 } 158 159 @Override 160 public void validateQuestionValues(Map<String, Object> values, Map<String, I18nizableText> errors) 161 { 162 super.validateQuestionValues(values, errors); 163 164 String format = (String) values.get(ATTRIBUTE_NUMBER_TYPE); 165 switch (format) 166 { 167 case DOUBLE_NUMBER_VALUE: 168 Number minDouble = (Number) values.getOrDefault(ATTRIBUTE_MIN_DOUBLE, null); 169 Number maxDouble = (Number) values.getOrDefault(ATTRIBUTE_MAX_DOUBLE, null); 170 if (minDouble != null && maxDouble != null && minDouble.doubleValue() > maxDouble.doubleValue()) 171 { 172 errors.put(ATTRIBUTE_MIN_DOUBLE, new I18nizableText("plugin.forms", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_GAP_ERROR")); 173 errors.put(ATTRIBUTE_MAX_DOUBLE, new I18nizableText("plugin.forms", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_GAP_ERROR")); 174 } 175 break; 176 177 case INTEGER_NUMBER_VALUE: 178 Number min = (Number) values.getOrDefault(ATTRIBUTE_MIN_INT, null); 179 Number max = (Number) values.getOrDefault(ATTRIBUTE_MAX_INT, null); 180 if (min != null && max != null && min.longValue() > max.longValue()) 181 { 182 errors.put(ATTRIBUTE_MIN_INT, new I18nizableText("plugin.forms", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_GAP_ERROR")); 183 errors.put(ATTRIBUTE_MAX_INT, new I18nizableText("plugin.forms", "PLUGINS_FORMS_QUESTIONS_DIALOG_NUMBER_GAP_ERROR")); 184 } 185 break; 186 187 default: 188 getLogger().error("Number format " + format + " is not supported"); 189 break; 190 } 191 } 192 193 public I18nizableText getDefaultTitle() 194 { 195 return new I18nizableText("plugin.forms", DEFAULT_TITLE); 196 } 197 198 @Override 199 public List<String> getFieldToDisableIfFormPublished(FormQuestion question) 200 { 201 List<String> fieldNames = super.getFieldToDisableIfFormPublished(question); 202 fieldNames.add(ATTRIBUTE_NUMBER_TYPE); 203 return fieldNames; 204 } 205}