791. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 10/18/2018 2:02:20 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

791.1 Files compared

# Location File Last Modified
1 VIX_SIV_v3_0_patch_201_build_8.zip\v3.0_patch_201_build_8\VISA\Java\ImagingVistaRealm\main\src\java\gov\va\med\imaging\tomcat\vistarealm AbstractVistaRealmImpl.java Thu Oct 11 13:30:18 2018 UTC
2 VIX_SIV_v3_0_patch_201_build_8.zip\v3.0_patch_201_build_8\VISA\Java\ImagingVistaRealm\main\src\java\gov\va\med\imaging\tomcat\vistarealm AbstractVistaRealmImpl.java Wed Oct 17 18:58:30 2018 UTC

791.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 4 3460
Changed 3 6
Inserted 0 0
Removed 0 0

791.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

791.4 Active regular expressions

No regular expressions were active.

791.5 Comparison detail

  1   package go v.va.med.i maging.tom cat.vistar ealm;
  2  
  3   import jav a.beans.Pr opertyChan geEvent;
  4   import jav a.beans.Pr opertyChan geListener ;
  5   import jav a.io.IOExc eption;
  6   import jav a.lang.man agement.Ma nagementFa ctory;
  7   import jav a.security .Principal ;
  8   import jav a.util.Arr ayList;
  9   import jav a.util.Col lection;
  10   import jav a.util.Col lections;
  11   import jav a.util.Has hMap;
  12   import jav a.util.Has htable;
  13   import jav a.util.Ite rator;
  14   import jav a.util.Lis t;
  15   import jav a.util.Map ;
  16  
  17   import jav ax.managem ent.Instan ceAlreadyE xistsExcep tion;
  18   import jav ax.managem ent.Instan ceNotFound Exception;
  19   import jav ax.managem ent.MBeanR egistratio nException ;
  20   import jav ax.managem ent.MBeanS erver;
  21   import jav ax.managem ent.Malfor medObjectN ameExcepti on;
  22   import jav ax.managem ent.NotCom pliantMBea nException ;
  23   import jav ax.managem ent.Object Instance;
  24   import jav ax.managem ent.Object Name;
  25  
  26   import org .apache.ca talina.Wra pper;
  27   import org .apache.ca talina.Con tainer;
  28   import org .apache.ca talina.Con text;
  29   import org .apache.ca talina.Lif ecycle;
  30   import org .apache.ca talina.Lif ecycleEven t;
  31   import org .apache.ca talina.Lif ecycleExce ption;
  32   import org .apache.ca talina.Lif ecycleList ener;
  33   import org .apache.ca talina.Rea lm;
  34   import org .apache.ca talina.con nector.Req uest;
  35   import org .apache.ca talina.con nector.Res ponse;
  36   import org .apache.to mcat.util. descriptor .web.Login Config;
  37   import org .apache.to mcat.util. descriptor .web.Secur ityCollect ion;
  38   import org .apache.to mcat.util. descriptor .web.Secur ityConstra int;
  39   import org .apache.ca talina.rea lm.Constan ts;
  40   import org .apache.lo gging.log4 j.LogManag er;
  41   import org .apache.lo gging.log4 j.Logger;
  42  
  43   /*
  44    * This cl ass implem ents all o f the REal m methods  except the  authentic ate method s.
  45    * the aut henticate  methods ar e implemen ted by the  derived c lasses.
  46    */
  47   public abs tract clas s Abstract VistaRealm Impl
  48   implements  Realm, or g.apache.c atalina.Li fecycle, A bstractVis taRealm, j avax.manag ement.MBea nRegistrat ion
  49   {
  50           //  propertie s that def ine the Vi stA site w e are prot ecting
  51           pr ivate Stri ng siteNum ber = null ; // this  MUST be in itialized  to null
  52           pr ivate Stri ng siteAbb reviation  = null;
  53           pr ivate Stri ng siteNam e = null;
  54  
  55           //  cache tun ing proper ties
  56           pr ivate bool ean usingP rincipalCa che = true ;
  57           pr ivate long  principal CacheLifes pan = 1200 00; // how  long shou ld Princip al
  58                                                                                                                     // map ping insta nces live  in
  59                                                                                                                     // the  cache
  60           pr ivate bool ean refres hPrincipal CacheEntry OnUse = fa lse; // if  true then
  61                                                                                                                                               //  the date  of
  62                                                                                                                                               //  the Princ ipal
  63                                                                                                                                               //  entry wil l be
  64                                                                                                                                               //  set to
  65           //  current t ime whenev er it is a ccessed
  66  
  67           //  Read-only  Realm pro perties
  68           pr ivate long  lastPrinc ipalCacheS weepDate =  0L;
  69  
  70           //  maps a us ername aga inst an ex isting Pri ncipal ins tance
  71           //  gets, put s, etc are  synchroni zed BUT th ere are so me operati ons that
  72           //  explicitl y synchron ize on pri ncipalCach e to assur e atomic o perations
  73           pr ivate Map< FullyQuali fiedPrinci palName, P rincipalCa cheValue>  principalC ache = 
  74                    Coll ections.sy nchronized Map(new Ha shMap<Full yQualified PrincipalN ame, Princ ipalCacheV alue>());
  75  
  76           //  maps a Co ntext to a
  77           //  map from  URL/HttpMe thod to th e array of  applicabl e Security Constraint
  78           pr ivate Map< Context, M ap<Securit yConstrain tCacheKey,  SecurityC onstraintC acheValue> > security Constraint Cache = 
  79                    Coll ections.sy nchronized Map(new Ha shMap<Cont ext, Map<S ecurityCon straintCac heKey, Sec urityConst raintCache Value>>()) ;
  80  
  81           //  An identi fier that  helps conn ect log me ssages eac h security  request i s assigned  a (proces s) unique  identifier
  82           //  that is l ogged alon g with inf o messages .  the ID  should not  be confus ed with a  VIX transa ction iden tifier.
  83           //  The realm  ID is onl y valid fo r the loca l server.   The VIX t ransaction  ID is val id for the  transacti on
  84           //  from end  to end.
  85           pr ivate Thre adLocal<St ring> real mSecurityI dentifier  = null;
  86  
  87           pr otected vo id setReal mSecurityI dentifier( )
  88           {
  89                    real mSecurityI dentifier  = new Thre adLocal<St ring>();
  90                    real mSecurityI dentifier. set("ID" +  System.cu rrentTimeM illis() +  (new Objec t().hashCo de()));
  91           }
  92           
  93           pr otected St ring getRe almSecurit yIdentifie r()
  94           {
  95                    retu rn realmSe curityIden tifier ==  null ? nul l : realmS ecurityIde ntifier.ge t();
  96           }
  97           
  98           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  99           //  Required  implementa tions
  100           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  101           pr otected ab stract Log ger getLog ger();
  102  
  103           /* *
  104        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#is Initialize d()
  105        */
  106           pu blic abstr act boolea n isInitia lized();
  107  
  108           /* *
  109        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tRealmImpl ementation Name()
  110        */
  111           pu blic Strin g getRealm Implementa tionName()
  112           {
  113                    retu rn this.ge tClass().g etName();
  114           }
  115  
  116           /* *
  117        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tVersion()
  118        */
  119           pu blic float  getVersio n()
  120           {
  121                    retu rn 1.0f;
  122           }
  123  
  124           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  125           //  MBeanRegi stration M ethods
  126           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  127           pr ivate Obje ctName des iredMBeanN ame = null ;
  128           pr ivate Obje ctName reg isteredMBe anName = n ull;
  129           
  130           //  create th e name tha t we would  like to b e register ed as
  131           pr ivate sync hronized O bjectName  getDesired MBeanName(
  132           th rows Malfo rmedObject NameExcept ion, NullP ointerExce ption
  133           {
  134                    if(d esiredMBea nName == n ull)
  135                    {
  136                             Hashta ble<String , String>  keys = new  Hashtable <String, S tring>();
  137                             keys.p ut("realm" , getRealm ());
  138                             desire dMBeanName  = new Obj ectName("g ov.va.med. imaging.to mcat.vista realm", ke ys);
  139                    }
  140                    
  141                    retu rn desired MBeanName;
  142           }
  143           
  144           /* *
  145        * @se e javax.ma nagement.M BeanRegist ration#pre Register(j avax.manag ement.MBea nServer, j avax.manag ement.Obje ctName)
  146        */
  147       @Overr ide
  148       public  ObjectNam e preRegis ter(MBeanS erver serv er, Object Name name)  
  149       throws  Exception
  150       {
  151           
  152           tr y
  153           { 
  154                    getL ogger().in fo(
  155                             "Realm  instance  '" + getDe siredMBean Name().toS tring() + 
  156                             "' bei ng registe red as '"  + (name ==  null ? ge tDesiredMB eanName(). toString()  : name.to String()) 
  157                             "'." )
  158           } 
  159           ca tch (Excep tion e){}
  160           
  161           if (name != n ull)                  // if we a re passed  a name the n use it
  162                    retu rn name;
  163           el se    
  164                    retu rn getDesi redMBeanNa me();
  165       }
  166  
  167           /* *
  168        * @se e javax.ma nagement.M BeanRegist ration#pos tRegister( java.lang. Boolean)
  169        */
  170       @Overr ide
  171       public  void post Register(B oolean reg istrationD one)
  172       {
  173           tr y{ getLogg er().info( "Realm ins tance '" +  getDesire dMBeanName ().toStrin g() + "' i s now regi stered.");  } 
  174           ca tch (Excep tion e){}
  175       }
  176  
  177           /* *
  178        * @se e javax.ma nagement.M BeanRegist ration#pre Deregister ()
  179        */
  180       @Overr ide
  181       public  void preD eregister( ) throws E xception
  182       {
  183           tr y{ getLogg er().info( "Realm ins tance '" +  getDesire dMBeanName ().toStrin g() + "' b eing de-re gistered." ); } 
  184           ca tch (Excep tion e){}
  185       }
  186  
  187           /* *
  188        * @se e javax.ma nagement.M BeanRegist ration#pos tDeregiste r()
  189        */
  190       @Overr ide
  191       public  void post Deregister ()
  192       {
  193           tr y{ getLogg er().info( "Realm ins tance '" +  getDesire dMBeanName ().toStrin g() + "' h as been de -registere d."); } 
  194           ca tch (Excep tion e){}
  195       }
  196  
  197       // === ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ==
  198       // the  realm is  registered  with the  MBeanserve r when the  realm is  started
  199       // and  de-regist ered when  the realm  is stopped
  200       // === ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ==
  201           pr otected vo id mBeanRe gistration ()
  202           {
  203                    //WF P-revisit  this again .
  204                    // r egister th e manageme nt interfa ce if the  MBeanServe r exists
  205                    MBea nServer mb s = Manage mentFactor y.getPlatf ormMBeanSe rver();
  206                    if ( mbs != nul l)
  207                    {
  208                             try
  209                             {
  210                                      if(regis teredMBean Name == nu ll){
  211                                               ObjectInst ance oi =  mbs.regist erMBean(th is, null);
  212                                               registered MBeanName  = oi.getOb jectName() ;
  213                                               getLogger( ).info( "R ealm '" +  getDesired MBeanName( ).toString () + "' re gistered a s '" + reg isteredMBe anName + " '." );
  214                                      }
  215                                      
  216                             } catc h (Instanc eAlreadyEx istsExcept ion e)
  217                             {
  218                                      getLogge r().error( e);
  219                             } catc h (MBeanRe gistration Exception  e)
  220                             {
  221                                      getLogge r().error( e);
  222                             } catc h (NotComp liantMBean Exception  e)
  223                             {
  224                                      getLogge r().error( e);
  225                             } catc h (Malform edObjectNa meExceptio n e)
  226                {
  227                                      getLogge r().error( e);
  228                } catch  (NullPoint erExceptio n e)
  229                {
  230                                      getLogge r().error( e);
  231                }
  232                    }
  233           }
  234  
  235           pr otected vo id mBeanUn Registrati on()
  236           {
  237                    MBea nServer mb s = Manage mentFactor y.getPlatf ormMBeanSe rver();
  238                    if ( mbs != nul l)
  239                    {
  240                             try
  241                             {
  242                                      if (regi steredMBea nName != n ull) 
  243                                      {
  244                                               mbs.unregi sterMBean( registered MBeanName) ;
  245                                               getLogger( ).info( "R ealm '" +  registered MBeanName  + "' de-re gistered."  );
  246                                               registered MBeanName  = null;
  247                                      }
  248                             } catc h (Instanc eNotFoundE xception x )
  249                             {
  250                                      getLogge r().error( x);
  251                             } catc h (MBeanRe gistration Exception  x)
  252                             {
  253                                      getLogge r().error( x);
  254                             }
  255                    }
  256           }
  257       
  258       
  259           /*
  260            *  ========= ========== ========== ========== ========== ========== ========== ========== =======
  261            *  Informati on string,  toString( )
  262            *  ========= ========== ========== ========== ========== ========== ========== ========== =======
  263            * /
  264           /* *
  265            *  Return de scriptive  informatio n about th is Realm i mplementat ion and th e
  266            *  correspon ding versi on number,  in the fo rmat <desc ription>/< version>.
  267            * /
  268           pu blic Strin g getInfo( )
  269           {
  270                    retu rn getReal mImplement ationName( ) + "/" +  getVersion ();
  271           }
  272  
  273           /* *
  274            *  @see java .lang.Obje ct#toStrin g()
  275            *  
  276            *  Returns a  String li ke: VistaR ealm [660- SLC Salt L ake City,  UT
  277            *  vista:URL ]
  278            * /
  279           @O verride
  280           pu blic Strin g toString ()
  281           {
  282                    Stri ngBuilder  sb = new S tringBuild er();
  283  
  284                    sb.a ppend(this .getInfo() );
  285                    sb.a ppend(" [" );
  286                    sb.a ppend(this .getSiteAb breviation ());
  287                    sb.a ppend("-") ;
  288                    sb.a ppend(this .getSiteNu mber());
  289                    sb.a ppend(" ") ;
  290                    sb.a ppend(this .getSiteNa me());
  291                    sb.a ppend("]") ;
  292  
  293                    retu rn sb.toSt ring();
  294           }
  295  
  296           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  297           //  JavaBean  Property A ccessors
  298           //  These pro perties ma y be set f rom the se rver confi guration.
  299           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  300           /* *
  301        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tSiteAbbre viation()
  302        */
  303           pu blic Strin g getSiteA bbreviatio n()
  304           {
  305                    retu rn siteAbb reviation;
  306           }
  307  
  308           pu blic void  setSiteAbb reviation( String loc alSiteAbbr eviation)
  309           {
  310                    this .siteAbbre viation =  localSiteA bbreviatio n;
  311           }
  312  
  313           /* *
  314        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tSiteName( )
  315        */
  316           pu blic Strin g getSiteN ame()
  317           {
  318                    retu rn siteNam e;
  319           }
  320  
  321           pu blic void  setSiteNam e(String l ocalSiteNa me)
  322           {
  323                    this .siteName  = localSit eName;
  324           }
  325  
  326           /* *
  327        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tSiteNumbe r()
  328        */
  329           pu blic Strin g getSiteN umber()
  330           {
  331                    retu rn siteNum ber;
  332           }
  333  
  334           pu blic Strin g getRealm ()
  335           {
  336                    retu rn getSite Number();
  337           }
  338           
  339           //  because o f the way  a Realm is  initializ ed by Tomc at
  340           //  the immut able prope rties cann ot be decl ared final , so
  341           //  we prohib it changes  after the  first in  code
  342           pu blic void  setSiteNum ber(String  localSite Number)
  343           {
  344                    if ( this.siteN umber == n ull)
  345                             this.s iteNumber  = localSit eNumber;
  346                    else
  347                             getLog ger().erro r(
  348                                      "The sit e number m ay not be  changed on ce it has  been set,  attempt to  change fr om '" + th is.siteNum ber + "' t o '"
  349                                               + localSit eNumber +  "' is bein g ignored. ");
  350           }
  351  
  352           //  ========= ========== ========== ========== ========== ========== ========== ========== =========
  353           //  Cache Tun ing Proper ties
  354           //  ========= ========== ========== ========== ========== ========== ========== ========== =========
  355           /* *
  356        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#is UsingPrinc ipalCache( )
  357        */
  358           pu blic Boole an isUsing PrincipalC ache()
  359           {
  360                    retu rn this.us ingPrincip alCache;
  361           }
  362  
  363           /* *
  364        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#se tUsingPrin cipalCache (java.lang .Boolean)
  365        */
  366           pu blic void  setUsingPr incipalCac he(Boolean  usingPrin cipalCache )
  367           {
  368                    // i f the cach e is being  turned of f then cle ar it
  369                    if ( this.using PrincipalC ache && !u singPrinci palCache)
  370                             clearP rincipalCa che();
  371  
  372                    this .usingPrin cipalCache  = usingPr incipalCac he;
  373           }
  374  
  375           /* *
  376        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tPrincipal CacheLifes pan()
  377        */
  378           pu blic Long  getPrincip alCacheLif espan()
  379           {
  380                    retu rn this.pr incipalCac heLifespan ;
  381           }
  382  
  383           /* *
  384        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#se tPrincipal CacheLifes pan(java.l ang.Long)
  385        */
  386           pu blic void  setPrincip alCacheLif espan(Long  principal CacheLifes pan)
  387           {
  388                    this .principal CacheLifes pan = prin cipalCache Lifespan;
  389           }
  390  
  391           /* *
  392        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#is RefreshPri ncipalCach eEntryOnUs e()
  393        */
  394           pu blic Boole an isRefre shPrincipa lCacheEntr yOnUse()
  395           {
  396                    retu rn this.re freshPrinc ipalCacheE ntryOnUse;
  397           }
  398  
  399           /* *
  400        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#se tRefreshPr incipalCac heEntryOnU se(java.la ng.Boolean )
  401        */
  402           pu blic void  setRefresh PrincipalC acheEntryO nUse(Boole an refresh PrincipalC acheEntryO nUse)
  403           {
  404                    this .refreshPr incipalCac heEntryOnU se = refre shPrincipa lCacheEntr yOnUse;
  405           }
  406  
  407           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ===
  408           //  Read-Only  propertie s, used by  JMX for m onitoring
  409           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ===
  410           /* *
  411        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tPrincipal CacheSize( )
  412        */
  413           pu blic int g etPrincipa lCacheSize ()
  414           {
  415                    retu rn princip alCache.si ze();
  416           }
  417  
  418           /* *
  419        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tSecurityC onstraintC acheSize()
  420        */
  421           pu blic int g etSecurity Constraint CacheSize( )
  422           {
  423                    retu rn this.se curityCons traintCach e.size();
  424           }
  425  
  426           /* *
  427            *  Get the n umber of c ached secu rity const raints for  the named  context.
  428            *  
  429            *  @param co ntext
  430            *  @return
  431            * /
  432           pu blic int g etContextS ecurityCon straintsCa cheSize(St ring conte xt)
  433           {
  434                    if ( context ==  null)
  435                             return  0;
  436  
  437                    for  (Context s ervicedCon text : sec urityConst raintCache .keySet())
  438                    {
  439                             if (co ntext.equa ls(service dContext.g etName()))
  440                             {
  441                                      Map<Secu rityConstr aintCacheK ey, Securi tyConstrai ntCacheVal ue> contex tSecurityC onstraintC ache = sec urityConst raintCache
  442                                               .get(servi cedContext );
  443                                      return c ontextSecu rityConstr aintCache. size();
  444                             }
  445                    }
  446  
  447                    retu rn 0;
  448           }
  449  
  450           /* *
  451        * @se e gov.va.m ed.imaging .tomcat.vi starealm.A bstractVis taRealm#ge tLastPrinc ipalCacheS weepDate()
  452        */
  453           pu blic long  getLastPri ncipalCach eSweepDate ()
  454           {
  455                    retu rn this.la stPrincipa lCacheSwee pDate;
  456           }
  457  
  458           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  459           //  Lifecycle  Listeners
  460           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  461           pr ivate List <Lifecycle Listener>  lifecycleL isteners =  new Array List<Lifec ycleListen er>();
  462  
  463           pu blic void  addLifecyc leListener (Lifecycle Listener l istener)
  464           {
  465                    life cycleListe ners.add(l istener);
  466           }
  467  
  468           pu blic void  removeLife cycleListe ner(Lifecy cleListene r listener )
  469           {
  470                    life cycleListe ners.remov e(listener );
  471           }
  472  
  473           pu blic Lifec ycleListen er[] findL ifecycleLi steners()
  474           {
  475                    Life cycleListe ner[] a =  new Lifecy cleListene r[lifecycl eListeners .size()];
  476                    life cycleListe ners.toArr ay(a);
  477  
  478                    retu rn a;
  479           }
  480  
  481           pr ivate void  notifyLif ecycleList eners(Life cycleEvent  event)
  482           {
  483                    for  (Lifecycle Listener l istener :  lifecycleL isteners)
  484                             listen er.lifecyc leEvent(ev ent);
  485           }
  486  
  487           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  488           //  Tomcat Li fecycleLis tener Impl ementation
  489           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  490           /* *
  491            *  This is w here the r ealm initi alization  occurs.
  492            *  
  493            *  Get the r ealm start ed, this i ncludes re storing th e realm st ate from
  494            *  context p roperties.
  495            * /
  496           @O verride
  497           pu blic void  start() th rows Lifec ycleExcept ion
  498           {
  499                    // S erver serv er = Serve rFactory.g etServer() ;
  500                    // l ogger.info ("VistaRea lm startin g on serve r " + serv er.getInfo ());
  501  
  502                    noti fyLifecycl eListeners (new Lifec ycleEvent( this, Life cycle.BEFO RE_START_E VENT, null ));
  503  
  504                    // r egister ou rselves wi th the JMX  MBean ser ver if it  exists
  505                    mBea nRegistrat ion();
  506  
  507                    if ( isInitiali zed())
  508                    {
  509                             getLog ger().info ("Realm["  + this.get RealmName( ) + "] ini tialized w ith author ization si te " + thi s.toString () + ".");
  510  
  511                             notify LifecycleL isteners(n ew Lifecyc leEvent(th is, Lifecy cle.START_ EVENT, nul l));
  512                             getLog ger().info ("Realm ["  + this.ge tRealmName () + "] is  started." );
  513                             notify LifecycleL isteners(n ew Lifecyc leEvent(th is, Lifecy cle.AFTER_ START_EVEN T, null));
  514                    } el se
  515                             getLog ger().warn ("[" + thi s.getRealm Name() + " ] is NOT i nitialized , use JMX  interface  to set req uired fiel ds and ini tialize.") ;
  516  
  517           }
  518           
  519  
  520           /* *
  521            *  We are st opping, no tify our l isteners a nd unregis ter oursel ves with t he
  522            *  MBean ser ver
  523            * /
  524           @O verride
  525           pu blic void  stop() thr ows Lifecy cleExcepti on
  526           {
  527                    getL ogger().in fo("Realm[ " + this.g etRealmNam e() + "] s topping.") ;
  528                    noti fyLifecycl eListeners (new Lifec ycleEvent( this, Life cycle.BEFO RE_STOP_EV ENT, null) );
  529                    mBea nUnRegistr ation();
  530                    noti fyLifecycl eListeners (new Lifec ycleEvent( this, Life cycle.AFTE R_STOP_EVE NT, null)) ;
  531           }
  532  
  533           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ==========
  534           //  Realm Pro perty chan ge Listene r
  535           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========= 
  536           /* *
  537            *  PropertyC hangeListe ner manage ment and n otificatio n
  538            * /
  539           pr ivate List <PropertyC hangeListe ner> prope rtyChangeL isteners =  new Array List<Prope rtyChangeL istener>() ;
  540  
  541           pu blic void  addPropert yChangeLis tener(Prop ertyChange Listener l istener)
  542           {
  543                    prop ertyChange Listeners. add(listen er);
  544           }
  545  
  546           pu blic void  removeProp ertyChange Listener(P ropertyCha ngeListene r listener )
  547           {
  548                    prop ertyChange Listeners. remove(lis tener);
  549           }
  550  
  551           pr otected vo id notifyP ropertyCha ngeListene rs(Propert yChangeEve nt event)
  552           {
  553                    for  (Iterator< PropertyCh angeListen er> proper tyChangeLi stenerIter  = propert yChangeLis teners.ite rator(); p ropertyCha ngeListene rIter
  554                             .hasNe xt();)
  555                             (prope rtyChangeL istenerIte r.next()). propertyCh ange(event );
  556           }
  557  
  558           pr otected vo id notifyP ropertyCha ngeListene rs(String  propertyNa me, Object  oldValue,  Object ne wValue)
  559           {
  560                    noti fyProperty ChangeList eners(new  PropertyCh angeEvent( this, prop ertyName,  oldValue,  newValue)) ;
  561           }
  562  
  563           
  564           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  565           //  Realm imp lementatio n
  566           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========
  567  
  568           /* *
  569            *  Is the gi ven role o ne of the  roles know n to this  Realm
  570            * /
  571           pu blic boole an isKnown Role(Strin g roleName )
  572           {
  573                    retu rn VistaRe almRoles.i sKnownRole Name(roleN ame);
  574           }
  575           
  576           /* *
  577            *  This must  be overri dden becau se the Rea lmBase imp lementatio n expects  an
  578            *  instance  of Generic Principal
  579            *  
  580            *  @see org. apache.cat alina.Real m.hasRole( Principal  principal,  String ro le)
  581            * /
  582           @O verride
  583           pu blic boole an hasRole (Wrapper w rapper, Pr incipal pr incipal, S tring role )
  584           {
  585                    getL ogger().de bug("hasRo le (" + (p rincipal ! = null ? p rincipal.g etName() :  "UNKNOWN" ) + ", " +  role + ") ");
  586                    try
  587                    {
  588                             return  ((VistaRe almPrincip al) princi pal).hasRo le(role);
  589                    } 
  590                    catc h (ClassCa stExceptio n ccX)
  591                    {
  592                             getLog ger().erro r("Expecti ng an inst ance of Vi staRealmPr incipal an d got an i nstance of  " + princ ipal.getCl ass().getN ame()
  593                                      + ", whi ch VistaRe alm does n ot underst and");
  594                             return  false;
  595                    }
  596           }
  597           
  598  
  599           /* *
  600            *  A Contain er is an o bject that  can execu te request s received  from a
  601            *  client, a nd return  responses  based on t hose reque sts. Engin e -
  602            *  Represent ation of t he entire  Catalina s ervlet eng ine. Host  -
  603            *  Represent ation of a  virtual h ost contai ning a num ber of Con texts. Con text -
  604            *  Represent ation of a  single Se rvletConte xt, which  will typic ally conta in
  605            *  one or mo re Wrapper s for the  supported  servlets.  Wrapper -  Representa tion
  606            *  of an ind ividual se rvlet defi nition.
  607            * /
  608           pr ivate Cont ainer cont ainer = nu ll;
  609  
  610           pu blic void  setContain er(Contain er contain er)
  611           {
  612                    this .container  = contain er;
  613           }
  614  
  615           pu blic Conta iner getCo ntainer()
  616           {
  617                    retu rn this.co ntainer;
  618           }
  619  
  620           /* *
  621            *  The realm  name is t he site nu mber.
  622            *  
  623            *  @return
  624            * /
  625           pu blic Strin g getRealm Name()
  626           {
  627                    retu rn getSite Number();
  628           }
  629  
  630           /*
  631            *  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ======
  632            *  Principal  Cache Imp lementatio n
  633            *  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ======
  634            * /
  635  
  636           /* *
  637            *  Execute a  periodic  task, such  as reload ing, etc.
  638            *  
  639            *  Executed  periodical ly to relo ad from da tabase, cl ear cache,  etc ...
  640            *  
  641            *  @see org. apache.cat alina.Real m.backgrou ndProcess( )
  642            * /
  643           @O verride
  644           pu blic void  background Process()
  645           {
  646                    long  now = Sys tem.curren tTimeMilli s();
  647  
  648                    // l ogically r unning evi ction will  have no e ffect if
  649                    // t he cache i s not bein g used, bu t having t his test h ere both
  650                    // s aves time  and allows  us to tur n off proc essing if  there is a n
  651                    // e rror in it .
  652                    if ( isUsingPri ncipalCach e())
  653                             evictO ldPrincipa lCacheEntr ies(now);
  654           }
  655  
  656           /* *
  657            *  This may  be called  from MBean  managemen t to force  an evicti on NOTE: t his
  658            *  method do es not che ck if the  cache is b eing used,  but simpl y runs the
  659            *  eviction  pass.
  660            * /
  661           pu blic void  evictOldPr incipalCac heEntries( )
  662           {
  663                    long  now = Sys tem.curren tTimeMilli s();
  664  
  665                    evic tOldPrinci palCacheEn tries(now) ;
  666           }
  667  
  668           /* *
  669            *  Clear all  principal  cache ent ries
  670            * /
  671           pu blic void  clearPrinc ipalCache( )
  672           {
  673                    prin cipalCache .clear();
  674           }
  675  
  676           /* *
  677            *  
  678            *  @param no w
  679            * /
  680           pr ivate void  evictOldP rincipalCa cheEntries (long now)
  681           {
  682                    last PrincipalC acheSweepD ate = now;
  683                    // e viction ag e is the d ate in the  past when  a cache e ntry must  have
  684                    // n een touche d/opened a fter to re main in th e cache
  685                    long  evictionA ge = now -  this.getP rincipalCa cheLifespa n();
  686  
  687                    // s ynchronize  on the pr incipalCac he so that  we do not  get a
  688                    // C oncurrentM odificatio nException
  689                    // i n the iter ator
  690                    sync hronized ( principalC ache)
  691                    {
  692                             for (I terator<Fu llyQualifi edPrincipa lName> ite r = princi palCache.k eySet().it erator();  iter.hasNe xt();)
  693                             {
  694                                      FullyQua lifiedPrin cipalName  fqPrincipa l = iter.n ext();
  695  
  696                                      Principa lCacheValu e principa lCacheValu e = princi palCache.g et(fqPrinc ipal);
  697                                      if (prin cipalCache Value.getD ate() < ev ictionAge)
  698                                               iter.remov e();
  699                             }
  700                    }
  701           }
  702           
  703           pr otected Pr incipalCac heValue ge tPrincipal CacheEntry (FullyQual ifiedPrinc ipalName f qPrincipal )
  704           {
  705                    retu rn princip alCache.ge t(fqPrinci pal);
  706           }
  707           
  708           pr otected vo id addPrin cipalCache EntryIfUni que(FullyQ ualifiedPr incipalNam e fqpn, Pr incipalCac heValue pr incipalCac heValue)
  709           {
  710                    getL ogger().in fo("Cachin g fully qu alified pr incipal na me '" + fq pn.toStrin g() + "'." );
  711                    // s ynchronize  on the pr incipal ca che so tha t the get,  the check  for exist ence
  712                    // a nd the put  are atomi c
  713                    sync hronized(p rincipalCa che)
  714                    {
  715                             // If  the princi pal is not  already c ached then  cache it.  
  716                             // Don 't PUT ove r an exist ing instan ce.
  717                             if( pr incipalCac he.get(fqp n) == null  )
  718                             {
  719                                      // clone  the Princ ipal objec t and cach e the clon e
  720                                      // DO NO T CACHE th e instance  that the  applicatio ns see bec ause they
  721                                      // may c hange the  values in  the Princi pal !!!!!
  722                                      principa lCache.put ( fqpn, pr incipalCac heValue );
  723                             }
  724                    }
  725           }
  726  
  727           /* *
  728            *  @param co ntext
  729            *  @param co nstraintKe y
  730            *  @return
  731            * /
  732           pr otected Se curityCons traint[] g etCachedSe curityCons traint(Con text conte xt, Securi tyConstrai ntCacheKey  constrain tKey)
  733           {
  734                    // f irst see i f there is  a securit y constrai nt map for  this cont ext
  735                    Map< SecurityCo nstraintCa cheKey, Se curityCons traintCach eValue> co ntextCache  = getCont extSecurit yConstrain tCache(con text);
  736                    if ( contextCac he != null )
  737                    {
  738                             Securi tyConstrai ntCacheVal ue cacheVa lue = cont extCache.g et(constra intKey);
  739                             if (ca cheValue ! = null)
  740                                      return c acheValue. getConstra ints();
  741                    }
  742  
  743                    retu rn null;
  744           }
  745  
  746           pr ivate Map< SecurityCo nstraintCa cheKey, Se curityCons traintCach eValue> ge tContextSe curityCons traintCach e(Context  context)
  747           {
  748                    retu rn securit yConstrain tCache.get (context);
  749           }
  750  
  751           pr ivate Map< SecurityCo nstraintCa cheKey, Se curityCons traintCach eValue> ge tOrCreateC ontextSecu rityConstr aintCache( Context co ntext)
  752           {
  753                    Map< SecurityCo nstraintCa cheKey, Se curityCons traintCach eValue> re sult = sec urityConst raintCache .get(conte xt);
  754                    if ( result ==  null)
  755                    {
  756                             result  = Collect ions.synch ronizedMap (new HashM ap<Securit yConstrain tCacheKey,  SecurityC onstraintC acheValue> ());
  757  
  758                             securi tyConstrai ntCache.pu t(context,  result);
  759                    }
  760                    retu rn result;
  761           }
  762  
  763           /* *
  764            *  @param co ntext
  765            *  @param co nstraintKe y
  766            *  @param re sults
  767            * /
  768           pr otected vo id putToSe curityCons traintsCac he(Context  context,  SecurityCo nstraintCa cheKey con straintKey ,
  769                    Coll ection<Sec urityConst raintMatch > matching SecurityCo nstraints)
  770           {
  771                    Secu rityConstr aint[] sec urityConst raintsArra y = new Se curityCons traint[mat chingSecur ityConstra ints.size( )];
  772  
  773                    int  index = 0;
  774                    for  (SecurityC onstraintM atch match ingSecurit yConstrain t : matchi ngSecurity Constraint s)
  775                             securi tyConstrai ntsArray[i ndex++] =  matchingSe curityCons traint.get SecurityCo nstraint() ;
  776  
  777                    putT oSecurityC onstraints Cache(cont ext, const raintKey,  securityCo nstraintsA rray);
  778           }
  779  
  780           pr ivate void  putToSecu rityConstr aintsCache (Context c ontext, Se curityCons traintCach eKey const raintKey,
  781                    Secu rityConstr aint[] sec urityConst raints)
  782           {
  783                    // f irst see i f there is  a securit y constrai nt map for  this cont ext
  784                    Map< SecurityCo nstraintCa cheKey, Se curityCons traintCach eValue> co ntextCache  = getOrCr eateContex tSecurityC onstraintC ache(conte xt);
  785                    cont extCache.p ut(constra intKey, ne w Security Constraint CacheValue (securityC onstraints ));
  786           }
  787           
  788           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========
  789           //  Preemptiv eAuthoriza tion Imple mentation
  790           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========
  791           /* *
  792            *  A non-aut horitative , pre-empt ive determ ination of  whether t he current ly logged  in user
  793            *  has privi leges to t he selecte d resource .
  794            *  
  795        * @se e gov.va.m ed.imaging .tomcat.vi starealm.P reemptiveA uthorizati on#isAutho rized(java .lang.Obje ct, java.l ang.String , java.lan g.String)
  796        */
  797       @Overr ide
  798       public  Preemptiv eAuthoriza tion.Resul t isAuthor ized(
  799                    Prin cipal prin cipal, 
  800                    Obje ct context
  801                    Stri ng context RequestPat h, 
  802                    Stri ng request Method)
  803       {
  804           ge tLogger(). info("Pree mptively c hecking au thorizatio n '" + pri ncipal.get Name() + " ' to '" +  requestMet hod + ":"  + contextR equestPath  + "'.");
  805           if (! (contex t instance of Context ) )
  806           {
  807                    getL ogger().wa rn("Attemp t to pre-e mptively d etermine a uthorizati on with a  context of  type othe r than Tom cat standa rd Context ");
  808                    retu rn Preempt iveAuthori zation.Res ult.Unknow n;
  809           }
  810           Co ntext tomc atContext  = (Context )context;
  811           
  812                    Stri ng request ContextPat h = tomcat Context.ge tName();
  813                    Stri ng request PathInfo =  requestCo ntextPath  + contextR equestPath ;
  814                    
  815           ge tLogger(). info("Pree mptively c hecking au thorizatio n, getting  security  constraint s.");
  816                    Secu rityConstr aint[] sec urityConst raints = f indSecurit yConstrain ts(tomcatC ontext, re questPathI nfo, reque stMethod,  contextReq uestPath);
  817  
  818           ge tLogger(). info("Pree mptively c hecking au thorizatio n, checkin g resource  permmissi ons.");
  819                    retu rn hasReso urcePermis sion(tomca tContext,  securityCo nstraints,  requestPa thInfo, pr incipal) ?
  820                                      Preempti veAuthoriz ation.Resu lt.True :  Preemptive Authorizat ion.Result .False;
  821       }
  822  
  823           
  824           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========
  825           //  Realm Imp lementatio n
  826           //  Other tha n authenti cate(), wh ich is don e by deriv ed classes
  827           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========
  828  
  829           /*
  830            *  Perform a ccess cont rol based  on the spe cified aut horization  constrain t.
  831            *  
  832            *  Servlet s pecificati on section s implemen ted: 12.8
  833            *  
  834            *  Specially  notable r equirement s: "An aut horization  constrain t that nam es
  835            *  no roles  indicates  that acces s to the c onstrained  requests  must not b e
  836            *  permitted  under any  circumsta nces."
  837            *  
  838            *  Section 1 2.8.1: "Wh en a url-p attern and  http-meth od pair oc curs in
  839            *  multiple  security c onstraints , the cons traints (o n the patt ern and
  840            *  method) a re defined  by combin ing the in dividual c onstraints . The rule s
  841            *  for combi ning const raints in  which the  same patte rn and met hod occur  are
  842            *  as follow s:
  843            *  
  844            *  The combi nation of  authorizat ion constr aints that  name role s or that
  845            *  imply rol es via the  name “*”  shall yiel d the unio n of the r ole names  in
  846            *  the indiv idual cons traints as  permitted  roles. A  security c onstraint  that
  847            *  does not  contain an  authoriza tion const raint shal l combine  with
  848            *  authoriza tion const raints tha t name or  imply role s to allow
  849            *  unauthent icated acc ess. The s pecial cas e of an au thorizatio n constrai nt
  850            *  that name s no roles  shall com bine with  any other  constraint s to overr ide
  851            *  their aff ects and c ause acces s to be pr ecluded.
  852            *  
  853            *  The combi nation of  user-data- constraint s that app ly to a co mmon
  854            *  urlpatter n and http -method sh all yield  the union  of connect ion types
  855            *  accepted  by the ind ividual co nstraints  as accepta ble connec tion types . A
  856            *  security  constraint  that does  not conta in a user- data-const raint shal l
  857            *  combine w ith other  user data- constraint s to cause  the unpro tected
  858            *  connectio n type to  be an acce pted conne ction type ."
  859            *  
  860            *  
  861            *  @param re quest
  862            *              Request  we are pro cessing
  863            *  @param re sponse
  864            *              Response  we are cr eating
  865            *  @param se curityCons traints
  866            *              applicab le securit y constrai nts as det ermined by  the
  867            *              web-reso urce-colle ction, see  findSecur ityConstra ints()
  868            *              security -constrain t elements  that were  returned  in the pre vious
  869            *              findSecu rityConstr aints() ca ll
  870            *              i.e. thi s is the l ist of app licable se curity con straints i n
  871            *              descendi ng order o f applicab ility
  872            *  @param co ntext
  873            *              The Cont ext to whi ch client  of this cl ass is att ached.
  874            *  
  875            *  @return < code>true< /code> if  this const raint is s atisfied a nd
  876            *          p rocessing  should con tinue, or  <code>fals e</code> o therwise.
  877            *  
  878            *  @exceptio n IOExcept ion
  879            *                  if a n input/ou tput error  occurs
  880            * /
  881           pu blic boole an hasReso urcePermis sion(
  882                             Reques t request,  
  883                             Respon se respons e, 
  884                             Securi tyConstrai nt[] secur ityConstra ints, 
  885                    Cont ext contex t) 
  886           th rows IOExc eption
  887           {
  888                    bool ean result  = false;          //  assume no  access
  889                    
  890                    Stri ng request Uri = requ est.getReq uestURI();
  891                    getL ogger().in fo("hasRes ourcePermi ssion (" +  request.g etRequestU RI() + ",  " + contex t.getName( ) + "," +  securityCo nstraints. length
  892                             + ") r sID='" + g etRealmSec urityIdent ifier() +  "'.");
  893  
  894                    // d ump debugg ing messag es, check  the debug  level firs t to avoid  executing  a bunch o f code
  895                    if ( getLogger( ).isDebugE nabled())
  896                             for (S ecurityCon straint c  : security Constraint s)
  897                             {
  898                                      getLogge r().debug( "  Securit yConstrain t '" + c.g etDisplayN ame() + "'  roles");
  899                                      for (Str ing roleNa me : c.fin dAuthRoles ())
  900                                               getLogger( ).debug("     role '"  + roleNam e + "'");
  901                             }
  902  
  903                    // U ser princi pal may ha ve been pr eviously a uthenticat ed
  904                    // i f the user  has not b een authen ticated th en access  will only  be
  905                    // g ranted whe re no secu rity-const raint is a pplicable
  906                    Prin cipal prin cipal = re quest.getP rincipal() ;
  907                    
  908                    resu lt = hasRe sourcePerm ission(
  909                                      context,  
  910                                      security Constraint s, 
  911                                      requestU ri, 
  912                                      principa l);
  913                    
  914                    // p ermission  is granted , log an a uthorizati on message
  915                    if(r esult)
  916                    {
  917                             getLog ger().info ("hasResou rcePermiss ion (" + r equestUri  + "...) rs ID='" + ge tRealmSecu rityIdenti fier()
  918                                      + "' - p ermission  GRANTED");
  919                    }
  920                    // i f permissi on was den ied for an y reason,  send a 403  response,  else just  log an au thorizatio n message
  921                    else
  922                    {
  923                             String  deniedMes sage = 
  924                                      "Access  to resourc e '" + req uestUri + 
  925                                      "' by us er '" + (p rincipal = = null ? " <unknown>"  : princip al.getName ()) + 
  926                                      "' is de nied.  " +  
  927                                      "Securit y realm un ique ID '"  + getReal mSecurityI dentifier( ) + "'.";
  928  
  929                             getLog ger().info (deniedMes sage);
  930                             respon se.sendErr or(403, de niedMessag e);
  931                    }
  932                    
  933                    retu rn result;
  934           }
  935  
  936           /* *
  937        * @pa ram securi tyConstrai nts
  938        * @pa ram contex t
  939        * @pa ram result
  940        * @pa ram reques tUri
  941        * @pa ram princi pal
  942        * @re turn
  943        */
  944       privat e boolean  hasResourc ePermissio n(
  945                    Cont ext contex t, 
  946                    Secu rityConstr aint[] sec urityConst raints, 
  947                    Stri ng request Uri,
  948                Principa l principa l)
  949       {
  950           bo olean resu lt = false ;
  951           
  952                // no se curity-con straints a pplicable  therefore  no restric tion
  953                    if(  securityCo nstraints  == null ||  securityC onstraints .length ==  0 )
  954                    {
  955                             getLog ger().debu g("hasReso urcePermis sion (" +  requestUri  + "...) r sID='" + g etRealmSec urityIdent ifier()
  956                                      + "' - n o security  constrain ts provide d, permiss ion GRANTE D");
  957                             result  = true;
  958                    }
  959                    else
  960                    {
  961                             // if  the login- config ele ment exist s and the  authorizat ion method  is FORM
  962                             // the re is some  special h andling of  error and  login URL s
  963                             if( is SpecialFor mAuthReque st(context .getLoginC onfig(), r equestUri)  )
  964                             {
  965                                      getLogge r().info(" hasResourc ePermissio n (" + req uestUri +  "...) rsID ='" + getR ealmSecuri tyIdentifi er()
  966                                               + "' - byp assing sec urity cons traints fo r special  form-based  authentic ation reso urces, per mission GR ANTED");
  967                                      result =  true;
  968                             }
  969  
  970                             // cre ate an ins tance of S ecurityCon straintLis t, which i s capable  of
  971                             // int elligently  combining  the autho rization c onstraints  of many S ecurityCon straint
  972                             Securi tyConstrai ntAuthoriz ationList< SecurityCo nstraint>  scList = 
  973                                      new Secu rityConstr aintAuthor izationLis t<Security Constraint >(security Constraint s);
  974  
  975                              // if  the user  is not aut henticated  then the  only way i n is if th e applicat ion
  976                             // all ows unauth enticated  access
  977                             if( pr incipal ==  null )
  978                             {
  979                                      result =  scList.is AllowUnaut henticated Access();
  980                                      getLogge r().info(" hasResourc ePermissio n (" + req uestUri +  "...) rsID ='" + getR ealmSecuri tyIdentifi er()
  981                                               + "' - no  principal,  permissio n " + (res ult ? "is  GRANTED" :  "is NOT G RANTED")
  982                                               + " on una uthenticat ed access. ");
  983                             }
  984                             else
  985                             {
  986                                      // we ca n only han dle our ow n Principa l realizat ions
  987                                      if( !(pr incipal in stanceof V istaRealmP rincipal)  )
  988                                      {
  989                                               // an erro r because  we should  never get  any other  kind of pr incipal,
  990                                               // and we  need the r ole inform ation stor ed in it
  991                                               getLogger( ).error("A ttempt to  determine  resource p ermissions , hasResou rcePermiss ion(), wit h an unkno wn princip al type.") ;
  992                                      }
  993                                      else
  994                                      {
  995                                               result = s cList.isAn yRoleAllow edAccess(  ((VistaRea lmPrincipa l)principa l).getRole s() );
  996                                      }
  997                             }
  998                    }
  999                return r esult;
  1000       }
  1001  
  1002           /* *
  1003            *  If the au thorizatio n method i s FORM and  the reque sted page  is one of  the
  1004            *  "special"  pages (er ror and lo gin) then  allow acce ss.
  1005            *  
  1006            *  @param co nfig
  1007            *  @param re questURI
  1008            * /
  1009           pr ivate bool ean isSpec ialFormAut hRequest(L oginConfig  config, S tring requ estURI)
  1010           {
  1011                    Stri ng authMet hod = conf ig.getAuth Method();
  1012                    if ( config !=  null && Co nstants.FO RM_METHOD. equals(aut hMethod))
  1013                    {
  1014                             String  loginPage  = config. getLoginPa ge();
  1015                             if (lo ginPage.eq uals(reque stURI))
  1016                             {
  1017                                      getLogge r().debug( " Allow ac cess to lo gin page "  + loginPa ge);
  1018                                      return t rue;
  1019                             }
  1020  
  1021                             // thi s is littl e strange  'cause it  means that  the error  page wont 't
  1022                             // be  returned t o
  1023                             // a u ser before  login. I' m leaving  it like th is on the  assertion
  1024                             // tha t this is  more
  1025                             // sec ure by not  allowing  any clues  about the  applicatio n to escap e
  1026                             // in  the error  page
  1027                             String  errorPage  = config. getErrorPa ge();
  1028                             if (er rorPage.eq uals(reque stURI))
  1029                             {
  1030                                      getLogge r().debug( " Allow ac cess to er ror page "  + errorPa ge);
  1031                                      return t rue;
  1032                             }
  1033  
  1034                             if (re questURI.e ndsWith(Co nstants.FO RM_ACTION) )
  1035                             {
  1036                                      getLogge r().debug( " Allow ac cess to us ername/pas sword subm ission");
  1037                                      return t rue;
  1038                             }
  1039                    }
  1040  
  1041                    retu rn false;
  1042           }
  1043  
  1044           /* *
  1045            *  Enforce a ny user da ta constra int requir ed by the  security c onstraint
  1046            *  guarding  this reque st URI. Re turn <code >true</cod e> if this  constrain t
  1047            *  was not v iolated an d processi ng should  continue,  or <code>f alse</code >
  1048            *  if we hav e created  a response  already.
  1049            *  
  1050            *  NOTE: thi s is essen tially a c opy of the  code in
  1051            *  org.apach e.catalina .realm.Bas icRealm. D eriving fr om that cl ass would  have
  1052            *  been a be tter solut ion howeve r it makes  assumptio ns related  to passwo rd
  1053            *  matching  that our a uthenticat ion store  will not s upport.
  1054            *  The secti on of the  web config uration th at this co de reflect s looks so mething li ke:
  1055            *  
  1056            *  <security -constrain t>
  1057            *       <dis play-name> XCA Respon ding Gatew ay</displa y-name>
  1058            *       <web -resource- collection >
  1059            *                <web-r esource-na me>Everyth ing</web-r esource-na me>
  1060            *                <descr iption>All  resources  within th e XCA Resp onding Gat eway are p rotected</ descriptio n>
  1061            *                <url-p attern>/*< /url-patte rn>
  1062            *       </we b-resource -collectio n>
  1063            *       <aut h-constrai nt>
  1064            *                <descr iption></d escription >
  1065            *                <role- name>xca</ role-name>
  1066            *                <role- name>devel oper</role -name>
  1067            *       </au th-constra int>
  1068            *       <use r-data-con straint>
  1069            *                <descr iption>Req uires encr yption</de scription>
  1070            *                <trans port-guara ntee>CONFI DENTIAL</t ransport-g uarantee>
  1071            *       </us er-data-co nstraint>
  1072            *  </securit y-constrai nt>
  1073            *  
  1074            *  @param re quest
  1075            *              Request  we are pro cessing
  1076            *  @param re sponse
  1077            *              Response  we are cr eating
  1078            *  @param co nstraints
  1079            *              Security  constrain t being ch ecked
  1080            *  @exceptio n IOExcept ion
  1081            *                  if a n input/ou tput error  occurs
  1082            * /
  1083           pu blic boole an hasUser DataPermis sion(Reque st request , Response  response,  SecurityC onstraint[ ] constrai nts) 
  1084           th rows IOExc eption
  1085           {
  1086                    getL ogger().de bug("hasUs erDataPerm ission(" +  request.g etRequestU RI() + ")  rsID='" +  getRealmSe curityIden tifier() +  "'");
  1087  
  1088                    // A re there a ny securit y-constrai nt element s ?
  1089                    if(  constraint s == null  || constra ints.lengt h == 0 )
  1090                    {
  1091                             getLog ger().info ("  hasUse rDataPermi ssion (" +  request.g etRequestU RI() + ")  rsID='" +  getRealmSe curityIden tifier()
  1092                                      + "', no  security  constraint s provided , returnin g true");
  1093                             return  true;
  1094                    }
  1095  
  1096                    // f or each se curity-con straint el ement in t he web con figuration
  1097                    for(  SecurityC onstraint  constraint  : constra ints )
  1098                    {
  1099                             // get  the user- data-const raints ele ment conte nt
  1100                             String  userConst raint = co nstraint.g etUserCons traint();
  1101                             if (us erConstrai nt == null )
  1102                             {
  1103                                      getLogge r().info("   hasUserD ataPermiss ion (" + r equest.get RequestURI () + ") rs ID='" + ge tRealmSecu rityIdenti fier()
  1104                                               + "', appl icable sec urity cons traint pro vided with  no user c onstraint,  returning  true");
  1105                                      return t rue;
  1106                             }
  1107                             if( Co nstants.NO NE_TRANSPO RT.equals( userConstr aint) )
  1108                             {
  1109                                      getLogge r().info("   hasUserD ataPermiss ion (" + r equest.get RequestURI () + ") rs ID='" + ge tRealmSecu rityIdenti fier()
  1110                                               + "', appl icable sec urity cons traint pro vided with  no transp ort securi ty require d, returni ng true");
  1111                                      return t rue;
  1112                             }
  1113                    }
  1114                    
  1115                    // T he request  is to a s ecure area  that requ ires eithe r INTEGRAL  or CONFID ENTIAL
  1116                    // t ransport g uarantee.  If the req uest is no t already  secure the n redirect  it
  1117                    // t o the secu re port.
  1118                    if(  request.is Secure() )
  1119                             return  true;
  1120                    else
  1121                    {
  1122                             // Val idate the  request ag ainst the  user data  constraint
  1123                             /*
  1124                              * if(  request.g etRequest( ).isSecure () ) { log ger.debug( " User dat a
  1125                              * con straint al ready sati sfied for  request ["  + request .getReques tURI() +
  1126                              * "]" ); return  true; }
  1127                              */
  1128                             
  1129                             // Ini tialize va riables we  need to d etermine t he appropr iate actio n
  1130                             int re directPort  = request .getConnec tor().getR edirectPor t();
  1131  
  1132                             // Is  redirectin g disabled ?
  1133                             if (re directPort  <= 0)
  1134                             {
  1135                                      getLogge r().info("   hasUserD ataPermiss ion (" + r equest.get RequestURI () + ") rs ID='" + ge tRealmSecu rityIdenti fier()
  1136                                               + "', SSL  redirect i s disabled , returnin g false (H TTP 403)") ;
  1137                                      response .sendError (403, requ est.getReq uestURI()) ;
  1138                                      return f alse;
  1139                             }
  1140  
  1141                             // Red irect to t he corresp onding SSL  port
  1142                             String Buffer fil e = new St ringBuffer ();
  1143                             String  protocol  = "https";
  1144                             String  host = re quest.getS erverName( );
  1145                             // Pro tocol
  1146                             file.a ppend(prot ocol).appe nd("://"). append(hos t);
  1147                             // Hos t with por t
  1148                             if (re directPort  != 443)
  1149                                      file.app end(":").a ppend(redi rectPort);
  1150  
  1151                             // URI
  1152                             file.a ppend(requ est.getReq uestURI()) ;
  1153                             String  requested SessionId  = request. getRequest edSessionI d();
  1154                             if ((r equestedSe ssionId !=  null) &&  request.is RequestedS essionIdFr omURL())
  1155                             {
  1156                                      file.app end(";jses sionid=");
  1157                                      file.app end(reques tedSession Id);
  1158                             }
  1159  
  1160                             String  queryStri ng = reque st.getQuer yString();
  1161                             if (qu eryString  != null)
  1162                             {
  1163                                      file.app end('?');
  1164                                      file.app end(queryS tring);
  1165                             }
  1166                             getLog ger().debu g("  Redir ecting req uest [" +  request.ge tRequestUR I() + "] t o [" + fil e.toString () + "]");
  1167                             respon se.sendRed irect(file .toString( ));
  1168  
  1169                             getLog ger().info ("  hasUse rDataPermi ssion (" +  request.g etRequestU RI() + ")  rsID='" +  getRealmSe curityIden tifier()
  1170                                               + " return ing false" );
  1171                             return  false;
  1172                    }
  1173                    
  1174           }
  1175  
  1176           /*
  1177            *  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========== ====
  1178            * /
  1179           /* *
  1180            *  Return th e Security Constraint s configur ed to guar d the requ est URI fo r
  1181            *  this requ est, or <c ode>null</ code> if t here is no  such cons traint.
  1182            *  
  1183            *  <security -constrain t> <web-re source-col lection> < web-resour ce-name>
  1184            *  <descript ion> <url- pattern> < http-metho d> <auth-c onstraint>  <role-nam e>
  1185            *  <user-dat a-constrai nt> <trans port-guara ntee>
  1186            *  
  1187            *  The web-r esource-co llection e lement is  used to id entify a s ubset of t he
  1188            *  resources  and HTTP  methods on  those res ources wit hin a web  applicatio n to
  1189            *  which a s ecurity co nstraint a pplies. If  no HTTP m ethods are  specified ,
  1190            *  then the  security c onstraint  applies to  all HTTP  methods.
  1191            *  
  1192            *  The url-p attern ele ment conta ins the ur l pattern  of the map ping. Must
  1193            *  follow th e rules sp ecified in  Section 1 1.2 of the  Servlet A PI
  1194            *  Specifica tion. Esse ntially th at means;  "/xxx/*" m atches any thing star ting
  1195            *  with /xxx  "*.xxx" m atches any thing endi ng with .x xx anythin g else mat ches
  1196            *  exactly.
  1197            *  
  1198            *  The http- method con tains an H TTP method  (GET | PO ST |...).  No http-me thod
  1199            *  matches a ny method
  1200            *  
  1201            *  @param re quest
  1202            *              Request  we are pro cessing
  1203            *  @param co ntext
  1204            *              Context  the Reques t is mappe d to
  1205            * /
  1206           pu blic Secur ityConstra int[] find SecurityCo nstraints( Request re quest, Con text conte xt)
  1207           {
  1208                    // f indSecurit yConstrain ts is the  first call  made for  each trans action,
  1209                    // c reate the  unique ID
  1210                    setR ealmSecuri tyIdentifi er();
  1211  
  1212                    // T he mapping  to applic able Secur ityConstra int is don e on the r equestURI  and the re quest meth od.
  1213                    // T he request PathInfo w ill contai n the path , includin g the cont ext.
  1214                    // e .g. /Vix/s ecure/Tran sactionLog .jspx 
  1215                    // w here: "Vix " is the c ontext nam e
  1216                    // a nd "secure /Transacti onLog.jspx " is the s ervlet pat h and addi tional pat h info
  1217                    // t he query s tring is N OT include d
  1218                    // T he request Method is  (probably)  an HTTP r equest met hod.
  1219                    Stri ng request PathInfo =  request.g etRequestU RI();
  1220                    Stri ng request Method = r equest.get Method();
  1221                    
  1222                    // r equestCont extPath is  the path  to the Con text
  1223                    Stri ng request ContextPat h = reques t.getConte xtPath();
  1224                    
  1225                    // g et the por tion of th e URL whic h is mappe d in the w eb context
  1226                    // u nder <secu rity-const raint> <we b-resource -collectio n> <url-pa ttern>
  1227                    Stri ng context RequestPat h = reques tPathInfo;
  1228                    
  1229                    // A s far as I 've been a ble to tel l, this ne xt test wi ll always  be true,
  1230                    // t hat is the  requestPa thInfo alw ays starts  with the  context.
  1231                    // T he context RequestPat h is the p ath withou t the cont ext part o f the path .
  1232                    if ( requestPat hInfo.star tsWith(req uestContex tPath))
  1233                             contex tRequestPa th = reque stPathInfo .substring (requestCo ntextPath. length());
  1234                    
  1235                    
  1236                    retu rn findSec urityConst raints(con text, requ estPathInf o, request Method, co ntextReque stPath);
  1237           }
  1238  
  1239           /* *
  1240            *  Return an  Array of  SecurityCo nstraint a pplicable  to the res ource as s pecified b y the
  1241            *  Context,  the reques t path and  the metho d.
  1242            *  
  1243        * @pa ram contex t - the ap plication  Context
  1244        * @pa ram reques tPathInfo  - the requ est path ( from the s ervlet req uest)
  1245        * @pa ram reques tMethod -  the reques t method,  probably a n HTTP met hod
  1246        * @pa ram contex tRequestPa th - the p ath within  the conte xt of the  requested  resource
  1247        *                                the c ontext nam e appended  to the co ntextReque stPath sho uld be the  requestPa thInfo
  1248        * 
  1249        * @re turn
  1250        */
  1251       privat e Security Constraint [] findSec urityConst raints(
  1252                    Cont ext contex t, 
  1253                    Stri ng request PathInfo, 
  1254                    Stri ng request Method,
  1255                String c ontextRequ estPath)
  1256       {
  1257                // The S ecurityCon straintKey  uses the  requestPat hInfo (wit h the cont ext path)  so tha the  cached
  1258                    // k eys includ e the cont ext (other wise we'd  apply a pr emission i n one web  app to the  same path
  1259                    // i n another  web app.
  1260                    Secu rityConstr aintCacheK ey constra intKey = n ew Securit yConstrain tCacheKey( requestPat hInfo, req uestMethod );
  1261  
  1262                    getL ogger().de bug(
  1263                                      "findSec urityConst raints(" +  context.g etName() +  ", " + co nstraintKe y.toString () + 
  1264                                      ") rsID= '" + getRe almSecurit yIdentifie r() + "'." );
  1265  
  1266                    Secu rityConstr aint[] res ult = null ;
  1267                    // i f security  constrain t caching  is turned  on then lo ok there f irst
  1268                    // t he cached  security c onstraints  are index ed by the  context an d the cons traintKey,  which
  1269                    // i s a combin ation of r equest pat h and requ est method .
  1270                    resu lt = getCa chedSecuri tyConstrai nt(context , constrai ntKey);
  1271                    getL ogger().de bug("findS ecurityCon straints("  + constra intKey.toS tring() +  ") rsID='"  + getReal mSecurityI dentifier( )
  1272                             + "' l ocated " +  (result = = null ? 0  : result. length) +  " constrai nts in cac he");
  1273                    
  1274                    // t he constra ints for t his URL we re not cac hed
  1275                    if(  result ==  null )
  1276                    {
  1277                             // Are  there any  defined s ecurity co nstraints?
  1278                             // if  not then r eturn null , i.e. if  there are  no securit y constrai nts
  1279                             // the n
  1280                             // the re are no  applicable  security  constraint s
  1281                             Securi tyConstrai nt[] conte xtSecurity Constraint s = contex t.findCons traints();
  1282                             getLog ger().debu g(
  1283                                               "findSecur ityConstra ints(" + c onstraintK ey.toStrin g() + 
  1284                                               ") rsID='"  + getReal mSecurityI dentifier( ) +
  1285                                      "'  " +  (contextSe curityCons traints ==  null ? 0  : contextS ecurityCon straints.l ength) + 
  1286                                      " securi ty constra ints defin ed for ent ire contex t '" + con text.getNa me() + 
  1287                                      "', all  requests w ill be gra nted if no  security  constraint s are defi ned.");
  1288                             
  1289                             // som e security  constrain ts are def ined, find  the ones  applicable  to this r equest 
  1290                             if( co ntextSecur ityConstra ints != nu ll || cont extSecurit yConstrain ts.length  > 0 )
  1291                             {
  1292                                      getLogge r().debug( "findSecur ityConstra ints findi ng securit y constrai nts applic able to pa th [" + co ntextReque stPath + " ] from "
  1293                                               + contextS ecurityCon straints.l ength + "  constraint s in conte xt");
  1294  
  1295                                      // selec ts the sec urity cons traints th at match t he path in fo, and me thod
  1296                                      ArrayLis t<Security Constraint Match> con textMatche dSecurityC onstraints  = 
  1297                                               getMatchin gSecurityC onstraints (contextSe curityCons traints, c ontextRequ estPath, r equestMeth od);
  1298  
  1299                                      if (cont extMatched SecurityCo nstraints  == null ||  contextMa tchedSecur ityConstra ints.size( ) < 1)
  1300                                               getLogger( ).debug("N o applicab le securit y constrai nts found  for '" + c onstraintK ey.toStrin g() + "'." );
  1301                                      else
  1302                                               Collection s.sort(con textMatche dSecurityC onstraints );
  1303  
  1304                                      getLogge r().debug( "For '" +  constraint Key.toStri ng() + "'  adding " +  contextMa tchedSecur ityConstra ints.size( ) + " secu rity const raints to  cache");
  1305  
  1306                                      putToSec urityConst raintsCach e(context,  constrain tKey, cont extMatched SecurityCo nstraints) ;
  1307  
  1308                                      getLogge r().debug( "findSecur ityConstra ints(" + c onstraintK ey.toStrin g() + ") r sID='" + g etRealmSec urityIdent ifier() +  "' - retur ning "
  1309                                               + contextM atchedSecu rityConstr aints.size () + " sec urity cons traints.") ;
  1310  
  1311                                      // retur ns null if  the List  is null or  zero leng th
  1312                                      result =  resultsTo Array(cont extMatched SecurityCo nstraints) ;
  1313                             }
  1314                    }
  1315                    
  1316                    // i f the resu lt is empt y then we  need to re turn null.   An empty  array is  not the sa me as a nu ll array ( they are h andled dif ferently).
  1317                    if(( result ==  null) || ( result.len gth <= 0))
  1318                             return  null;
  1319                    
  1320                    retu rn result;
  1321       }
  1322  
  1323           /* *
  1324        * @pa ram reques tPathInfo
  1325        * @pa ram reques tMethod
  1326        * @pa ram securi tyConstrai nts
  1327        * @re turn
  1328        */
  1329       privat e ArrayLis t<Security Constraint Match> get MatchingSe curityCons traints(
  1330           Se curityCons traint[] s ecurityCon straints, 
  1331           St ring reque stPathInfo
  1332           St ring reque stMethod)
  1333       {
  1334                ArrayLis t<Security Constraint Match> res ults = 
  1335                    new  ArrayList< SecurityCo nstraintMa tch>();
  1336                
  1337                    // f or each of  the <secu rity-const raint> ele ments (in  the web ap p
  1338                    // d eployment  descriptor )
  1339                    for  (SecurityC onstraint  securityCo nstraint :  securityC onstraints )
  1340                    {
  1341                             getLog ger().debu g("  Evalu ating <sec urity-cons traint> '"  + securit yConstrain t + "' aga inst " + r equestMeth od + "-" +  requestPa thInfo);
  1342  
  1343                             // Fin d the web- resource-c ollection  elements w ithin the  security
  1344                             // con straints
  1345                             // A w eb-resourc e-collecti on element  includes  the url-pa ttern and
  1346                             // htt p-method e lements. T he request
  1347                             // mus t match ag ainst both  url-patte rn and htt p-method.
  1348                             Securi tyCollecti on[] webRe sourceColl ections =  securityCo nstraint.f indCollect ions();
  1349  
  1350                             if (we bResourceC ollections  == null)
  1351                             {
  1352                                      getLogge r().debug( "  <securi ty-constra int> '" +  securityCo nstraint +  "' has no  web resou rces defin ed, ignori ng ...");
  1353                                      continue ;
  1354                             }
  1355  
  1356                             // log ger.debug( " Checking  constrain t '" + sec urityConst raint +
  1357                             // "'  against "  + requestM ethod + "  " + pathIn fo + " -->  " +
  1358                             // sec urityConst raint.incl uded(pathI nfo, reque stMethod)) ;
  1359  
  1360                             // sea rch for an y exact ma tches to t he request URI
  1361                             for (S ecurityCol lection we bResourceC ollection  : webResou rceCollect ions)
  1362                             {
  1363                                      getLogge r().debug( "    Check ing <web-r esource-co llection>  '" + webRe sourceColl ection + " ' against  " + reques tMethod +  "-"
  1364                                               + requestP athInfo);
  1365  
  1366                                      // get t he url-pat tern eleme nts within  the
  1367                                      // web-r esource-co llection
  1368                                      String[]  urlPatter ns = webRe sourceColl ection.fin dPatterns( );
  1369  
  1370                                      if (urlP atterns ==  null)
  1371                                               continue;
  1372  
  1373                                      // for e ach patter n in the w eb-resourc e-collecti on
  1374                                      // In th e Web appl ication de ployment d escriptor,  the follo wing
  1375                                      // synta x is used  to define
  1376                                      // mappi ngs:
  1377                                      // • A s tring begi nning with  a ‘/’ cha racter and  ending wi th a
  1378                                      // ‘/*’  suffix is  used
  1379                                      // for p ath mappin g.
  1380                                      // • A s tring begi nning with  a ‘*.’ pr efix is us ed as an
  1381                                      // exten sion mappi ng.
  1382                                      // • A s tring cont aining onl y the ’/’  character  indicates  the
  1383                                      // "defa ult" servl et of
  1384                                      // the a pplication . In this  case the s ervlet pat h is the r equest
  1385                                      // URI m inus the c ontext
  1386                                      // path  and the pa th info is  null.
  1387                                      // • All  other str ings are u sed for ex act matche s only.
  1388                                      //
  1389                                      // Exact  match tak es precede nce over p ath and ex tension.
  1390                                      // Path  match take s preceden ce over ex tension.
  1391                                      // Defau lt servlet  matches a nything el se.
  1392                                      for (int  urlPatter nIndex = 0 ; urlPatte rnIndex <  urlPattern s.length;  urlPattern Index++)
  1393                                      {
  1394                                               String url Pattern =  urlPattern s[urlPatte rnIndex];
  1395                                               boolean pa tternIsDef aultMatch  = "/".equa ls(urlPatt ern);
  1396                                               boolean pa tternIsPat hMatch = u rlPattern. startsWith ("/") && u rlPattern. endsWith(" /*");
  1397                                               boolean pa tternIsAny PathMatch  = "/*".equ als(urlPat tern);
  1398                                               boolean pa tternIsExt ensionMatc h = urlPat tern.start sWith("*." );
  1399                                               boolean pa tternIsExa ctMatch =  !patternIs DefaultMat ch && !pat ternIsAnyP athMatch & & !pattern IsPathMatc h
  1400                                                       &&  !patternI sExtension Match;
  1401  
  1402                                               getLogger( ).debug("     Checkin g <url-pat tern> '" +  urlPatter n + (patte rnIsDefaul tMatch ? " ' as defau lt match"  : "")
  1403                                                       +  (patternIs AnyPathMat ch ? "' as  any path  match" : " ") + (patt ernIsExact Match ? "'  as exact  match" : " ")
  1404                                                       +  (patternIs PathMatch  ? "' as pa th match"  : "") + (p atternIsEx tensionMat ch ? "' as  extension  match" :  "")
  1405                                                       +  "' against  " + reque stMethod +  " " + req uestPathIn fo);
  1406  
  1407                                               if (patter nIsDefault Match && w ebResource Collection .findMetho d(requestM ethod))
  1408                                               {
  1409                                                       ge tLogger(). debug("Def ault match  '" + urlP attern + " ' found");
  1410                                                       re sults.add( SecurityCo nstraintMa tch.create DefaultSec urityConst raintMatch (securityC onstraint,  urlPatter n));
  1411                                               } else if  (patternIs AnyPathMat ch && webR esourceCol lection.fi ndMethod(r equestMeth od))
  1412                                               {
  1413                                                       ge tLogger(). debug("Any  path patt ern match  '" + urlPa ttern + "'  found");
  1414                                                       re sults.add( SecurityCo nstraintMa tch.create PathSecuri tyConstrai ntMatch(se curityCons traint, ur lPattern)) ;
  1415                                               }
  1416                                               // if the  url-patter n is an ex act match  for the re quest URI
  1417                                               // then ad d it direc tly to the  results a rray
  1418                                               else if (p atternIsEx actMatch & & requestP athInfo.eq uals(urlPa ttern) &&  webResourc eCollectio n.findMeth od(request Method))
  1419                                               {
  1420                                                       ge tLogger(). debug("Exa ct pattern  match '"  + urlPatte rn + "' fo und");
  1421                                                       re sults.add( SecurityCo nstraintMa tch.create ExactSecur ityConstra intMatch(s ecurityCon straint, u rlPattern) );
  1422                                               } else if  (patternIs PathMatch)
  1423                                               {
  1424                                                       St ring[] url PatternPat hComponent s = urlPat tern.split ("/");
  1425                                                       St ring[] req uestCompon ents = req uestPathIn fo.split(" /");
  1426                                                       in t patternL ength = ur lPatternPa thComponen ts.length;
  1427                                                       in t requestC omponentsL ength = re questCompo nents.leng th;
  1428  
  1429                                                       //  if the re quest has  fewer elem ents than  the patter n
  1430                                                       //  then it c annot matc h
  1431                                                       bo olean matc hes = requ estCompone ntsLength  >= pattern Length;
  1432                                                       fo r (int pat ternCompon entIndex =  0; matche s && patte rnComponen tIndex < p atternLeng th
  1433                                                                && ( !"*".equal s(urlPatte rnPathComp onents[pat ternCompon entIndex]) ); ++patte rnComponen tIndex)
  1434                                                       {
  1435                                                                Stri ng pattern Component  = urlPatte rnPathComp onents[pat ternCompon entIndex];
  1436                                                                Stri ng request Component  = requestC omponents[ patternCom ponentInde x];
  1437  
  1438                                                                getL ogger().de bug("       Checking  <url-patte rn> path c omponent ' " + patter nComponent  + "' to r equest com ponent '"
  1439                                                                         + requ estCompone nt + "'");
  1440  
  1441                                                                // i f path com ponent doe sn't match , set matc hes to
  1442                                                                // f alse
  1443                                                                matc hes = patt ernCompone nt.equals( requestCom ponent);
  1444                                                       }
  1445                                                       //  if we mat ched all o f the patt ern compon ents
  1446                                                       if  (matches)
  1447                                                       {
  1448                                                                getL ogger().de bug("Path  pattern ma tch '" + u rlPattern  + "' found ");
  1449                                                                resu lts.add(Se curityCons traintMatc h.createPa thSecurity Constraint Match(secu rityConstr aint, urlP attern));
  1450                                                       }
  1451                                               } else if  (patternIs ExtensionM atch)
  1452                                               {
  1453                                                       in t extensio nIndex = u rlPattern. indexOf('. ');
  1454                                                       St ring exten sion = url Pattern.su bstring(ex tensionInd ex);
  1455                                                       if  (requestP athInfo.en dsWith(ext ension) &&  webResour ceCollecti on.findMet hod(reques tMethod))
  1456                                                       {
  1457                                                                getL ogger().de bug("Exten sion patte rn match ' " + urlPat tern + "'  found");
  1458                                                                resu lts.add(Se curityCons traintMatc h.createEx tensionSec urityConst raintMatch (securityC onstraint,  urlPatter n));
  1459                                                       }
  1460                                               }
  1461                                      }
  1462                             }
  1463                    }
  1464                return r esults;
  1465       }
  1466  
  1467           /* *
  1468            *  Convert a n ArrayLis t to a Sec urityContr aint [].
  1469            * /
  1470           pr ivate Secu rityConstr aint[] res ultsToArra y(ArrayLis t<Security Constraint Match> res ults)
  1471           {
  1472                    if ( results ==  null || r esults.siz e() < 1)
  1473                             return  null;
  1474  
  1475                    Secu rityConstr aint[] arr ay = new S ecurityCon straint[re sults.size ()];
  1476  
  1477                    int  index = 0;
  1478                    for  (SecurityC onstraintM atch match  : results )
  1479                    {
  1480                             array[ index] = m atch.getSe curityCons traint();
  1481                             ++inde x;
  1482                    }
  1483  
  1484                    retu rn array;
  1485           }
  1486           
  1487           
  1488           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========
  1489           //  Inner cla sses
  1490           //  Cache key s and valu es
  1491           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== ========
  1492  
  1493           cl ass FullyQ ualifiedPr incipalNam e
  1494           {
  1495                    priv ate final  String rea lm;
  1496                    priv ate final  String nam e;
  1497  
  1498                    publ ic FullyQu alifiedPri ncipalName (VistaReal mPrincipal  principal )
  1499                    {
  1500                             this.r ealm = pri ncipal.get Realm();
  1501                             this.n ame = prin cipal.getA ccessCode( );
  1502                    }
  1503  
  1504                    publ ic FullyQu alifiedPri ncipalName (String re alm, Strin g name)
  1505                    {
  1506                             this.r ealm = rea lm;
  1507                             this.n ame = name ;
  1508                    }
  1509  
  1510                    publ ic String  getRealm()
  1511                    {
  1512                             return  realm;
  1513                    }
  1514  
  1515                    publ ic String  getName()
  1516                    {
  1517                             return  name;
  1518                    }
  1519  
  1520                    @Ove rride
  1521                    publ ic String  toString()
  1522                    {
  1523                             return  getRealm( ) + "/" +  getName();
  1524                    }
  1525  
  1526                    @Ove rride
  1527                    publ ic int has hCode()
  1528                    {
  1529                             final  int prime  = 31;
  1530                             int re sult = 1;
  1531                             result  = prime *  result +  ((name ==  null) ? 0  : name.has hCode());
  1532                             result  = prime *  result +  ((realm ==  null) ? 0  : realm.h ashCode()) ;
  1533                             return  result;
  1534                    }
  1535  
  1536                    @Ove rride
  1537                    publ ic boolean  equals(Ob ject obj)
  1538                    {
  1539                             if (th is == obj)
  1540                                      return t rue;
  1541                             if (ob j == null)
  1542                                      return f alse;
  1543                             if (ge tClass() ! = obj.getC lass())
  1544                                      return f alse;
  1545                             final  FullyQuali fiedPrinci palName ot her = (Ful lyQualifie dPrincipal Name) obj;
  1546                             if (na me == null )
  1547                             {
  1548                                      if (othe r.name !=  null)
  1549                                               return fal se;
  1550                             } else  if (!name .equals(ot her.name))
  1551                                      return f alse;
  1552                             if (re alm == nul l)
  1553                             {
  1554                                      if (othe r.realm !=  null)
  1555                                               return fal se;
  1556                             } else  if (!real m.equals(o ther.realm ))
  1557                                      return f alse;
  1558                             return  true;
  1559                    }
  1560           }
  1561  
  1562           /* *
  1563            *  
  1564            * /
  1565           cl ass Princi palCacheVa lue
  1566           {
  1567                    priv ate long d ate = Syst em.current TimeMillis ();
  1568                    priv ate VistaR ealmPrinci pal princi pal = null ;
  1569  
  1570                    Prin cipalCache Value(Vist aRealmPrin cipal prin cipal)
  1571                    {
  1572                             // thi s.principa l = princi pal.clone( );
  1573                             this.p rincipal =  principal ;
  1574                    }
  1575  
  1576                    publ ic long ge tDate()
  1577                    {
  1578                             return  this.date ;
  1579                    }
  1580  
  1581                    publ ic VistaRe almPrincip al getPrin cipal()
  1582                    {
  1583                             return  this.prin cipal;
  1584                    }
  1585  
  1586                    /**
  1587                     * S et the inc eption dat e on this  cache entr y to the c urrent dat e
  1588                     */
  1589                    void  touch()
  1590                    {
  1591                             this.d ate = Syst em.current TimeMillis ();
  1592                    }
  1593           }
  1594  
  1595           /* *
  1596            *  
  1597              * @author  PI I
  1598            *  
  1599            * /
  1600           cl ass Securi tyConstrai ntCacheKey
  1601           {
  1602                    priv ate String  requestUr i;
  1603                    priv ate String  httpMetho d;
  1604  
  1605                    publ ic Securit yConstrain tCacheKey( String req uestUri, S tring http Method)
  1606                    {
  1607                             super( );
  1608                             this.r equestUri  = requestU ri;
  1609                             this.h ttpMethod  = httpMeth od;
  1610                    }
  1611  
  1612                    publ ic String  getHttpMet hod()
  1613                    {
  1614                             return  this.http Method;
  1615                    }
  1616  
  1617                    publ ic String  getRequest Uri()
  1618                    {
  1619                             return  this.requ estUri;
  1620                    }
  1621  
  1622                    @Ove rride
  1623                    publ ic int has hCode()
  1624                    {
  1625                             final  int PRIME  = 31;
  1626                             int re sult = 1;
  1627                             result  = PRIME *  result +  ((this.htt pMethod ==  null) ? 0  : this.ht tpMethod.h ashCode()) ;
  1628                             result  = PRIME *  result +  ((this.req uestUri ==  null) ? 0  : this.re questUri.h ashCode()) ;
  1629                             return  result;
  1630                    }
  1631  
  1632                    @Ove rride
  1633                    publ ic boolean  equals(Ob ject obj)
  1634                    {
  1635                             if (th is == obj)
  1636                                      return t rue;
  1637                             if (ob j == null)
  1638                                      return f alse;
  1639                             if (ge tClass() ! = obj.getC lass())
  1640                                      return f alse;
  1641                             final  SecurityCo nstraintCa cheKey oth er = (Secu rityConstr aintCacheK ey) obj;
  1642                             if (th is.httpMet hod == nul l)
  1643                             {
  1644                                      if (othe r.httpMeth od != null )
  1645                                               return fal se;
  1646                             } else  if (!this .httpMetho d.equals(o ther.httpM ethod))
  1647                                      return f alse;
  1648                             if (th is.request Uri == nul l)
  1649                             {
  1650                                      if (othe r.requestU ri != null )
  1651                                               return fal se;
  1652                             } else  if (!this .requestUr i.equals(o ther.reque stUri))
  1653                                      return f alse;
  1654                             return  true;
  1655                    }
  1656  
  1657                    @Ove rride
  1658                    publ ic String  toString()
  1659                    {
  1660                             return  this.getC lass().get SimpleName () + ":" +  this.http Method + " -" + this. requestUri ;
  1661                    }
  1662           }
  1663  
  1664           /* *
  1665            *  
  1666              * @author  PI I
  1667            *  
  1668            * /
  1669           cl ass Securi tyConstrai ntCacheVal ue
  1670           {
  1671                    priv ate long d ate = Syst em.current TimeMillis ();
  1672                    priv ate Securi tyConstrai nt[] const raints;
  1673  
  1674                    publ ic Securit yConstrain tCacheValu e(Security Constraint [] constra ints)
  1675                    {
  1676                             super( );
  1677                             // mak e a copy o f the arra y so that  if someone  else mess es with it ,
  1678                             // our  copy is s till valid
  1679                             this.c onstraints  = new Sec urityConst raint[cons traints.le ngth];
  1680                             System .arraycopy (constrain ts, 0, thi s.constrai nts, 0, co nstraints. length);
  1681                    }
  1682  
  1683                    publ ic Securit yConstrain t[] getCon straints()
  1684                    {
  1685                             return  this.cons traints;
  1686                    }
  1687  
  1688                    publ ic long ge tDate()
  1689                    {
  1690                             return  this.date ;
  1691                    }
  1692  
  1693                    void  touch()
  1694                    {
  1695                             this.d ate = Syst em.current TimeMillis ();
  1696                    }
  1697           }
  1698  
  1699           /*  (non-Java doc)
  1700            *  @see java .lang.Obje ct#hashCod e()
  1701            * /
  1702           @O verride
  1703           pu blic int h ashCode()
  1704           {
  1705                    fina l int prim e = 31;
  1706                    int  result = 1 ;
  1707                    resu lt = prime  * result  + ((this.s iteNumber  == null) ?  0 : this. siteNumber .hashCode( ));
  1708                    retu rn result;
  1709           }
  1710  
  1711           /*  (non-Java doc)
  1712            *  @see java .lang.Obje ct#equals( java.lang. Object)
  1713            * /
  1714           @O verride
  1715           pu blic boole an equals( Object obj )
  1716           {
  1717                    if ( this == ob j)
  1718                             return  true;
  1719                    if ( obj == nul l)
  1720                             return  false;
  1721                    if ( getClass()  != obj.ge tClass())
  1722                             return  false;
  1723                    Abst ractVistaR ealmImpl o ther = (Ab stractVist aRealmImpl ) obj;
  1724                    if ( this.siteN umber == n ull)
  1725                    {
  1726                             if (ot her.siteNu mber != nu ll)
  1727                                      return f alse;
  1728                    }
  1729                    else  if (!this .siteNumbe r.equals(o ther.siteN umber))
  1730                             return  false;
  1731                    retu rn true;
  1732           }
  1733   }