@@ -88,72 +88,100 @@ def build_services
8888
8989 # Builds operations for a given port.
9090 #
91- # Resolves binding and port_type once, then iterates all operations
92- # directly .
91+ # Resolves binding and port_type once, then delegates each operation
92+ # to {#build_single_operation} .
9393 #
9494 # @param port [Parser::Port] the port
9595 # @return [Hash{String => Hash, Array<Hash>}] operation data keyed by name
96- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
9796 def build_operations ( port )
9897 binding = port . fetch_binding ( @documents )
9998 port_type = binding . fetch_port_type ( @documents )
10099 operations = { }
101100 element_builder = XML ::ElementBuilder . new ( @schemas , limits : @limits , issues : @build_issues )
102101
103102 binding . operations . to_a . each do |op_entry |
104- op_name = op_entry [ :name ]
105- input_name = op_entry [ :input_name ]
106- metadata = default_operation ( op_name , input_name :)
107-
108- binding_op = binding . operations . fetch ( op_name , input_name :)
109- port_type_op = port_type . operations . fetch ( op_name , input_name :) { nil }
110-
111- unless port_type_op
112- record_build_issue ( op_name ,
113- "Binding operation #{ op_name . inspect } not found in portType #{ port_type . name . inspect } " )
114- store_operation ( operations , op_name , metadata . freeze )
115- next
116- end
117-
118- op_info = Parser ::OperationInfo . new (
119- op_name , binding_op , port_type_op ,
120- documents : @documents , schemas : @schemas ,
121- limits : @limits , issues : @build_issues ,
122- element_builder :
123- )
124-
125- metadata [ :soap_action ] = op_info . soap_action
126- metadata [ :soap_version ] = op_info . soap_version
127-
128- if binding_op . input?
129- metadata [ :input_style ] = op_info . input_style
130- metadata [ :output_style ] = op_info . output_style
131- metadata [ :rpc_input_namespace ] = binding_op . input_body [ :namespace ]
132- metadata [ :rpc_output_namespace ] = binding_op . output_body &.dig ( :namespace )
133- else
134- record_build_issue ( op_name ,
135- "Binding operation #{ op_name . inspect } is missing a required <input> element" )
136- end
137-
138- metadata [ :schema_complete ] = schema_complete_for_operation? ( op_info )
139- metadata [ :input ] = build_message ( op_info . input )
140- metadata [ :output ] = op_info . output ? build_message ( op_info . output ) : nil
141- store_operation ( operations , op_name , metadata . freeze )
103+ metadata = build_single_operation ( op_entry , binding , port_type , element_builder )
104+ store_operation ( operations , op_entry [ :name ] , metadata . freeze )
142105 end
143106
144107 operations
145108 rescue UnresolvedReferenceError => e
146109 record_build_issue ( nil , e . message )
147110 { }
148111 end
149- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
112+
113+ # Builds a single operation's metadata hash.
114+ #
115+ # Resolves binding and port type operations, validates the port type
116+ # match, and populates the metadata from the resolved operation info.
117+ # Returns a default metadata hash when the port type operation is missing.
118+ #
119+ # @param op_entry [Hash] operation entry from {Parser::OperationMap#to_a}
120+ # @param binding [Parser::Binding] the resolved binding
121+ # @param port_type [Parser::PortType] the resolved port type
122+ # @param element_builder [XML::ElementBuilder] shared element builder
123+ # @return [Hash] operation metadata
124+ def build_single_operation ( op_entry , binding , port_type , element_builder )
125+ op_name = op_entry [ :name ]
126+ metadata = default_operation ( op_name , input_name : op_entry [ :input_name ] )
127+
128+ binding_op = binding . operations . fetch ( op_name , input_name : op_entry [ :input_name ] )
129+ port_type_op = port_type . operations . fetch ( op_name , input_name : op_entry [ :input_name ] ) { nil }
130+
131+ unless port_type_op
132+ record_build_issue ( op_name ,
133+ "Binding operation #{ op_name . inspect } not found in portType #{ port_type . name . inspect } " )
134+ return metadata
135+ end
136+
137+ op_info = Parser ::OperationInfo . new (
138+ op_name , binding_op , port_type_op ,
139+ documents : @documents , schemas : @schemas ,
140+ limits : @limits , issues : @build_issues ,
141+ element_builder :
142+ )
143+
144+ populate_operation_metadata ( metadata , op_name , op_info )
145+ metadata
146+ end
147+
148+ # Populates an operation metadata hash from resolved operation info.
149+ #
150+ # Sets SOAP protocol fields, binding styles, schema completeness,
151+ # and resolved input/output messages. All data is accessed through the
152+ # {Parser::OperationInfo} facade rather than reaching into lower-level
153+ # binding or port type objects directly.
154+ #
155+ # @param metadata [Hash] the operation metadata hash to populate
156+ # @param op_name [String] the operation name (for error reporting)
157+ # @param op_info [Parser::OperationInfo] the resolved operation info
158+ # @return [void]
159+ # rubocop:disable Metrics/AbcSize -- data-mapping method; high ABC from 9 hash assignments, not complexity
160+ def populate_operation_metadata ( metadata , op_name , op_info )
161+ metadata [ :soap_action ] = op_info . soap_action
162+ metadata [ :soap_version ] = op_info . soap_version
163+
164+ if op_info . input?
165+ metadata [ :input_style ] = op_info . input_style
166+ metadata [ :output_style ] = op_info . output_style
167+ metadata [ :rpc_input_namespace ] = op_info . rpc_input_namespace
168+ metadata [ :rpc_output_namespace ] = op_info . rpc_output_namespace
169+ else
170+ record_build_issue ( op_name ,
171+ "Binding operation #{ op_name . inspect } is missing a required <input> element" )
172+ end
173+
174+ metadata [ :schema_complete ] = schema_complete_for_operation? ( op_info )
175+ metadata [ :input ] = build_message ( op_info . input )
176+ metadata [ :output ] = op_info . output ? build_message ( op_info . output ) : nil
177+ end
178+ # rubocop:enable Metrics/AbcSize
150179
151180 # Returns an operation hash with safe defaults.
152181 #
153- # Each field starts as nil/empty. The loop in {#build_operations}
154- # progressively enhances the hash with binding-level metadata and
155- # resolved message data. If any step fails, the rescue stores
156- # whatever was captured up to that point.
182+ # Each field starts as nil/empty. {#build_single_operation} and
183+ # {#populate_operation_metadata} progressively enhance the hash
184+ # with binding-level metadata and resolved message data.
157185 #
158186 # @param name [String] the operation name
159187 # @param input_name [String, nil] disambiguator for overloaded operations
0 commit comments