/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI 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.openengsb.core.api.remote; import java.io.Serializable; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import javax.xml.bind.annotation.XmlRootElement; /** * Representation of a most general method call containing a {@link #methodName}, {@link #args} you want to give to the * method and so called {@link #metaData}. Since the target system often requires additional information for calling * specific methods (e.g. context setup, target thread, security, active user, ...) it is allowed to add additional * information to each method call to make. Finally this abstraction can extract all {@link Class} objects in the * {@link #getClasses()} required to load this method call correctly into the class loader. The classes are used to * identify the right method. */ @SuppressWarnings("serial") @XmlRootElement public class MethodCall implements Serializable { private String methodName; private Object[] args; private Map<String, String> metaData; private List<String> classes; public MethodCall() { } public MethodCall(Method method, Object[] args) { this(method, args, Collections.<String, String>emptyMap()); } public MethodCall(Method method, Object[] args, Map<String, String> metaData) { this(method.getName(), args, metaData, getRealClassImplementation(method, args)); } public MethodCall(String methodName, Object[] args) { this(methodName, args, Collections.<String, String>emptyMap()); } public MethodCall(String methodName, Object[] args, Map<String, String> metaData) { this(methodName, args, metaData, getRealClassImplementation(null, args)); } public MethodCall(String methodName, Object[] args, List<String> classes) { this(methodName, args, Collections.<String, String>emptyMap(), classes); } public MethodCall(String methodName, Object[] args, Map<String, String> metaData, List<String> classes) { super(); this.methodName = methodName; this.args = args; this.classes = classes; this.metaData = metaData; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } public Object[] getArgs() { return args; } public void setArgs(Object[] args) { this.args = args; } public Map<String, String> getMetaData() { return metaData; } public void setMetaData(Map<String, String> metaData) { this.metaData = metaData; } public List<String> getClasses() { return classes; } public void setClasses(List<String> classes) { this.classes = classes; } private static List<String> getRealClassImplementation(Method method, Object[] args) { if (args == null) { return Collections.emptyList(); } List<String> argClasses = new ArrayList<String>(args.length); for (int i = 0; i < args.length; i++) { argClasses.add(getArgumentClass(method, args[i], i)); } return argClasses; } private static String getArgumentClass(Method method, Object arg, int argIndex) { if (arg == null) { if (method == null) { throw new IllegalArgumentException("cannot determine type of null argument"); } return method.getParameterTypes()[argIndex].getName(); } else if (arg instanceof List<?>) { return List.class.getName(); } else { return arg.getClass().getName(); } } @Override public int hashCode() { return Objects.hash(methodName, args, classes, metaData); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof MethodCall) { MethodCall other = (MethodCall) obj; return Objects.equals(methodName, other.methodName) && Objects.deepEquals(args, other.args) && Objects.equals(classes, other.classes) && Objects.equals(metaData, other.metaData); } return false; } }