001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package io.jboot.web.handler;
018
019
020import java.lang.reflect.Method;
021import java.lang.reflect.Parameter;
022
023
024/**
025 * 参考  https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java
026 */
027public final class JbootActionReporterUtil {
028
029    /**
030     * void(V).
031     */
032    public static final char JVM_VOID = 'V';
033
034    /**
035     * boolean(Z).
036     */
037    public static final char JVM_BOOLEAN = 'Z';
038
039    /**
040     * byte(B).
041     */
042    public static final char JVM_BYTE = 'B';
043
044    /**
045     * char(C).
046     */
047    public static final char JVM_CHAR = 'C';
048
049    /**
050     * double(D).
051     */
052    public static final char JVM_DOUBLE = 'D';
053
054    /**
055     * float(F).
056     */
057    public static final char JVM_FLOAT = 'F';
058
059    /**
060     * int(I).
061     */
062    public static final char JVM_INT = 'I';
063
064    /**
065     * long(J).
066     */
067    public static final char JVM_LONG = 'J';
068
069    /**
070     * short(S).
071     */
072    public static final char JVM_SHORT = 'S';
073
074
075    /**
076     * get class desc.
077     * boolean[].class => "[Z"
078     * Object.class => "Ljava/lang/Object;"
079     *
080     * @param c class.
081     * @return desc.
082     */
083    public static String getDesc(Class<?> c) {
084        StringBuilder ret = new StringBuilder();
085
086        while (c.isArray()) {
087            ret.append('[');
088            c = c.getComponentType();
089        }
090
091        if (c.isPrimitive()) {
092            String t = c.getName();
093            if ("void".equals(t)) {
094                ret.append(JVM_VOID);
095            } else if ("boolean".equals(t)) {
096                ret.append(JVM_BOOLEAN);
097            } else if ("byte".equals(t)) {
098                ret.append(JVM_BYTE);
099            } else if ("char".equals(t)) {
100                ret.append(JVM_CHAR);
101            } else if ("double".equals(t)) {
102                ret.append(JVM_DOUBLE);
103            } else if ("float".equals(t)) {
104                ret.append(JVM_FLOAT);
105            } else if ("int".equals(t)) {
106                ret.append(JVM_INT);
107            } else if ("long".equals(t)) {
108                ret.append(JVM_LONG);
109            } else if ("short".equals(t)) {
110                ret.append(JVM_SHORT);
111            }
112        } else {
113            ret.append('L');
114            ret.append(c.getName().replace('.', '/'));
115            ret.append(';');
116        }
117        return ret.toString();
118    }
119
120
121    /**
122     * get method desc.
123     * "(I)I", "()V", "(Ljava/lang/String;Z)V"
124     *
125     * @param m method.
126     * @return desc.
127     */
128    public static String getMethodDescWithoutName(Method m) {
129        StringBuilder ret = new StringBuilder();
130        ret.append('(');
131        Class<?>[] parameterTypes = m.getParameterTypes();
132        for (int i = 0; i < parameterTypes.length; i++) {
133            ret.append(getDesc(parameterTypes[i]));
134        }
135        ret.append(')').append(getDesc(m.getReturnType()));
136        return ret.toString();
137    }
138
139
140    /**
141     * get method string
142     *
143     * @param m
144     * @return
145     */
146    public static String getMethodString(Method m) {
147        StringBuilder ret = new StringBuilder(m.getName());
148        ret.append('(');
149        Parameter[] parameters = m.getParameters();
150        int index = 0;
151        for (Parameter p : parameters) {
152            if (!p.isNamePresent()) {
153                // 必须通过添加 -parameters 进行编译,才可以获取 Parameter 的编译前的名字
154                throw new RuntimeException(" Maven or IDE config is error. see https://jfinal.com/doc/3-3 ");
155            }
156            ret.append(p.getType().getSimpleName());
157            ret.append(" ").append(p.getName());
158            if (index++ < parameters.length - 1) {
159                ret.append(", ");
160            }
161        }
162
163        ret.append(')');
164        return ret.toString();
165    }
166
167
168}