Produced by Araxis Merge on 4/5/2017 4:21:45 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.
| # | Location | File | Last Modified |
|---|---|---|---|
| 1 | C:\working_scrub\Unredacted\eHX Code Base\eHX_Bld2_Source Code_CIF_2017-02-14\NHIN_adapter\AdapterEJB\src\main\java\gov\va\med\nhin\adapter\policyengine | AdapterPolicyEngine.java | Fri Feb 10 15:41:44 2017 UTC |
| 2 | eHX-CIF.zip\eHX-CIF\eHX Code Base\eHX_Bld2_Source Code_CIF_2017-02-14\NHIN_adapter\AdapterEJB\src\main\java\gov\va\med\nhin\adapter\policyengine | AdapterPolicyEngine.java | Mon Apr 3 14:23:28 2017 UTC |
| Description | Between Files 1 and 2 |
|
|---|---|---|
| Text Blocks | Lines | |
| Unchanged | 2 | 714 |
| Changed | 1 | 2 |
| Inserted | 0 | 0 |
| Removed | 0 | 0 |
| 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 |
No regular expressions were active.
| 1 | package go v.va.med.n hin.adapte r.policyen gine; | |
| 2 | ||
| 3 | import gov .hhs.fha.n hinc.commo n.nhinccom mon.Assert ionType; | |
| 4 | import gov .hhs.fha.n hinc.commo n.nhinccom mon.Person NameType; | |
| 5 | import gov .hhs.fha.n hinc.commo n.nhinccom monadapter .CheckPoli cyRequestT ype; | |
| 6 | import gov .hhs.fha.n hinc.commo n.nhinccom monadapter .CheckPoli cyResponse Type; | |
| 7 | import gov .va.med.nh in.adapter .audit.Aud it; | |
| 8 | import gov .va.med.nh in.adapter .audit.Aud itManager; | |
| 9 | import gov .va.med.nh in.adapter .audit.Aud itManagerL ocal; | |
| 10 | import gov .va.med.nh in.adapter .datamanag er.DataMan ager; | |
| 11 | import gov .va.med.nh in.adapter .datamanag er.DataQue ry; | |
| 12 | import gov .va.med.nh in.adapter .datamanag er.ejb.Dat aManagerLo cal; | |
| 13 | import gov .va.med.nh in.adapter .documentr epository. Document; | |
| 14 | import gov .va.med.nh in.adapter .documentr epository. DocumentRe pository; | |
| 15 | import gov .va.med.nh in.adapter .documentr epository. DocumentRe positoryLo cal; | |
| 16 | import gov .va.med.nh in.adapter .facilitym anager.Fac ilityManag er; | |
| 17 | import gov .va.med.nh in.adapter .facilitym anager.Fac ilityManag erLocal; | |
| 18 | import gov .va.med.nh in.adapter .policyeng ine.pdppro xy.PDPProx y; | |
| 19 | import gov .va.med.nh in.adapter .policyeng ine.pdppro xy.PDPProx yLocal; | |
| 20 | import gov .va.med.nh in.adapter .propertyl ookup.Prop ertyLookup ; | |
| 21 | import gov .va.med.nh in.adapter .propertyl ookup.Prop ertyLookup Local; | |
| 22 | import gov .va.med.nh in.adapter .utils.Nul lChecker; | |
| 23 | ||
| 24 | import jav a.util.Dat e; | |
| 25 | import jav a.util.Lis t; | |
| 26 | import jav a.util.Map ; | |
| 27 | ||
| 28 | import jav ax.ejb.EJB ; | |
| 29 | import jav ax.ejb.Sta teless; | |
| 30 | import jav ax.jws.Web Service; | |
| 31 | ||
| 32 | import org .slf4j.Log ger; | |
| 33 | import org .slf4j.Log gerFactory ; | |
| 34 | ||
| 35 | import oas is.names.t c.xacml._2 _0.context .schema.os .ActionTyp e; | |
| 36 | import oas is.names.t c.xacml._2 _0.context .schema.os .Attribute Type; | |
| 37 | import oas is.names.t c.xacml._2 _0.context .schema.os .Attribute ValueType; | |
| 38 | import oas is.names.t c.xacml._2 _0.context .schema.os .RequestTy pe; | |
| 39 | import oas is.names.t c.xacml._2 _0.context .schema.os .ResourceT ype; | |
| 40 | import oas is.names.t c.xacml._2 _0.context .schema.os .ResponseT ype; | |
| 41 | import oas is.names.t c.xacml._2 _0.context .schema.os .SubjectTy pe; | |
| 42 | ||
| 43 | /** | |
| 44 | * | |
| 45 | * @author David Vaz quez | |
| 46 | * | |
| 47 | * inputs ch eckPolicyR equest | |
| 48 | * | |
| 49 | * returns b oolean tru e authoriz ed => Deci sionType.P ERMIT fals e not | |
| 50 | * authorize d => Decis ionType.DE NY | |
| 51 | * | |
| 52 | * if the pa ssed in IC N from the request i s found in the OPTED IN patient | |
| 53 | * list then they are authorized | |
| 54 | * | |
| 55 | * | |
| 56 | */ | |
| 57 | // No need for this to be a we b service right now. | |
| 58 | //@WebServ ice(servic eName = "A dapterPoli cyEngine", portName = "Adapter PolicyEngi nePortSoap ", endpoin tInterface = "gov.hh s.fha.nhin c.adapterp olicyengin e.AdapterP olicyEngin ePortType" , targetNa mespace = "urn:gov:h hs:fha:nhi nc:adapter policyengi ne", wsdlL ocation = "META-INF/ wsdl/Adapt erPolicyEn gine.wsdl" ) | |
| 59 | @Stateless (name = "A dapterPoli cyEngine") | |
| 60 | public cla ss Adapter PolicyEngi ne impleme nts Adapte rPolicyEng inePortTyp eLocal | |
| 61 | { | |
| 62 | pr ivate stat ic Logger logger = L oggerFacto ry.getLogg er(Adapter PolicyEngi ne.class.g etName()); | |
| 63 | ||
| 64 | st atic priva te final S tring ACTI ON_ATTRIBU TE_ID = "u rn:oasis:n ames:tc:xa cml:1.0:ac tion:actio n-id"; | |
| 65 | st atic priva te final S tring RESO URCE_ATTRI BUTE_ID = "urn:oasis :names:tc: xacml:1.0: resource:r esource-id "; | |
| 66 | st atic priva te final S tring RESO URCE_DOCUM ENT_ATTRIB UTE_ID = " urn:gov:hh s:fha:nhin c:document -id"; | |
| 67 | st atic priva te final S tring RESO URCE_HOME_ COMMUNITY_ ATTRIBUTE_ ID = "urn: gov:hhs:fh a:nhinc:ho me-communi ty-id"; | |
| 68 | ||
| 69 | pr ivate Prop ertyLookup propertyL ookup; | |
| 70 | pr ivate Docu mentReposi tory docum entReposit ory; | |
| 71 | pr ivate Audi tManager a uditManage r; | |
| 72 | pr ivate Faci lityManage r facility Manager; | |
| 73 | pr ivate PDPP roxy pdpPr oxy; | |
| 74 | pr ivate Data Manager da taManager; | |
| 75 | ||
| 76 | @E JB(beanInt erface = D ocumentRep ositoryLoc al.class, beanName = "Document Repository ") | |
| 77 | pu blic void setDocumen tRepositor y(Document Repository documentR epository) | |
| 78 | { | |
| 79 | this .documentR epository = document Repository ; | |
| 80 | } | |
| 81 | ||
| 82 | @E JB(beanInt erface = P ropertyLoo kupLocal.c lass, bean Name = "Pr opertyLook up") | |
| 83 | pu blic void setPropert yLookup(Pr opertyLook up propert yLookup) | |
| 84 | { | |
| 85 | this .propertyL ookup = pr opertyLook up; | |
| 86 | } | |
| 87 | ||
| 88 | @E JB(beanInt erface = F acilityMan agerLocal. class, bea nName = "F acilityMan ager") | |
| 89 | pu blic void setFacilit yManager(F acilityMan ager facil ityManager ) | |
| 90 | { | |
| 91 | this .facilityM anager = f acilityMan ager; | |
| 92 | } | |
| 93 | ||
| 94 | @E JB(beanInt erface = A uditManage rLocal.cla ss, beanNa me = "Audi tManager") | |
| 95 | pu blic void setAuditMa nager(Audi tManager a uditManage r) | |
| 96 | { | |
| 97 | this .auditMana ger = audi tManager; | |
| 98 | } | |
| 99 | ||
| 100 | @E JB(beanInt erface = P DPProxyLoc al.class, beanName = "PDPProxy VAP") | |
| 101 | pu blic void setPdpProx y(PDPProxy pdpProxy) | |
| 102 | { | |
| 103 | this .pdpProxy = pdpProxy ; | |
| 104 | } | |
| 105 | ||
| 106 | @E JB(beanInt erface = D ataManager Local.clas s, beanNam e = "DataM anager") | |
| 107 | pu blic void setDataMan ager(DataM anager dat aManager) | |
| 108 | { | |
| 109 | this .dataManag er = dataM anager; | |
| 110 | } | |
| 111 | ||
| 112 | pu blic Check PolicyResp onseType c heckPolicy (CheckPoli cyRequestT ype checkP olicyReque st) | |
| 113 | { | |
| 114 | logg er.debug(" checkPolic y() reques t {}", che ckPolicyRe quest); | |
| 115 | ||
| 116 | Requ estType re questType = checkPol icyRequest .getReques t(); | |
| 117 | Stri ng action = extractV alueFromAc tion(reque stType.get Action(), ACTION_ATT RIBUTE_ID) ; | |
| 118 | ||
| 119 | if(a ction.equa lsIgnoreCa se("Docume ntRetrieve In")) | |
| 120 | { | |
| 121 | fixRes ources(req uestType); | |
| 122 | } | |
| 123 | ||
| 124 | // F IXME - use next 4 li nes in DEV until con nection is sue is | |
| 125 | // r esolved... and need t o comment out the pd pProxy.che ckPolicy l ine when | |
| 126 | // d eploying t o DEV. | |
| 127 | // E rror snipp et: "...bu t could no t connect over HTTP to server: | |
| 128 | // 'labws. iam. DNS ', port: ' 80'" | |
| 129 | ||
| 130 | // R esponseTyp e response = new Res ponseType( ); | |
| 131 | // R esultType policyResu lt = new R esultType( ); | |
| 132 | // p olicyResul t.setDecis ion(Decisi onType.PER MIT); | |
| 133 | // r esponse.ge tResult(). add(policy Result); | |
| 134 | ||
| 135 | Resp onseType r esponse = pdpProxy.c heckPolicy (requestTy pe); | |
| 136 | ||
| 137 | gov. hhs.fha.nh inc.common .nhinccomm onadapter. ObjectFact ory objFac tory = new gov.hhs.f ha.nhinc.c ommon.nhin ccommonada pter.Objec tFactory() ; | |
| 138 | ||
| 139 | Chec kPolicyRes ponseType checkPolic yResponse = objFacto ry.createC heckPolicy ResponseTy pe(); | |
| 140 | chec kPolicyRes ponse.setR esponse(re sponse); | |
| 141 | ||
| 142 | // P D Audit Re port - Beg in | |
| 143 | if(a ction.equa lsIgnoreCa se("Patien tDiscovery Out") || a ction.equa lsIgnoreCa se("Patien tDiscovery In")) | |
| 144 | { | |
| 145 | ||
| 146 | Audit audit = ne w Audit(); | |
| 147 | audit. setAction( "CheckPoli cy"); | |
| 148 | audit. setAuditTi me(new Dat e()); | |
| 149 | audit. setPatient Id(extract ValueFromR esource(re questType. getResourc e().get(0) , RESOURCE _ATTRIBUTE _ID).subst ring(0, 17 )); | |
| 150 | ||
| 151 | DataQu ery query = dataMana ger.getQue ry("Compos ite.findDe mographics 2"); | |
| 152 | String icn = ext ractValueF romResourc e(requestT ype.getRes ource().ge t(0), RESO URCE_ATTRI BUTE_ID); | |
| 153 | query. setParamet er("icn", icn); | |
| 154 | List<M ap> result s = query. getResults (); | |
| 155 | if(!Nu llChecker. isNullOrEm pty(result s)) | |
| 156 | { | |
| 157 | Map resu lt = resul ts.get(0); | |
| 158 | Map demo graphics = (Map) res ult.get("d emographic s"); | |
| 159 | audit.se tPatientLa stName((St ring) demo graphics.g et("nameFa mily")); | |
| 160 | audit.se tPatientGi venName((S tring) dem ographics. get("nameG iven")); | |
| 161 | audit.se tPatientSS N((String) demograph ics.get("S SN")); | |
| 162 | audit.se tPatientFa cilityNumb er((String ) result.g et("patien tPreferred FacilityNu mber")); | |
| 163 | audit.se tPatientFa cilityName ((String) result.get ("patientP referredFa cilityName ")); | |
| 164 | } | |
| 165 | ||
| 166 | String organizat ion = null ; | |
| 167 | String demograph icDetails = "icn=" + extractVa lueFromRes ource(requ estType.ge tResource( ).get(0), RESOURCE_A TTRIBUTE_I D) + ", "; | |
| 168 | ||
| 169 | Assert ionType as sertion = checkPolic yRequest.g etAssertio n(); | |
| 170 | if(ass ertion != null) | |
| 171 | { | |
| 172 | ||
| 173 | if(asser tion.getHo meCommunit y() != nul l && !Null Checker.is NullOrEmpt y(assertio n.getHomeC ommunity() .getHomeCo mmunityId( ))) | |
| 174 | { | |
| 175 | organizati on = asser tion.getHo meCommunit y().getHom eCommunity Id(); | |
| 176 | } | |
| 177 | ||
| 178 | /* | |
| 179 | * Comme nted out f or now due to lack o f data if | |
| 180 | * (!Nul lChecker.i sNullOrEmp ty(asserti on.getSSN( ))) { | |
| 181 | * demog raphicDeta ils += "ss n=" + asse rtion.getS SN(); | |
| 182 | * demog raphicDeta ils += ", "; } else { demograp hicDetails += | |
| 183 | * "ssn= , "; } | |
| 184 | * | |
| 185 | * if (a ssertion.g etPersonNa me() != nu ll && | |
| 186 | * !Null Checker.is NullOrEmpt y(assertio n.getPerso nName(). | |
| 187 | * getFa milyName() )) { demog raphicDeta ils += "la stName=" + | |
| 188 | * asser tion.getPe rsonName() .getFamily Name(); de mographicD etails | |
| 189 | * += ", "; } else { demogra phicDetail s += "last Name=, "; } if | |
| 190 | * (asse rtion.getP ersonName( ) != null && | |
| 191 | * !Null Checker.is NullOrEmpt y(assertio n.getPerso nName(). | |
| 192 | * getGi venName()) ) { demogr aphicDetai ls += "fir stName=" + | |
| 193 | * asser tion.getPe rsonName() .getGivenN ame(); dem ographicDe tails | |
| 194 | * += ", "; } else { demogra phicDetail s += "firs tName=, "; } if | |
| 195 | * (!Nul lChecker.i sNullOrEmp ty(asserti on.getDate OfBirth()) ) { | |
| 196 | * demog raphicDeta ils += "do b=" + asse rtion.getD ateOfBirth (); | |
| 197 | * demog raphicDeta ils += ", "; } else { demograp hicDetails += | |
| 198 | * "dob= , "; } | |
| 199 | */ | |
| 200 | ||
| 201 | audit.se tUserId(as sertion.ge tUserInfo( ).getUserN ame()); | |
| 202 | audit.se tUserRole( assertion. getUserInf o().getRol eCoded().g etCode()); | |
| 203 | audit.se tPurposeFo rUse(asser tion.getPu rposeOfDis closureCod ed().getCo de()); | |
| 204 | audit.se tUserFacil ityNumber( assertion. getUserInf o().getOrg ().getHome CommunityI d()); | |
| 205 | audit.se tUserFacil ityName(as sertion.ge tUserInfo( ).getOrg() .getName() ); | |
| 206 | if(asser tion.getUs erInfo().g etPersonNa me() != nu ll) | |
| 207 | { | |
| 208 | PersonName Type perso nName = as sertion.ge tUserInfo( ).getPerso nName(); | |
| 209 | if(!NullCh ecker.isNu llOrEmpty( personName .getFullNa me())) | |
| 210 | { | |
| 211 | au dit.setUse rName(pers onName.get FullName() ); | |
| 212 | } | |
| 213 | else | |
| 214 | { | |
| 215 | St ringBuilde r userName = new Str ingBuilder (); | |
| 216 | ||
| 217 | if (NullCheck er.isNotNu llOrEmpty( personName .getGivenN ame())) | |
| 218 | { | |
| 219 | user Name.appen d(personNa me.getGive nName()); | |
| 220 | } | |
| 221 | ||
| 222 | if (NullCheck er.isNotNu llOrEmpty( personName .getFamily Name())) | |
| 223 | { | |
| 224 | if(u serName.le ngth() > 0 ) | |
| 225 | { | |
| 226 | userNa me.append( ' '); | |
| 227 | } | |
| 228 | ||
| 229 | user Name.appen d(personNa me.getFami lyName()); | |
| 230 | } | |
| 231 | ||
| 232 | au dit.setUse rName(user Name.toStr ing()); | |
| 233 | } | |
| 234 | } | |
| 235 | } | |
| 236 | ||
| 237 | // If Assertion Organizati on is empt y, assume VA | |
| 238 | if(Nul lChecker.i sNullOrEmp ty(organiz ation)) | |
| 239 | { | |
| 240 | organiza tion = fac ilityManag er.getFaci lityByFaci lityNumber ("VA").get FullHomeCo mmunityId( ); | |
| 241 | } | |
| 242 | audit. setOrganiz ationId(or ganization ); | |
| 243 | ||
| 244 | // PD Out Extern al Org | |
| 245 | String externalO rganizatio n = null; | |
| 246 | if(act ion.equals IgnoreCase ("PatientD iscoveryOu t")) | |
| 247 | { | |
| 248 | external Organizati on = "urn: oid:" + ex tractValue FromResour ce(request Type.getRe source().g et(0), RES OURCE_HOME _COMMUNITY _ATTRIBUTE _ID); | |
| 249 | } | |
| 250 | else | |
| 251 | { | |
| 252 | external Organizati on = facil ityManager .getFacili tyByFacili tyNumber(" VA").getFu llHomeComm unityId(); | |
| 253 | } | |
| 254 | audit. setRemoteO rganizatio nId(extern alOrganiza tion); | |
| 255 | ||
| 256 | // Get CheckPoli cy Decisio n | |
| 257 | String responseV alue = nul l; | |
| 258 | if(che ckPolicyRe sponse != null && ch eckPolicyR esponse.ge tResponse( ) != null && checkPo licyRespon se.getResp onse().get Result() ! = null && checkPolic yResponse. getRespons e().getRes ult().get( 0) != null && checkP olicyRespo nse.getRes ponse().ge tResult(). get(0).get Decision() != null & & !NullChe cker.isNul lOrEmpty(c heckPolicy Response.g etResponse ().getResu lt().get(0 ).getDecis ion().valu e())) | |
| 259 | { | |
| 260 | response Value = ch eckPolicyR esponse.ge tResponse( ).getResul t().get(0) .getDecisi on().value (); | |
| 261 | } | |
| 262 | ||
| 263 | // Bui ld Details Field | |
| 264 | String details = ""; | |
| 265 | if(!Nu llChecker. isNullOrEm pty(respon seValue)) | |
| 266 | { | |
| 267 | details += respons eValue + " "; | |
| 268 | } | |
| 269 | ||
| 270 | if(!Nu llChecker. isNullOrEm pty(action )) | |
| 271 | { | |
| 272 | details += action + " "; | |
| 273 | } | |
| 274 | ||
| 275 | if(!Nu llChecker. isNullOrEm pty(extern alOrganiza tion)) | |
| 276 | { | |
| 277 | details += "Remote Facility= " + extern alOrganiza tion + " " ; | |
| 278 | } | |
| 279 | ||
| 280 | if(!Nu llChecker. isNullOrEm pty(demogr aphicDetai ls)) | |
| 281 | { | |
| 282 | details += demogra phicDetail s + " "; | |
| 283 | } | |
| 284 | ||
| 285 | audit. setDetails (details); | |
| 286 | ||
| 287 | auditM anager.sto reAudit(au dit); | |
| 288 | } | |
| 289 | ||
| 290 | // P D Audit Re port - End | |
| 291 | ||
| 292 | retu rn checkPo licyRespon se; | |
| 293 | } | |
| 294 | ||
| 295 | pr ivate void fixResour ces(Reques tType requ estType) | |
| 296 | { | |
| 297 | for( ResourceTy pe resourc eType : re questType. getResourc e()) | |
| 298 | { | |
| 299 | String patientId = extract ValueFromR esource(re sourceType , RESOURCE _ATTRIBUTE _ID); | |
| 300 | ||
| 301 | if(Nul lChecker.i sNullOrEmp ty(patient Id)) | |
| 302 | { | |
| 303 | String d ocumentId = extractV alueFromRe source(res ourceType, RESOURCE_ DOCUMENT_A TTRIBUTE_I D); | |
| 304 | if(!Null Checker.is NullOrEmpt y(document Id)) | |
| 305 | { | |
| 306 | Document d ocument = documentRe pository.g etDocument ByDocument UniqueId(d ocumentId) ; | |
| 307 | if(documen t != null) | |
| 308 | { | |
| 309 | At tributeTyp e attribut e = new At tributeTyp e(); | |
| 310 | at tribute.se tAttribute Id(RESOURC E_ATTRIBUT E_ID); | |
| 311 | ||
| 312 | At tributeVal ueType att ributeValu e = new At tributeVal ueType(); | |
| 313 | at tributeVal ue.getCont ent().add( qualifyPat ientId(doc ument.getP atientId() )); | |
| 314 | at tribute.ge tAttribute Value().ad d(attribut eValue); | |
| 315 | ||
| 316 | re sourceType .getAttrib ute().add( attribute) ; | |
| 317 | } | |
| 318 | } | |
| 319 | } | |
| 320 | } | |
| 321 | } | |
| 322 | ||
| 323 | pr ivate Stri ng extract ValueFromA ction(Acti onType act ionType, S tring key) | |
| 324 | { | |
| 325 | retu rn extract ValueFromA ttributes( actionType .getAttrib ute(), key ); | |
| 326 | } | |
| 327 | ||
| 328 | pr ivate Stri ng extract ValueFromS ubject(Sub jectType s ubjectType , String k ey) | |
| 329 | { | |
| 330 | retu rn extract ValueFromA ttributes( subjectTyp e.getAttri bute(), ke y); | |
| 331 | } | |
| 332 | ||
| 333 | pr ivate Stri ng extract ValueFromR esource(Re sourceType resourceT ype, Strin g key) | |
| 334 | { | |
| 335 | retu rn extract ValueFromA ttributes( resourceTy pe.getAttr ibute(), k ey); | |
| 336 | } | |
| 337 | ||
| 338 | pr ivate Stri ng extract ValueFromA ttributes( List<Attri buteType> attributes , String k ey) | |
| 339 | { | |
| 340 | Stri ng ret = n ull; | |
| 341 | ||
| 342 | for( AttributeT ype attrib ute : attr ibutes) | |
| 343 | { | |
| 344 | if(att ribute != null && at tribute.ge tAttribute Id() != nu ll && attr ibute.getA ttributeId ().equalsI gnoreCase( key) && !N ullChecker .isNullOrE mpty(attri bute.getAt tributeVal ue()) && ! NullChecke r.isNullOr Empty(attr ibute.getA ttributeVa lue().get( 0)) && !Nu llChecker. isNullOrEm pty(attrib ute.getAtt ributeValu e().get(0) .getConten t())) | |
| 345 | { | |
| 346 | ret = at tribute.ge tAttribute Value().ge t(0).getCo ntent().ge t(0).toStr ing(); | |
| 347 | break; | |
| 348 | } | |
| 349 | } | |
| 350 | ||
| 351 | retu rn ret; | |
| 352 | } | |
| 353 | ||
| 354 | pr ivate Stri ng qualify PatientId( String icn ) | |
| 355 | { | |
| 356 | retu rn "'" + i cn + "^^^& " + proper tyLookup.g etProperty ("HomeComm unityId") + "&ISO'"; | |
| 357 | } | |
| 358 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.