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  }