1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support;
14
15 import com.eviware.soapui.impl.wsdl.WsdlOperation;
16 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
17 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
18 import com.eviware.soapui.model.iface.Operation;
19 import org.apache.log4j.Logger;
20 import org.apache.xmlbeans.SchemaGlobalElement;
21 import org.apache.xmlbeans.SchemaType;
22 import org.apache.xmlbeans.XmlException;
23 import org.apache.xmlbeans.XmlObject;
24
25 import javax.wsdl.*;
26 import javax.xml.namespace.QName;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31
32 /***
33 * XmlObject based wrapper for manipulation, etc..
34 *
35 * @author Ole.Matzura
36 */
37
38 public class MessageXmlObject
39 {
40 private XmlObject messageObj;
41 private WsdlContext wsdlContext;
42 private List<MessageXmlPart> messageParts = new ArrayList<MessageXmlPart>();
43
44 private final static Logger log = Logger.getLogger( MessageXmlObject.class );
45 private final String messageContent;
46 private Operation operation;
47 private final boolean isRequest;
48
49 public MessageXmlObject( WsdlOperation operation, String messageContent, boolean isRequest )
50 {
51 this.messageContent = messageContent;
52 this.operation = operation;
53 this.isRequest = isRequest;
54 wsdlContext = operation.getInterface().getWsdlContext();
55 }
56
57 public String getMessageContent()
58 {
59 if( messageObj == null )
60 {
61 return messageContent;
62 }
63 else
64 {
65 for( int c = 0; c < messageParts.size(); c++ )
66 messageParts.get( c ).update();
67
68 return messageObj.xmlText();
69 }
70 }
71
72 public XmlObject getMessageObj() throws XmlException
73 {
74 if( messageObj == null )
75 {
76 messageObj = XmlObject.Factory.parse( getMessageContent() );
77 }
78
79 return messageObj;
80 }
81
82 public MessageXmlPart [] getMessageParts() throws Exception
83 {
84 String operationName = operation.getName();
85 BindingOperation bindingOperation = findBindingOperation( operationName );
86 if (bindingOperation == null)
87 {
88 throw new Exception("Missing operation [" + operationName + "] in wsdl definition");
89 }
90
91 if( !wsdlContext.hasSchemaTypes() )
92 {
93 throw new Exception("Missing schema types for message");
94 }
95
96 XmlObject msgXml = getMessageObj();
97 Part[] inputParts = isRequest ? WsdlUtils.getInputParts(bindingOperation) : WsdlUtils.getOutputParts(bindingOperation);
98 messageParts.clear();
99
100 if( WsdlUtils.isRpc( wsdlContext.getDefinition(), bindingOperation ))
101 {
102
103 XmlObject[] paths = msgXml.selectPath( "declare namespace env='" +
104 wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" +
105 "declare namespace ns='" + wsdlContext.getDefinition().getTargetNamespace() + "';" +
106 "$this/env:Envelope/env:Body/ns:" + bindingOperation.getName() );
107
108 if( paths.length != 1 )
109 {
110 throw new Exception("Missing message wrapper element [" +
111 wsdlContext.getDefinition().getTargetNamespace() + "@" + bindingOperation.getName() );
112 }
113 else
114 {
115 XmlObject wrapper = paths[0];
116
117 for (int i = 0; i < inputParts.length; i++)
118 {
119 Part part = inputParts[i];
120
121
122 QName partName = part.getElementName();
123 if( partName == null )
124 partName = new QName( part.getName() );
125
126 XmlObject[] children = wrapper.selectChildren( partName );
127
128
129 if( WsdlUtils.isAttachmentInputPart( part, bindingOperation ))
130 {
131
132 if( children.length == 1 )
133 {
134 QName typeName = part.getTypeName();
135 SchemaType type = typeName == null ? null : wsdlContext.getSchemaTypeLoader().findType( typeName );
136 messageParts.add( new MessageXmlPart( children[0], type, part, bindingOperation, isRequest ));
137 }
138 }
139 else if( children.length != 1 )
140 {
141 log.error("Missing message part [" + part.getName() + "]" );
142 }
143 else
144 {
145 QName typeName = part.getTypeName();
146 if( typeName == null )
147 {
148 typeName = partName;
149 SchemaGlobalElement type = wsdlContext.getSchemaTypeLoader().findElement( typeName );
150
151 if( type != null )
152 {
153 messageParts.add( new MessageXmlPart( children[0], type.getType(), part, bindingOperation, isRequest ) );
154 }
155 else log.error( "Missing element [" + typeName + "] in associated schema for part [" + part.getName() + "]" );
156 }
157 else
158 {
159 SchemaType type = wsdlContext.getSchemaTypeLoader().findType( typeName );
160 if( type != null )
161 {
162 messageParts.add( new MessageXmlPart( children[0], type, part, bindingOperation, isRequest ));
163 }
164 else log.error( "Missing type [" + typeName + "] in associated schema for part [" + part.getName() + "]" );
165 }
166 }
167 }
168 }
169 }
170 else
171 {
172 Part part = inputParts[0];
173 QName elementName = part.getElementName();
174 if( elementName != null )
175 {
176
177 XmlObject[] paths = msgXml.selectPath( "declare namespace env='" +
178 wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" +
179 "declare namespace ns='" + elementName.getNamespaceURI() + "';" +
180 "$this/env:Envelope/env:Body/ns:" + elementName.getLocalPart() );
181
182 if( paths.length == 1 )
183 {
184 SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement( elementName );
185 if( elm != null )
186 {
187 messageParts.add( new MessageXmlPart( paths[0], elm.getType(), part, bindingOperation, isRequest ));
188 }
189 else throw new Exception("Missing part type in associated schema" );
190 }
191 else throw new Exception("Missing message part with name [" + elementName + "]" );
192 }
193 }
194
195 return messageParts.toArray( new MessageXmlPart[messageParts.size()] );
196 }
197
198 private BindingOperation findBindingOperation(String operationName) throws Exception
199 {
200 Map<?,?> services = wsdlContext.getDefinition().getAllServices();
201 Iterator<?> i = services.keySet().iterator();
202 while( i.hasNext() )
203 {
204 Service service = (Service) wsdlContext.getDefinition().getService( (QName) i.next());
205 Map<?,?> ports = service.getPorts();
206
207 Iterator<?> iterator = ports.keySet().iterator();
208 while( iterator.hasNext() )
209 {
210 Port port = (Port) service.getPort( (String) iterator.next() );
211 BindingOperation bindingOperation = port.getBinding().getBindingOperation( operationName, null, null );
212 if( bindingOperation != null ) return bindingOperation;
213 }
214 }
215
216 Map<?,?> bindings = wsdlContext.getDefinition().getAllBindings();
217 i = bindings.keySet().iterator();
218 while( i.hasNext() )
219 {
220 Binding binding = (Binding) bindings.get( i.next() );
221 BindingOperation bindingOperation = binding.getBindingOperation( operationName, null, null );
222 if( bindingOperation != null ) return bindingOperation;
223 }
224
225 return null;
226 }
227 }