Skip to main content
summaryrefslogtreecommitdiffstats
blob: 5208c8af35c137cfc9f218883d0cecaf93e86237 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/*******************************************************************************
 * Copyright (c) 2002-2005 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsi.internal.core.profile.validator.impl.wsdl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.wsdl.Binding;
import javax.xml.namespace.QName;

import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.WSITag;
import org.eclipse.wst.wsi.internal.core.analyzer.AssertionFailException;
import org.eclipse.wst.wsi.internal.core.analyzer.AssertionNotApplicableException;
import org.eclipse.wst.wsi.internal.core.profile.TestAssertion;
import org.eclipse.wst.wsi.internal.core.profile.validator.EntryContext;
import org.eclipse.wst.wsi.internal.core.profile.validator.impl.AssertionProcess;
import org.eclipse.wst.wsi.internal.core.report.AssertionResult;
import org.eclipse.wst.wsi.internal.core.xml.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * AP2908
 *
 * <context>For a candidate wsdl:binding</context>
 * <assertionDescription>The mime:part element in a DESCRIPTION does not have a name attribute.</assertionDescription>
 */
public class AP2908 extends AssertionProcess implements WSITag
{
  private final WSDLValidatorImpl validator;

  /**
   * @param WSDLValidatorImpl
   */
  public AP2908(WSDLValidatorImpl impl)
  {
    super(impl);
    this.validator = impl;
  }

  /* Validates the test assertion.
  * @see org.wsi.test.profile.validator.impl.BaseValidatorImpl.AssertionProcess#validate(org.wsi.test.profile.TestAssertion, org.wsi.test.profile.validator.EntryContext)
  */
  public AssertionResult validate(
    TestAssertion testAssertion,
    EntryContext entryContext)
    throws WSIException
  {
    try
    {
      // Getting a wsdl:binding
      Binding wsdlBinding = (Binding) entryContext.getEntry().getEntryDetail();

      // Since WSDL4J 1.4 ignores any attributes of mime:part, use Xerces 2.6.2 instead
      Document doc = XMLUtils.parseXMLDocument(validator.wsdlURL);

      // Finding the wsdl:binding element being processed
      Element binding = getBindingElement(
        doc.getDocumentElement(), wsdlBinding.getQName().getLocalPart());

      List ops = getChildElements(binding, WSDL_OPERATION);

      // A variable that indicates a binding contains at least one
      // mime:multipartRelated element
      boolean multipartsFound = false;

      // Going through the operation elements
      for (int i = 0; i < ops.size(); i++)
      {
        Element bindingOperation = (Element) ops.get(i);

        // Getting wsdl:input and wsdl:output elements of an operation
        Element bindingInput = getChildElement(bindingOperation, WSDL_INPUT);
        Element bindingOutput = getChildElement(bindingOperation, WSDL_OUTPUT);

        // Collecting all the mime:multipartRelated elements from wsdl:input and wsdl:output
        List inputMultiparts = getMimeMultipartElements(bindingInput);
        List outputMultiparts = getMimeMultipartElements(bindingOutput);

        // If the wsdl:input contains mime:multipartRelated elements
        if (!inputMultiparts.isEmpty())
        {
          multipartsFound = true;

          // If there is a mime:part element containing a name attribute,
          // the assertion failed
          if (containsInvalidMimePart(inputMultiparts))
          {
            throw new AssertionFailException("The invalid "
                + "mime:part element is in the wsdl:input of the \""
                + bindingOperation.getAttribute(WSIConstants.ATTR_NAME)
                + "\" binding operation.");
          }
        }

        // If the wsdl:output contains mime:multipartRelated elements
        if (!outputMultiparts.isEmpty())
        {
          multipartsFound = true;

          // If there is a mime:part element containing a name attribute,
          // the assertion failed
          if (containsInvalidMimePart(outputMultiparts))
          {
            throw new AssertionFailException("The invalid "
                + "mime:part element is in the wsdl:output of the \""
                + bindingOperation.getAttribute(WSIConstants.ATTR_NAME)
                + "\" binding operation.");
          }
        }
      }
      // If the binding contains no one mime:multipartRelated element,
      // the assertion is not applicable
      if (!multipartsFound)
        throw new AssertionNotApplicableException();
    }
    catch (IOException ioe)
    {
      result = AssertionResult.RESULT_NOT_APPLICABLE;
    }
    catch (AssertionNotApplicableException anae)
    {
      result = AssertionResult.RESULT_NOT_APPLICABLE;
    }
    catch (AssertionFailException afe)
    {
      result = AssertionResult.RESULT_FAILED;
      failureDetail = validator.createFailureDetail(
        afe.getMessage(), entryContext);
    }
    // Return assertion result
    return validator.createAssertionResult(
      testAssertion, result, failureDetail);
  }

