protocol/dubbo/hessian2/java_class.go (160 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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 hessian2 import ( "fmt" "reflect" "strings" "time" ) import ( hessian "github.com/apache/dubbo-go-hessian2" perrors "github.com/pkg/errors" ) var ( NilError = perrors.Errorf("object should not be nil") UnexpectedTypeError = perrors.Errorf("object should be a POJO") notBasicClassError = perrors.Errorf("object isn't a basic class") ) // GetJavaName returns java name of an object func GetJavaName(obj any) (string, error) { if obj == nil { return "", NilError } t := reflect.TypeOf(obj) // basic types, e.g. bool, int, etc. if jtype, err := getBasicJavaName(t); err == nil { return jtype, nil } // complicated types, e.g. array, slice, etc. switch t.Kind() { case reflect.Array, reflect.Slice: sb := &strings.Builder{} itemtyp := t for itemtyp.Kind() == reflect.Array || itemtyp.Kind() == reflect.Slice { sb.WriteString("[]") itemtyp = itemtyp.Elem() } var ( javaName string err error ) if javaName, err = getBasicJavaName(itemtyp); err != nil { if javaName, err = GetJavaName(reflect.New(itemtyp).Elem().Interface()); err != nil { return "", err } } return fmt.Sprintf("%s%s", javaName, sb), nil case reflect.Map: return "java.util.Map", nil default: pojo, ok := obj.(hessian.POJO) if !ok { return "", UnexpectedTypeError } return pojo.JavaClassName(), nil } } func getBasicJavaName(typ reflect.Type) (string, error) { switch typ.Kind() { case reflect.Bool: return "boolean", nil case reflect.Int, reflect.Int64: // in 64-bit processor, Int takes a 64-bit space return "long", nil case reflect.Int32: return "int", nil case reflect.Int8, reflect.Int16: return "short", nil case reflect.Uint, reflect.Uint64: // in 64-bit processor, Uint takes a 64-bit space return "unsigned long", nil case reflect.Uint32: return "unsigned int", nil case reflect.Uint16: return "unsigned short", nil case reflect.Uint8: return "char", nil case reflect.Float32: return "float", nil case reflect.Float64: return "double", nil case reflect.String: return "java.lang.String", nil } return "", notBasicClassError } // GetClassDesc get class desc. // - boolean[].class => "[Z" // - Object.class => "Ljava/lang/Object;" func GetClassDesc(v any) string { if v == nil { return "V" } switch v := v.(type) { // Serialized tags for base types case nil: return "V" case bool: return "Z" case []bool: return "[Z" case byte: return "B" case []byte: return "[B" case int8: return "B" case []int8: return "[B" case int16: return "S" case []int16: return "[S" case uint16: // Equivalent to Char of Java return "C" case []uint16: return "[C" // case rune: // return "C" case int: return "J" case []int: return "[J" case int32: return "I" case []int32: return "[I" case int64: return "J" case []int64: return "[J" case time.Time: return "java.util.Date" case []time.Time: return "[Ljava.util.Date" case float32: return "F" case []float32: return "[F" case float64: return "D" case []float64: return "[D" case string: return "java.lang.String" case []string: return "[Ljava.lang.String;" case []hessian.Object: return "[Ljava.lang.Object;" case map[any]any: // return "java.util.HashMap" return "java.util.Map" case hessian.POJOEnum: return v.(hessian.POJOEnum).JavaClassName() // Serialized tags for complex types default: t := reflect.TypeOf(v) if reflect.Ptr == t.Kind() { t = reflect.TypeOf(reflect.ValueOf(v).Elem()) } switch t.Kind() { case reflect.Struct: return "java.lang.Object" case reflect.Slice, reflect.Array: if t.Elem().Kind() == reflect.Struct { return "[Ljava.lang.Object;" } // return "java.util.ArrayList" return "java.util.List" case reflect.Map: // Enter here, map may be map[string]int return "java.util.Map" default: return "" } } }