dubbo.apache.org/dubbo-go/v3@v3.1.1/protocol/dubbo/hessian2/java_class.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package hessian2 19 20 import ( 21 "fmt" 22 "reflect" 23 "strings" 24 "time" 25 ) 26 27 import ( 28 hessian "github.com/apache/dubbo-go-hessian2" 29 30 perrors "github.com/pkg/errors" 31 ) 32 33 var ( 34 NilError = perrors.Errorf("object should not be nil") 35 UnexpectedTypeError = perrors.Errorf("object should be a POJO") 36 notBasicClassError = perrors.Errorf("object isn't a basic class") 37 ) 38 39 // GetJavaName returns java name of an object 40 func GetJavaName(obj interface{}) (string, error) { 41 if obj == nil { 42 return "", NilError 43 } 44 45 t := reflect.TypeOf(obj) 46 47 // basic types, e.g. bool, int, etc. 48 if jtype, err := getBasicJavaName(t); err == nil { 49 return jtype, nil 50 } 51 52 // complicated types, e.g. array, slice, etc. 53 switch t.Kind() { 54 case reflect.Array, reflect.Slice: 55 sb := &strings.Builder{} 56 itemtyp := t 57 for itemtyp.Kind() == reflect.Array || itemtyp.Kind() == reflect.Slice { 58 sb.WriteString("[]") 59 itemtyp = itemtyp.Elem() 60 } 61 var ( 62 javaName string 63 err error 64 ) 65 if javaName, err = getBasicJavaName(itemtyp); err != nil { 66 if javaName, err = GetJavaName(reflect.New(itemtyp).Elem().Interface()); err != nil { 67 return "", err 68 } 69 } 70 return fmt.Sprintf("%s%s", javaName, sb), nil 71 case reflect.Map: 72 return "java.util.Map", nil 73 default: 74 pojo, ok := obj.(hessian.POJO) 75 if !ok { 76 return "", UnexpectedTypeError 77 } 78 return pojo.JavaClassName(), nil 79 } 80 } 81 82 func getBasicJavaName(typ reflect.Type) (string, error) { 83 switch typ.Kind() { 84 case reflect.Bool: 85 return "boolean", nil 86 case reflect.Int, reflect.Int64: // in 64-bit processor, Int takes a 64-bit space 87 return "long", nil 88 case reflect.Int32: 89 return "int", nil 90 case reflect.Int8, reflect.Int16: 91 return "short", nil 92 case reflect.Uint, reflect.Uint64: // in 64-bit processor, Uint takes a 64-bit space 93 return "unsigned long", nil 94 case reflect.Uint32: 95 return "unsigned int", nil 96 case reflect.Uint16: 97 return "unsigned short", nil 98 case reflect.Uint8: 99 return "char", nil 100 case reflect.Float32: 101 return "float", nil 102 case reflect.Float64: 103 return "double", nil 104 case reflect.String: 105 return "java.lang.String", nil 106 } 107 108 return "", notBasicClassError 109 } 110 111 // GetClassDesc get class desc. 112 // - boolean[].class => "[Z" 113 // - Object.class => "Ljava/lang/Object;" 114 func GetClassDesc(v interface{}) string { 115 if v == nil { 116 return "V" 117 } 118 119 switch v := v.(type) { 120 // Serialized tags for base types 121 case nil: 122 return "V" 123 case bool: 124 return "Z" 125 case []bool: 126 return "[Z" 127 case byte: 128 return "B" 129 case []byte: 130 return "[B" 131 case int8: 132 return "B" 133 case []int8: 134 return "[B" 135 case int16: 136 return "S" 137 case []int16: 138 return "[S" 139 case uint16: // Equivalent to Char of Java 140 return "C" 141 case []uint16: 142 return "[C" 143 // case rune: 144 // return "C" 145 case int: 146 return "J" 147 case []int: 148 return "[J" 149 case int32: 150 return "I" 151 case []int32: 152 return "[I" 153 case int64: 154 return "J" 155 case []int64: 156 return "[J" 157 case time.Time: 158 return "java.util.Date" 159 case []time.Time: 160 return "[Ljava.util.Date" 161 case float32: 162 return "F" 163 case []float32: 164 return "[F" 165 case float64: 166 return "D" 167 case []float64: 168 return "[D" 169 case string: 170 return "java.lang.String" 171 case []string: 172 return "[Ljava.lang.String;" 173 case []hessian.Object: 174 return "[Ljava.lang.Object;" 175 case map[interface{}]interface{}: 176 // return "java.util.HashMap" 177 return "java.util.Map" 178 case hessian.POJOEnum: 179 return v.(hessian.POJOEnum).JavaClassName() 180 // Serialized tags for complex types 181 default: 182 t := reflect.TypeOf(v) 183 if reflect.Ptr == t.Kind() { 184 t = reflect.TypeOf(reflect.ValueOf(v).Elem()) 185 } 186 switch t.Kind() { 187 case reflect.Struct: 188 return "java.lang.Object" 189 case reflect.Slice, reflect.Array: 190 if t.Elem().Kind() == reflect.Struct { 191 return "[Ljava.lang.Object;" 192 } 193 // return "java.util.ArrayList" 194 return "java.util.List" 195 case reflect.Map: // Enter here, map may be map[string]int 196 return "java.util.Map" 197 default: 198 return "" 199 } 200 } 201 }