  /**
   * Validates mime:part elements for each of mime:multipartRelated element.
   * @param multiparts a list of mime:multipartRelated elements.
   * @return true, if any mime:part contains a name attribute, false otherwise.
   */
  private boolean containsInvalidMimePart(List multiparts) {
    // Going through a list of mime:multipartRelated elements
    for (int i = 0; i < multiparts.size(); i++)
    {
      // Getting a list of mime:part elements
      List mimeParts =
        getChildElements((Element) multiparts.get(i), WSDL_MIME_PART);
      // Going through all the mime:part elements
      for (int j = 0; j < mimeParts.size(); j++)
      {
        Element mimePart = (Element) mimeParts.get(j);
        // If the mime:part element contains a name attribute,
        // return true
        if (mimePart.getAttributeNode(WSIConstants.ATTR_NAME) != null)
        {
          return true;
        }
      }
    }
    // No one invalid mime:part element is found, return false
    return false;
  }

  /**
   * Collects all mime:multipartRelated elements.
   * @param parent an element which the child elements are gathered from.
   * @return the list of mime:multipartRelated elements found.
   */
  private List getMimeMultipartElements(Element parent)
  {
    List mimeMultipartElements = new ArrayList();
    // If the parent is not null
    if (parent != null)
    {
      // Getting the first parent's child
      Element child = XMLUtils.getFirstChild(parent);
      while (child != null)
      {
        // If the child is a mime:multipartRelated element
        if (child.getNamespaceURI().equals(WSDL_MIME_MULTIPART.getNamespaceURI())
          && child.getLocalName().equals(WSDL_MIME_MULTIPART.getLocalPart()))
        {
          // Adding the element to the list being returned
          mimeMultipartElements.add(child);

          // Getting mime:partS from the element
          List mimeParts = getChildElements(child, WSDL_MIME_PART);
          // Going through all the mime:part elements
          for (int i = 0; i < mimeParts.size(); i++)
          {
            // Collecting all the mime:multipartRelated elements of this mime:part
            List elems = getMimeMultipartElements((Element) mimeParts.get(i));
            // Adding the elements to the list being returned
            mimeMultipartElements.addAll(elems);
          }
        }
        // Getting the next child
        child = XMLUtils.getNextSibling(child);
      }
    }

    return mimeMultipartElements;
  }

  /**
   * Looks for an element's child element.
   * @param parent a parent element.
   * @param childName a qualified element name being found.
   * @return an element or null if it is not found.
   */
  private Element getChildElement(Element parent, QName childName)
  {
    // Getting the first parent's child
    Element child = XMLUtils.getFirstChild(parent);
    while (child != null)
    {
      // If the child has the required qualified name
      if (child.getNamespaceURI().equals(childName.getNamespaceURI())
        && child.getLocalName().equals(childName.getLocalPart()))
      {
        // return the child
        return child;
      }
      // Getting the next child
      child = XMLUtils.getNextSibling(child);
    }
    return null;
  }

  /**
   * Collects element's child elements.
   * @param parent a parent element.
   * @param childName a qualified element name being found.
   * @return a list of elements found.
   */
  private List getChildElements(Element parent, QName childName)
  {
    List children = new ArrayList();
    if (parent != null)
    {
      // Getting the first parent's child
      Element child = XMLUtils.getFirstChild(parent);
      while (child != null)
      {
        // If the child has the required qualified name
        if (child.getNamespaceURI().equals(childName.getNamespaceURI())
          && child.getLocalName().equals(childName.getLocalPart()))
        {
          // Adding the child to the list
          children.add(child);
        }
        // Getting the next binding's child
        child = XMLUtils.getNextSibling(child);
      }
    }
    return children;
  }

  /**
   * Looks for wsdl:binding element.
   * @param definitions a wsdl:definitions element.
   * @param bindingName a name of wsdl:binding element.
   * @return a wsdl:binding element or null if it is not found.
   */
  private Element getBindingElement(Element definitions, String bindingName)
  {
    // Getting the first definitions' child
    Element child = XMLUtils.getFirstChild(definitions);
    while (child != null)
    {
      // If definitions' child is wsdl:binding element
      // and is the same that is being processed by WSDLValidator
      if (child.getNamespaceURI().equals(WSDL_BINDING.getNamespaceURI())
        && child.getLocalName().equals(WSDL_BINDING.getLocalPart())
        && child.getAttribute(WSIConstants.ATTR_NAME).equals(bindingName))
      {
        // return the wsdl:binding element
        return child;
      }
      // Getting the next definitions' child
      child = XMLUtils.getNextSibling(child);
    }
    // return null, is there is no such wsdl:binding
    return null;
  }
}

Back to the top