| /* |
| * Copyright 2012 Google Inc. |
| * |
| * 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 com.google.gwt.validation.client.impl; |
| |
| import com.google.gwt.validation.client.impl.metadata.BeanMetadata; |
| import com.google.gwt.validation.client.impl.metadata.ValidationGroupsMetadata; |
| |
| import java.lang.annotation.ElementType; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import javax.validation.groups.Default; |
| import javax.validation.metadata.ConstraintDescriptor; |
| import javax.validation.metadata.ElementDescriptor.ConstraintFinder; |
| import javax.validation.metadata.Scope; |
| |
| /** |
| * Finds constraints declared on an element using specified criteria. |
| */ |
| public final class ConstraintFinderImpl implements ConstraintFinder { |
| private Set<ConstraintDescriptorImpl<?>> constraintDescriptors; |
| private ValidationGroupsMetadata validationGroupsMetadata; |
| private List<Class<?>> groups; |
| private Set<ConstraintOrigin> definedInSet; |
| private Set<ElementType> elementTypes; |
| private BeanMetadata beanMetadata; |
| |
| public ConstraintFinderImpl(BeanMetadata beanMetadata, |
| ValidationGroupsMetadata validationGroupsMetadata, |
| Set<ConstraintDescriptorImpl<?>> constraintDescriptors) { |
| this.validationGroupsMetadata = validationGroupsMetadata; |
| this.constraintDescriptors = constraintDescriptors; |
| this.beanMetadata = beanMetadata; |
| elementTypes = new HashSet<ElementType>(); |
| elementTypes.add(ElementType.TYPE); |
| elementTypes.add(ElementType.METHOD); |
| elementTypes.add(ElementType.FIELD); |
| definedInSet = new HashSet<ConstraintOrigin>(); |
| definedInSet.add(ConstraintOrigin.DEFINED_LOCALLY); |
| definedInSet.add(ConstraintOrigin.DEFINED_IN_HIERARCHY); |
| groups = Collections.emptyList(); |
| } |
| |
| @Override |
| public ConstraintFinder declaredOn(ElementType... types) { |
| elementTypes.clear(); |
| elementTypes.addAll(Arrays.asList(types)); |
| return this; |
| } |
| |
| @Override |
| public Set<ConstraintDescriptor<?>> getConstraintDescriptors() { |
| if (validationGroupsMetadata == null) { |
| // sanity check - this could be null if the caller does not set group metadata first |
| throw new IllegalStateException("ConstraintFinderImpl not initialized properly. A " + |
| "ValidationGroupsMetadata object is required by GWT to properly find all constraint " + |
| "descriptors."); |
| } |
| Set<ConstraintDescriptor<?>> matchingDescriptors = new HashSet<ConstraintDescriptor<?>>(); |
| findMatchingDescriptors(matchingDescriptors); |
| return Collections.unmodifiableSet(matchingDescriptors); |
| } |
| |
| @Override |
| public boolean hasConstraints() { |
| return !getConstraintDescriptors().isEmpty(); |
| } |
| |
| @Override |
| public ConstraintFinder lookingAt(Scope scope) { |
| if (scope.equals(Scope.LOCAL_ELEMENT)) { |
| definedInSet.remove(ConstraintOrigin.DEFINED_IN_HIERARCHY); |
| } |
| return this; |
| } |
| |
| @Override |
| public ConstraintFinder unorderedAndMatchingGroups(Class<?>... groups) { |
| this.groups = new ArrayList<Class<?>>(); |
| for (Class<?> clazz : groups) { |
| if (Default.class.equals(clazz) && beanMetadata.defaultGroupSequenceIsRedefined()) { |
| this.groups.addAll(beanMetadata.getDefaultGroupSequence()); |
| } |
| else { |
| this.groups.add(clazz); |
| } |
| } |
| return this; |
| } |
| |
| private void addMatchingDescriptorsForGroup(Class<?> group, |
| Set<ConstraintDescriptor<?>> matchingDescriptors) { |
| for (ConstraintDescriptorImpl<?> descriptor : constraintDescriptors) { |
| if (definedInSet.contains(descriptor.getDefinedOn()) |
| && elementTypes.contains(descriptor.getElementType()) |
| && descriptor.getGroups().contains(group)) { |
| matchingDescriptors.add(descriptor); |
| } |
| } |
| } |
| |
| private void findMatchingDescriptors(Set<ConstraintDescriptor<?>> matchingDescriptors) { |
| if (!groups.isEmpty()) { |
| GroupChain groupChain = |
| new GroupChainGenerator(validationGroupsMetadata).getGroupChainFor(groups); |
| Iterator<Group> groupIterator = groupChain.getGroupIterator(); |
| while (groupIterator.hasNext()) { |
| Group g = groupIterator.next(); |
| addMatchingDescriptorsForGroup(g.getGroup(), matchingDescriptors); |
| } |
| } |
| else { |
| for (ConstraintDescriptorImpl<?> descriptor : constraintDescriptors) { |
| if (definedInSet.contains(descriptor.getDefinedOn()) && |
| elementTypes.contains(descriptor.getElementType())) { |
| matchingDescriptors.add(descriptor); |
| } |
| } |
| } |
| } |
| |
| } |