View Javadoc

1   /*
2    * Copyright  1999-2004 The Apache Software Foundation.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *
16   */
17  
18  package org.apache.axis.message.addressing.util;
19  
20  import org.apache.axis.message.addressing.Constants;
21  import org.apache.axis.message.addressing.AddressingHeaders;
22  
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.ArrayList;
26  
27  import javax.xml.soap.Name;
28  import javax.xml.soap.SOAPHeader;
29  import javax.xml.soap.SOAPHeaderElement;
30  import javax.xml.soap.SOAPElement;
31  import javax.xml.soap.SOAPException;
32  
33  import javax.wsdl.Input;
34  import javax.wsdl.Output;
35  import javax.wsdl.Operation;
36  import javax.wsdl.extensions.AttributeExtensible;
37  
38  import javax.xml.namespace.QName;
39  import javax.xml.rpc.handler.MessageContext;
40  
41  /***
42   * Class AddressingUtils
43   * 
44   * @author Jarek Gawor (gawor@apache.org)
45   */
46  public class AddressingUtils {
47  
48      /***
49       * Removes all instances of a given header name in WS-Addressing
50       * namespace for a given actor.
51       */
52      public static void removeHeader(SOAPHeader soapHeader, 
53                                      String actorURI,
54                                      String headerName) {
55          if (soapHeader == null) {
56              return;
57          }
58          Iterator headers = soapHeader.examineHeaderElements(actorURI);
59          List existingElements = new ArrayList();
60          while (headers.hasNext()) {
61              SOAPHeaderElement hElement = (SOAPHeaderElement) headers.next();
62              Name hName = hElement.getElementName();
63              if (isAddressingNamespaceURI( hName.getURI() ) &&
64                  hName.getLocalName().equals(headerName)) {
65                  existingElements.add(hElement);
66              }
67          }
68          for (int i = 0; i < existingElements.size(); i++) {
69              SOAPHeaderElement el = (SOAPHeaderElement) existingElements.get(i);
70              el.detachNode();
71          }
72      }
73  
74      public static boolean isAddressingNamespaceURI( String nsURI ) {
75          return Constants.ADDRESSING_NS_URI_SET.contains( nsURI );
76      }
77  
78      /***
79       * Removes all instances of all WS-Addressing headers for a given
80       * actor.
81       */
82      public static void removeHeaders(SOAPHeader soapHeader, 
83                                       String actorURI) {
84          if (soapHeader == null) {
85              return;
86          }
87          Iterator headers = soapHeader.examineHeaderElements(actorURI);
88          List existingElements = new ArrayList();
89          while (headers.hasNext()) {
90              SOAPHeaderElement hElement = (SOAPHeaderElement) headers.next();
91              Name hName = hElement.getElementName();
92              if (isAddressingNamespaceURI( hName.getURI() )) {
93                  existingElements.add(hElement);
94              }
95          }
96          for (int i = 0; i < existingElements.size(); i++) {
97              SOAPHeaderElement el = (SOAPHeaderElement) existingElements.get(i);
98              el.detachNode();
99          }
100     }
101     
102     /***
103      * Gets response <code>AddressingHeaders</code> associated with the 
104      * specified context. If there are no <code>AddressingHeaders</code>
105      * associated with the context, new reponse <code>AddressingHeaders</code>
106      * are created and associated with the context.
107      */
108     public static AddressingHeaders getResponseHeaders(MessageContext msgCtx) {
109         return getHeaders(msgCtx, Constants.ENV_ADDRESSING_RESPONSE_HEADERS);
110     }
111     
112     /***
113      * Gets request <code>AddressingHeaders</code> associated with the 
114      * specified context. If there are no <code>AddressingHeaders</code>
115      * associated with the context, new request <code>AddressingHeaders</code>
116      * are created and associated with the context.
117      */
118     public static AddressingHeaders getRequestHeaders(MessageContext msgCtx) {
119         return getHeaders(msgCtx, Constants.ENV_ADDRESSING_REQUEST_HEADERS);
120     }
121     
122     private static AddressingHeaders getHeaders(MessageContext msgCtx,
123                                                 String type) {
124         AddressingHeaders headers =
125             (AddressingHeaders)msgCtx.getProperty(type);
126         
127         if (headers == null) {
128             headers = new AddressingHeaders();
129             // set property so other handlers might have a chance to use/modify
130             msgCtx.setProperty(type, headers);
131         }
132         
133         return headers;
134     }
135 
136     /***
137      * Gets input action. See section 3.3 of the 2004 WS-Addressing 
138      * specification.
139      */
140     public static String getInputAction(QName portTypeQName,
141                                         Operation operation) {
142         if (portTypeQName == null || operation == null) {
143             throw new IllegalArgumentException("Null parameters are not allowed.");
144         }
145         Input input = operation.getInput();
146         if (input == null) {
147             return null;
148         }
149         return getAction(input, input.getName(), 
150                          portTypeQName, operation, "Request");
151     }
152 
153     /***
154      * Gets output action. See section 3.3 of the 2004 WS-Addressing 
155      * specification.
156      */
157     public static String getOutputAction(QName portTypeQName,
158                                          Operation operation) {
159         if (portTypeQName == null || operation == null) {
160             throw new IllegalArgumentException("Null parameters are not allowed.");
161         }
162         Output output = operation.getOutput();
163         if (output == null) {
164             return null;
165         }
166         return getAction(output, output.getName(), 
167                          portTypeQName, operation, "Response");
168     }
169     
170     private static String getAction(AttributeExtensible inputOutput,
171                                     String inputOutputName,
172                                     QName portTypeQName,
173                                     Operation operation,
174                                     String defaultName) {
175         Object value = 
176             inputOutput.getExtensionAttribute(Constants.QNAME_ACTION);
177         if (value != null) {
178             // wsdl4j returns a qname by default?
179             if (value instanceof QName) {
180                 return ((QName)value).getLocalPart();
181             } else {
182                 return value.toString();
183             }
184         }
185         String name = inputOutputName;
186         if (name == null) {
187             name = operation.getName() + defaultName;
188         }
189         StringBuffer buf = new StringBuffer(50);
190         buf.append(portTypeQName.getNamespaceURI());
191         if (!portTypeQName.getNamespaceURI().endsWith("/")) {
192             buf.append("/");
193         }
194         buf.append(portTypeQName.getLocalPart()).append("/").append(name);
195         return buf.toString();
196     }
197     
198     /***
199      * Gets prefix for a given namespace. If the prefix is already defined
200      * for the namespace given, it is returned. Otherwise, a new prefix is 
201      * automatically registered with the given namespace and returned.
202      *
203      */
204     public static String getNamespacePrefix(SOAPElement element,
205                                             String namespace) 
206         throws SOAPException {
207         if (element == null || namespace == null) {
208             throw new IllegalArgumentException("Null parameters are not allowed.");
209         }
210         Iterator iter = element.getVisibleNamespacePrefixes();
211         String prefix = null;
212         String ns = null;
213         while(iter.hasNext()) {
214             prefix = (String)iter.next();
215             ns = element.getNamespaceURI(prefix);
216             if (namespace.equals(ns)) {
217                 return prefix;
218             }
219         }
220         
221         int i = 0;
222         prefix = "ns" + i;
223         while (element.getNamespaceURI(prefix) != null) {
224             prefix = "ns" + i++;
225         }
226         
227         element.addNamespaceDeclaration(prefix, namespace);
228         
229         return prefix;
230     }
231 }