98. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 12/5/2017 12:06:37 PM Central Standard 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.

98.1 Files compared

# Location File Last Modified
1 IV-eHMP_CIF.zip\IMAG_Source\VISA\Java\CoreRouter\main\src\java\gov\va\med\imaging\core\router AbstractCommandImpl.java Mon Dec 4 21:34:54 2017 UTC
2 IV-eHMP_CIF.zip\IMAG_Source\VISA\Java\CoreRouter\main\src\java\gov\va\med\imaging\core\router AbstractCommandImpl.java Mon Dec 4 21:58:24 2017 UTC

98.2 Comparison summary

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

98.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

98.4 Active regular expressions

No regular expressions were active.

98.5 Comparison detail

  1   /**
  2    * Package : MAG - Vi stA Imagin g
  3    * WARNING : Per VHA  Directive  2004-038,  this routi ne should  not be mod ified.
  4    * Date Cr eated: Sep  24, 2008
  5    * Site Na me:  Washi ngton OI F ield Offic e, Silver  Spring, MD
  6    * @author         
BECKEC
  7    * @versio n 1.0
  8    *
  9    * ------- ---------- ---------- ---------- ---------- ---------- -------
  10    * Propert y of the U S Governme nt.
  11    * No perm ission to  copy or re distribute  this soft ware is gi ven.
  12    * Use of  unreleased  versions  of this so ftware req uires the  user
  13    * to exec ute a writ ten test a greement w ith the Vi stA Imagin g
  14    * Develop ment Offic e of the D epartment  of Veteran s Affairs,
  15    * telepho ne (301) 7 34-0100.
  16    * 
  17    * The Foo d and Drug  Administr ation clas sifies thi s software  as
  18    * a Class  II medica l device.   As such,  it may not  be change d
  19    * in any  way.  Modi fications  to this so ftware may  result in  an
  20    * adulter ated medic al device  under 21CF R820, the  use of whi ch
  21    * is cons idered to  be a viola tion of US  Federal S tatutes.
  22    * ------- ---------- ---------- ---------- ---------- ---------- -------
  23    */
  24   package go v.va.med.i maging.cor e.router;
  25  
  26   import gov .va.med.Ro utingToken ;
  27   import gov .va.med.Ro utingToken Impl;
  28   import gov .va.med.We llKnownOID ;
  29   import gov .va.med.ex ceptions.R outingToke nFormatExc eption;
  30   import gov .va.med.im aging.GUID ;
  31   import gov .va.med.im aging.core .CommandCo ntextImpl;
  32   import gov .va.med.im aging.core .RouterImp l;
  33   import gov .va.med.im aging.core .interface s.exceptio ns.Composi teExceptio nComponent ;
  34   import gov .va.med.im aging.core .interface s.exceptio ns.Composi teMethodEx ception;
  35   import gov .va.med.im aging.core .interface s.exceptio ns.Connect ionExcepti on;
  36   import gov .va.med.im aging.core .interface s.exceptio ns.MethodE xception;
  37   import gov .va.med.im aging.core .interface s.router.A synchronou sCommandRe sult;
  38   import gov .va.med.im aging.core .interface s.router.A synchronou sCommandRe sultListen er;
  39   import gov .va.med.im aging.core .interface s.router.C ommand;
  40   import gov .va.med.im aging.core .interface s.router.C ommandCont ext;
  41   import gov .va.med.im aging.core .router.qu eue.Schedu ledPriorit yQueueElem ent;
  42   import gov .va.med.im aging.data source.Dat aSourcePro vider;
  43   import gov .va.med.im aging.exch ange.busin ess.Transa ctionConte xtLogEntry Snapshot;
  44   import gov .va.med.im aging.tran sactioncon text.Inval idTransact ionContext MementoExc eption;
  45   import gov .va.med.im aging.tran sactioncon text.Trans actionCont ext;
  46   import gov .va.med.im aging.tran sactioncon text.Trans actionCont extFactory ;
  47   import gov .va.med.im aging.tran sactioncon text.Trans actionCont extMemento ;
  48   import jav a.io.Seria lizable;
  49   import jav a.util.Dat e;
  50   import jav a.util.Has hSet;
  51   import jav a.util.Ite rator;
  52   import jav a.util.Lis t;
  53   import jav a.util.Set ;
  54   import jav a.util.con current.Ca llable;
  55   import org .apache.lo gging.log4 j.LogManag er;
  56   import org .apache.lo gging.log4 j.Logger;
  57  
  58   /**
  59    * An abst ract threa d pool tas k to compl ete. Execu tes the as signed tas k.
  60    * @author         
WERFEJ
  61    * 
  62    * The abs tract clas s that con tains the  strategy f or process ing asynch ronous
  63    * command s.
  64    * 
  65    * @author         
BECKEC
  66    *
  67    */
  68   public abs tract clas s Abstract CommandImp l<R>
  69   implements  Command<R >, Callabl e<Asynchro nousComman dResult<R> >, Schedul edPriority QueueEleme nt, Serial izable
  70   {
  71           //  The seria lVersionUI D is requi red and mu st be main tained 
  72           pr ivate stat ic final l ong serial VersionUID  = -506930 6441372156 085L;
  73           
  74           pr ivate tran sient Logg er logger  = null;
  75           pr ivate fina l Set<Asyn chronousCo mmandResul tListener< R>> listen ers;
  76           pr ivate Tran sactionCon textMement o transact ionContext Memento;
  77           pr ivate fina l String p arentComma ndClassNam e;
  78           pr ivate tran sient Comm andContext  commandCo ntext;
  79           pr ivate fina l GUID com mandIdenti fier = new  GUID();       // a u nique iden tifier of  every comm and
  80           pr ivate GUID  parentCom mandIdenti fier = nul l;             // by  default, n o parent,  this is a  root comma nd
  81           pr ivate bool ean childC ommand = f alse; // b y default,  not a chi ld command
  82           
  83           //  these pro perties ar e all asso ciated wit h asynchro nous proce ssing
  84           pr otected Da te accessi bilityDate ;
  85           pr ivate Prio rity prior ity;
  86           pr ivate Date  processin gTargetCom mencementD ate;
  87           pr ivate long  processin gDurationE stimate;
  88           
  89           //  these pro perties ar e all asso ciated wit h periodic  processin g
  90           pr ivate bool ean isPeri odic = fal se;
  91           pr ivate int  periodicEx ecutionDel ay;
  92           pr ivate bool ean period icProcessi ngTerminat ed = false ;
  93  
  94           pr otected St ring getLo calSiteId(
  95           {
  96                    retu rn getComm andContext ().getLoca lSite().ge tArtifactS ource().ge tRepositor yId();
  97           }
  98  
  99           pu blic boole an isPerio dic()
  100           {
  101                    retu rn isPerio dic;
  102           }
  103           
  104           pu blic void  setPeriodi c(boolean  isPeriodic )
  105           {
  106                    this .isPeriodi c = isPeri odic;
  107           }
  108           
  109           pu blic int g etPeriodic ExecutionD elay()
  110           {
  111                    retu rn periodi cExecution Delay;
  112           }
  113           
  114           pu blic void  setPeriodi cExecution Delay(int  periodicEx ecutionDel ay)
  115           {
  116                    this .periodicE xecutionDe lay = peri odicExecut ionDelay;
  117           }
  118           
  119           pu blic Comma nd<R> getN ewPeriodic Instance()
  120           th rows Metho dException
  121           {
  122                    thro w new Meth odExceptio n("getNewP eriodicIns tance is u ndefined f or this co mmand. It  must be im plemented  if the com mand will  be used in  an asynch ronous per iodic fash ion.");
  123           }
  124           
  125           /* *
  126            *  Return th e list of  fatal peri odic comma nd excepti ons. If a  periodic c ommand thr ows an exc eption and  that exce ption is i n this lis t of fatal  exception s, the per iodic 
  127            *  command w ill not be  reschedul ed
  128            *  @return L ist of cla sses that  extend Thr owable tha t are fata l exceptio ns for thi s periodic  command
  129            * /
  130           pu blic List< Class<? ex tends Meth odExceptio n>> getFat alPeriodic ExceptionC lasses()
  131           {
  132                    retu rn null;
  133           }
  134           
  135           /* *
  136            *  This meth od is call ed when a  periodic c ommand has  thrown a  fatal exce ption as d efined by  the list i n getFatal PeriodicEx ceptionCla sses(). At  the point  when this  method is  called
  137            *  the perio dic comman d has alre ady stoppe d executin g and will  not execu te again.   This meth od is mean t to allow  the comma nd to aler t someone  of the fai lure (such  as by sen ding 
  138            *  an email  message)
  139            *  @param t
  140            * /
  141           pu blic void  handleFata lPeriodicE xception(T hrowable t )
  142           {
  143                    // i mplement i n other co mmands
  144           }
  145  
  146           
  147           pu blic GUID  getParentC ommandIden tifier()
  148           {
  149                    retu rn this.pa rentComman dIdentifie r;
  150           }
  151  
  152           pu blic void  setParentC ommandIden tifier(GUI D parentCo mmandIdent ifier)
  153           {
  154                    this .parentCom mandIdenti fier = par entCommand Identifier ;
  155           }
  156  
  157           pu blic GUID  getCommand Identifier ()
  158           {
  159                    retu rn this.co mmandIdent ifier;
  160           }
  161  
  162           pu blic boole an isChild Command()
  163           {
  164                    retu rn childCo mmand;
  165           }
  166           
  167           /*  (non-Java doc)
  168            *  @see gov. va.med.ima ging.core. interfaces .router.Co mmand#setC hildComman d(boolean)
  169            * /
  170           @O verride
  171           pu blic void  setChildCo mmand(bool ean childC ommand) 
  172           {
  173                    this .childComm and = chil dCommand;
  174           }
  175  
  176           /* *
  177            *  
  178            * /
  179           pr otected Ab stractComm andImpl() 
  180           {
  181                    // g et the cur rent trans action con text and c opy it to  our local  reference
  182                    // s et the com mand name  in the con text to ou r command  name, whil e preservi ng
  183                    // a ll other c ontext pro perties
  184                    gov. va.med.ima ging.trans actioncont ext.Transa ctionConte xt transac tionContex t =
  185                               gov. va.med.ima ging.trans actioncont ext.Transa ctionConte xtFactory. get();
  186                    pare ntCommandC lassName =  transacti onContext. getCommand ClassName( );               // m ay be null  if no par ent comman d
  187                    
  188                    // A lways save  a copy of  the trans action con text that  this insta nce was cr eated
  189                    // u nder.  At  this point  we do not  know whet her we wil l execute  synchronou sly or
  190                    // a synchronou sly, or as  a child c ommand.
  191                    this .transacti onContextM emento = t ransaction Context.ge tMemento() ;
  192                    
  193                    this .listeners  = new Has hSet<Async hronousCom mandResult Listener<R >>();
  194  
  195                    // s et the asy nchronous  processing  propertie s to 
  196                    // m ake the co mmand avai lable for  execution  immediatel y at norma l priority .
  197                    this .accessibi lityDate =  new Date( );    // b y default,  available  for immed iate proce ssing
  198                    this .priority  = Schedule dPriorityQ ueueElemen t.Priority .NORMAL;   // normal  priority       
  199                    this .processin gTargetCom mencementD ate = new  Date();      // by de fault, get  it done A SAP
  200                    this .processin gDurationE stimate =  -1L;  // b y default,  do not pr ovide an e stimated d uration, f orces prio rity only  sort
  201           }
  202           
  203           /* *
  204            *  @return t he provide r
  205            * /
  206           pr otected Da taSourcePr ovider get Provider()
  207           {
  208                    retu rn this.ge tCommandCo ntext().ge tProvider( );
  209           }
  210  
  211           /* *
  212            *  Get the L ogger to u se for inf o, debug,  errors, et c ...
  213            *  This is N OT the tra nsaction l ogger.
  214            *  
  215            *  @return
  216            * /
  217           pr otected sy nchronized  Logger ge tLogger()
  218       {
  219                    if(l ogger == n ull)
  220                             logger  = LogMana ger.getLog ger(Abstra ctCommandI mpl.class) ;
  221           re turn logge r;
  222       }
  223  
  224           /* *
  225            *  The comma nd context  contains  references  to the en vironment  in which t he Command
  226            *  is runnin g.
  227            *  @return t he command Context
  228            * /
  229           pr otected Co mmandConte xt getComm andContext ()
  230           {
  231                    retu rn this.co mmandConte xt;
  232           }
  233           
  234           /* *
  235            *  @param co mmandConte xt the com mandContex t to set
  236            * /
  237           pu blic void  setCommand Context(Co mmandConte xt command Context)
  238           {
  239                    this .commandCo ntext = co mmandConte xt;
  240           }
  241  
  242           @D eprecated
  243           pr otected Ro uterImpl g etRouterIm pl()
  244           {
  245                    retu rn ((Comma ndContextI mpl)getCom mandContex t()).getRo uterImpl() ;
  246           }
  247  
  248           /* *
  249            *  Based on  the given  routing to ken, retur n a Routin gToken of  a reposito ry
  250            *  that will  provide a  treating  facility l ist.
  251            *  If the gi ven routin g token is  not a VA  destinatio n then thi s will ret urn null.
  252            *  If the gi ven routin g token is  a VA dest ination th en this re turns the  local site .
  253            *  
  254            *  @param ro utingToken
  255            *  @return
  256            *  @throws M ethodExcep tion
  257            * /
  258           pr otected Ro utingToken  getTreati ngFacility Repository RoutingTok en(String  homeCommun ityId)
  259           th rows Metho dException
  260           {
  261                    Well KnownOID o id = WellK nownOID.ge t(homeComm unityId);
  262                    Rout ingToken l ocalRoutin gToken = n ull;
  263                    
  264                    Tran sactionCon text xacti onContext  = Transact ionContext Factory.ge t();
  265                    Stri ng realmSi teNumber =  xactionCo ntext.getR ealm();
  266                    
  267                    try
  268                    {
  269                             switch (oid)
  270                             {
  271                             case V A_DOCUMENT :
  272                                      //String  localSite Number = g etCommandC ontext().g etRouter() .getAppCon figuration ().getLoca lSiteNumbe r();
  273                                      localRou tingToken  = RoutingT okenImpl.c reateVADoc umentSite( realmSiteN umber);
  274                                      break;
  275                             case V A_RADIOLOG Y_IMAGE:
  276                                      //String  localSite Number = g etCommandC ontext().g etRouter() .getAppCon figuration ().getLoca lSiteNumbe r();
  277                                      localRou tingToken  = RoutingT okenImpl.c reateVARad iologySite (realmSite Number);
  278                                      break;
  279                             defaul t:
  280                                      break;
  281                             }
  282                    }
  283                    catc h (Routing TokenForma tException  x)
  284                    {
  285                             getLog ger().erro r(x);
  286                             throw  new Method Exception( x);
  287                    }
  288                    
  289                    retu rn localRo utingToken ;
  290           }        
  291           
  292           /* *
  293            *  Get a rou ting token  that will  route to  the local  VA site.
  294            *  
  295            *  @return
  296            *  @throws M ethodExcep tion
  297            * /
  298           pr otected Ro utingToken  getLocalR ealmRadiol ogyRouting Token()
  299           th rows Metho dException
  300           {
  301                    try
  302                    {
  303                             Transa ctionConte xt xaction Context =  Transactio nContextFa ctory.get( );
  304                             String  realmSite Number = x actionCont ext.getRea lm();
  305                             
  306                             //Stri ng localSi teNumber =  getComman dContext() .getRouter ().getAppC onfigurati on().getLo calSiteNum ber();
  307                             Routin gToken loc alRoutingT oken = Rou tingTokenI mpl.create VARadiolog ySite(real mSiteNumbe r);
  308                             
  309                             return  localRout ingToken;
  310                    }
  311                    catc h (Routing TokenForma tException  x)
  312                    {
  313                             getLog ger().erro r(x);
  314                             throw  new Method Exception( x);
  315                    }
  316           }
  317           
  318           /* *
  319            *  Get a rou ting token  that will  route to  the local  VA site.
  320            *  
  321            *  @return
  322            *  @throws M ethodExcep tion
  323            * /
  324           pr otected Ro utingToken  getLocalR ealmDocume ntRoutingT oken()
  325           th rows Metho dException
  326           {
  327                    try
  328                    {
  329                             Transa ctionConte xt xaction Context =  Transactio nContextFa ctory.get( );
  330                             String  realmSite Number = x actionCont ext.getRea lm();
  331                             
  332                             //Stri ng localSi teNumber =  getComman dContext() .getRouter ().getAppC onfigurati on().getLo calSiteNum ber();
  333                             Routin gToken loc alRoutingT oken = Rou tingTokenI mpl.create VADocument Site(realm SiteNumber );
  334                             
  335                             return  localRout ingToken;
  336                    }
  337                    catc h (Routing TokenForma tException  x)
  338                    {
  339                             getLog ger().erro r(x);
  340                             throw  new Method Exception( x);
  341                    }
  342           }
  343           
  344           /* *
  345            *  By defaul t, route r equests to  ourselves  as radiol ogy artifa cts.
  346            * /
  347           @O verride
  348           pu blic Routi ngToken ge tRoutingTo ken()
  349           th rows Metho dException
  350           {
  351                    retu rn getLoca lRealmRadi ologyRouti ngToken();
  352           }
  353  
  354           /* *
  355        * @re turn the l isteners
  356        */
  357       public  Set<Async hronousCom mandResult Listener<R >> getList eners()
  358       {
  359           re turn this. listeners;
  360       }
  361       
  362       public  void addL istener(As ynchronous CommandRes ultListene r listener )
  363       {
  364           if (listener  != null)
  365                    list eners.add( listener);
  366       }
  367       
  368       public  void remo veListener (Asynchron ousCommand ResultList ener liste ner)
  369       {
  370           if (listener  != null)
  371                    list eners.remo ve(listene r);
  372       }
  373  
  374           pu blic Strin g getParen tCommandCl assName()
  375           {
  376                    retu rn this.pa rentComman dClassName ;
  377           }
  378  
  379           /* *
  380            *  @return t he transac tionContex tMemento
  381            * /
  382           pu blic Trans actionCont extMemento  getTransa ctionConte xtMemento( )
  383           {
  384                    retu rn this.tr ansactionC ontextMeme nto;
  385           }
  386           
  387           //  Retryable  commands  may turn o ff listene r notifica tion if th e
  388       // com mand faile d and it w ill be ret ried.
  389       // Thi s flag is  always set  before th e command  is execute d and chec ked immedi ately
  390       // the  listeners  are notif ied.
  391       // Der ived class es may cal l resetLis tenerNotif ication()  in its com mandComple tionNotifi cation()
  392       // met hod if the  listeners  should no t be notif ied
  393           pr ivate bool ean notify Listeners;
  394           
  395           pr otected vo id resetLi stenerNoti fication()
  396           {
  397                    noti fyListener s = false;
  398           }
  399           pr otected vo id setList enerNotifi cation()
  400           {
  401                    noti fyListener s = true;
  402           }
  403           pu blic boole an isListe nerNotific ation()
  404           {
  405                    retu rn notifyL isteners;
  406           }
  407           
  408           /* *
  409            *  Getting a  resolved  site (i.e.  the URL l ist of a p articular  site) is d ependent o n the
  410            *  SPI and t he method  arguments.   The incl usion of t he method  arguments  is to allo w
  411            *  the overr ide provid ers the op portunity  to inspect  and make  routing
  412            *  determina tions base d on those  values.
  413            *    
  414            *  @param si teNumber
  415            *  @param sp iClass
  416            *  @param me thodName
  417            *  @param me thodParame terTypes
  418            *  @param me thodParame ters
  419            *  @return
  420            *  @throws M ethodExcep tion
  421            * /
  422           /*
  423           pr otected Re solvedSite  getResolv edSite(
  424                    Stri ng siteNum ber,
  425                    Clas s<? extend s Versiona bleDataSou rceSpi> sp iClass,
  426                    Stri ng methodN ame,
  427                    Clas s<?>[] met hodParamet erTypes,
  428                    Obje ct[] metho dParameter s) 
  429           th rows Metho dException
  430           {
  431                    Reso lvedSite r esolvedSit e = null;
  432                    try
  433                    {
  434                             Method  spiMethod  = spiClas s.getDecla redMethod( "getPatien tDocumentS ets", meth odParamete rTypes);
  435                             resolv edSite = g etCommandC ontext().g etSite(sit eNumber, s piClass,   spiMethod,  methodPar ameters );
  436                    }
  437                    catc h(Throwabl e t)
  438                    {
  439                             getLog ger().erro r("Excepti on [" + t. getMessage () + "] ge tting site  number wi th redirec t handling , using de fault site  resolutio n.", t);
  440                             resolv edSite = g etCommandC ontext().g etSite(sit eNumber);
  441                    }
  442                    
  443                    // I f there ar e no URLs  to try the n throw a  MethodConn ectionExce ption
  444                    // w hich is an  indicatio n that we  could not  establish  a connecti on
  445                    // d uring a me thod call
  446                    if(r esolvedSit e == null  || resolve dSite.getI nterfaceUr ls() == nu ll || reso lvedSite.g etInterfac eUrls().is Empty())
  447                    {
  448                             throw  new Method Connection Exception(  new Conne ctionExcep tion(
  449                                      "The sit e '" + sit eNumber +  "' has no  available  interface  URLs.\n" +
  450                                      "Please  check that  the proto col handle rs are pro perly inst alled and  that the \ n" +
  451                                      "protoco l preferen ces for th e site spe cify valid  protocols .")
  452                             );
  453                    }
  454                    
  455                    retu rn resolve dSite;
  456           }* /
  457  
  458           
  459           /* *
  460            *  This meth od should  be called  to execute  a command  synchrono usly.  It  will
  461            *  populate  the transa ction cont ext fields  correctly .
  462            *  Do not al low derive d classes  to overrid e this met hod so tha t the tran saction
  463            *  informati on is corr ectly popu lated.
  464            *  
  465            * /
  466           pu blic final  R callSyn chronously ()
  467           th rows Metho dException , Connecti onExceptio n
  468           {
  469                    R re sult = nul l;
  470                    Thro wable comm andExcepti on = null;
  471                    
  472                    if(i sChildComm and())
  473                    {
  474                             try
  475                             {
  476                                      // push  the transa ction cont ext of the  client, m aking it t he current  TC
  477                                      Transact ionContext Factory.pu shTransact ionContext (getTransa ctionConte xtMemento( ));
  478                             } 
  479                             catch  (InvalidTr ansactionC ontextMeme ntoExcepti on itcmX)
  480                             {
  481                                      String e rrorMessag e = "Unabl e to push  transactio n context  (make it t he current  context).   Command  cannot be  executed." ;
  482                                      getLogge r().error( errorMessa ge);
  483                                      throw ne w MethodEx ception(er rorMessage );
  484                             }
  485                    }
  486                    
  487                    Tran sactionCon text trans actionCont ext = Tran sactionCon textFactor y.get();
  488                    tran sactionCon text.setCo mmandClass Name(this. getClass() .getSimple Name());
  489                    tran sactionCon text.setAs ynchronous Command(fa lse);
  490                    tran sactionCon text.setVi xSoftwareV ersion (ge tCommandCo ntext().ge tRouter(). getAppConf iguration( ).getVixSo ftwareVers ion ());
  491                    tran sactionCon text.setVi xSiteNumbe r(getComma ndContext( ).getRoute r().getApp Configurat ion().getL ocalSiteNu mber());
  492                    tran sactionCon text.setCo mmandId(th is.getComm andIdentif ier().toSt ring());
  493                    tran sactionCon text.setTh readId(Thr ead.curren tThread(). getName()) ;
  494                    if(i sChildComm and())
  495                    {
  496                             transa ctionConte xt.setStar tTime( new  Long(Syst em.current TimeMillis ()) );
  497                             if(get ParentComm andIdentif ier() != n ull)
  498                             {
  499                                      transact ionContext .setParent CommandId( getParentC ommandIden tifier().t oString()) ;
  500                             }
  501                             else
  502                             {
  503                                      getLogge r().warn(" command '"  + this.ge tClass().g etName() +  "' is a c hild comma nd but par entCommand Id is null , this sho uld never  happen..." );
  504                             }
  505                    }
  506                    
  507                    try
  508                    {
  509                             result  = callSyn chronously InTransact ionContext ();
  510                    }
  511                    catc h(Composit eMethodExc eption cmX )
  512                    {
  513                             String Builder sb  = new Str ingBuilder ();
  514                             sb.app end(cmX.ge tClass().g etSimpleNa me());
  515                             sb.app end('-');
  516                             sb.app end(cmX.ge tMessage() );
  517                             sb.app end('\n');
  518                             sb.app end( Integ er.toStrin g(cmX.size ()) );
  519                             sb.app end(" exce ptions in  composite.  \n");
  520                             for(It erator<Com positeExce ptionCompo nent<Metho dException >> iter =  cmX.iterat or(); iter .hasNext() ; )
  521                             {
  522                                      Composit eException Component< MethodExce ption> cxc  = iter.ne xt();
  523                                      Exceptio n x = cxc. getExcepti on();
  524                                      sb.appen d(x == nul l ? "<null >" : x.get Class().ge tSimpleNam e());
  525                                      sb.appen d('-');
  526                                      sb.appen d(x == nul l ? "" : x .getMessag e());
  527                                      sb.appen d('\n');
  528                             }
  529                             getLog ger().erro r(sb.toStr ing());
  530                             comman dException  = cmX;
  531                             throw  cmX;
  532                    }
  533                    catc h (MethodE xception x )
  534                    {
  535                             getLog ger().erro r(x);
  536                             comman dException  = x;
  537                             throw  x;
  538                    }
  539                    catc h (Connect ionExcepti on x)
  540                    {
  541                             getLog ger().erro r(x);
  542                             comman dException  = x;
  543                             throw  x;
  544                    }
  545                    fina lly
  546                    {
  547                             if(isC hildComman d())
  548                             {
  549                                      long dur ation = Sy stem.curre ntTimeMill is() - tra nsactionCo ntext.getS tartTime() .longValue ();
  550                                      transact ionContext .setDurati on( new Lo ng(duratio n) );
  551                             }
  552                             
  553                             if(com mandExcept ion != nul l)
  554                             {
  555                                      transact ionContext .setExcept ionClassNa me(command Exception. getClass() .getSimple Name());
  556                                      transact ionContext .setErrorM essage(com mandExcept ion.getMes sage());
  557                             }
  558                             
  559                             // res tore the t ransaction  context i f it was p ushed
  560                             if(isC hildComman d())
  561                             {
  562                                      try
  563                                      {
  564                                               getCommand Context(). getTransac tionLogger Service(). writeLogEn try(new Tr ansactionC ontextLogE ntrySnapsh ot(Transac tionContex tFactory.g et()));
  565                                      }
  566                                      catch (E xception x
  567                                      {
  568                                               StringBuil der sb = n ew StringB uilder();
  569                                               StackTrace Element[]  stackTrace  = x.getSt ackTrace() ;
  570                                               if(stackTr ace != nul l && stack Trace.leng th > 0)
  571                                               {
  572                                                       sb .append( x .getMessag e() );
  573                                                       sb .append( ' @' );
  574                                                       sb .append( s tackTrace[ 0].getFile Name() );
  575                                                       sb .append( ' [' );
  576                                                       sb .append( s tackTrace[ 0].getLine Number() ) ;
  577                                                       sb .append( ' ]' );
  578                                                       
  579                                                       ge tLogger(). error (sb. toString() , x);
  580                                               }
  581                                               else
  582                                                       ge tLogger(). error (x);
  583                                      }
  584                                      
  585                                      // save  the transa ction cont ext so any  changes m ade are pr eserved
  586                                      this.tra nsactionCo ntextMemen to = trans actionCont ext.getMem ento();
  587                                      Transact ionContext Factory.po pTransacti onContext( );
  588                             }
  589                    }
  590                    
  591                    retu rn result;
  592           }
  593           
  594           /* *
  595            *  This meth od is call ed by the  asynchrono us executo r when a c ommand is  being exec uted
  596            *  ... async hronously.
  597            *  Do not al low derive d classes  to overrid e this met hod becaus e the tran saction co ntext
  598            *  must be c orrectly e stablished .
  599            *  
  600            *  @see java .util.conc urrent.Cal lable#call ()
  601            * /
  602           @O verride
  603       public  final Asy nchronousC ommandResu lt<R> call () 
  604       {
  605                    R re sult = nul l;
  606                    
  607                    try
  608                    {
  609                             // pus h the tran saction co ntext of t he client,  making it  the curre nt TC
  610                             Transa ctionConte xtFactory. pushTransa ctionConte xt(getTran sactionCon textMement o());
  611                    } 
  612                    catc h (Invalid Transactio nContextMe mentoExcep tion itcmX )
  613                    {
  614                             getLog ger().erro r("Unable  to push tr ansaction  context (m ake it the  current c ontext).   Command ca nnot be ex ecuted.",  itcmX);
  615                             return  new Async hronousCom mandResult <R>(this,  itcmX);
  616                    }
  617                    
  618                    Tran sactionCon text threa dContext =  Transacti onContextF actory.get ();
  619                    
  620                    if(t hreadConte xt == null )
  621                    {
  622                             getLog ger().erro r("PANIC -  transacti on context  not assoc iated with  an asynch rnonous co mmand!");
  623                    }
  624                    else
  625                    {
  626                             if(thr eadContext .getStartT ime() == n ull && !is ChildComma nd())
  627                             {
  628                                      getLogge r().warn(" Transactio n context  start time  was not s et and thi s is not a  child com mand.  Sta rt time is  being set  to now.") ;
  629                                      threadCo ntext.setS tartTime(  new Long(S ystem.curr entTimeMil lis()) );
  630                             }
  631                             
  632                             thread Context.se tCommandCl assName(th is.getClas s().getSim pleName()) ;
  633                             thread Context.se tAsynchron ousCommand (true);
  634                             thread Context.se tCommandId (this.getC ommandIden tifier().t oString()) ;
  635                             thread Context.se tThreadId( Thread.cur rentThread ().getName ());
  636                             if(get CommandCon text() ==  null || ge tCommandCo ntext().ge tRouter()  == null ||  
  637                                               getCommand Context(). getRouter( ).getAppCo nfiguratio n() == nul l)
  638                             {
  639                                      threadCo ntext.setV ixSoftware Version("< unknown ve rsion, no  applicatio n context  available> ");
  640                                      threadCo ntext.setV ixSiteNumb er("<unkno wn site nu mber, no a pplication  context a vailable>" );
  641                             }
  642                             else
  643                             {
  644                                      threadCo ntext.setV ixSoftware Version(
  645                                                       ge tCommandCo ntext().ge tRouter(). getAppConf iguration( ).getVixSo ftwareVers ion());
  646                                      threadCo ntext.setV ixSiteNumb er(getComm andContext ().getRout er().getAp pConfigura tion().get LocalSiteN umber());
  647                             }
  648                             
  649                             
  650                             if(isC hildComman d() || isP eriodic())
  651                             {
  652                                      threadCo ntext.setS tartTime(  new Long(S ystem.curr entTimeMil lis()) );
  653                                      if(isChi ldCommand( ))
  654                                      {
  655                                               if(getPare ntCommandI dentifier( ) != null)
  656                                               {
  657                                                       th readContex t.setParen tCommandId (getParent CommandIde ntifier(). toString() );
  658                                               }
  659                                               else
  660                                               {
  661                                                       ge tLogger(). warn("comm and is a c hild comma nd but par entCommand Id is null , this sho uld never  happen..." );
  662                                               }
  663                                      }
  664                             }
  665                    }
  666                    
  667                    Asyn chronousCo mmandResul t<R> async hResult =  null;
  668                    try
  669                    {
  670                             setLis tenerNotif ication();
  671                             result  = callSyn chronously InTransact ionContext ();
  672                             asynch Result = n ew Asynchr onousComma ndResult<R >(this, re sult);
  673                    }
  674                    catc h(Composit eMethodExc eption cmX )
  675                    {
  676                             String Builder sb  = new Str ingBuilder ();
  677                             sb.app end( "Task  [" + thre adContext. getRequest Type() + " -" + threa dContext.g etChildReq uestType()  + "]");
  678                             sb.app end( "comp leted with  composite  exception , details  follow.\n" );
  679                             getLog ger().erro r(sb.toStr ing());
  680                             
  681                             asynch Result = n ew Asynchr onousComma ndResult<R >(this, cm X);
  682                    }
  683                    catc h(Throwabl e t)
  684                    {
  685                             t.prin tStackTrac e();
  686                             getLog ger().info ("Task ["  + threadCo ntext.getR equestType () + "-" +  threadCon text.getCh ildRequest Type() + " ] complete d with dec lared exce ption.");        
  687                             asynch Result = n ew Asynchr onousComma ndResult<R >(this, t) ;
  688                    }
  689                    fina lly
  690                    {
  691                             if(thr eadContext  == null)
  692                             {
  693                                      getLogge r().error( "PANIC - t ransaction  context h as been lo st !, logg ed transac tion infor mation is  cursory.") ;
  694                                      threadCo ntext = Tr ansactionC ontextFact ory.get();
  695                                      threadCo ntext.setC ommandClas sName(this .getClass( ).getSimpl eName());
  696                                      threadCo ntext.setV ixSoftware Version (g etCommandC ontext().g etRouter() .getAppCon figuration ().getVixS oftwareVer sion ());
  697                             }
  698                             
  699                             if(thr eadContext .getStartT ime() == n ull)
  700                             {
  701                                      getLogge r().error( "PANIC - T ransaction  context s tart time  was not se t.");
  702                                      threadCo ntext.setD uration( n ew Long(0L ) );
  703                             }
  704                             else i f(isChildC ommand())
  705                             {
  706                                      long dur ation = Sy stem.curre ntTimeMill is() - thr eadContext .getStartT ime().long Value();
  707                                      threadCo ntext.setD uration( n ew Long(du ration) );
  708                             }
  709                             
  710                             if(asy nchResult. getThrowab le() != nu ll)
  711                             {
  712                                      threadCo ntext.setE xceptionCl assName(as ynchResult .getExcept ion().getC lass().get SimpleName ());
  713                                      threadCo ntext.setE rrorMessag e(asynchRe sult.getEx ception(). getMessage ());
  714                             }
  715                             
  716                             // for  the momen t don't ca re if it w as success ful or not , just log  it
  717                             getLog ger().info (
  718                                      "Task ["  + threadC ontext.get CommandCla ssName() +  "-" + 
  719                                      this.get CommandIde ntifier()  +
  720                                      (isChild Command()  ? ("->" +  this.getPa rentComman dIdentifie r() ): "")  + 
  721                                      "] compl eted, writ ing transa ction log  entry."
  722                             );       
  723                             
  724                             try
  725                             {
  726                                      if (getC ommandCont ext() != n ull){
  727                                               getCommand Context(). getTransac tionLogger Service(). writeLogEn try(new Tr ansactionC ontextLogE ntrySnapsh ot(Transac tionContex tFactory.g et()));
  728                                      }
  729                             }
  730                             catch  (Exception  x) 
  731                             {
  732                                      StringBu ilder sb =  new Strin gBuilder() ;
  733                                      StackTra ceElement[ ] stackTra ce = x.get StackTrace ();
  734                                      if(stack Trace != n ull && sta ckTrace.le ngth > 0)
  735                                      {
  736                                               sb.append(  x.getMess age() );
  737                                               sb.append(  '@' );
  738                                               sb.append(  stackTrac e[0].getFi leName() ) ;
  739                                               sb.append(  '[' );
  740                                               sb.append(  stackTrac e[0].getLi neNumber()  );
  741                                               sb.append(  ']' );
  742                                              
  743                                               getLogger( ).error (s b.toString (), x);
  744                                      }
  745                                      else
  746                                               getLogger( ).error (x );
  747                             }
  748  
  749                             // cal lback to t he Command Processor,  used by t he retryab le command s
  750                             // to  decrement  its remain ing retry  count
  751                             comman dProcessin gComplete( );
  752  
  753                             // sav e the tran saction co ntext so a ny changes  made are  preserved
  754                             this.t ransaction ContextMem ento = thr eadContext .getMement o();
  755                             // res tore the t ransaction  context
  756                             Transa ctionConte xtFactory. popTransac tionContex t();
  757                    }
  758                    
  759                    retu rn asynchR esult;
  760       }
  761           
  762           /* *
  763            *  A method  that may b e overridd en by deri ved classe s to recei ve notific ation
  764            *  that the  command ha s run, whi le the tra nsaction c ontext is  still set  correctly.
  765            *  This is u sed by the  Retryable  commands  to track t he executi on attempt s. 
  766            *  In this i mplementat ion it doe s nothing.
  767            *  Retryable  commands  may turn o ff listene r notifica tion if th e
  768            *  command f ailed and  it will be  retried.
  769            *  This flag  is always  set befor e the comm and is exe cuted and  checked im mediately
  770            *  before th e listener s are noti fied.
  771            *  Derived c lasses may  call rese tListenerN otificatio n() in its  commandCo mpletionNo tification ()
  772            *  method if  the liste ners shoul d not be n otified
  773            * /
  774           pr otected vo id command Processing Complete()
  775           {
  776                    
  777           }
  778  
  779           /* *
  780            *  Notify th e command  completion  listeners  that the  command ha s complete d.
  781            *  This meth od is call ed while t he Transac tionContex t is set c orrectly s o that
  782            *  listeners  may opera te in that  context.
  783            *  @param re sult 
  784            * /
  785           pr ivate void  notifyLis teners(Asy nchronousC ommandResu lt<R> resu lt)
  786           {
  787                    for(  Asynchron ousCommand ResultList ener<R> li stener : l isteners )
  788                             listen er.command Complete(r esult);
  789           }
  790           
  791           /* *
  792            *  This meth od execute s the comm and synchr onously an d assumes  that the t ransaction
  793            *  context i s correctl y set.  
  794            *  For a typ ical synch ronous cal l (on a To mcat HTTP  thread) th is method  may be cal led direct ly.
  795            *  For an as ynchronous  call the  call() met hod will b e invoked  by the com mand execu tor,
  796            *  which wil l set the  transactio n context,  call this  method, w rap the re sult in a
  797            *  Asynchron ousCommand Result ins tance and  notify lis teners.
  798            *  
  799            *  @return
  800            *  @throws E xception
  801            * /
  802           pu blic abstr act R call Synchronou slyInTrans actionCont ext()
  803           th rows Metho dException , Connecti onExceptio n;
  804           
  805           //  ========= ========== ========== ========== ========== ========== ========== ========
  806           //  Scheduled PriorityQu eueElement  implement ation
  807           //  ========= ========== ========== ========== ========== ========== ========== ========
  808           
  809           @O verride
  810       public  Date getA ccessibili tyDate()
  811       {
  812                return a ccessibili tyDate;
  813       }
  814  
  815  
  816           @O verride
  817       public  Priority  getPriorit y()
  818       {
  819                return p riority;
  820       }
  821  
  822  
  823           @O verride
  824       public  Date getP rocessingC ommencemen tTargetDat e()
  825       {
  826                return p rocessingT argetComme ncementDat e;
  827       }
  828  
  829  
  830           @O verride
  831       public  long getP rocessingD urationEst imate()
  832       {
  833                return p rocessingD urationEst imate;
  834       }
  835  
  836           /* *
  837            *  @param ac cessibilit yDate the  accessibil ityDate to  set
  838            * /
  839           pu blic void  setAccessi bilityDate (Date acce ssibilityD ate)
  840           {
  841                    this .accessibi lityDate =  accessibi lityDate;
  842           }
  843  
  844           /* *
  845            *  @param pr iority the  priority  to set
  846            * /
  847           pu blic void  setPriorit y(int ordi nal)
  848           {
  849                    this .priority  = Priority .valueOfNo rmalized(o rdinal);
  850           }
  851  
  852           /* *
  853            *  @param pr ocessingDu rationEsti mate the p rocessingD urationEst imate to s et
  854            * /
  855           pu blic void  setProcess ingDuratio nEstimate( long proce ssingDurat ionEstimat e)
  856           {
  857                    this .processin gDurationE stimate =  processing DurationEs timate;
  858           }
  859  
  860           /* *
  861            *  @return t he process ingTargetC ommencemen tDate
  862            * /
  863           Da te getProc essingTarg etCommence mentDate()
  864           {
  865                    retu rn this.pr ocessingTa rgetCommen cementDate ;
  866           }
  867  
  868           /* *
  869            *  @param pr ocessingTa rgetCommen cementDate  the proce ssingTarge tCommencem entDate to  set
  870            * /
  871           vo id setProc essingTarg etCommence mentDate(D ate proces singTarget Commenceme ntDate)
  872           {
  873                    this .processin gTargetCom mencementD ate = proc essingTarg etCommence mentDate;
  874           }
  875  
  876           /* *
  877            *  Force der ived class es to defi ne a meani ngful equa ls() metho d.
  878            *  The resul t of the . equals() m ethod MUST  follow th e semantic s defined
  879            *  in the co re Java AP I and must :
  880            *  1.) for i dempotent  commands m ust return  .equals()  when the  type and t he paramet ers of the  command a re equals,  or
  881            *      the r esults of  the comman d are expe cted to be  equal ass uming no c hange in s tate of th e source d ata
  882            *  2.) for m ethods tha t are NOT  idempotent  (logging,  etc...) t he .equals () must ne ver return  true
  883            *    
  884            *  @see java .lang.Obje ct#equals( java.lang. Object)
  885            * /
  886       @Overr ide
  887       public  abstract  boolean eq uals(Objec t obj);
  888  
  889       /**
  890        * A s imple gene ric toStri ng() imple mentation  to make de bugging an d manageme nt easier.
  891        *  
  892        * @se e java.lan g.Object#t oString()
  893        */
  894       @Overr ide
  895       public  String to String()
  896       {
  897           St ringBuffer  sb = new  StringBuff er();
  898           sb .append(ge tClass().g etSimpleNa me());
  899           sb .append("[ ");
  900           sb .append(ge tClass().g etSimpleNa me());
  901           sb .append("( ");
  902           sb .append(pa rameterToS tring());
  903           sb .append(") ]");
  904           re turn sb.to String(); 
  905       }
  906       
  907       /**
  908        * Jus t used for  producing  a meaning ful toStri ng() resul t
  909        * @re turn
  910        */
  911       protec ted abstra ct String  parameterT oString();
  912  
  913           /*  (non-Java doc)
  914            *  @see gov. va.med.ima ging.core. interfaces .router.Co mmand#setP arentComma ndIdString (java.lang .String)
  915            * /
  916           @O verride
  917           pu blic void  setParentC ommandIdSt ring(Strin g parentCo mmandId) 
  918           {
  919                    if(p arentComma ndId != nu ll)                       
  920                             setPar entCommand Identifier (new GUID( parentComm andId));
  921                    else
  922                             getLog ger().warn ("Setting  null paren t command  Id String,  this shou ldn't happ en!");
  923           }
  924  
  925           @O verride
  926           pu blic boole an isPerio dicProcess ingTermina ted()
  927           {
  928                    retu rn periodi cProcessin gTerminate d;
  929           }
  930  
  931           @O verride
  932           pu blic void  setPeriodi cProcessin gTerminate d(
  933                             boolea n periodic Processing Terminated )
  934           {
  935                    this .periodicP rocessingT erminated  = periodic Processing Terminated ;
  936           }
  937  
  938           pr otected vo id rethrow IfFatalExc eption(Exc eption e)  throws Met hodExcepti on 
  939           {
  940                    if ( e instance of MethodE xception)
  941                    {
  942                             // We  need to re throw Inva lidUserCre dentialsEx ception if  that was  the cause  of the err or.
  943                             // Thi s will all ow the per iodic comm and to be  shut down  gracefully .
  944                             if (ge tFatalPeri odicExcept ionClasses ().contain s(e.getCla ss()))
  945                             {
  946                                      throw (M ethodExcep tion)e;
  947                             }
  948                    }
  949           }
  950  
  951  
  952   }