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

br.com.anteros.bean.validation.groups.GroupsComputer Maven / Gradle / Ivy

There is a newer version: 1.0.18
Show newest version
/*******************************************************************************
 * Copyright 2012 Anteros Tecnologia
 *  
 * 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 br.com.anteros.bean.validation.groups;


import java.util.*;

import br.com.anteros.validation.api.GroupDefinitionException;
import br.com.anteros.validation.api.GroupSequence;
import br.com.anteros.validation.api.ValidationException;
import br.com.anteros.validation.api.groups.Default;

/**
 * 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 - 2025 Weber Informatics LLC | Privacy Policy