Clover coverage report - Apache Addressing - 1.0
Coverage timestamp: Tue Mar 22 2005 07:59:24 EST
file stats: LOC: 596   Methods: 18
NCLOC: 390   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
AddressingHandler.java 30% 42.5% 55.6% 39%
coverage coverage
 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.handler;
 19   
 
 20   
 import org.apache.axis.AxisFault;
 21   
 import org.apache.axis.Message;
 22   
 import org.apache.axis.MessageContext;
 23   
 import org.apache.axis.client.Call;
 24   
 import org.apache.axis.client.Service;
 25   
 import org.apache.axis.message.SOAPEnvelope;
 26   
 import org.apache.axis.message.SOAPBodyElement;
 27   
 import org.apache.axis.message.RPCElement;
 28   
 import org.apache.axis.description.OperationDesc;
 29   
 import org.apache.axis.components.uuid.UUIDGen;
 30   
 import org.apache.axis.components.uuid.UUIDGenFactory;
 31   
 import org.apache.axis.handlers.BasicHandler;
 32   
 import org.apache.axis.message.addressing.Action;
 33   
 import org.apache.axis.message.addressing.AttributedURI;
 34   
 import org.apache.axis.message.addressing.AddressingHeaders;
 35   
 import org.apache.axis.message.addressing.Constants;
 36   
 import org.apache.axis.message.addressing.EndpointReference;
 37   
 import org.apache.axis.message.addressing.EndpointReferenceType;
 38   
 import org.apache.axis.message.addressing.MessageID;
 39   
 import org.apache.axis.message.addressing.To;
 40   
 import org.apache.axis.message.addressing.util.AddressingUtils;
 41   
 import org.apache.axis.types.URI;
 42   
 
 43   
 import org.apache.commons.logging.Log;
 44   
 import org.apache.commons.logging.LogFactory;
 45   
 
 46   
 import javax.xml.namespace.QName;
 47   
 import java.util.ArrayList;
 48   
 import java.util.List;
 49   
 import java.util.StringTokenizer;
 50   
 
 51   
 /**
 52   
  * Class AddressingHandler
 53   
  *
 54   
  * @author Davanum Srinivas (dims@yahoo.com)
 55   
  */
 56   
 public class AddressingHandler extends BasicHandler {
 57   
 
 58   
     protected static Log log =
 59   
         LogFactory.getLog(AddressingHandler.class.getName());
 60   
 
 61   
     // let's reuse uuid generator
 62   
     private static UUIDGen uuidGen = UUIDGenFactory.getUUIDGen();
 63   
 
 64   
     // A list of QNames of reference properties specified by the
 65   
     // deployer that need to be handled.
 66   
     // If the ignore flag (above) is set to false, and this list is
 67   
     // null - we process all headers
 68   
     private List refPropQNames;
 69   
     
 70   
     private String actor;
 71   
 
 72   
     private boolean removeHeaders = false;
 73   
     
 74  8
     public AddressingHandler() {}
 75   
     
 76   
     /**
 77   
      * Initialize the addressing handler.
 78   
      */
 79  8
     public void init() {
 80  8
         super.init();
 81  8
         initializeReferencePropertyNames();
 82  8
         initializeRemoveHeaders();
 83  8
         initializeActor();
 84   
     }
 85   
     
 86  8
     protected void initializeActor() {
 87  8
         actor = (String) getOption("actor");
 88   
     }
 89   
     
 90  8
     private void initializeRemoveHeaders() {
 91  8
         String property = (String) getOption("removeHeaders");
 92  8
         this.removeHeaders = "true".equalsIgnoreCase(property);
 93   
     }
 94   
 
 95   
     /**
 96   
      * Method invoke
 97   
      *
 98   
      * @param msgContext
 99   
      * @throws AxisFault
 100   
      */
 101  14
     public void invoke(MessageContext msgContext) throws AxisFault {
 102  14
         boolean setMustUnderstand = 
 103   
             msgContext.isPropertyTrue(Constants.ENV_ADDRESSING_SET_MUST_UNDERSTAND);
 104   
 
 105  14
         try {
 106  14
             if (msgContext.isClient()) {
 107  8
                 if (!msgContext.getPastPivot()) {
 108  4
                     processClientRequest(msgContext, setMustUnderstand);
 109   
                 } else {
 110  4
                     processClientResponse(msgContext);
 111   
                 }
 112   
             } else {
 113  6
                 if (!msgContext.getPastPivot()) {
 114  3
                     processServerRequest(msgContext);
 115   
                 } else {
 116  3
                     processServerResponse(msgContext, setMustUnderstand);
 117   
                 }
 118   
             }
 119   
         } catch (Exception e) {
 120  0
             log.error("Exception in AddressingHandler", e);
 121  0
             throw AxisFault.makeFault(e);
 122   
         }
 123   
     }
 124   
 
 125  0
     public void onFault(MessageContext msgContext) {
 126  0
         if (msgContext.isClient()) {
 127  0
             return;
 128   
         }
 129  0
         try {
 130  0
             processFault(msgContext);
 131   
         } catch (Exception e) {
 132  0
             log.error("Exception in AddressingHandler", e);
 133   
         }
 134   
     }
 135   
 
 136  0
     protected void processFault(MessageContext msgContext)
 137   
         throws Exception {
 138  0
         AddressingHeaders reqHeaders =
 139   
             (AddressingHeaders) msgContext.getProperty(
 140   
                   Constants.ENV_ADDRESSING_REQUEST_HEADERS
 141   
              );
 142   
 
 143  0
         if (reqHeaders == null) {
 144   
             // error?
 145  0
             return;
 146   
         }
 147   
 
 148  0
         AddressingHeaders resHeaders = 
 149   
             AddressingUtils.getResponseHeaders(msgContext);
 150   
 
 151   
         // set From
 152  0
         EndpointReference fromEPR = resHeaders.getFrom();
 153  0
         if (fromEPR == null) {
 154  0
             To toURI = reqHeaders.getTo();
 155  0
             if (toURI != null) {
 156  0
                 fromEPR = new EndpointReference(toURI);
 157  0
                 fromEPR.setProperties(reqHeaders.getReferenceProperties());
 158  0
                 resHeaders.setFrom(fromEPR);
 159   
             }
 160   
         }
 161   
 
 162   
         // set action for fault only with 04 spec. 03 spec unclear on that issue
 163  0
         if (Constants.NS_URI_ADDRESSING_DEFAULT.equals(Constants.NS_URI_ADDRESSING_2004_03)) {
 164  0
             resHeaders.setAction(new Action(new URI(Constants.FAULT_ACTION)));
 165   
         }
 166   
 
 167  0
         MessageID msgID = null;
 168   
 
 169   
         // process RelatesTo
 170  0
         msgID = reqHeaders.getMessageID();
 171  0
         if (msgID != null) {
 172  0
             resHeaders.addRelatesTo(msgID.toString(),
 173   
                                     Constants.QNAME_RESPONSE);
 174   
         }
 175   
 
 176   
         // process MessageID
 177  0
         msgID = new MessageID(new URI("uuid:" + uuidGen.nextUUID()));
 178  0
         resHeaders.setMessageID(msgID);
 179   
 
 180   
         // now put all headers into soap env.
 181  0
         Message msg = msgContext.getCurrentMessage();
 182  0
         if (msg == null) {
 183  0
             return;
 184   
         }
 185   
 
 186  0
         resHeaders.toEnvelope(msg.getSOAPEnvelope());
 187   
 
 188   
         // process FaultTo
 189  0
         EndpointReferenceType faultTo = reqHeaders.getFaultTo();
 190  0
         if (faultTo != null) {
 191  0
             AttributedURI address = faultTo.getAddress();
 192  0
             if (address != null) {
 193  0
                 String uri = address.toString();
 194  0
                 if (uri != null) {
 195   
                     // send the msg to fault to
 196  0
                     forwardMessage(faultTo, msg);
 197   
                     // Somehow make the response empty, or create a new empty
 198   
                     // response
 199  0
                     msgContext.setCurrentMessage(null);
 200   
                 }
 201   
             }
 202   
         }
 203   
     }
 204   
 
 205   
     /**
 206   
      * Method processClientRequest
 207   
      *
 208   
      * @param msgContext
 209   
      */
 210  4
     protected void processClientRequest(MessageContext msgContext,
 211   
                                         boolean setMustUnderstand)
 212   
         throws Exception {
 213   
 
 214  4
         AddressingHeaders sharedHeaders =
 215   
             (AddressingHeaders) msgContext.getProperty(
 216   
                   Constants.ENV_ADDRESSING_SHARED_HEADERS
 217   
             );
 218   
 
 219  4
         AddressingHeaders headers = 
 220   
             AddressingUtils.getRequestHeaders(msgContext);
 221   
 
 222  4
         headers.setSetMustUnderstand(setMustUnderstand);
 223   
 
 224   
         // set MessageID 
 225  4
         if (headers.getMessageID() == null) {
 226  4
             MessageID id = 
 227   
                 new MessageID(new URI("uuid:" + uuidGen.nextUUID()));
 228  4
             headers.setMessageID(id);
 229   
         }
 230   
 
 231   
         // set To
 232  4
         To to = headers.getTo();
 233  4
         if (to == null) {
 234  4
             if (sharedHeaders != null) {
 235   
                 // To is always set in shared headers
 236  2
                 headers.setTo(sharedHeaders.getTo());
 237   
             } else {
 238  2
                 headers.setTo(new To(msgContext.getStrProp(MessageContext.TRANS_URL)));
 239   
             }
 240   
         }
 241   
         
 242   
         // set Action
 243  4
         String action = msgContext.getSOAPActionURI();
 244  4
         if (action != null) {
 245  4
             headers.setAction(new Action(new URI(action)));
 246  0
         } else if(headers.getAction() != null) {
 247  0
             msgContext.setUseSOAPAction(true);
 248   
             // Make SOAP action match
 249  0
             msgContext.setSOAPActionURI(headers.getAction().toString());
 250   
         }
 251   
         
 252   
         // set From
 253  4
         if (headers.getFrom() == null) {
 254  4
             String from = 
 255   
                 msgContext.getStrProp(Constants.ENV_ADDRESSING_FROM_URI);
 256  4
             if (from != null) {
 257  0
                 headers.setFrom(new EndpointReference(from));
 258   
             } else {
 259  4
                 headers.setFrom(new EndpointReference(
 260   
                                      Constants.NS_URI_ANONYMOUS));
 261   
             }
 262   
         }
 263   
 
 264   
         // set ReplyTo
 265  4
         if (msgContext.isPropertyTrue(Constants.ENV_ADDRESSING_SEND_REPLYTO)) {
 266  0
             if (headers.getReplyTo() == null) {
 267  0
                 String replyTo = msgContext.getStrProp(Constants.ENV_ADDRESSING_REPLYTO_URI);
 268  0
                 if (replyTo != null) {
 269  0
                     headers.setReplyTo(new EndpointReference(replyTo));
 270   
                 } else {
 271  0
                     headers.setReplyTo(headers.getFrom());
 272   
                 }
 273   
             }
 274   
         }
 275   
         
 276   
         // set FaultTo
 277  4
         if (headers.getFaultTo() == null) {
 278  4
             String faultTo = 
 279   
                 msgContext.getStrProp(Constants.ENV_ADDRESSING_FAULTTO_URI);
 280  4
             if (faultTo != null) {
 281  0
                 headers.setFaultTo(new EndpointReference(faultTo));
 282   
             }
 283   
         }
 284   
 
 285  4
         if (sharedHeaders != null) {
 286  2
             headers.setReferenceProperties(sharedHeaders.getReferenceProperties());
 287   
         }
 288  4
         Message msg = msgContext.getRequestMessage();
 289  4
         headers.toEnvelope(msg.getSOAPEnvelope(), this.actor);
 290   
     }
 291   
 
 292   
     /**
 293   
      * Method processClientResponse
 294   
      *
 295   
      * @param msgContext
 296   
      */
 297  4
     protected void processClientResponse(MessageContext msgContext)
 298   
         throws Exception {
 299   
         // if no response - do nothing
 300  4
         Message msg = msgContext.getResponseMessage();
 301  4
         if (msg == null) {
 302  0
             return;
 303   
         }
 304   
 
 305  4
         AddressingHeaders headers = 
 306   
             new AddressingHeaders(msg.getSOAPEnvelope(), 
 307   
                                   this.actor, 
 308   
                                   true,
 309   
                                   this.removeHeaders, 
 310   
                                   false, 
 311   
                                   this.refPropQNames);
 312  4
         msgContext.setProperty(Constants.ENV_ADDRESSING_RESPONSE_HEADERS,
 313   
                                headers);
 314   
     }
 315   
 
 316   
     /**
 317   
      * Method processServerRequest
 318   
      *
 319   
      * @param msgContext
 320   
      * @throws Exception
 321   
      */
 322  3
     protected void processServerRequest(MessageContext msgContext)
 323   
         throws Exception {
 324  3
         Message msg = msgContext.getRequestMessage();
 325  3
         if (msg == null) {
 326  0
             return;
 327   
         }
 328  3
         AddressingHeaders headers =
 329   
             new AddressingHeaders(msg.getSOAPEnvelope(),
 330   
                                   this.actor, 
 331   
                                   true,
 332   
                                   this.removeHeaders,
 333   
                                   false,
 334   
                                   this.refPropQNames);
 335   
 
 336  3
         if (headers.getTo()==null)
 337   
         {
 338   
             // not a WS-A request; let it pass thru w/out doing anything
 339  0
             return;
 340   
         }
 341  3
         if (headers.getAction()==null)
 342   
         {
 343   
             // should we throw a SOAPFaultException here?
 344  0
             log.debug("WS-A request to endpoint " + headers.getTo() + " is missing the required wsa:Action header.");
 345   
         }
 346   
 
 347  3
         msgContext.setProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS,
 348   
                                headers);
 349   
 
 350   
         // set the target service based on To header if it hasn't already
 351   
         // been determined.  NOTE: May want to add an option to override
 352   
         // later.
 353  3
         if (msgContext.getService() == null && 
 354   
             msgContext.getTargetService() == null) {
 355  0
             setTargetService(msgContext, headers);
 356   
             
 357  0
             if (msgContext.getService() != null) {
 358  0
                 resetOperations(msgContext);
 359   
             }
 360   
         }
 361   
     }
 362   
     
 363  0
     protected void resetOperations(MessageContext msgContext) 
 364   
         throws AxisFault {
 365  0
         resetContextOperations(msgContext);
 366   
     }
 367   
     
 368   
     // Reinitializes the RPCElement with right operations
 369   
     // so that things are nicely deserialized
 370  0
     public static void resetContextOperations(MessageContext msgContext) 
 371   
         throws AxisFault {
 372  0
         Message msg = msgContext.getCurrentMessage();
 373  0
         if (msg == null) {
 374  0
             return;
 375   
         }
 376  0
         SOAPEnvelope env = msg.getSOAPEnvelope();
 377  0
         if (env == null) {
 378  0
             return;
 379   
         }
 380  0
         SOAPBodyElement bodyElement = env.getFirstBody();
 381  0
         if (bodyElement != null && bodyElement instanceof RPCElement) {
 382  0
             RPCElement element = (RPCElement)bodyElement;
 383   
             // update the operations in RPCElement
 384  0
             element.updateOperationsByQName();
 385  0
             OperationDesc [] operations = element.getOperations();
 386   
             // and set operation if appropriate
 387  0
             if (operations == null) {
 388  0
                 element.updateOperationsByName();
 389  0
             } else if (operations.length == 1) {
 390  0
                 msgContext.setOperation(operations[0]);
 391   
             }
 392   
         } else {
 393  0
             msg.getSOAPPartAsString();
 394   
         }
 395   
     }
 396   
     
 397   
     /**
 398   
      * Can be overridden by subclasses to customize
 399   
      * how the wsa:to header is interpreted
 400   
      */
 401  0
     protected void setTargetService(MessageContext msgContext,
 402   
                                     AddressingHeaders headers)
 403   
         throws Exception {
 404  0
         To toURI = headers.getTo();
 405  0
         if (toURI == null) {
 406  0
             return;
 407   
         }
 408  0
         String to = toURI.getPath();
 409  0
         if (to == null) {
 410  0
             return;
 411   
         }
 412   
         // set the target service
 413  0
         int i = to.lastIndexOf('/');
 414  0
         msgContext.setTargetService(to.substring(i + 1));
 415   
     }
 416   
 
 417   
     /**
 418   
      * Method processServerResponse
 419   
      *
 420   
      * @param msgContext
 421   
      */
 422  3
     protected void processServerResponse(MessageContext msgContext,
 423   
                                          boolean setMustUnderstand)
 424   
         throws Exception {
 425   
         // if no response - do nothing
 426  3
         Message msg = msgContext.getResponseMessage();
 427  3
         if (msg == null) {
 428  0
             return;
 429   
         }
 430   
 
 431  3
         AddressingHeaders reqHeaders =
 432   
             (AddressingHeaders) msgContext.getProperty(
 433   
                   Constants.ENV_ADDRESSING_REQUEST_HEADERS
 434   
              );
 435   
 
 436  3
         if (reqHeaders == null) {
 437   
             // error?
 438  0
             return;
 439   
         }
 440   
 
 441  3
         AddressingHeaders resHeaders = 
 442   
             AddressingUtils.getResponseHeaders(msgContext);
 443   
 
 444  3
         resHeaders.setSetMustUnderstand(setMustUnderstand);
 445   
 
 446   
         // set From
 447  3
         EndpointReference fromEPR = resHeaders.getFrom();
 448  3
         if (fromEPR == null) {
 449  3
             To toURI = reqHeaders.getTo();
 450  3
             if (toURI != null) {
 451  3
                 fromEPR = new EndpointReference(toURI);
 452  3
                 fromEPR.setProperties(reqHeaders.getReferenceProperties());
 453  3
                 resHeaders.setFrom(fromEPR);
 454   
             }
 455   
         }
 456   
 
 457   
         // set Action
 458  3
         Action action = resHeaders.getAction();
 459  3
         if (action == null) {
 460   
             // not set - try request headers
 461  3
             action = reqHeaders.getAction();
 462  3
             if (action != null) {
 463  3
                 resHeaders.setAction(new Action(new URI(action.toString() +
 464   
                                                         "Response")));
 465   
             }
 466   
         }
 467   
 
 468  3
         if (resHeaders.getFrom() == null && reqHeaders.getFrom() != null) {
 469  0
             resHeaders.setTo(reqHeaders.getFrom().getAddress());
 470   
         } else {
 471  3
             resHeaders.setTo(new To(Constants.NS_URI_ANONYMOUS));
 472   
         }
 473   
 
 474  3
         MessageID msgID = null;
 475   
 
 476   
         // process RelatesTo
 477  3
         msgID = reqHeaders.getMessageID();
 478  3
         if (msgID != null) {
 479  3
             resHeaders.addRelatesTo(msgID.toString(),
 480   
                                     Constants.QNAME_RESPONSE);
 481   
         }
 482   
 
 483   
         // process MessageID
 484  3
         msgID = new MessageID(new URI("uuid:" + uuidGen.nextUUID()));
 485  3
         resHeaders.setMessageID(msgID);
 486   
 
 487  3
         resHeaders.toEnvelope(msg.getSOAPEnvelope(), this.actor);
 488   
 
 489   
         // process ReplyTo
 490  3
         EndpointReferenceType replyTo = reqHeaders.getReplyTo();
 491  3
         if (replyTo != null) {
 492  0
             AttributedURI address = replyTo.getAddress();
 493  0
             if (address != null) {
 494  0
                 String uri = address.toString();
 495  0
                 if (uri != null && !uri.equals(Constants.NS_URI_ANONYMOUS)) {
 496   
                     // send the msg to reply to
 497  0
                     forwardMessage(replyTo, msg);
 498   
                     // Somehow make the response empty, or create a new empty
 499   
                     // response
 500  0
                     msgContext.setResponseMessage(null);
 501   
                 }
 502   
             }
 503   
         }
 504   
     }
 505   
 
 506  0
     protected void forwardMessage(EndpointReferenceType epr,
 507   
                                   Message msg)
 508   
         throws Exception {
 509  0
         AttributedURI address = epr.getAddress();
 510   
 
 511  0
         AddressingHeaders headers = null;
 512  0
         MessageContext msgContext = msg.getMessageContext();
 513  0
         if (msgContext != null) {
 514  0
             headers = (AddressingHeaders) msgContext.getProperty(Constants.ENV_ADDRESSING_RESPONSE_HEADERS);
 515   
         }
 516  0
         if (headers == null)
 517   
         {
 518  0
             headers = new AddressingHeaders();
 519   
         }
 520   
         
 521  0
         headers.setTo(address);
 522  0
         headers.setReferenceProperties(epr.getProperties());
 523   
 
 524  0
         Service service = getService(msgContext);
 525   
 
 526  0
         Call c = (Call) service.createCall();
 527  0
         c.setTargetEndpointAddress(address.toString());
 528  0
         c.setRequestMessage(msg);
 529  0
         c.setProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS, headers);
 530  0
         configureCall(c, msgContext);
 531  0
         c.invoke();
 532   
     }
 533   
     
 534   
     /**
 535   
      * Override this method if you need something other than the default Service.<br>
 536   
      * The service returned by this method is used in creating the new Call object.
 537   
      * Something like: <br>
 538   
      * <pre>
 539   
      * Service service = getService(msgContext);
 540   
      * Call call = service.createCall()
 541   
      * call.setTargetEndpointAddress(toEndPointReference.getAddress().toString());
 542   
      * </pre>
 543   
      * 
 544   
      * @param msgContext
 545   
      * @return
 546   
      */
 547  0
     protected Service getService(MessageContext msgContext) {
 548  0
         return new Service();
 549   
     }
 550   
     
 551   
     /**
 552   
      * Override this method to prepare the new call, for instance to add
 553   
      * properties from the old MessageContext that may be needed by other
 554   
      * handlers.
 555   
      * 
 556   
      * @param call Call object about to be invoked
 557   
      * @param oldContext MessageContext of the original request/response.
 558   
      * 
 559   
      */
 560  0
     protected void configureCall(Call call, MessageContext oldContext) {
 561   
     }
 562   
 
 563   
     /**
 564   
      * Retrieve QNames for reference properties from deployment
 565   
      * and initialize the refPropQNames list which is the list
 566   
      * of reference properties that this handler should care
 567   
      * about.
 568   
      */
 569  8
     private void initializeReferencePropertyNames() {
 570   
         // check if the user wants to process all headers, this means
 571   
         // the user wants to treat non ws-addr headers as reference props
 572   
         // If this option is not enabled, the non ws-addr headers will not
 573   
         // be deserialized.
 574  8
         String refPropNames = (String) getOption("referencePropertyNames");
 575  8
         if (refPropNames == null) {
 576  8
             this.refPropQNames = new ArrayList();
 577  0
         } else if (refPropNames.equals("*")) {
 578  0
             this.refPropQNames = null;
 579   
         } else {
 580  0
             this.refPropQNames = new ArrayList();
 581  0
             StringTokenizer tkn = new StringTokenizer(refPropNames, ",");
 582  0
             while (tkn.hasMoreTokens()) {
 583  0
                 String qnameString = tkn.nextToken().trim();
 584  0
                 try {
 585  0
                     QName qname = QName.valueOf(qnameString);
 586  0
                     refPropQNames.add(qname);
 587   
                 } catch (Exception e) {
 588   
                     // Ignore QNames which were written incorrectly
 589   
                     // if their parsing results in errors
 590   
                 }
 591   
             }
 592   
         }
 593   
     }
 594   
     
 595   
 }
 596