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.sources; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.configuration.Configurable; 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.ConfigurationException; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.commons.lang3.StringUtils; 030 031import org.ametys.core.util.JSONUtils; 032import org.ametys.plugins.forms.question.types.ChoicesListQuestionType; 033import org.ametys.plugins.forms.repository.FormEntry; 034import org.ametys.plugins.forms.repository.FormQuestion; 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.runtime.model.ModelItem; 037import org.ametys.runtime.model.type.ModelItemTypeConstants; 038import org.ametys.runtime.plugin.component.AbstractLogEnabled; 039import org.ametys.runtime.plugin.component.PluginAware; 040 041/** 042 * Static class for creating {@link ChoiceSourceType} from xml congig 043 */ 044public abstract class AbstractSourceType extends AbstractLogEnabled implements ChoiceSourceType, Serviceable, Configurable, PluginAware 045{ 046 /** The question param key */ 047 public static final String QUESTION_PARAM_KEY = "question"; 048 049 /** JSON helper */ 050 protected JSONUtils _jsonUtils; 051 052 /** Forms */ 053 protected String _pluginName; 054 /** Id of source type */ 055 protected String _id; 056 /** Label of source type */ 057 protected I18nizableText _label; 058 059 public void service(ServiceManager manager) throws ServiceException 060 { 061 _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE); 062 } 063 064 public void setPluginInfo(String pluginName, String featureName, String id) 065 { 066 _pluginName = pluginName; 067 } 068 069 public void configure(Configuration configuration) throws ConfigurationException 070 { 071 _id = configuration.getAttribute("id"); 072 073 Configuration childLabel = configuration.getChild("label"); 074 _label = I18nizableText.getI18nizableTextValue(childLabel, "plugin." + _pluginName, childLabel.getValue()); 075 } 076 077 public String getId() 078 { 079 return _id; 080 } 081 082 public I18nizableText getLabel() 083 { 084 return _label; 085 } 086 087 public List<String> getFieldToDisableIfFormPublished() 088 { 089 return new ArrayList<>(); 090 } 091 092 public String getStorageType(FormQuestion question) 093 { 094 return ModelItemTypeConstants.STRING_TYPE_ID; 095 } 096 097 public String getJSRenderer() 098 { 099 return "Ametys.plugins.forms.helper.SearchEntriesGridHelper.renderStringChoiceList"; 100 } 101 102 public String getJSConverter() 103 { 104 return null; 105 } 106 107 public Object removeEmptyOrOtherValue(Object value) 108 { 109 if (value == null) 110 { 111 return null; 112 } 113 114 if (value.getClass().isArray()) 115 { 116 List<String> newVal = new ArrayList<>(); 117 for (String val : (String[]) value) 118 { 119 if (StringUtils.isNotBlank(val) && !val.equals(ChoicesListQuestionType.OTHER_OPTION_VALUE)) 120 { 121 newVal.add(val); 122 } 123 } 124 125 if (newVal.isEmpty()) 126 { 127 return null; 128 } 129 130 return newVal.toArray(new String[newVal.size()]); 131 } 132 else if (StringUtils.isNotBlank((String) value) && !value.equals(ChoicesListQuestionType.OTHER_OPTION_VALUE)) 133 { 134 return value; 135 } 136 137 return null; 138 } 139 140 /** 141 * Get question from params 142 * @param params the params 143 * @return the form question 144 */ 145 protected FormQuestion _getQuestionFromParam(Map<String, Object> params) 146 { 147 return (FormQuestion) params.get(QUESTION_PARAM_KEY); 148 } 149 150 public Object valueToJSONForClient(Object value, FormQuestion question, FormEntry entry, ModelItem modelItem) throws Exception 151 { 152 return _getComputedStringValue(value, question, entry); 153 } 154 155 /** 156 * Get computed string value for choice list 157 * @param valueToJSONForClient the value for this question 158 * @param question the question 159 * @param entry the entry 160 * @return the computed value 161 * @throws Exception if an error occurred during computing 162 */ 163 protected Object _getComputedStringValue(Object valueToJSONForClient, FormQuestion question, FormEntry entry) throws Exception 164 { 165 String name = question.getNameForForm(); 166 ChoicesListQuestionType type = (ChoicesListQuestionType) question.getType(); 167 168 if (entry.isMultiple(name)) 169 { 170 List<Map<String, Object>> values = new ArrayList<>(); 171 if (valueToJSONForClient != null) 172 { 173 for (Object val : (List) valueToJSONForClient) 174 { 175 Map<String, Object> transformedValue = new HashMap<>(); 176 transformedValue.put("value", val); 177 178 Map<String, Object> enumParam = new HashMap<>(); 179 enumParam.put(AbstractSourceType.QUESTION_PARAM_KEY, question); 180 transformedValue.put("label", type.getSourceType(question).getEntry(new ChoiceOption(val), enumParam)); 181 182 values.add(transformedValue); 183 } 184 } 185 186 if (type.hasOtherOption(question)) 187 { 188 String otherValue = entry.getValue(ChoicesListQuestionType.OTHER_PREFIX_DATA_NAME + name); 189 if (StringUtils.isNotBlank(otherValue)) 190 { 191 Map<String, Object> transformedValue = new HashMap<>(); 192 transformedValue.put("value", otherValue); 193 transformedValue.put("label", otherValue); 194 195 values.add(transformedValue); 196 } 197 } 198 199 return values; 200 } 201 else 202 { 203 Map<String, Object> transformedValue = new HashMap<>(); 204 205 if (type.hasOtherOption(question) && StringUtils.isNotBlank(entry.getValue(ChoicesListQuestionType.OTHER_PREFIX_DATA_NAME + name))) 206 { 207 String otherValue = entry.getValue(ChoicesListQuestionType.OTHER_PREFIX_DATA_NAME + name); 208 transformedValue.put("value", otherValue); 209 transformedValue.put("label", otherValue); 210 } 211 else if (valueToJSONForClient != null) 212 { 213 transformedValue.put("value", valueToJSONForClient); 214 215 Map<String, Object> enumParam = new HashMap<>(); 216 enumParam.put(AbstractSourceType.QUESTION_PARAM_KEY, question); 217 transformedValue.put("label", type.getSourceType(question).getEntry(new ChoiceOption(valueToJSONForClient), enumParam)); 218 } 219 220 221 return transformedValue; 222 } 223 } 224 225 /** 226 * Get computed complex value as user or content for choice list 227 * @param valueToJSONForClient the value for this question 228 * @param question the question 229 * @param entry the entry 230 * @return the computed value 231 * @throws Exception if an error occurred 232 */ 233 protected Object _getComputedComplexValue(Object valueToJSONForClient, FormQuestion question, FormEntry entry) throws Exception 234 { 235 String name = question.getNameForForm(); 236 ChoicesListQuestionType type = (ChoicesListQuestionType) question.getType(); 237 238 if (!type.hasOtherOption(question)) 239 { 240 return valueToJSONForClient; 241 } 242 243 if (entry.isMultiple(name)) 244 { 245 String otherValue = entry.getValue(ChoicesListQuestionType.OTHER_PREFIX_DATA_NAME + name); 246 if (StringUtils.isNotBlank(otherValue)) 247 { 248 Map<String, Object> transformedValue = new HashMap<>(); 249 transformedValue.put("value", otherValue); 250 transformedValue.put("isOther", true); 251 252 @SuppressWarnings("unchecked") 253 List<Object> computedVal = valueToJSONForClient != null ? (List<Object>) valueToJSONForClient : new ArrayList<>(); 254 computedVal.add(transformedValue); 255 256 return computedVal; 257 } 258 } 259 else 260 { 261 String otherValue = entry.getValue(ChoicesListQuestionType.OTHER_PREFIX_DATA_NAME + name); 262 if (StringUtils.isNotBlank(otherValue)) 263 { 264 Map<String, Object> transformedValue = new HashMap<>(); 265 transformedValue.put("value", otherValue); 266 transformedValue.put("isOther", true); 267 268 return transformedValue; 269 } 270 } 271 272 return valueToJSONForClient; 273 } 274}