@@ -514,44 +514,81 @@ def do_object(self, parent=None, ident=0):
514514 # TODO:
515515 raise NotImplementedError ("externalContents isn't implemented yet" )
516516
517- if classdesc .flags & ClassDescFlags .SC_SERIALIZABLE :
518- # Handle each class in the hierarchy separately, from most derived to root
519- self ._read_class_data (java_object , classdesc , ident )
517+ # Process class data for the entire hierarchy
518+ self ._read_serializable_data (java_object , classdesc , ident )
520519
521520 log_debug (">>> java_object: {0}" .format (java_object ), ident )
522521 return java_object
523522
524- def _read_class_data (self , java_object , classdesc , ident ):
523+ def _read_serializable_data (self , java_object , classdesc , ident ):
525524 """
526- Recursively reads class data for the inheritance hierarchy
525+ Read serializable data following the Java specification more closely.
526+ According to the spec, for each class in the hierarchy (from super to sub):
527+ 1. Read primitive fields
528+ 2. If SC_WRITE_METHOD is set, read custom writeObject data until TC_ENDBLOCKDATA
527529 """
528- if classdesc is None :
529- return
530+ if classdesc . superclass :
531+ self . _read_serializable_data ( java_object , classdesc . superclass , ident + 1 )
530532
531- # First, handle the superclass data
532- if classdesc .superclass is not None :
533- self ._read_class_data (java_object , classdesc .superclass , ident )
533+ if classdesc .flags & ClassDescFlags .SC_SERIALIZABLE :
534+ # TODO: look at ObjectInputStream.readSerialData()
535+ # FIXME: Handle the SC_WRITE_METHOD flag
536+
537+ log_debug ("Constructing class..." , ident )
538+ log_debug ("Class: {0}" .format (classdesc .name ), ident + 1 )
539+ if classdesc .fields_names :
540+ class_fields_str = " - " .join (
541+ " " .join ((str (field_type ), field_name ))
542+ for field_type , field_name in zip (
543+ classdesc .fields_types , classdesc .fields_names
544+ )
545+ )
546+ log_debug (class_fields_str , ident + 2 )
534547
535- # Then handle this class's data
536- log_debug ("Reading class data for: {0}" .format (classdesc .name ), ident )
548+ log_debug ("Values count: {0}" .format (len (classdesc .fields_names )), ident )
549+ log_debug ("Prepared list of values: {0}" .format (classdesc .fields_names ), ident )
550+ log_debug ("Prepared list of types: {0}" .format (classdesc .fields_types ), ident )
537551
538- # Read field values for this specific class
539- for field_name , field_type in zip (classdesc .fields_names , classdesc .fields_types ):
540- log_debug ("Reading field: {0} - {1}" .format (field_type , field_name ), ident )
541- res = self ._read_value (field_type , ident , name = field_name )
542- java_object .__setattr__ (field_name , res )
552+ for field_name , field_type in zip (classdesc .fields_names , classdesc .fields_types ):
553+ log_debug (
554+ "Reading field: {0} - {1}" .format (field_type , field_name )
555+ )
556+ res = self ._read_value (field_type , ident , name = field_name )
557+ java_object .__setattr__ (field_name , res )
543558
544- # Handle annotations if this class has the SC_WRITE_METHOD flag
545- if classdesc .flags & ClassDescFlags .SC_WRITE_METHOD :
546- log_debug ("Reading annotations for class: {0}" .format (classdesc .name ), ident )
559+ has_write_method = classdesc .flags & ClassDescFlags .SC_SERIALIZABLE and classdesc .flags & ClassDescFlags .SC_WRITE_METHOD
560+ has_block_data = classdesc .flags & ClassDescFlags .SC_EXTERNALIZABLE and classdesc .flags & ClassDescFlags .SC_BLOCK_DATA
561+ if has_write_method or has_block_data :
562+ # objectAnnotation
563+ log_debug (
564+ "java_object.annotations before: {0}" .format (
565+ java_object .annotations
566+ ),
567+ ident ,
568+ )
547569
548- while True :
570+ opcode = None
571+ while opcode != TerminalCode .TC_ENDBLOCKDATA :
549572 opcode , obj = self ._read_and_exec_opcode (ident = ident + 1 )
550- if opcode == TerminalCode .TC_ENDBLOCKDATA :
551- break
552- java_object .annotations .append (obj )
573+ # , expect=[self.TC_ENDBLOCKDATA, self.TC_BLOCKDATA,
574+ # self.TC_OBJECT, self.TC_NULL, self.TC_REFERENCE])
575+ if opcode != TerminalCode .TC_ENDBLOCKDATA :
576+ java_object .annotations .append (obj )
577+
553578 log_debug ("objectAnnotation value: {0}" .format (obj ), ident )
554579
580+ log_debug (
581+ "java_object.annotations after: {0}" .format (
582+ java_object .annotations
583+ ),
584+ ident ,
585+ )
586+
587+ # Allow extra loading operations
588+ if hasattr (java_object , "__extra_loading__" ):
589+ log_debug ("Java object has extra loading capability." )
590+ java_object .__extra_loading__ (self , ident )
591+
555592 def do_string (self , parent = None , ident = 0 ):
556593 """
557594 Handles a TC_STRING opcode
0 commit comments