001package co.codewizards.cloudstore.ls.core.invoke;
002
003import static java.util.Objects.*;
004
005import java.io.Serializable;
006import java.util.Arrays;
007
008public class MethodInvocationRequest implements Serializable {
009        private static final long serialVersionUID = 1L;
010
011        private final String className;
012
013        private final Object object;
014
015        private final String methodName;
016
017        private final String[] argumentTypeNames;
018
019        private final Object[] arguments;
020
021        private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
022
023        protected MethodInvocationRequest(final String className, final Object object, final String methodName, final String[] argumentTypeNames, final Object[] arguments) {
024                this.className = className;
025                this.object = object;
026                this.methodName = methodName;
027                this.argumentTypeNames = argumentTypeNames;
028                this.arguments = arguments;
029        }
030
031        public static MethodInvocationRequest forConstructorInvocation(final String className, final String[] argumentTypeNames, final Object ... arguments) {
032                return new MethodInvocationRequest(requireNonNull(className, "className"), null, null, argumentTypeNames, arguments);
033        }
034
035        public static MethodInvocationRequest forStaticInvocation(final String className, final String methodName, final String[] argumentTypeNames, final Object ... arguments) {
036                return new MethodInvocationRequest(
037                                requireNonNull(className, "className"), null, requireNonNull(methodName, "methodName"), argumentTypeNames, arguments);
038        }
039
040        public static MethodInvocationRequest forObjectInvocation(final Object object, final String methodName, final String[] argumentTypeNames, final Object ... arguments) {
041                if (argumentTypeNames != null) {
042                        if (argumentTypeNames.length > 0 && arguments == null)
043                                throw new IllegalArgumentException("argumentTypeNames != null && argumentTypeNames.length > 0 && arguments == null");
044
045                        int argumentsLength = arguments == null ? 0 : arguments.length;
046                        if (argumentTypeNames.length != argumentsLength)
047                                throw new IllegalArgumentException(String.format("argumentTypeNames.length != arguments.length :: %d != %d", argumentTypeNames.length, argumentsLength));
048                }
049                return new MethodInvocationRequest(
050                                null, requireNonNull(object, "object"), requireNonNull(methodName, "methodName"), argumentTypeNames, arguments);
051        }
052
053        public String getClassName() {
054                return className;
055        }
056
057        public Object getObject() {
058                return object;
059        }
060
061        public String getMethodName() {
062                return methodName;
063        }
064
065        public String[] getArgumentTypeNames() {
066                return argumentTypeNames;
067        }
068
069        public Object[] getArguments() {
070                return arguments == null ? EMPTY_OBJECT_ARRAY : arguments;
071        }
072
073        public InvocationType getInvocationType() {
074                if (className != null) {
075                        if (methodName == null)
076                                return InvocationType.CONSTRUCTOR;
077                        else
078                                return InvocationType.STATIC;
079                }
080                else if (object != null)
081                        return InvocationType.OBJECT;
082
083                throw new IllegalStateException("Cannot determine InvocationType!");
084        }
085
086        @Override
087        public String toString() {
088                final InvocationType invocationType = getInvocationType();
089                final String argumentsString = arguments == null ? "[]" : Arrays.toString(arguments);
090                switch (invocationType) {
091                        case CONSTRUCTOR:
092                                return String.format("%s[%s, %s, %s]", getClass().getSimpleName(), invocationType, className, argumentsString);
093                        case STATIC:
094                                return String.format("%s[%s, %s, %s, %s]", getClass().getSimpleName(), invocationType, className, methodName, argumentsString);
095                        case OBJECT:
096                                return String.format("%s[%s, %s, %s, %s, %s]", getClass().getSimpleName(), invocationType, object.getClass().getName(), object, methodName, argumentsString);
097                }
098                throw new IllegalStateException("Unexpected InvocationType!");
099        }
100}