001/* 002 * Copyright 2019 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.runtime.config; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Comparator; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.Map.Entry; 025 026import org.ametys.runtime.i18n.I18nizableText; 027import org.ametys.runtime.model.CategorizedElementDefinitionHelper; 028import org.ametys.runtime.model.CategorizedElementDefinitionWrapper; 029import org.ametys.runtime.model.ElementDefinition; 030import org.ametys.runtime.model.Model; 031import org.ametys.runtime.model.ModelItem; 032import org.ametys.runtime.model.ModelItemGroup; 033import org.ametys.runtime.model.ModelViewItem; 034import org.ametys.runtime.model.ModelViewItemGroup; 035import org.ametys.runtime.model.View; 036import org.ametys.runtime.model.ViewElement; 037import org.ametys.runtime.model.ViewItemGroup; 038 039/** 040 * Helper for {@link ConfigParameterDefinitionWrapper} 041 */ 042public final class ConfigParameterDefinitionHelper 043{ 044 private ConfigParameterDefinitionHelper() 045 { 046 //Nothing 047 } 048 049 /** 050 * Get definitions of all elements parsed in this {@link CategorizedElementDefinitionWrapper} {@link Collection}, as a flat map. 051 * @param elements a {@link Collection} of {@link CategorizedElementDefinitionWrapper} 052 * @return a map with the definition name as key, containing all definitions 053 */ 054 public static Map<String, ElementDefinition> getFlatDefinitions(Collection<ConfigParameterDefinitionWrapper> elements) 055 { 056 Map<String, ElementDefinition> flatDefinitions = new HashMap<>(); 057 for (ConfigParameterDefinitionWrapper element : elements) 058 { 059 ElementDefinition definition = element.getDefinition(); 060 flatDefinitions.put(definition.getName(), definition); 061 } 062 return flatDefinitions; 063 } 064 065 /** 066 * Categorize the ModlItems based on the informations in the {@link CategorizedElementDefinitionWrapper} collection 067 * Category and groups are not sorted, only definitions, based on the position. 068 * Sorting of category and groups have to be done when the view is created (each usage can be different) 069 * @param elements collection of categorized elements 070 * @return a list of {@link ModelItem} with the correct tree (category/group/definitions) 071 */ 072 public static List<ModelItem> categorizeConfigParameters(Collection<ConfigParameterDefinitionWrapper> elements) 073 { 074 Model model = ConfigManager.getInstance(); 075 Map<I18nizableText, Map<I18nizableText, List<ConfigParameterDefinitionWrapper>>> categories = CategorizedElementDefinitionHelper.categorizeElementDefinitionWrappers(elements); 076 //This list is not sorted, only definition are sorted, not groups. 077 //Groups should be sorted elsewhere (when creating the view for example) 078 List<ModelItem> modelItems = new ArrayList<>(); 079 for (Entry<I18nizableText, Map<I18nizableText, List<ConfigParameterDefinitionWrapper>>> categoryEntry : categories.entrySet()) 080 { 081 ModelItemGroup category = new ModelItemGroup(); 082 category.setModel(model); 083 category.setLabel(categoryEntry.getKey()); 084 modelItems.add(category); 085 Map<I18nizableText, List<ConfigParameterDefinitionWrapper>> values = categoryEntry.getValue(); 086 for (Entry<I18nizableText, List<ConfigParameterDefinitionWrapper>> groupEntry : values.entrySet()) 087 { 088 ModelItemGroup group = new ModelItemGroup(); 089 group.setModel(model); 090 group.setLabel(groupEntry.getKey()); 091 category.addChild(group); 092 093 for (ConfigParameterDefinitionWrapper orderedDefinition : groupEntry.getValue()) 094 { 095 ElementDefinition definition = orderedDefinition.getDefinition(); 096 definition.setParent(group); 097 098 group.addChild(definition, orderedDefinition.isGroupSwitch()); 099 } 100 } 101 } 102 return modelItems; 103 } 104 105 /** 106 * Generate the view for a list of {@link ModelItem}, using comparators to sort the categories and the groups 107 * This works only on the very specific categories/group/fieldset hierarchy and an {@link IllegalArgumentException} will be thrown if the hierarchy is incorrect. 108 * @param categories list of {@link ModelItem} 109 * @param categoriesComparator {@link Comparator} used for the categories (can be null to keep order) 110 * @param groupsComparator {@link Comparator} for the groups (can be null to keep order) 111 * @param elementsComparator {@link Comparator} for the elements (can be null to keep order) 112 * @return A {@link View} ordered from the {@link ModelItem} using the {@link Comparator} 113 * @throws IllegalArgumentException the hierarchy of the categories/groups/elements is incorrect 114 */ 115 public static View buildConfigParametersView(Collection<? extends ModelItem> categories, Comparator<? super ModelItem> categoriesComparator, Comparator<? super ModelItem> groupsComparator, Comparator<? super ModelItem> elementsComparator) throws IllegalArgumentException 116 { 117 View view = new View(); 118 119 Collection<? extends ModelItem> sorted = _sort(categories, categoriesComparator); 120 121 for (ModelItem modelItem : sorted) 122 { 123 view.addViewItem(_buildCategoryViewItem(modelItem, groupsComparator, elementsComparator)); 124 } 125 return view; 126 } 127 128 private static ModelViewItemGroup _buildCategoryViewItem(ModelItem modelItem, Comparator<? super ModelItem> groupsComparator, Comparator<? super ModelItem> elementsComparator) throws IllegalArgumentException 129 { 130 if (modelItem instanceof ModelItemGroup) 131 { 132 ModelItemGroup category = (ModelItemGroup) modelItem; 133 ModelViewItemGroup categoryViewItem = new ModelViewItemGroup(); 134 categoryViewItem.setRole(ViewItemGroup.TAB_ROLE); 135 categoryViewItem.setDefinition(category); 136 137 Collection<? extends ModelItem> groups = _sort(category.getChildren(), groupsComparator); 138 139 for (ModelItem group : groups) 140 { 141 categoryViewItem.addViewItem(_buildGroupViewItem(group, elementsComparator)); 142 } 143 return categoryViewItem; 144 } 145 else 146 { 147 throw new IllegalArgumentException("Category " + modelItem.getPath() + " should be an instance of ModelItemGroup"); 148 } 149 } 150 151 private static ModelViewItemGroup _buildGroupViewItem(ModelItem modelItem, Comparator<? super ModelItem> elementsComparator) throws IllegalArgumentException 152 { 153 if (modelItem instanceof ModelItemGroup) 154 { 155 ModelItemGroup group = (ModelItemGroup) modelItem; 156 ModelViewItemGroup groupViewItem = new ModelViewItemGroup(); 157 groupViewItem.setRole(ViewItemGroup.FIELDSET_ROLE); 158 groupViewItem.setDefinition(group); 159 160 Collection<? extends ModelItem> items = _sort(group.getChildren(), elementsComparator); 161 162 for (ModelItem item : items) 163 { 164 groupViewItem.addViewItem(_buildElementViewItem(item)); 165 } 166 return groupViewItem; 167 } 168 else 169 { 170 throw new IllegalArgumentException("Group " + modelItem.getPath() + " should be an instance of ModelItemGroup"); 171 } 172 } 173 174 private static ModelViewItem _buildElementViewItem(ModelItem modelItem) throws IllegalArgumentException 175 { 176 if (modelItem instanceof ElementDefinition) 177 { 178 ElementDefinition definition = (ElementDefinition) modelItem; 179 180 ViewElement parameterViewItem = new ViewElement(); 181 parameterViewItem.setDefinition(definition); 182 return parameterViewItem; 183 } 184 else 185 { 186 throw new IllegalArgumentException("Item " + modelItem.getPath() + " should be an instance of ElementDefinition"); 187 } 188 } 189 190 /** 191 * sort a model item list using comparator 192 * @param items list of items to sort 193 * @param comparator a comparator, can be null to avoid sort 194 * @return a sorted list (or a copy of the list if the comparator is null) 195 */ 196 private static Collection<? extends ModelItem> _sort(Collection<? extends ModelItem> items, Comparator<? super ModelItem> comparator) 197 { 198 if (comparator == null) 199 { 200 return items; 201 } 202 else 203 { 204 List<ModelItem> sorted = new ArrayList<>(items); 205 sorted.sort(comparator); 206 return sorted; 207 } 208 } 209}