1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }