com.oracle.bedrock.runtime.concurrent.callable.RemoteCallableStaticMethod Maven / Gradle / Ivy
Show all versions of bedrock-runtime Show documentation
/*
* File: RemoteCallableStaticMethod.java
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* The contents of this file are subject to the terms and conditions of
* the Common Development and Distribution License 1.0 (the "License").
*
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the License by consulting the LICENSE.txt file
* distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file LICENSE.txt.
*
* MODIFICATIONS:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*/
package com.oracle.bedrock.runtime.concurrent.callable;
import com.oracle.bedrock.runtime.concurrent.RemoteCallable;
import com.oracle.bedrock.util.ReflectionHelper;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
/**
* A {@link RemoteCallable} for a static {@link Method}.
*
* Copyright (c) 2014. All Rights Reserved. Oracle Corporation.
* Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
*
* @author Brian Oliver
*/
public class RemoteCallableStaticMethod implements RemoteCallable
{
/**
* Required for {@link Serializable}.
*/
private static final long serialVersionUID = 201407070813L;
/**
* The name of the {@link Class} on which the static method is defined.
*/
private final String className;
/**
* The name of the static method.
*/
private final String methodName;
/**
* The arguments for the method.
*/
private Object[] args;
/**
* Constructs an {@link RemoteCallableStaticMethod} for a String-based var-arg
* static methods (like public static void main(String[] args)
methods).
*
* ie: This constructor assumes the method being represented is declared as
* methodName(String[] args)
or methodName(String... args)
.
*
* @param className the name of the class
* @param methodName the name of the static method
* @param args the arguments for the method
*/
public RemoteCallableStaticMethod(String className,
String methodName,
Iterable args)
{
this.className = className;
this.methodName = methodName;
ArrayList argumentList = new ArrayList();
for (String arg : args)
{
argumentList.add(arg);
}
String[] argumentArray = new String[argumentList.size()];
argumentList.toArray(argumentArray);
this.args = new Object[] {argumentArray};
}
/**
* Constructs an {@link RemoteCallableStaticMethod}.
*
* If the method is defined using a var-arg, the last parameter to this constructor
* must be an array. eg: the method "methodName(Foo... args)" must be
* represented as a call this this constructor as:
* RemoteCallableStaticMethod(className, "methodName", new Foo[]{...});
*
* @param className the name of the class
* @param methodName the name of the static method
* @param args the arguments for the method
*/
public RemoteCallableStaticMethod(String className,
String methodName,
Object... args)
{
this.className = className;
this.methodName = methodName;
this.args = args;
}
@Override
public T call() throws Exception
{
// use the Thread's context ClassLoader to resolve the Class.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class> clazz = classLoader.loadClass(className);
// resolve the static method to call
Method method = ReflectionHelper.getCompatibleMethod(clazz, methodName, args);
// was the method found?
if (method == null)
{
throw new NoSuchMethodException("The specified method [" + className + "." + methodName
+ "] for the arguments " + Arrays.toString(args) + " could not be located");
}
else
{
// ensure that the method is static
if (Modifier.isStatic(method.getModifiers()))
{
return args.length > 0 ? (T) method.invoke(null, args) : (T) method.invoke(null);
}
else
{
throw new IllegalArgumentException("The specified method [" + className + "." + methodName
+ "] is not static");
}
}
}
@Override
public String toString()
{
return "RemoteCallableStaticMethod{ClassName=\'" + className + '\'' + ", Method='" + methodName + '\''
+ ", Arguments=" + Arrays.toString(args) + '}';
}
}