Clover coverage report - Cactus 1.5 for J2EE API 1.3
Coverage timestamp: Wed Feb 18 2004 09:09:13 EST
file stats: LOC: 691   Methods: 34
NCLOC: 290   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
BaseWebRequest.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  * ====================================================================
 3   
  *
 4   
  * The Apache Software License, Version 1.1
 5   
  *
 6   
  * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 7   
  * reserved.
 8   
  *
 9   
  * Redistribution and use in source and binary forms, with or without
 10   
  * modification, are permitted provided that the following conditions
 11   
  * are met:
 12   
  *
 13   
  * 1. Redistributions of source code must retain the above copyright
 14   
  *    notice, this list of conditions and the following disclaimer.
 15   
  *
 16   
  * 2. Redistributions in binary form must reproduce the above copyright
 17   
  *    notice, this list of conditions and the following disclaimer in
 18   
  *    the documentation and/or other materials provided with the
 19   
  *    distribution.
 20   
  *
 21   
  * 3. The end-user documentation included with the redistribution, if
 22   
  *    any, must include the following acknowlegement:
 23   
  *       "This product includes software developed by the
 24   
  *        Apache Software Foundation (http://www.apache.org/)."
 25   
  *    Alternately, this acknowlegement may appear in the software itself,
 26   
  *    if and wherever such third-party acknowlegements normally appear.
 27   
  *
 28   
  * 4. The names "The Jakarta Project", "Cactus" and "Apache Software
 29   
  *    Foundation" must not be used to endorse or promote products
 30   
  *    derived from this software without prior written permission. For
 31   
  *    written permission, please contact apache@apache.org.
 32   
  *
 33   
  * 5. Products derived from this software may not be called "Apache"
 34   
  *    nor may "Apache" appear in their names without prior written
 35   
  *    permission of the Apache Group.
 36   
  *
 37   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 38   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 39   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 40   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 41   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 42   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 43   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 44   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 45   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 46   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 47   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 48   
  * SUCH DAMAGE.
 49   
  * ====================================================================
 50   
  *
 51   
  * This software consists of voluntary contributions made by many
 52   
  * individuals on behalf of the Apache Software Foundation.  For more
 53   
  * information on the Apache Software Foundation, please see
 54   
  * <http://www.apache.org/>.
 55   
  *
 56   
  */
 57   
 package org.apache.cactus;
 58   
 
 59   
 import java.io.InputStream;
 60   
 
 61   
 import java.util.Enumeration;
 62   
 import java.util.Hashtable;
 63   
 import java.util.Vector;
 64   
 
 65   
 import org.apache.cactus.client.authentication.Authentication;
 66   
 import org.apache.cactus.configuration.Configuration;
 67   
 import org.apache.cactus.util.ChainedRuntimeException;
 68   
 
 69   
 /**
 70   
  * Contains all HTTP request data for a test case but independently of
 71   
  * the fact that there is or there is not a Cactus redirector. It is the 
 72   
  * data that will be sent to the server side.
 73   
  *
 74   
  * @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
 75   
  * @author <a href="mailto:Jason.Robertson@acs-inc.com">Jason Robertson</a>
 76   
  *
 77   
  * @version $Id: BaseWebRequest.java,v 1.9 2003/06/27 08:34:11 cmlenz Exp $
 78   
  */
 79   
 public class BaseWebRequest implements Request
 80   
 {
 81   
     /**
 82   
      * GET Method identifier.
 83   
      */
 84   
     public static final String GET_METHOD = "GET";
 85   
 
 86   
     /**
 87   
      * POST Method identifier.
 88   
      */
 89   
     public static final String POST_METHOD = "POST";
 90   
 
 91   
     /**
 92   
      * Cactus configuration
 93   
      */
 94   
     private Configuration configuration;
 95   
 
 96   
     /**
 97   
      * The request parameters that need to be sent in the body (POST)
 98   
      */
 99   
     private Hashtable parametersPost = new Hashtable();
 100   
 
 101   
     /**
 102   
      * The request parameters that need to be sent in the URL (GET)
 103   
      */
 104   
     private Hashtable parametersGet = new Hashtable();
 105   
 
 106   
     /**
 107   
      * The Cookies
 108   
      */
 109   
     private Vector cookies = new Vector();
 110   
 
 111   
     /**
 112   
      * HTTP Headers.
 113   
      */
 114   
     private Hashtable headers = new Hashtable();
 115   
 
 116   
     /**
 117   
      * Binary data to send in the request body (if any)
 118   
      */
 119   
     private InputStream dataStream;
 120   
 
 121   
     /**
 122   
      * The content type to set in the http request
 123   
      */
 124   
     private String contentType = "application/x-www-form-urlencoded";
 125   
 
 126   
     /**
 127   
      * The Authentication Object that will configure the http request
 128   
      */
 129   
     private Authentication authentication;
 130   
 
 131   
     /**
 132   
      * Default constructor that requires that 
 133   
      * {@link #setConfiguration(Configuration)} be called before the methods
 134   
      * requiring a configuration object.
 135   
      * 
 136   
      */
 137  0
     public BaseWebRequest()
 138   
     {
 139   
     }
 140   
 
 141   
     /**
 142   
      * @param theConfiguration the Cactus configuration
 143   
      */
 144  0
     public BaseWebRequest(Configuration theConfiguration)
 145   
     {
 146  0
         this.configuration = theConfiguration;
 147   
     }
 148   
 
 149   
     /**
 150   
      * @return the Cactus configuration
 151   
      */
 152  0
     protected Configuration getConfiguration()
 153   
     {
 154  0
         return this.configuration;
 155   
     }
 156   
 
 157   
     /**
 158   
      * @param theConfiguration the cactus configuration to assign to this 
 159   
      *        request
 160   
      */
 161  0
     public void setConfiguration(Configuration theConfiguration)
 162   
     {
 163  0
         this.configuration = theConfiguration;
 164   
     }
 165   
 
 166   
     /**
 167   
      * Sets the content type that will be set in the http request
 168   
      *
 169   
      * @param theContentType the content type
 170   
      */
 171  0
     public void setContentType(String theContentType)
 172   
     {
 173  0
         this.contentType = theContentType;
 174   
     }
 175   
 
 176   
     /**
 177   
      * @return the content type that will be set in the http request
 178   
      */
 179  0
     public String getContentType()
 180   
     {
 181  0
         return this.contentType;
 182   
     }
 183   
 
 184   
     /**
 185   
      * Allow the user to send arbitrary data in the request body
 186   
      *
 187   
      * @param theDataStream the stream on which the data are put by the user
 188   
      */
 189  0
     public void setUserData(InputStream theDataStream)
 190   
     {
 191  0
         this.dataStream = theDataStream;
 192   
     }
 193   
 
 194   
     /**
 195   
      * @return the data stream set up by the user
 196   
      */
 197  0
     public InputStream getUserData()
 198   
     {
 199  0
         return this.dataStream;
 200   
     }
 201   
 
 202   
     /**
 203   
      * Adds a parameter to the request. It is possible to add several times the
 204   
      * the same parameter name, but with different value (the same as for the
 205   
      * <code>HttpServletRequest</code>).
 206   
      *
 207   
      * @param theName the parameter's name
 208   
      * @param theValue the parameter's value
 209   
      * @param theMethod GET_METHOD or POST_METHOD. If GET_METHOD then the
 210   
      *        parameter will be sent in the query string of the URL. If
 211   
      *        POST_METHOD, it will be sent as a parameter in the request body.
 212   
      */
 213  0
     public void addParameter(String theName, String theValue, String theMethod)
 214   
     {
 215  0
         Hashtable parameters;
 216   
 
 217   
         // Decide if the parameter is to be sent using in the url or not
 218  0
         if (theMethod.equalsIgnoreCase(BaseWebRequest.POST_METHOD))
 219   
         {
 220  0
             parameters = this.parametersPost;
 221   
         }
 222  0
         else if (theMethod.equalsIgnoreCase(BaseWebRequest.GET_METHOD))
 223   
         {
 224  0
             parameters = this.parametersGet;
 225   
         }
 226   
         else
 227   
         {
 228  0
             throw new ChainedRuntimeException("The method need to be either "
 229   
                 + "\"POST\" or \"GET\"");
 230   
         }
 231   
 
 232   
         // If there is already a parameter of the same name, add the
 233   
         // new value to the Vector. If not, create a Vector an add it to the
 234   
         // hashtable
 235  0
         if (parameters.containsKey(theName))
 236   
         {
 237  0
             Vector v = (Vector) parameters.get(theName);
 238   
 
 239  0
             v.addElement(theValue);
 240   
         }
 241   
         else
 242   
         {
 243  0
             Vector v = new Vector();
 244   
 
 245  0
             v.addElement(theValue);
 246  0
             parameters.put(theName, v);
 247   
         }
 248   
     }
 249   
 
 250   
     /**
 251   
      * Adds a parameter to the request. The parameter is added to the query
 252   
      * string of the URL.
 253   
      *
 254   
      * @param theName  the parameter's name
 255   
      * @param theValue the parameter's value
 256   
      *
 257   
      * @see #addParameter(String, String, String)
 258   
      */
 259  0
     public void addParameter(String theName, String theValue)
 260   
     {
 261  0
         addParameter(theName, theValue, BaseWebRequest.GET_METHOD);
 262   
     }
 263   
 
 264   
     /**
 265   
      * @return the parameter names that will be passed in the request body
 266   
      * (POST)
 267   
      */
 268  0
     public Enumeration getParameterNamesPost()
 269   
     {
 270  0
         return getParameterNames(this.parametersPost);
 271   
     }
 272   
 
 273   
     /**
 274   
      * @return the parameter names that will be passed in the URL (GET)
 275   
      */
 276  0
     public Enumeration getParameterNamesGet()
 277   
     {
 278  0
         return getParameterNames(this.parametersGet);
 279   
     }
 280   
 
 281   
     /**
 282   
      * Returns all the values in the passed hashtable of parameters.
 283   
      *
 284   
      * @param theParameters the hashtable of parameters
 285   
      * @return the parameter names
 286   
      */
 287  0
     private Enumeration getParameterNames(Hashtable theParameters)
 288   
     {
 289  0
         return theParameters.keys();
 290   
     }
 291   
 
 292   
     /**
 293   
      * Returns the first value corresponding to this parameter's name (provided
 294   
      * this parameter is passed in the URL).
 295   
      *
 296   
      * @param theName the parameter's name
 297   
      * @return the first value corresponding to this parameter's name or null
 298   
      *         if not found in the list of parameters to be sent in the URL
 299   
      */
 300  0
     public String getParameterGet(String theName)
 301   
     {
 302  0
         String[] values = getParameterValuesGet(theName);
 303   
 
 304  0
         if (values != null)
 305   
         {
 306  0
             return values[0];
 307   
         }
 308   
 
 309  0
         return null;
 310   
     }
 311   
 
 312   
     /**
 313   
      * Returns the first value corresponding to this parameter's name (provided
 314   
      * this parameter is passed in the request body - POST).
 315   
      *
 316   
      * @param theName the parameter's name
 317   
      * @return the first value corresponding to this parameter's name or null
 318   
      *         if not found in the list of parameters to be sent in the request
 319   
      *         body
 320   
      */
 321  0
     public String getParameterPost(String theName)
 322   
     {
 323  0
         String[] values = getParameterValuesPost(theName);
 324   
 
 325  0
         if (values != null)
 326   
         {
 327  0
             return values[0];
 328   
         }
 329   
 
 330  0
         return null;
 331   
     }
 332   
 
 333   
     /**
 334   
      * Returns all the values corresponding to this parameter's name (provided
 335   
      * this parameter is passed in the URL).
 336   
      *
 337   
      * @param theName the parameter's name
 338   
      * @return the first value corresponding to this parameter's name or null
 339   
      *         if not found in the list of parameters to be sent in the URL
 340   
      */
 341  0
     public String[] getParameterValuesGet(String theName)
 342   
     {
 343  0
         return getParameterValues(theName, this.parametersGet);
 344   
     }
 345   
 
 346   
     /**
 347   
      * Returns all the values corresponding to this parameter's name (provided
 348   
      * this parameter is passed in the request body - POST).
 349   
      *
 350   
      * @param theName the parameter's name
 351   
      * @return the first value corresponding to this parameter's name or null
 352   
      *         if not found in the list of parameters to be sent in the request
 353   
      *         body
 354   
      */
 355  0
     public String[] getParameterValuesPost(String theName)
 356   
     {
 357  0
         return getParameterValues(theName, this.parametersPost);
 358   
     }
 359   
 
 360   
     /**
 361   
      * Returns all the values corresponding to this parameter's name in the
 362   
      * provided hashtable.
 363   
      *
 364   
      * @param theName the parameter's name
 365   
      * @param theParameters the hashtable containing the parameters
 366   
      * @return the first value corresponding to this parameter's name or null
 367   
      *         if not found in the passed hashtable
 368   
      */
 369  0
     private String[] getParameterValues(String theName, Hashtable theParameters)
 370   
     {
 371  0
         if (theParameters.containsKey(theName))
 372   
         {
 373  0
             Vector v = (Vector) theParameters.get(theName);
 374   
 
 375  0
             Object[] objs = new Object[v.size()];
 376   
 
 377  0
             v.copyInto(objs);
 378   
 
 379  0
             String[] result = new String[objs.length];
 380   
 
 381  0
             for (int i = 0; i < objs.length; i++)
 382   
             {
 383  0
                 result[i] = (String) objs[i];
 384   
             }
 385   
 
 386  0
             return result;
 387   
         }
 388   
 
 389  0
         return null;
 390   
     }
 391   
 
 392   
     /**
 393   
      * Adds a cookie to the request. The cookie will be created with a
 394   
      * default localhost domain. If you need to specify a domain for the cookie,
 395   
      * use the {@link #addCookie(String, String, String)} method or the method
 396   
      * {@link #addCookie(Cookie)}.
 397   
      *
 398   
      * @param theName the cookie's name
 399   
      * @param theValue the cookie's value
 400   
      */
 401  0
     public void addCookie(String theName, String theValue)
 402   
     {
 403  0
         addCookie("localhost", theName, theValue);
 404   
     }
 405   
 
 406   
     /**
 407   
      * Adds a cookie to the request. The cookie will be created with the
 408   
      * domain passed as parameter (i.e. the cookie will get sent only to
 409   
      * requests to that domain).
 410   
      *
 411   
      * Note that the domain must match either the redirector host
 412   
      * (specified in <code>cactus.properties</code>) or the host set
 413   
      * using <code>setURL()</code>.
 414   
      *
 415   
      * @param theDomain the cookie domain
 416   
      * @param theName the cookie name
 417   
      * @param theValue the cookie value
 418   
      */
 419  0
     public void addCookie(String theDomain, String theName, String theValue)
 420   
     {
 421  0
         addCookie(new Cookie(theDomain, theName, theValue));
 422   
     }
 423   
 
 424   
     /**
 425   
      * Adds a cookie to the request.
 426   
      *
 427   
      * Note that the domain must match either the redirector host
 428   
      * (specified in <code>cactus.properties</code>) or the host set
 429   
      * using <code>setURL()</code>.
 430   
      *
 431   
      * @param theCookie the cookie to add
 432   
      */
 433  0
     public void addCookie(Cookie theCookie)
 434   
     {
 435  0
         if (theCookie == null)
 436   
         {
 437  0
             throw new IllegalStateException("The cookie cannot be null");
 438   
         }
 439  0
         this.cookies.addElement(theCookie);
 440   
     }
 441   
 
 442   
     /**
 443   
      * @return the cookies (vector of <code>Cookie</code> objects)
 444   
      */
 445  0
     public Vector getCookies()
 446   
     {
 447  0
         return this.cookies;
 448   
     }
 449   
 
 450   
     /**
 451   
      * Adds a header to the request. Supports adding several values for the
 452   
      * same header name.
 453   
      *
 454   
      * @param theName  the header's name
 455   
      * @param theValue the header's value
 456   
      */
 457  0
     public void addHeader(String theName, String theValue)
 458   
     {
 459   
         // If the header is "Content-type", then call setContentType() instead.
 460   
         // This is to prevent the content type to be set twice.
 461  0
         if (theName.equalsIgnoreCase("Content-type"))
 462   
         {
 463  0
             setContentType(theValue);
 464   
 
 465  0
             return;
 466   
         }
 467   
 
 468   
         // If there is already a header of the same name, add the
 469   
         // new header to the Vector. If not, create a Vector an add it to the
 470   
         // hashtable
 471  0
         if (this.headers.containsKey(theName))
 472   
         {
 473  0
             Vector v = (Vector) this.headers.get(theName);
 474   
 
 475  0
             v.addElement(theValue);
 476   
         }
 477   
         else
 478   
         {
 479  0
             Vector v = new Vector();
 480   
 
 481  0
             v.addElement(theValue);
 482  0
             this.headers.put(theName, v);
 483   
         }
 484   
     }
 485   
 
 486   
     /**
 487   
      * @return the header names
 488   
      */
 489  0
     public Enumeration getHeaderNames()
 490   
     {
 491  0
         return this.headers.keys();
 492   
     }
 493   
 
 494   
     /**
 495   
      * Returns the first value corresponding to this header's name.
 496   
      *
 497   
      * @param  theName the header's name
 498   
      * @return the first value corresponding to this header's name or null if
 499   
      *         not found
 500   
      */
 501  0
     public String getHeader(String theName)
 502   
     {
 503  0
         String[] values = getHeaderValues(theName);
 504   
 
 505  0
         if (values != null)
 506   
         {
 507  0
             return values[0];
 508   
         }
 509   
 
 510  0
         return null;
 511   
     }
 512   
 
 513   
     /**
 514   
      * Returns all the values associated with this header's name.
 515   
      *
 516   
      * @param  theName the header's name
 517   
      * @return the values corresponding to this header's name or null if not
 518   
      *         found
 519   
      */
 520  0
     public String[] getHeaderValues(String theName)
 521   
     {
 522  0
         if (this.headers.containsKey(theName))
 523   
         {
 524  0
             Vector v = (Vector) this.headers.get(theName);
 525   
 
 526  0
             Object[] objs = new Object[v.size()];
 527   
 
 528  0
             v.copyInto(objs);
 529   
 
 530  0
             String[] result = new String[objs.length];
 531   
 
 532  0
             for (int i = 0; i < objs.length; i++)
 533   
             {
 534  0
                 result[i] = (String) objs[i];
 535   
             }
 536   
 
 537  0
             return result;
 538   
         }
 539   
 
 540  0
         return null;
 541   
     }
 542   
 
 543   
     /**
 544   
      * @return a string representation of the request
 545   
      */
 546  0
     public String toString()
 547   
     {
 548  0
         StringBuffer buffer = new StringBuffer();
 549   
 
 550   
         // Append cookies
 551  0
         buffer.append("cookies = [");
 552  0
         buffer.append(toStringAppendCookies());
 553  0
         buffer.append("], ");
 554   
 
 555   
         // Append headers
 556  0
         buffer.append("headers = [");
 557  0
         buffer.append(toStringAppendHeaders());
 558  0
         buffer.append("], ");
 559   
 
 560   
         // Append parameters
 561  0
         buffer.append("GET parameters = [");
 562  0
         buffer.append(toStringAppendParametersGet());
 563  0
         buffer.append("], ");
 564  0
         buffer.append("POST parameters = [");
 565  0
         buffer.append(toStringAppendParametersPost());
 566  0
         buffer.append("]");
 567   
 
 568  0
         return buffer.toString();
 569   
     }
 570   
 
 571   
     /**
 572   
      * @return a string representation of the headers
 573   
      */
 574  0
     private String toStringAppendHeaders()
 575   
     {
 576  0
         StringBuffer buffer = new StringBuffer();
 577   
 
 578  0
         Enumeration headers = getHeaderNames();
 579   
 
 580  0
         while (headers.hasMoreElements())
 581   
         {
 582  0
             buffer.append("[");
 583   
 
 584  0
             String headerName = (String) headers.nextElement();
 585  0
             String[] headerValues = getHeaderValues(headerName);
 586   
 
 587  0
             buffer.append("[" + headerName + "] = [");
 588   
 
 589  0
             for (int i = 0; i < (headerValues.length - 1); i++)
 590   
             {
 591  0
                 buffer.append("[" + headerValues[i] + "], ");
 592   
             }
 593   
 
 594  0
             buffer.append("[" + headerValues[headerValues.length - 1] + "]]");
 595  0
             buffer.append("]");
 596   
         }
 597   
 
 598  0
         return buffer.toString();
 599   
     }
 600   
 
 601   
     /**
 602   
      * @return a string representation of the cookies
 603   
      */
 604  0
     private String toStringAppendCookies()
 605   
     {
 606  0
         StringBuffer buffer = new StringBuffer();
 607   
 
 608  0
         Enumeration cookies = getCookies().elements();
 609   
 
 610  0
         while (cookies.hasMoreElements())
 611   
         {
 612  0
             Cookie cookie = (Cookie) cookies.nextElement();
 613   
 
 614  0
             buffer.append("[" + cookie + "]");
 615   
         }
 616   
 
 617  0
         return buffer.toString();
 618   
     }
 619   
 
 620   
     /**
 621   
      * @return a string representation of the parameters to be added in the
 622   
      *         request body
 623   
      */
 624  0
     private String toStringAppendParametersPost()
 625   
     {
 626  0
         return toStringAppendParameters(this.parametersPost);
 627   
     }
 628   
 
 629   
     /**
 630   
      * @return a string representation of the parameters to be added in the
 631   
      *         URL
 632   
      */
 633  0
     private String toStringAppendParametersGet()
 634   
     {
 635  0
         return toStringAppendParameters(this.parametersGet);
 636   
     }
 637   
 
 638   
     /**
 639   
      * @param theParameters the HTTP parameters
 640   
      * @return a string representation of the HTTP parameters passed as
 641   
      *         parameters
 642   
      */
 643  0
     private String toStringAppendParameters(Hashtable theParameters)
 644   
     {
 645  0
         StringBuffer buffer = new StringBuffer();
 646   
 
 647  0
         Enumeration parameters = getParameterNames(theParameters);
 648   
 
 649  0
         while (parameters.hasMoreElements())
 650   
         {
 651  0
             buffer.append("[");
 652   
 
 653  0
             String parameterName = (String) parameters.nextElement();
 654  0
             String[] parameterValues = getParameterValues(parameterName, 
 655   
                 theParameters);
 656   
 
 657  0
             buffer.append("[" + parameterName + "] = [");
 658   
 
 659  0
             for (int i = 0; i < (parameterValues.length - 1); i++)
 660   
             {
 661  0
                 buffer.append("[" + parameterValues[i] + "], ");
 662   
             }
 663   
 
 664  0
             buffer.append("[" + parameterValues[parameterValues.length - 1]
 665   
                 + "]]");
 666  0
             buffer.append("]");
 667   
         }
 668   
 
 669  0
         return buffer.toString();
 670   
     }
 671   
 
 672   
     /**
 673   
      * Sets the authentication object that will configure the http request
 674   
      *
 675   
      * @param theAuthentication the authentication object
 676   
      */
 677  0
     public void setAuthentication(Authentication theAuthentication)
 678   
     {
 679  0
         this.authentication = theAuthentication;
 680   
     }
 681   
 
 682   
     /**
 683   
      * @return the authentication that will configure the http request
 684   
      */
 685  0
     public Authentication getAuthentication()
 686   
     {
 687  0
         return this.authentication;
 688   
     }
 689   
 
 690   
 }
 691