001package org.apache.commons.beanutils2; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import static org.apache.commons.beanutils2.Assertions.checkArgument; 023import static org.apache.commons.beanutils2.Assertions.checkNotNull; 024import static org.apache.commons.beanutils2.TypeUtils.isAssignmentCompatible; 025 026/** 027 * An argument represents a value of some type that can be passed to a method or 028 * constructor. 029 * 030 * @param <T> the type of the argument. 031 */ 032public final class Argument<T> 033{ 034 035 /** 036 * Factory method for arguments. Creates an argument by taking a value and determining the type of the given value. 037 * 038 * @param value the value to be wrapped by the new argument object. Must not be {@code null}! If you want to create 039 * a null argument use {@link #nullArgument(Class)} instead. 040 * @param <A> the type of the argument. 041 * @return a new argument of type {@code value.getClass()} 042 */ 043 public static <A> Argument<A> argument( A value ) 044 { 045 value = checkNotNull( value, "Null not supported when specifying value only" ); 046 @SuppressWarnings( "unchecked" ) 047 Class<A> type = (Class<A>) value.getClass(); 048 return argument( type, value ); 049 } 050 051 /** 052 * Creates a new null argument of the given type. Shortcut for {@code argument( type, null )}. 053 * 054 * @param type the type of the new argument. Must not be {@code null}! 055 * @param <A> the type of argument. 056 * @return an argument with {@code value == null}. 057 */ 058 public static <A> Argument<A> nullArgument( Class<A> type ) 059 { 060 return argument( type, null ); 061 } 062 063 /** 064 * Creates a new argument of the given type with the given value. 065 * 066 * @param type the type of the new argument. Must not be {@code null}! 067 * @param value the value of the new argument. 068 * @param <T> the type of the argument. 069 * @param <V> the type of the value of the argument. 070 * @return a new argument of the given type with the given value. 071 */ 072 public static <T, V extends T> Argument<T> argument( Class<T> type, V value ) 073 { 074 type = checkNotNull( type, "type must be specified (while value is nullable)" ); 075 if ( value != null ) 076 { 077 // this should never happen since the compiler prevents it. Check it anyway... 078 checkArgument( isAssignmentCompatible( type, value.getClass() ), 079 "value type %s does not match the given type %s", 080 value.getClass().getName(), 081 type.getName() ); 082 } 083 return new Argument<T>( type, value ); 084 } 085 086 /** 087 * Determines the types of the given arguments. 088 * 089 * @param arguments the arguments to determine the types of. None must be {@code null}! 090 * @return an array of {@code Class} objects representing the types of the 091 * given arguments. The first {@code class} object represents the 092 * type of the first argument and so on. 093 */ 094 static Class<?>[] getParameterTypes( Argument<?>...arguments ) 095 { 096 int argumentsLength = arguments.length; 097 Class<?>[] parameterTypes = new Class[argumentsLength]; 098 for ( int i = 0; i < argumentsLength; i++ ) 099 { 100 parameterTypes[i] = arguments[i].getType(); 101 } 102 return parameterTypes; 103 } 104 105 /** 106 * Determines the objects of the given arguments. 107 * 108 * @param arguments the arguments to determine the types of. None must be {@code null}! 109 * @return an array of {@code Object}s representing the values of the given arguments. 110 */ 111 static Object[] getParameters( Argument<?>...arguments ) 112 { 113 int argumentsLength = arguments.length; 114 Object[] parameters = new Object[argumentsLength]; 115 for ( int i = 0; i < argumentsLength; i++ ) 116 { 117 parameters[i] = arguments[i].getValue(); 118 } 119 return parameters; 120 } 121 122 private final Class<T> type; 123 124 private final T value; 125 126 private Argument( Class<T> type, T value ) 127 { 128 this.type = type; 129 this.value = value; 130 } 131 132 /** 133 * Returns the argument's type. Note that the type returned maybe a super type of the actual type of the value 134 * returned by {@link #getValue()} depending on how the argument was created. For example: 135 * </br>{@code argument( Number.class, Integer.valueOf( 4 ) );}</br> 136 * will create an argument with an Integer as Value but Number.class as type. 137 * 138 * @return the argument's type 139 */ 140 public Class<T> getType() 141 { 142 return type; 143 } 144 145 /** 146 * Returns the value of the argument. Maybe {@code null} if this is a null argument. 147 * 148 * @return the value of the argument. 149 */ 150 public T getValue() 151 { 152 return value; 153 } 154 155}