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