| /* |
| * 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.jclouds.rest; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| |
| import java.util.List; |
| |
| import javax.inject.Inject; |
| |
| import org.jclouds.predicates.Validator; |
| import org.jclouds.reflect.Invocation; |
| import org.jclouds.rest.annotations.ParamValidators; |
| |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import com.google.common.reflect.Parameter; |
| import com.google.inject.Injector; |
| |
| /** |
| * Validates method parameters. |
| * |
| * Checks the {@link ParamValidators} annotation for validators. There can be method-level validators that apply to all |
| * parameters, and parameter-level validators. When validation on at least one parameter doesn't pass, throws |
| * {@link IllegalStateException}. |
| */ |
| public class InputParamValidator { |
| |
| private final Injector injector; |
| |
| @Inject |
| public InputParamValidator(Injector injector) { |
| this.injector = injector; |
| } |
| |
| public InputParamValidator() { |
| injector = null; |
| } |
| |
| /** |
| * Validates that method parameters are correct, according to {@link ParamValidators}. |
| * |
| * @param method |
| * method with optionally set {@link ParamValidators} |
| * @param args |
| * method arguments with optionally set {@link ParamValidators} |
| * @see ParamValidators |
| * @see Validator |
| * |
| * @throws IllegalStateException |
| * if validation failed |
| */ |
| public void validateMethodParametersOrThrow(Invocation invocation, List<Parameter> parameters) { |
| try { |
| performMethodValidation(checkNotNull(invocation, "invocation")); |
| performParameterValidation(invocation, checkNotNull(parameters, "parameters")); |
| } catch (IllegalArgumentException e) { |
| throw new IllegalArgumentException(String.format("Validation on '%s' didn't pass:%n Reason: %s.", parameters, |
| e.getMessage()), e); |
| } |
| } |
| |
| /** |
| * Returns if all the method parameters passed all of the method-level validators or throws an |
| * {@link IllegalArgumentException}. |
| * |
| * @param method |
| * method with optionally set {@link ParamValidators}. This can not be null. |
| * @param args |
| * method's parameters |
| */ |
| private void performMethodValidation(Invocation invocation) { |
| ParamValidators paramValidatorsAnnotation = invocation.getInvokable().getAnnotation(ParamValidators.class); |
| if (paramValidatorsAnnotation == null) |
| return; // by contract |
| |
| List<Validator<?>> methodValidators = getValidatorsFromAnnotation(paramValidatorsAnnotation); |
| |
| runPredicatesAgainstArgs(methodValidators, invocation.getArgs()); |
| } |
| |
| /** |
| * Returns if all the method parameters passed all of their corresponding validators or throws an |
| * {@link IllegalArgumentException}. |
| * |
| * @param parameters |
| * annotations for method's arguments |
| * @param args |
| * arguments that correspond to the array of annotations |
| */ |
| private void performParameterValidation(Invocation invocation, List<Parameter> parameters) { |
| for (Parameter param : parameters) { |
| ParamValidators annotation = param.getAnnotation(ParamValidators.class); |
| if (annotation == null) |
| continue; |
| List<Validator<?>> parameterValidators = getValidatorsFromAnnotation(annotation); |
| // TODO position guava issue 1243 |
| runPredicatesAgainstArg(parameterValidators, invocation.getArgs().get(param.hashCode())); |
| } |
| } |
| |
| private List<Validator<?>> getValidatorsFromAnnotation(ParamValidators paramValidatorsAnnotation) { |
| List<Validator<?>> validators = Lists.newArrayList(); |
| for (Class<? extends Validator<?>> validator : paramValidatorsAnnotation.value()) { |
| validators.add(checkNotNull(injector.getInstance(validator))); |
| } |
| return validators; |
| } |
| |
| @SuppressWarnings("unchecked") |
| private void runPredicatesAgainstArg(List<Validator<?>> predicates, Object arg) { |
| for (@SuppressWarnings("rawtypes") |
| Validator validator : predicates) { |
| validator.apply(arg); |
| } |
| } |
| |
| @SuppressWarnings({"CheckReturnValue", "unchecked"}) |
| private void runPredicatesAgainstArgs(List<Validator<?>> predicates, List<Object> args) { |
| for (@SuppressWarnings("rawtypes") |
| Validator validator : predicates) { |
| Iterables.all(args, validator); |
| } |
| } |
| |
| } |