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