All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.bval.jsr303.groups.GroupsComputer Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.bval.jsr303.groups;


import javax.validation.GroupDefinitionException;
import javax.validation.GroupSequence;
import javax.validation.ValidationException;
import javax.validation.groups.Default;
import java.util.*;

/**
 * Description: compute group order, based on the RI behavior as to guarantee
 * compatibility with interpretations of the spec.
* Implementation is thread-safe. */ public class GroupsComputer { /** The default group array used in case any of the validate methods is called without a group. */ private static final Groups DEFAULT_GROUPS; static { DEFAULT_GROUPS = new GroupsComputer().computeGroups(Arrays.asList(getDefaultGroupArray())); } /** * Get the default group array. * @return {@link Default}.class only */ public static Class[] getDefaultGroupArray() { return new Class[] { Default.class }; } /** caching resolved groups in a thread-safe map. */ private final Map, List> resolvedSequences = Collections .synchronizedMap(new HashMap, List>()); /** * Compute groups from an array of group classes. * @param groups * @return {@link Groups} */ public Groups computeGroups(Class[] groups) { if (groups == null) { throw new IllegalArgumentException("null passed as group"); } // if no groups is specified use the default if (groups.length == 0) { return DEFAULT_GROUPS; } return computeGroups(Arrays.asList(groups)); } /** * Main compute implementation. * @param groups * @return {@link Groups} */ protected Groups computeGroups(Collection> groups) { if (groups == null || groups.size() == 0) { throw new IllegalArgumentException("At least one group has to be specified."); } for (Class clazz : groups) { if (!clazz.isInterface()) { throw new ValidationException( "A group has to be an interface. " + clazz.getName() + " is not."); } } Groups chain = new Groups(); for (Class clazz : groups) { GroupSequence anno = clazz.getAnnotation(GroupSequence.class); if (anno == null) { Group group = new Group(clazz); chain.insertGroup(group); insertInheritedGroups(clazz, chain); } else { insertSequence(clazz, anno, chain); } } return chain; } private void insertInheritedGroups(Class clazz, Groups chain) { for (Class extendedInterface : clazz.getInterfaces()) { Group group = new Group(extendedInterface); chain.insertGroup(group); insertInheritedGroups(extendedInterface, chain); } } private void insertSequence(Class clazz, GroupSequence anno, Groups chain) { List sequence; if (resolvedSequences.containsKey(clazz)) { sequence = resolvedSequences.get(clazz); } else { sequence = resolveSequence(clazz, anno, new HashSet>()); } chain.insertSequence(sequence); } private List resolveSequence(Class group, GroupSequence sequenceAnnotation, Set> processedSequences) { if (processedSequences.contains(group)) { throw new GroupDefinitionException("Cyclic dependency in groups definition"); } else { processedSequences.add(group); } List resolvedGroupSequence = new LinkedList(); Class[] sequenceArray = sequenceAnnotation.value(); for (Class clazz : sequenceArray) { GroupSequence anno = clazz.getAnnotation(GroupSequence.class); if (anno == null) { resolvedGroupSequence.add(new Group(clazz)); // group part of sequence } else { List tmpSequence = resolveSequence(clazz, anno, processedSequences); // recursion! resolvedGroupSequence.addAll(tmpSequence); } } resolvedSequences.put(group, resolvedGroupSequence); return resolvedGroupSequence; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy