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.List;
17
18 import javax.wsdl.BindingOperation;
19 import javax.wsdl.Part;
20 import javax.xml.namespace.QName;
21
22 import org.apache.log4j.Logger;
23 import org.apache.xmlbeans.SchemaGlobalElement;
24 import org.apache.xmlbeans.SchemaType;
25 import org.apache.xmlbeans.XmlException;
26 import org.apache.xmlbeans.XmlObject;
27
28 import com.eviware.soapui.impl.wsdl.WsdlOperation;
29 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
30 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
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 WsdlOperation 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 = operation.getBindingOperation();
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
98 .getOutputParts( bindingOperation );
99 messageParts.clear();
100
101 if( WsdlUtils.isRpc( wsdlContext.getDefinition(), bindingOperation ) )
102 {
103
104 XmlObject[] paths = msgXml.selectPath( "declare namespace env='"
105 + wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" + "declare namespace ns='"
106 + wsdlContext.getDefinition().getTargetNamespace() + "';" + "$this/env:Envelope/env:Body/ns:"
107 + bindingOperation.getName() );
108
109 if( paths.length != 1 )
110 {
111 throw new Exception( "Missing message wrapper element [" + wsdlContext.getDefinition().getTargetNamespace()
112 + "@" + bindingOperation.getName() );
113 }
114 else
115 {
116 XmlObject wrapper = paths[0];
117
118 for( int i = 0; i < inputParts.length; i++ )
119 {
120 Part part = inputParts[i];
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,
154 isRequest ) );
155 }
156 else
157 log.error( "Missing element [" + typeName + "] in associated schema for part ["
158 + part.getName() + "]" );
159 }
160 else
161 {
162 SchemaType type = wsdlContext.getSchemaTypeLoader().findType( typeName );
163 if( type != null )
164 {
165 messageParts.add( new MessageXmlPart( children[0], type, part, bindingOperation, isRequest ) );
166 }
167 else
168 log.error( "Missing type [" + typeName + "] in associated schema for part [" + part.getName()
169 + "]" );
170 }
171 }
172 }
173 }
174 }
175 else
176 {
177 Part part = inputParts[0];
178 QName elementName = part.getElementName();
179 if( elementName != null )
180 {
181
182
183 XmlObject[] paths = msgXml.selectPath( "declare namespace env='"
184 + wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" + "declare namespace ns='"
185 + elementName.getNamespaceURI() + "';" + "$this/env:Envelope/env:Body/ns:"
186 + elementName.getLocalPart() );
187
188 if( paths.length == 1 )
189 {
190 SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement( elementName );
191 if( elm != null )
192 {
193 messageParts.add( new MessageXmlPart( paths[0], elm.getType(), part, bindingOperation, isRequest ) );
194 }
195 else
196 throw new Exception( "Missing part type in associated schema" );
197 }
198 else
199 throw new Exception( "Missing message part with name [" + elementName + "]" );
200 }
201 }
202
203 return messageParts.toArray( new MessageXmlPart[messageParts.size()] );
204 }
205 }