/* * Copyright 2012 Google Inc. Copyright 2016 Manfred Tremmel * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package de.knightsoftnet.validators.client.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.validation.GroupDefinitionException; import javax.validation.groups.Default; /** * An instance of {@code GroupChain} defines the group order during one full validation call. * <p> * Modified from the Hibernate validator for use with GWT. * </p> */ public final class GroupChain { /** * The list of single groups to be used this validation. */ private final List<Group> groupList = new ArrayList<Group>(); /** * The different sequences for this validation. The map contains the list of groups mapped to * their sequence name. */ private final Map<Class<?>, List<Group>> sequenceMap = new HashMap<Class<?>, List<Group>>(); /** * check if default group sequence is expandable. * * @param defaultGroupSequence list of group classes * @throws GroupDefinitionException if it's no default group */ public void checkDefaultGroupSequenceIsExpandable(final List<Class<?>> defaultGroupSequence) throws GroupDefinitionException { for (final Map.Entry<Class<?>, List<Group>> entry : this.sequenceMap.entrySet()) { final Class<?> sequence = entry.getKey(); final List<Group> groups = entry.getValue(); final List<Group> defaultGroupList = this.buildTempGroupList(defaultGroupSequence, sequence); final int defaultGroupIndex = this.containsDefaultGroupAtIndex(sequence, groups); if (defaultGroupIndex != -1) { this.ensureDefaultGroupSequenceIsExpandable(groups, defaultGroupList, defaultGroupIndex); } } } public Collection<Group> getAllGroups() { return this.groupList; } public Iterator<Group> getGroupIterator() { return this.groupList.iterator(); } public Iterator<List<Group>> getSequenceIterator() { return this.sequenceMap.values().iterator(); } /** * insert a single group. * * @param group to add */ public void insertGroup(final Group group) { if (!this.groupList.contains(group)) { this.groupList.add(group); } } /** * insert a sequence (list) of groups. * * @param groups list of groups to add */ public void insertSequence(final List<Group> groups) { if (groups != null && !groups.isEmpty()) { if (!this.sequenceMap.containsValue(groups)) { this.sequenceMap.put(groups.get(0).getSequence(), groups); } } } @Override public String toString() { return "GroupChain{" + "groupList=" + this.groupList + ", sequenceMap=" + this.sequenceMap + "}"; } private List<Group> buildTempGroupList(final List<Class<?>> defaultGroupSequence, final Class<?> sequence) { final List<Group> groups = new ArrayList<Group>(); for (final Class<?> clazz : defaultGroupSequence) { final Group g = new Group(clazz, sequence); groups.add(g); } return groups; } private int containsDefaultGroupAtIndex(final Class<?> sequence, final List<Group> groupList) { final Group defaultGroup = new Group(Default.class, sequence); return groupList.indexOf(defaultGroup); } private void ensureDefaultGroupSequenceIsExpandable(final List<Group> groupList, final List<Group> defaultGroupList, final int defaultGroupIndex) throws GroupDefinitionException { for (int i = 0; i < defaultGroupList.size(); i++) { final Group group = defaultGroupList.get(i); if (group.getGroup().equals(Default.class)) { // we don't have to consider the default group since it is the one we want to replace continue; } // check whether the sequence contains group of the default group sequence final int index = groupList.indexOf(group); if (index == -1) { continue; // if the group is not in the sequence we can continue } if (i == 0 && index == defaultGroupIndex - 1 || i == defaultGroupList.size() - 1 && index == defaultGroupIndex + 1) { // if we are at the beginning or end of he defaultGroupSequence and the matches are either // directly before resp after we can continue as well, since we basically have two groups continue; } throw new GroupDefinitionException("Unable to expand default group list " + defaultGroupList + " into sequence " + groupList); } } }