001    /*
002     * Created on Feb 20, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2009 the original author or authors.
015     */
016    package org.fest.reflect.method;
017    
018    import static org.fest.reflect.method.Invoker.newInvoker;
019    import static org.fest.reflect.method.StaticMethodParameterTypes.newParameterTypes;
020    import static org.fest.reflect.method.StaticMethodReturnType.newReturnType;
021    import static org.fest.reflect.method.StaticMethodReturnTypeRef.newReturnTypeRef;
022    import static org.fest.util.Strings.isEmpty;
023    
024    import org.fest.reflect.reference.TypeRef;
025    
026    /**
027     * Understands the name of a static method to invoke using Java Reflection.
028     * <p>
029     * The following is an example of proper usage of this class:
030     * <pre>
031     *   // Equivalent to call 'Jedi.setCommonPower("Jump")'
032     *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
033     *                                 .{@link StaticMethodParameterTypes#in(Class) in}(Jedi.class)
034     *                                 .{@link Invoker#invoke(Object...) invoke}("Jump");
035     *
036     *   // Equivalent to call 'Jedi.addPadawan()'
037     *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link StaticMethodName#in(Class) in}(Jedi.class).{@link Invoker#invoke(Object...) invoke}();
038     *
039     *   // Equivalent to call 'Jedi.commonPowerCount()'
040     *   String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link StaticMethodName#withReturnType(Class) withReturnType}(String.class)
041     *                                                 .{@link StaticMethodReturnType#in(Class) in}(Jedi.class)
042     *                                                 .{@link Invoker#invoke(Object...) invoke}();
043     *
044     *   // Equivalent to call 'Jedi.getCommonPowers()'
045     *   List&lt;String&gt; powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}&lt;List&lt;String&gt;&gt;() {})
046     *                                                        .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
047     *                                                        .{@link Invoker#invoke(Object...) invoke}();
048     * </pre>
049     * </p>
050     *
051     * @author Alex Ruiz
052     */
053    public final class StaticMethodName {
054    
055      /**
056       * Creates a new </code>{@link StaticMethodName}</code>: the starting point of the fluent interface for accessing
057       * static methods using Java Reflection.
058       * @param name the name of the method to access using Java Reflection.
059       * @return the created <code>StaticMethodName</code>.
060       * @throws NullPointerException if the given name is <code>null</code>.
061       * @throws IllegalArgumentException if the given name is empty.
062       */
063      public static StaticMethodName startStaticMethodAccess(String name) {
064        validateIsNotNullOrEmpty(name);
065        return new StaticMethodName(name);
066      }
067    
068      private static void validateIsNotNullOrEmpty(String name) {
069        if (name == null)
070          throw new NullPointerException("The name of the static method to access should not be null");
071        if (isEmpty(name))
072          throw new IllegalArgumentException("The name of the static method to access should not be empty");
073      }
074    
075      private final String name;
076    
077      private StaticMethodName(String name) {
078        this.name = name;
079      }
080    
081      /**
082       * Specifies the return type of the static method to invoke. This method call is optional if the return type of the
083       * method to invoke is <code>void</code>.
084       * @param <T> the generic type of the method's return type.
085       * @param type the return type of the method to invoke.
086       * @return the created return type holder.
087       * @throws NullPointerException if the given type is <code>null</code>.
088       */
089      public <T> StaticMethodReturnType<T> withReturnType(Class<T> type) {
090        return newReturnType(name, type);
091      }
092    
093      /**
094       * Specifies the return type reference of the static method to invoke. This method call is optional if the return type
095       * of the method to invoke is <code>void</code>.
096       * @param <T> the generic type of the method's return type.
097       * @param type the return type reference of the method to invoke.
098       * @return the created return type holder.
099       * @throws NullPointerException if the given type reference is <code>null</code>.
100       */
101      public <T> StaticMethodReturnTypeRef<T> withReturnType(TypeRef<T> type) {
102        return newReturnTypeRef(name, type);
103      }
104    
105      /**
106       * Specifies the parameter types of the static method to invoke. This method call is optional if the method to invoke
107       * does not take arguments.
108       * @param parameterTypes the parameter types of the method to invoke.
109       * @return the created parameter types holder.
110       * @throws NullPointerException if the array of parameter types is <code>null</code>.
111       */
112      public StaticMethodParameterTypes<Void> withParameterTypes(Class<?>... parameterTypes) {
113        return newParameterTypes(name, parameterTypes);
114      }
115    
116      /**
117       * Creates a new invoker for a static method that takes no parameters and return value <code>void</code>.
118       * @param target the object containing the method to invoke.
119       * @return the created method invoker.
120       * @throws NullPointerException if the given target is <code>null</code>.
121       */
122      public Invoker<Void> in(Class<?> target) {
123        return newInvoker(name, target);
124      }
125    }