View Javadoc

1   /*
2    * Copyright  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  package org.apache.ws.addressing.handler;
18  
19  import org.apache.axis.message.addressing.Constants;
20  import org.apache.axis.message.addressing.MessageID;
21  import org.apache.axis.message.addressing.uuid.AxisUUIdGenerator;
22  import org.apache.axis.types.URI;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.ws.addressing.uuid.UUIdGeneratorFactory;
26  
27  import javax.xml.namespace.QName;
28  import javax.xml.rpc.JAXRPCException;
29  import javax.xml.rpc.handler.GenericHandler;
30  import javax.xml.rpc.handler.HandlerInfo;
31  import javax.xml.rpc.handler.MessageContext;
32  import java.util.ArrayList;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.StringTokenizer;
36  
37  /***
38   * Abstract JAX-RPC {@link javax.xml.rpc.handler.Handler} containing base WS-Addressing
39   * functionality that is used by both client-side and server-side subclasses.
40   *
41   * @author Davanum Srinivas (dims@yahoo.com)
42   * @author Ian P. Springer <ian_springer@hp.com>
43   */
44  public abstract class AbstractAddressingHandler extends GenericHandler
45  {
46  
47      public static final String CONFIG_PROP__ACTOR = "actor";
48      public static final String CONFIG_PROP__REFERENCE_PROPERTY_NAMES = "referencePropertyNames";
49      public static final String CONFIG_PROP__REMOVE_HEADERS = "removeHeaders";
50  
51      static final String UUID_URI_SCHEME = "uuid";
52  
53      private static final QName[] UNDERSTOOD_HEADERS = new QName[]{
54          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.ACTION),
55          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.FAULT_TO),
56          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.FROM),
57          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.MESSAGE_ID),
58          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.RECIPIENT),
59          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.RELATES_TO),
60          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.REPLY_TO),
61          new QName(Constants.NS_URI_ADDRESSING_2003_03, Constants.TO),
62          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.ACTION),
63          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.FAULT_TO),
64          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.FROM),
65          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.MESSAGE_ID),
66          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.RECIPIENT),
67          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.RELATES_TO),
68          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.REPLY_TO),
69          new QName(Constants.NS_URI_ADDRESSING_2004_03, Constants.TO),
70          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.ACTION),
71          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.FAULT_TO),
72          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.FROM),
73          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.MESSAGE_ID),
74          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.RECIPIENT),
75          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.RELATES_TO),
76          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.REPLY_TO),
77          new QName(Constants.NS_URI_ADDRESSING_2004_08, Constants.TO)
78      };
79  
80      /***
81       * Constant to be returned by handleRequest(), handleResponse(), and handleFault().
82       */
83      protected static final boolean CONTINUE_HANDLER_CHAIN_PROCESSING = true;
84  
85      private static final Log LOG =
86              LogFactory.getLog( AbstractAddressingHandler.class.getName() );
87  
88      private Map handlerConfigProps;
89      private List refPropQNames;
90  
91      /***
92       * Returns a list QNames of the SOAP headers that this handler processes.
93       *
94       * @return Returns a list QNames of the SOAP headers that this handler processes
95       */
96      public QName[] getHeaders()
97      {
98          return UNDERSTOOD_HEADERS;
99      }
100 
101     /***
102      * Initializes this handler. This handler supports the following configuration properties:
103      * <ul>
104      * <li>actor (optional) - only SOAP headers with this actor URI will be processed</li>
105      * <li>referencePropertyNames (optional) - a list of QNames of reference properties (i.e. - non-WSA SOAP headers)
106      * that should be processed; if set to "*", all properties will be processed,
107      * if not specified, only WSA headers will be processed</li>
108      * <li>removeHeaders (optional) - if set to "true", headers will be removed from the SOAP envelope after they have
109      * been processed</li>
110      * </ul>
111      *
112      * @param handlerInfo handler info containing handler configuration properties from deployment descriptor
113      */
114     public void init( HandlerInfo handlerInfo )
115     {
116         super.init( handlerInfo );
117         LOG.info( "Initializing JAX-RPC handler " + this.getClass().getName() + "..." );
118         handlerConfigProps = handlerInfo.getHandlerConfig();
119         initReferencePropertyQNames();
120     }
121 
122     /***
123      * Returns this handler's configuration properties.
124      *
125      * @return this handler's configuration properties
126      */
127     protected Map getHandlerConfigProperties()
128     {
129         return handlerConfigProps;
130     }
131 
132     /***
133      * Returns the value of the specified handler configuration property.
134      *
135      * @param propName the name of a configuration property
136      *
137      * @return the value of the specified handler configuration property
138      */
139     protected String getHandlerConfigProperty( String propName )
140     {
141         return (String) getHandlerConfigProperties().get( propName );
142     }
143 
144     /***
145      * Returns true if the value of the specified handler configuration property is "true",
146      * or false otherwise.
147      *
148      * @param propName the name of a configuration property
149      *
150      * @return true if the value of the specified handler configuration property is "true",
151      *         or false otherwise
152      */
153     protected boolean isHandlerConfigPropertyTrue( String propName )
154     {
155         return Boolean.TRUE.toString().equalsIgnoreCase( getHandlerConfigProperty( propName ) );
156     }
157 
158     /***
159      * This method uses the Java UUID Generator (JUG) library to generate a UUID. Subclasses
160      * can optionally override it to use a different UUID generator.
161      *
162      * @return
163      */
164     protected String generateUUId()
165     {
166         try
167         {
168             return UUIdGeneratorFactory.createUUIdGenerator( AxisUUIdGenerator.class ).generateUUId();
169         }
170         catch ( RuntimeException re )
171         {
172             throw new JAXRPCException( "Failed to generate UUId using default UUId generator " + UUIdGeneratorFactory.DEFAULT_IMPL_CLASSNAME + ".", re );
173         }
174     }
175 
176     protected boolean isMustUnderstandEnabled( MessageContext msgContext )
177     {
178         return isPropertyTrue( msgContext, Constants.ENV_ADDRESSING_SET_MUST_UNDERSTAND );
179     }
180 
181     protected boolean isPropertyTrue( MessageContext msgContext, String propName )
182     {
183         return Boolean.TRUE.toString().equals( msgContext.getProperty( propName ) );
184     }
185 
186     protected MessageID createMessageID()
187             throws URI.MalformedURIException
188     {
189         return new MessageID( new URI( UUID_URI_SCHEME + ":" + generateUUId() ) );
190     }
191 
192     protected List getReferencePropertyQNames()
193     {
194         return refPropQNames;
195     }
196 
197     /***
198      * Returns the value of the "actor" handler config property.
199      *
200      * @return the value of the "actor" handler config property
201      */
202     protected String getActor()
203     {
204         return getHandlerConfigProperty( CONFIG_PROP__ACTOR );
205     }
206 
207     /***
208      * Returns the value of the "removeHeaders" handler config property.
209      *
210      * @return the value of the "removeHeaders" handler config property
211      */
212     protected boolean isRemoveHeadersEnabled()
213     {
214         return isHandlerConfigPropertyTrue( CONFIG_PROP__REMOVE_HEADERS );
215     }
216 
217     /***
218      * Retrieves QNames for reference properties from WSDD and initializes
219      * refPropQNames - the list of reference properties that this handler
220      * should care about.
221      */
222     protected void initReferencePropertyQNames()
223     {
224         String refPropNamesConfigPropValue = getHandlerConfigProperty( CONFIG_PROP__REFERENCE_PROPERTY_NAMES );
225 
226         if ( refPropNamesConfigPropValue == null )
227         {
228             LOG.debug( "No reference properties will be processed." );
229             refPropQNames = new ArrayList();
230         }
231         else if ( refPropNamesConfigPropValue.equals( "*" ) )
232         {
233             LOG.debug( "All reference properties will be processed." );
234             refPropQNames = null;
235         }
236         else
237         {
238             refPropQNames = new ArrayList();
239             StringTokenizer tokenizer = new StringTokenizer( refPropNamesConfigPropValue, "," );
240             while ( tokenizer.hasMoreTokens() )
241             {
242                 String qnameString = tokenizer.nextToken().trim();
243                 try
244                 {
245                     QName qname = QName.valueOf( qnameString );
246                     LOG.debug( "Reference properties with QName '" + qnameString + "' will be processed." );
247                     refPropQNames.add( qname );
248                 }
249                 catch ( IllegalArgumentException iae )
250                 {
251                     LOG.warn( "Invalid QName '" + qnameString + "' specified in handler config." );
252                 }
253             }
254         }
255     }    
256 
257 }