266. EPMO Open Source Coordination Office Redaction File Detail Report

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

266.1 Files compared

# Location File Last Modified
1 IV-eHMP_CIF.zip\IMAG_Source\VISA\Java\ImagingCommon\main\src\java\gov\va\med URN.java Mon Dec 4 21:34:16 2017 UTC
2 IV-eHMP_CIF.zip\IMAG_Source\VISA\Java\ImagingCommon\main\src\java\gov\va\med URN.java Mon Dec 4 22:01:51 2017 UTC

266.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 1864
Changed 1 2
Inserted 0 0
Removed 0 0

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

266.4 Active regular expressions

No regular expressions were active.

266.5 Comparison detail

  1   package go v.va.med;
  2  
  3   import gov .va.med.im aging.exce ptions.Ima geURNForma tException ;
  4   import gov .va.med.im aging.exce ptions.URN FormatExce ption;
  5   import gov .va.med.im aging.exch ange.utili ty.Base32;
  6   import gov .va.med.im aging.exch ange.utili ty.Base32C onversionU tility;
  7   import jav a.io.Seria lizable;
  8   import jav a.net.URI;
  9   import jav a.net.URIS yntaxExcep tion;
  10   import jav a.util.Arr ays;
  11   import jav a.util.reg ex.Matcher ;
  12   import jav a.util.reg ex.Pattern ;
  13   import org .apache.lo gging.log4 j.LogManag er;
  14   import org .apache.lo gging.log4 j.Logger;
  15  
  16   /**
  17    * @author         
BECKEC
  18    * 
  19    * An impl ementation  of URN th at is cons istent wit h RFC 2141 .
  20    * @see ht tp://www.i etf.org/rf c/rfc2141. txt
  21    * 
  22    * NOTICE:  Please re ad the com ments on e ach of the  construct ors.  This  class, an d its deri vatives
  23    * are cre ated both  by a stati c factory  within thi s class an d directly  by static  create me thods or
  24    * "new" i nstantiati ons.  The  static fac tory requi res a spec ific const ructor and  expects c ertain
  25    * behavio r within t hat constr uctor.
  26    * 
  27    * This cl ass is the  superclas s of the " opaque" id entifiers  which are  presented  to the out side world  (the DOD) .
  28    * This cl ass is res ponsible f or parsing  and build ing the ge neric URN  portion of  a imaging  URN.
  29    * Subclas ses (Image  and Study ) provide  the Namesp ace-Specif ic-String  (NSS) pars ing and in terpretati on.
  30    * This cl ass does c ontain hel per method s (Pattern  instances , etc) whe re the NSS  interpret ation is s imilar
  31    * between  subclasse s, but thi s should n ot be cons trued as m eaning tha t this cla ss is resp onsible fo r the
  32    * semanti cs of the  NSS.
  33    * 
  34    * The out side world  must get  only the S tring repr esentation  of this c lass (and  its subcla sses).  Th e toString ()
  35    * method  is overrid den in thi s class in  a way tha t should p roduce a p roper, par sable URN  representa tion for 
  36    * subclas ses.
  37    * 
  38    * This cl ass and al l derivati ons implem ent an RFC 2141 compl iant URN.   The defau lt behavio r of all c lasses
  39    * is to f ollow RFC2 141 the sp ecificatio n.  The in ternal sto rage of th e URN comp onents mus t be in co mplaint
  40    * format  and the to String() a nd parsing  functions  must also  operate i n a RFC214 1 complian t manner.
  41    * 
  42    *   ===== ========== ========== ========== ========== ========== ========== ========== ========== ====
  43    *   From  RFC 2141 
  44    *   
  45    *   All U RNs have t he followi ng syntax  (phrases e nclosed in  quotes ar e REQUIRED ):
  46    *   
  47    *   <URN>  ::= "urn: " <NID> ": " <NSS>
  48    *   where  <NID> is  the Namesp ace Identi fier, and  <NSS> is t he Namespa ce Specifi c String.   
  49    *   The l eading "ur n:" sequen ce is case -insensiti ve. The Na mespace ID  determine
  50    *   the _ syntactic_  interpret ation of t he Namespa ce Specifi c String ( as discuss ed in [1]) .
  51    *   
  52    *   NID : := <let-nu m> [ 1,31< let-num-hy p> ]
  53    *   
  54    *   As re quired by  RFC 2141,  there is a  single ca nonical re presentati on of the  NSS portio
  55    *   of an  URN.   Th e format o f this sin gle canoni cal form f ollows:
  56    *   <NSS>          : := 1*<URN  chars>
  57    *   <URN  chars>   : := <trans>  | "%" <he x> <hex>
  58    *   <tran s>       : := <upper>  | <lower>  | <number > | <other > | <reser ved>
  59    *   <hex>          : := <number > | "A" |  "B" | "C"  | "D" | "E " | "F" |  "a" | "b"  | "c" | "d " | "e" |  "f"
  60    *   <othe r>       : := "(" | " )" | "+" |  "," | "-"  | "." | " :" | "=" |  "@" | ";"  | "$" | " _" | "!" |  "*" | "'"
  61    *   
  62    * from RF C 2141
  63    * "Depend ing on the  rules gov erning a n amespace,  valid iden tifiers in  a 
  64    * namespa ce might c ontain cha racters th at are not  members o f the URN
  65    * charact er set abo ve (<URN c hars>).  S uch string s MUST be  translated
  66    * into ca nonical NS S format b efore usin g them as  protocol e lements or
  67    * otherwi se passing  them on t o other ap plications . Translat ion is don e
  68    * by enco ding each  character  outside th e URN char acter set  as a
  69    * sequenc e of one t o six octe ts using U TF-8 encod ing, and t he
  70    * encodin g of each  of those o ctets as " %" followe d by two c haracters
  71    * from th e <hex> ch aracter se t above. T he two cha racters gi ve the
  72    * hexadec imal repre sentation  of that oc tet."
  73    * 
  74    * NOTE: I mplicitly  this means  that the  % characte r is an al lowable ch aracter
  75    * if it i s followed  by (2 to  8) hex dig its.
  76    * 
  77    * BIG NOT E: There i s a proble m here if  we ever ne eded to su pport char acters out side
  78    * the ASC II charact ers set (i .e. beyond  UTF-8 sin gle octet  encoding).   The prob lem is tha t
  79    * the reg ular expre ssion can' t determin e where an  encoded c haracter e nds if the  length
  80    * of the  octet sequ ence is no t fixed.   For exampl e "%20AC"  could be d ecoded as  a  either
  81    * " AC" ( i.e an ASC II space f ollowed by  "AC") or  as a euro  symbol (re presented  by octet
  82    * sequenc e %20AC.)   For the f oreseeable  future th is is not  an issue,  the regula
  83    * express ion assume s exactly  2 hex digi ts followi ng the per cent sign.
  84    * 
  85    *
  86    *   ===== ========== ========== ========== ========== ========== ========== ========== ========== ========== ========== ===
  87    *   Diffe rences fro m RFC-2141
  88    *   
  89    *   This  implementa tion also  allows up  to 5 addit ional iden tifiers to  be append ed to the  stringifie d represen tation
  90    *   of a  URN.  This  feature i s required  because t he VIX nee ds study a nd patient  identifie rs with im age URNs
  91    *   that  come from  the DoD.   The defaul t stringif ication of  a URN sho uld not in clude thes e addition al
  92    *   ident ifiers.
  93    *   
  94    *    Requ ired Strin gification  Methods
  95    *    toSt ring() - f orm a stri ngified fo rm of the  URN in RFC -2141 comp liant form
  96    *    toSt ringAsVAIn ternal() -  form a st ringified  representa tion with  the additi onal ident ifiers app ended
  97    *    toSt ringAsNati ve() - imp lementatio n dependen t, form a  stringifie d represen tation of  the URN in  a form
  98    *                           con sistent wi th that of  the sourc e system,  by default  this is t he same as  toString( )
  99    *    toSt ringAsBase 32() - sel ect portio ns of the  namespace  specific s tring may  be encoded  as Base32 , classes  overriding
  100    *                           thi s method M UST also p rovide a c reateFromB ase32() st atic facto ry method
  101    *    
  102    *    For  consistenc y in imple mentation,  the inter nal repres entation o f the name space spec ific strin g is alway s
  103    *    the  RFC2141 co mpliant fo rm.  Deriv ations tha t override  getNamesp aceSpecifi cString()  and parseN amespaceSp ecificStri ng
  104    *    stor e the comp onents use d to build  the NSS i ndividuall y. 
  105    *    
  106    *    Requ ired Facto ry, Constr uctor and  parsing me thods
  107    *    
  108    */
  109   public cla ss URN
  110   implements  Serializa ble
  111   {
  112           pr ivate stat ic final l ong serial VersionUID  = 1L;
  113           
  114           pr otected st atic final  OctetSequ enceEscapi ng RFC2141 _ESCAPING;
  115           pr otected st atic final  OctetSequ enceEscapi ng FILENAM E_ESCAPING ;
  116           pr otected st atic final  OctetSequ enceEscapi ng FILENAM E_TO_RFC21 41_ESCAPIN G;
  117           pr otected st atic final  OctetSequ enceEscapi ng CDTP_ES CAPING;
  118  
  119           //  a REGEX m atching on  a sequenc e of 1 or  more base  32 legal c haracters
  120       public  static fi nal String  BASE32_CO MPONENT_RE GEX = "["  + Base32.B ASE32_CHAR S + "]+";
  121  
  122           pu blic stati c final St ring urnCo mponentDel imiter = " :";                                             // the  delimiter  of the UR N componen ts
  123  
  124           //  a URI tha t starts w ith 'urn'  and follow s the URN  syntax is  a URN
  125           pu blic stati c final St ring urnSc hemaIdenti fier = "ur n";                                             // the  scheme na me that id entifies a  URI as a  URN
  126           pr otected st atic final  String ur nSchemaIde ntifierReg ex = "[uU] [rR][nN]";                  // b y URN defi nition, is  case inse nsitive
  127           pu blic stati c final Pa ttern urnS chemaIdent ifierPatte rn = Patte rn.compile (urnSchema Identifier Regex);
  128           
  129           //  NID is <l et-num> [  1,31<let-n um-hyp> ]
  130           pr otected st atic final  String ur nNamespace Identifier Regex = "[ a-zA-Z0-9] [a-zA-Z0-9 \\-]{0,31} ";
  131           pu blic stati c final Pa ttern urnN amespaceId entifierPa ttern = Pa ttern.comp ile(urnNam espaceIden tifierRege x);
  132  
  133           //  The chara cter sets,  regular e xpressions  and patte rns realiz ing the RF C 2141 NSS  definitio n
  134           //  of the na mespace sp ecific str ing.
  135           //  NOTE: if  the value  of RFC2141 _LEGAL_NSS _CHARSET c hanges the n the valu e of RFC21 41_LEGAL_N SS_CHARS
  136           //  must be m anually ch anged to m atch.
  137           pr otected st atic final  String RF C2141_LEGA L_NSS_CHAR SET = "a-z A-Z0-9\\(\ \)\\+,\\-\ \.:=@;$_!\ \*'";
  138           pr otected st atic final  String RF C2141_LEGA L_NSS_REGE X = "[" +  RFC2141_LE GAL_NSS_CH ARSET + "] *";
  139           pu blic stati c final Pa ttern RFC2 141_LEGAL_ NSS_PATTER N = Patter n.compile( RFC2141_LE GAL_NSS_RE GEX);
  140           pr otected st atic final  String RF C2141_ILLE GAL_NSS_RE GEX = "[^"  + RFC2141 _LEGAL_NSS _CHARSET +  "]*";
  141           pu blic stati c final Pa ttern RFC2 141_ILLEGA L_NSS_PATT ERN = Patt ern.compil e(RFC2141_ ILLEGAL_NS S_REGEX);
  142           
  143           //  The names pace speci fic string  allows an y characte r.  Portio ns of the  NSS that a re delimit ed with sq uare
  144           //  brackets  will be pa rsed as ad ditionalId entifiers.
  145           //  old stuff  -- "[a-zA -Z0-9\\(\\ )\\+,\\-\\ .\\^:=@;$_ !\\*'%[0-9 a-fA-F]{2, 2}]*";
  146           pr otected st atic final  String na mespaceSpe cificStrin gRegex = " [^\\[]*";
  147           pu blic stati c final Pa ttern name spaceSpeci ficStringP attern = P attern.com pile(names paceSpecif icStringRe gex);
  148           
  149           pr otected st atic final  String ap pendedIden tifierRege x = "[a-zA -Z0-9][a-z A-Z0-9\\(\ \)\\+,\\-\ \.:=@;$_!\ \*'%]*";
  150           pu blic stati c final Pa ttern appe ndedIdenti fierPatter n = Patter n.compile( appendedId entifierRe gex);
  151           
  152           //  Within a  namespace  specific s tring the  dash chara cter is co mmonly use d to delim it
  153           //  identifie r componen ts.  Addit ional comp onents, no t part of  the identi fier
  154           //  may be ad ded if del imited by  square bra ckets.
  155           pu blic stati c final ch ar namespa ceSpecific StringDeli miter = '- ';
  156           pu blic stati c final St ring names paceSpecif icStringDe limiterReg ex = "\\-" ;
  157           pu blic stati c final ch ar appende dIdentifie rStartDeli miter = '[ ';
  158           pu blic stati c final St ring appen dedIdentif ierStartDe limiterReg ex = "\\[" ;
  159           pu blic stati c final ch ar appende dIdentifie rEndDelimi ter = ']';
  160           pu blic stati c final St ring appen dedIdentif ierEndDeli miterRegex  = "\\]";
  161           
  162           //  Yeah, it  is kinda'  cheesy wit h the repe ated group , anyone t hat wants  to
  163           //  figure ou t how to d o repeatin g groups i n regex ma tching, ha ve at it.
  164           pr otected st atic final  String ap pendedIden tifiersReg ex =
  165                    "(?: " + 
  166                    "(?: " + append edIdentifi erStartDel imiterRege x + ")" +
  167                    "("  + appended Identifier Regex + ") " + 
  168                    "(?: " + append edIdentifi erEndDelim iterRegex  + ")" +
  169                    ")?"
  170                    "(?: " + 
  171                    "(?: " + append edIdentifi erStartDel imiterRege x + ")" +
  172                    "("  + appended Identifier Regex + ") " + 
  173                    "(?: " + append edIdentifi erEndDelim iterRegex  + ")" +
  174                    ")?"
  175                    "(?: " + 
  176                    "(?: " + append edIdentifi erStartDel imiterRege x + ")" +
  177                    "("  + appended Identifier Regex + ") " + 
  178                    "(?: " + append edIdentifi erEndDelim iterRegex  + ")" +
  179                    ")?"
  180                    "(?: " + 
  181                    "(?: " + append edIdentifi erStartDel imiterRege x + ")" +
  182                    "("  + appended Identifier Regex + ") " + 
  183                    "(?: " + append edIdentifi erEndDelim iterRegex  + ")" +
  184                    ")?"
  185                    "(?: " + 
  186                    "(?: " + append edIdentifi erStartDel imiterRege x + ")" +
  187                    "("  + appended Identifier Regex + ") " + 
  188                    "(?: " + append edIdentifi erEndDelim iterRegex  + ")" +
  189                    ")?" ;
  190           pu blic stati c final Pa ttern appe ndedIdenti fiersPatte rn = Patte rn.compile (appendedI dentifiers Regex);
  191           
  192           //  the strin gified for m of the N SS portion  with addi tional ide ntifiers,
  193           //  this is u sed by som e derived  classes to  parse NSS  strings b uilt inter nally
  194           pu blic final  static St ring exten dedNamespa ceSpecific StringRege x = 
  195                    "("  + namespac eSpecificS tringRegex  + ")" +
  196                    appe ndedIdenti fiersRegex ;
  197           
  198           pu blic final  static in t urnXnssC omponentGr oup = 1;                // the n amespace s pecific st ring i.e.  a VA image  identifie r
  199           pu blic final  static in t urnXnssA dditionalI dentifierC omponentGr oup1 = 2;  // the fir st of five  of additi onal ident ifiers
  200           pu blic final  static in t urnXnssA dditionalI dentifierC omponentGr oup2 = 3;  // the sec ond of fiv e of addit ional iden tifiers
  201           pu blic final  static in t urnXnssA dditionalI dentifierC omponentGr oup3 = 4;  // the thi rd of five  of additi onal ident ifiers
  202           pu blic final  static in t urnXnssA dditionalI dentifierC omponentGr oup4 = 5;  // the fou rth of fiv e of addit ional iden tifiers
  203           pu blic final  static in t urnXnssA dditionalI dentifierC omponentGr oup5 = 6;  // the fif th of five  of additi onal ident ifiers
  204           pu blic final  static in t URN_XNSS _MAX_ADDIT IONAL_IDEN TIFIER_GRO UPS = 5;
  205           
  206           pu blic final  static Pa ttern EXTE NDED_NSS_P ATTERN = P attern.com pile(exten dedNamespa ceSpecific StringRege x);
  207           
  208           //  e.g. of s tringified  form is:
  209           //  urn:vaima ge:111-222 -333-444[5 5-666][7-8 ][999-aaa]
  210           pu blic final  static St ring urnRe gex = 
  211                    "(?: " + urnSch emaIdentif ierRegex +  ")" + urn ComponentD elimiter +  
  212                    "("  + urnNames paceIdenti fierRegex  + ")" + ur nComponent Delimiter  +
  213                    exte ndedNamesp aceSpecifi cStringReg ex;
  214           pu blic final  static Pa ttern urnP attern = P attern.com pile(urnRe gex);
  215  
  216           //  once a st ring has b een parsed  the Match er makes t he compone nt pieces
  217           //  available  as groups  with the  following  indexes.
  218           //  Derived c lasses may  additiona lly parse  the namesp ace specif ic string,  that
  219           //  functiona lity is no t addresse d in this  class.
  220           pu blic final  static in t urnNames paceCompon entGroup =  1; // the  namespace  identifie r e.g. "va image"
  221           pu blic final  static in t urnNssCo mponentGro up = 1 + u rnXnssComp onentGroup ;                // t he namespa ce specifi c string i .e. a VA i mage ident ifier
  222           pu blic final  static in t urnAddit ionalIdent ifierCompo nentGroup1  = 1 + urn XnssAdditi onalIdenti fierCompon entGroup1;         //  the first  of N numb er of addi tional ide ntifiers
  223           pu blic final  static in t urnAddit ionalIdent ifierCompo nentGroup2  = 1 + urn XnssAdditi onalIdenti fierCompon entGroup2;         //  the first  of N numb er of addi tional ide ntifiers
  224           pu blic final  static in t urnAddit ionalIdent ifierCompo nentGroup3  = 1 + urn XnssAdditi onalIdenti fierCompon entGroup3;         //  the first  of N numb er of addi tional ide ntifiers
  225           pu blic final  static in t urnAddit ionalIdent ifierCompo nentGroup4  = 1 + urn XnssAdditi onalIdenti fierCompon entGroup4;         //  the first  of N numb er of addi tional ide ntifiers
  226           pu blic final  static in t urnAddit ionalIdent ifierCompo nentGroup5  = 1 + urn XnssAdditi onalIdenti fierCompon entGroup5;         //  the first  of N numb er of addi tional ide ntifiers
  227  
  228           st atic
  229           {
  230                    LogM anager.get Logger(URN .class).in fo("urnNam espaceIden tifierRege x = '" + u rnNamespac eIdentifie rRegex + " '");
  231                    LogM anager.get Logger(URN .class).in fo("namesp aceSpecifi cStringReg ex = '" +  namespaceS pecificStr ingRegex +  "'");
  232                    LogM anager.get Logger(URN .class).in fo("extend edNamespac eSpecificS tringRegex  = '" + ex tendedName spaceSpeci ficStringR egex + "'" );
  233                    LogM anager.get Logger(URN .class).in fo("urnReg ex = '" +  urnRegex +  "'");
  234  
  235                    RFC2 141_ESCAPI NG = Octet SequenceEs caping.cre ateRFC2141 EscapeEngi ne();
  236                    FILE NAME_ESCAP ING = Octe tSequenceE scaping.cr eateFilena meLegalEsc apeEngine( );
  237                    // F inally, cr eate an es caping eng ine for th ose charac ters that  are NOT fi lename
  238                    // l egal but a re RFC2141  legal.  T his will b e used to  convert NS S that hav e had file name
  239                    // e scaping ap plied to t hem back t o RFC2141  safe (i.e.  the inter nal) form.
  240                    FILE NAME_TO_RF C2141_ESCA PING = Oct etSequence Escaping.c reateRFC21 41toFilena meLegalEsc apeEngine( );
  241                    CDTP _ESCAPING  = OctetSeq uenceEscap ing.create CDTPEscape Engine();
  242           }
  243           
  244           /* *
  245            *  Simply re turns true  if the gi ven string  is the UR N schema i dentifier,
  246            *  that is ' urn' as a  non-case s ensitive m atch.
  247            *  
  248            *  @param sc hema
  249            * /
  250           pu blic stati c final bo olean isUr nSchemaIde ntifier(St ring schem a)
  251           {
  252                    retu rn Pattern .matches(u rnSchemaId entifierRe gex, schem a);
  253           }
  254           
  255           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== =====
  256           //  Instance  Members
  257           //  ========= ========== ========== ========== ========== ========== ========== ========== ========== =====
  258           pr ivate Name spaceIdent ifier name spaceIdent ifier;
  259           pr ivate Stri ng namespa ceSpecific String;
  260           pr ivate Stri ng[] addit ionalIdent ifiers;
  261           pr ivate tran sient Logg er logger  = null;
  262           
  263           /* *
  264            *  This cons tructor is  intended  for use by  a child c lass when  the
  265            *  child cla ss is bein g created  with the n amespace s pecific st ring
  266            *  in its co nstituent  parts. 
  267            *  e.g. new  ImageURN(s iteId, pat ientId, in stanceId,  modality);
  268            *  
  269            *  public Im ageURN(Str ing siteId , String p atientId,  String ins tanceId, S tring moda lity)
  270            *  throws UR NFormatExc eption
  271            *  {
  272            *                super(  new Names paceIdenti fier("vaim age") );
  273            *                this.s iteId = si teId;
  274            *       ...
  275            *  }
  276            *  
  277            *  Derived c lasses may  not use t he namespa ce specifi c string i f
  278            *  this cons tructor is  used, as  it is set  to null an d declared  final.
  279            *  The names pace speci fic compon ent must b e stored i n the deri ved class
  280            *  and the g etNamespac eSpecificS tring() me thod must  be overrid den.
  281            *  
  282            *  This cons tructor is  NOT REQUI RED by the  static fa ctory.
  283            *  This cons tructor sh ould not b e overridd en by clas ses that 
  284            *  are immut able and o paque (e.g . BHIE ide ntifiers).
  285            *  
  286            *  @param na mespaceIde ntifier
  287            *  @param na mespaceSpe cificStrin g
  288            *  @throws I mageURNFor matExcepti on 
  289            * /
  290           pr otected UR N(Namespac eIdentifie r namespac eIdentifie r) 
  291           th rows URNFo rmatExcept ion
  292           {
  293                    if(n amespaceId entifier = = null ||  namespaceI dentifier. getNamespa ce() == nu ll)
  294                             throw  new URNFor matExcepti on("Unable  to create  a URN wit h a null n amespace i dentifier. ");
  295                    
  296                    this .namespace Identifier  = namespa ceIdentifi er;
  297                    setN amespaceSp ecificStri ng(null);
  298                    this .additiona lIdentifie rs = null;
  299           }
  300           
  301           /* *
  302            *  Derived c lass that  have an un parsed nam espace spe cific stri ng, option ally, addi tional ide ntifiers
  303            *  can use t he storage  within th is class f or their m ember prop erty stora ge.
  304            *  
  305            *  @param na mespaceIde ntifier
  306            *  @param na mespaceSpe cificStrin g
  307            *  @param ad ditionalId entifiers
  308            *  @throws U RNFormatEx ception
  309            * /
  310           pr otected UR N(
  311                    Name spaceIdent ifier name spaceIdent ifier, 
  312                    Stri ng namespa ceSpecific String, 
  313                    Stri ng... addi tionalIden tifiers) 
  314           th rows URNFo rmatExcept ion
  315           {
  316                    if(n amespaceId entifier = = null ||  namespaceI dentifier. getNamespa ce() == nu ll)
  317                             throw  new URNFor matExcepti on("Unable  to create  a URN wit h a null n amespace i dentifier. ");
  318                    
  319                    this .namespace Identifier  = namespa ceIdentifi er;
  320                    pars eNamespace SpecificSt ring(names paceIdenti fier, name spaceSpeci ficString,  SERIALIZA TION_FORMA T.NATIVE);
  321                    this .additiona lIdentifie rs = addit ionalIdent ifiers;
  322           }
  323           
  324           /* *
  325            *  This cons tructor is  used by t he static  factory me thods with in this cl ass to
  326            *  create an  instance  of this cl ass after  parsing
  327            *  a string  into its U RN compone nts.
  328            *  This cons tructor sh ould be ov erridden b y derived  classes if
  329            *  the deriv ed class i s parsing  the namesp ace specif ic string  and is NOT
  330            *  using thi s classes  namespaceS pecificStr ing field  for storag e.
  331            *  
  332            *  e.g. Imag eURN image Urn = (Ima geURN)URN. create("ur n:vaimage: 66677-7766 -8877-9988 ");
  333            *  
  334            *  protected  URN(URNCo mponents u rnComponen ts)
  335            *  throws UR NFormatExc eption
  336            *  {
  337            *                super(  urnCompon ents );
  338            *                parseN amespaceSp ecificStri ng(urnComp onents.get NamespaceS pecificStr ing());
  339            *  }
  340            *  
  341            *  
  342            *  This cons tructor is  REQUIRED  by the sta tic factor y.
  343            *  Derived c lasses ove rriding th is constru ctor MUST  also overr ide
  344            *  the getNa mespaceSpe cificStrin g() method  if they d o not call  this
  345            *  construct or (i.e. s uper(URNCo mponents).
  346            *  
  347            *  @param ur nComponent s
  348            * /
  349           pr otected UR N(URNCompo nents urnC omponents,  SERIALIZA TION_FORMA T serializ ationForma t)
  350           th rows URNFo rmatExcept ion
  351           {
  352                    if(u rnComponen ts.getName spaceIdent ifier() ==  null || u rnComponen ts.getName spaceIdent ifier().ge tNamespace () == null )
  353                             throw  new URNFor matExcepti on("Unable  to create  a URN wit h a null n amespace i dentifier. ");
  354                    
  355                    this .namespace Identifier  = urnComp onents.get NamespaceI dentifier( );
  356                    // s et the add itional id entifiers  before par sing the n amespace s pecific
  357                    // s tring beca use some d erived cla sses may u se the val ues in the  additiona l
  358                    // i dentifiers  in the pa rsing
  359                    this .additiona lIdentifie rs = deser ializeAddi tionalIden tifiers(ur nComponent s.getAddit ionalIdent ifers(), s erializati onFormat);
  360                    pars eNamespace SpecificSt ring(urnCo mponents.g etNamespac eIdentifie r(), urnCo mponents.g etNamespac eSpecificS tring(), s erializati onFormat ) ;
  361           }
  362  
  363           /* *
  364            *  The "do-n othing" de fault impl ementation .  Derived  classes m ay overrid e to deser ialize the  additiona l
  365            *  identifie rs.
  366            *  This meth od is call ed immedia tely befor e parseNam espaceSpec ificString ().
  367            *  
  368            *  @param ad ditionalId entifers
  369            *  @param se rializatio nFormat
  370            *  @return
  371            * /
  372           pr otected St ring[] des erializeAd ditionalId entifiers(
  373                    Stri ng[] addit ionalIdent ifiers, 
  374                    SERI ALIZATION_ FORMAT ser ialization Format)
  375           {
  376                    retu rn additio nalIdentif iers;
  377           }
  378  
  379           /* *
  380            *  Return th e namespac e identifi er that th is URN was  created a s.
  381            *  Note that  namespace  identifie r is a fin al field a nd that
  382            *  it is req uired in a ll constru ctors.
  383            *  
  384            *  @return
  385            * /
  386           pu blic Names paceIdenti fier getNa mespaceIde ntifier()
  387           {
  388                    retu rn namespa ceIdentifi er;
  389           }
  390  
  391           /* *
  392            *  Return th e addition al identif iers as an  array of  String
  393            *  instances .
  394            *  
  395            *  @return
  396            * /
  397           pu blic Strin g[] getAdd itionalIde ntifiers()
  398           {
  399                    retu rn this.ad ditionalId entifiers;
  400           }
  401           
  402           /* *
  403            *  
  404            *  @param in dex
  405            *  @return
  406            * /
  407           pu blic Strin g getAddit ionalIdent ifier(int  index)
  408           {
  409                    retu rn 
  410                             this.a dditionalI dentifiers  == null | | this.add itionalIde ntifiers.l ength < in dex ?
  411                                      null :
  412                                      this.add itionalIde ntifiers[i ndex];
  413           }
  414  
  415           pr otected vo id setAddi tionalIden tifiers(St ring[] add itionalIde ntifiers)
  416           {
  417                    // a dd the add itional in dividually  and in-or der so tha t the 
  418                    // p rocessing  of their v alues in t he set is  executed
  419                    for( int index= 0; index <  additiona lIdentifie rs.length;  ++index)
  420                             setAdd itionalIde ntifier(in dex, addit ionalIdent ifiers[ind ex]);
  421           }
  422  
  423           /* *
  424            *  
  425            *  @param in dex
  426            *  @param ad ditionalId entifier
  427            * /
  428           pr otected vo id setAddi tionalIden tifier(int  index, St ring addit ionalIdent ifier)
  429           {
  430                    addi tionalIden tifier = U RN.RFC2141 _ESCAPING. escapeIlle galCharact ers(additi onalIdenti fier);
  431                    
  432                    if(  this.addit ionalIdent ifiers ==  null )
  433                    {
  434                             this.a dditionalI dentifiers  = new Str ing[index+ 1];
  435                             this.a dditionalI dentifiers [index] =  additional Identifier ;
  436                    }
  437                    else  if( index  >= this.a dditionalI dentifiers .length )
  438                    {
  439                             String [] temp =  new String [index + 1 ];
  440                             System .arraycopy (this.addi tionalIden tifiers, 0 , temp, 0,  this.addi tionalIden tifiers.le ngth);
  441                             temp[i ndex] = ad ditionalId entifier;
  442                             this.a dditionalI dentifiers  = temp;
  443                    }
  444                    else
  445                             this.a dditionalI dentifiers [index] =  additional Identifier ;
  446           }
  447  
  448           /* *
  449            *  Return th e addition al identif iers as a  square-bra cket delim ited
  450            *  concatena ted String .
  451            *  
  452            *  @return
  453            * /
  454           pu blic final  String ge tAdditiona lIdentifie rsString()
  455           {
  456                    retu rn getAddi tionalIden tifiersStr ing(SERIAL IZATION_FO RMAT.NATIV E);
  457           }
  458           
  459           pu blic final  String ge tAdditiona lIdentifie rsString(S ERIALIZATI ON_FORMAT  serializat ionFormat)
  460           {
  461                    Stri ngBuilder  ahnold = n ew StringB uilder();
  462                    
  463                    if(g etAddition alIdentifi ers() != n ull)
  464                    {
  465                             int la stUsedInde x = 0;
  466                             for(in t index=0;  index < g etAddition alIdentifi ers().leng th; ++inde x)
  467                             {
  468                                      String a dditionalI dentifier  = getAddit ionalIdent ifier(inde x);
  469                                      if(addit ionalIdent ifier != n ull)
  470                                      {
  471                                               // put the  blanks in , if any,  from the l ast used i ndex
  472                                               for(int bl ankIndex=l astUsedInd ex; blankI ndex < ind ex-1; ++bl ankIndex)
  473                                                       ah nold.appen d("[]");
  474                                               ahnold.app end(URN.ap pendedIden tifierStar tDelimiter );
  475                                               ahnold.app end( SERIA LIZATION_F ORMAT.seri alize(addi tionalIden tifier, se rializatio nFormat) ) ;
  476                                               ahnold.app end(URN.ap pendedIden tifierEndD elimiter);
  477                                               lastUsedIn dex = inde x;
  478                                      }
  479                             }
  480                    }
  481                    
  482                    retu rn ahnold. toString() ;
  483           }
  484           
  485           /* *
  486            *  Return th e NSS port ion of the  URN.
  487            *  Derived c lasses tha t parse th e namespac e specific  string
  488            *  MUST also  override  this metho d to build  the names pace
  489            *  specific  string fro m its pars ed compone nts.
  490            *  The names pace speci fic string  should be  the NSS p ortion of
  491            *  the RFC-2 141 string ified form  of the UR N, it shou ld not
  492            *  include a ny additio nal identi fiers.
  493            *  The defau lt impleme ntation of  toString( ) calls th is method
  494            *  to build  the NSS pa rt of the  RFC-2141 f orm.
  495            *  @return
  496            * /
  497           pu blic final  String ge tNamespace SpecificSt ring()
  498           {
  499                    retu rn getName spaceSpeci ficString( SERIALIZAT ION_FORMAT .RFC2141);
  500           }
  501           
  502           pu blic Strin g getNames paceSpecif icString(S ERIALIZATI ON_FORMAT  serializat ionFormat)
  503           {
  504                    retu rn seriali zationForm at.seriali ze( RFC214 1_ESCAPING .unescapeI llegalChar acters(thi s.namespac eSpecificS tring) );
  505           }
  506           
  507           pu blic void  setNamespa ceSpecific String(Str ing namesp aceSpecifi cString)
  508           {
  509                    this .namespace SpecificSt ring = RFC 2141_ESCAP ING.escape IllegalCha racters(na mespaceSpe cificStrin g);
  510           }
  511           
  512           /* *
  513            *  By defaul t the URN  class does n't really  parse the  NSS,
  514            *  it just s tores it a s a single  String.
  515            *  Derived c lasses whe re the NSS  is not op aque may o verride th is
  516            *  method to  store the  individua l componen ts of the  NSS.
  517            *  The NSS s hould not  include th e addition al identif iers and t his method
  518            *  will thro w a URNExc eption if  it does.
  519            *  NOTE: The  namespace  specific  string tha t is passe d into thi s method
  520            *  does not  have escap e octet st rings subs tituted fo r the ille gal charac ters.
  521            *  It is up  to the der ived class es to call  URN.escap eIllegalCh aracters()  if
  522            *  their may  be illega l (accordi ng to RFC  2141) char acters in  the NSS.
  523            *  
  524            *  @param se rializatio nFormat -  specifies  the format  that the  namespace  specific s tring is
  525            *  presented  to this m ethod as.
  526            * /
  527           pu blic void  parseNames paceSpecif icString(N amespaceId entifier n amespace,  String nam espaceSpec ificString , SERIALIZ ATION_FORM AT seriali zationForm at)
  528           th rows URNFo rmatExcept ion
  529           {
  530                    if(n amespaceSp ecificStri ng == null )
  531                             this.n amespaceSp ecificStri ng = null;
  532                    else
  533                    {
  534                             switch (serializa tionFormat )
  535                             {
  536                             case P ATCH83_VFT P:
  537                                      setNames paceSpecif icString(  Base32Conv ersionUtil ity.base32 Decode(nam espaceSpec ificString ) );
  538                                      break;
  539                                      
  540                             case R FC2141:
  541                                      setNames paceSpecif icString(  namespaceS pecificStr ing );
  542                                      break;
  543                                      
  544                             case C DTP:
  545                                      setNames paceSpecif icString(n amespaceSp ecificStri ng);
  546                                      break;
  547                                      
  548                             case V FTP:               //  VFTP enco des the en tire NSS i n RFC2141  safe manne r
  549                             case R AW:                //  RAW does  not encode  anything,  but inclu des all id entifiers
  550                                      String n ss = seria lizationFo rmat.deser ialize(nam espaceSpec ificString );
  551                                      Matcher  nssMatcher  = EXTENDE D_NSS_PATT ERN.matche r(nss);
  552                                      if(nssMa tcher.matc hes())
  553                                      {
  554                                               setNamespa ceSpecific String( ns sMatcher.g roup(URN.u rnXnssComp onentGroup ) );
  555                                               String add itionalIde ntifier =  null;
  556                                               additional Identifier  = nssMatc her.group( urnXnssAdd itionalIde ntifierCom ponentGrou p1);
  557                                               if(additio nalIdentif ier != nul l && addit ionalIdent ifier.leng th() > 0)
  558                                                       se tAdditiona lIdentifie r(0, addit ionalIdent ifier);
  559                                               additional Identifier  = nssMatc her.group( urnXnssAdd itionalIde ntifierCom ponentGrou p2);
  560                                               if(additio nalIdentif ier != nul l && addit ionalIdent ifier.leng th() > 0)
  561                                                       se tAdditiona lIdentifie r(1, addit ionalIdent ifier);
  562                                               additional Identifier  = nssMatc her.group( urnXnssAdd itionalIde ntifierCom ponentGrou p3);
  563                                               if(additio nalIdentif ier != nul l && addit ionalIdent ifier.leng th() > 0)
  564                                                       se tAdditiona lIdentifie r(2, addit ionalIdent ifier);
  565                                               additional Identifier  = nssMatc her.group( urnXnssAdd itionalIde ntifierCom ponentGrou p4);
  566                                               if(additio nalIdentif ier != nul l && addit ionalIdent ifier.leng th() > 0)
  567                                                       se tAdditiona lIdentifie r(3, addit ionalIdent ifier);
  568                                               additional Identifier  = nssMatc her.group( urnXnssAdd itionalIde ntifierCom ponentGrou p5);
  569                                               if(additio nalIdentif ier != nul l && addit ionalIdent ifier.leng th() > 0)
  570                                                       se tAdditiona lIdentifie r(4, addit ionalIdent ifier);
  571                                      }
  572                                      else
  573                                               throw new  URNFormatE xception(
  574                                                       "T he namespa ce specifi c string ' " + namesp aceSpecifi cString + 
  575                                                       "'  does not  match the  required f ormat of ' " + nssMat cher.patte rn().toStr ing() + "' ."
  576                                               );
  577                                      break;
  578                                      
  579                             case N ATIVE:
  580                             defaul t:
  581                                      setNames paceSpecif icString(  namespaceS pecificStr ing );
  582                                      break;
  583                             }
  584                             
  585                             if( !n amespaceSp ecificStri ngPattern. matcher(ge tNamespace SpecificSt ring()).ma tches() )
  586                                      throw ne w URNForma tException ("The name space spec ific strin g '" + nam espaceSpec ificString  + "' is n ot valid." );
  587                    }
  588           }
  589           
  590           /* *
  591            *  A Logger  instance t hat all of  the URN d erived cla sses may u se.
  592            *  
  593            *  @return
  594            * /
  595           pr otected sy nchronized  Logger ge tLogger()
  596           {
  597                    if(t his.logger  == null)
  598                             this.l ogger = Lo gManager.g etLogger(U RN.class);
  599                    retu rn this.lo gger;
  600           }
  601           
  602           @O verride
  603           pu blic Strin g toString ()
  604           {
  605                    retu rn toStrin g(SERIALIZ ATION_FORM AT.RFC2141 );
  606           }
  607           
  608           /* *
  609            *  It is str ongly enco uraged tha t derived  classes sh ould use t he
  610            *  toStringX XX methods  defined i n this cla ss wheneve r possible .  Otherwi se
  611            *  maintenan ce becomes  a real he adache in  trying to  figure whi ch method
  612            *  is being  used to se rialize.
  613            *  
  614            *  @param se rializatio nFormat
  615            *  @return
  616            * /
  617           pu blic final  String to String(SER IALIZATION _FORMAT se rializatio nFormat)
  618           {
  619                    swit ch(seriali zationForm at)
  620                    {
  621                    case  PATCH83_V FTP:
  622                             return  toStringP atch83VFTP ();
  623                    case  CDTP:
  624                             return  toStringC DTP();
  625                    case  NATIVE:
  626                             return  toStringN ative();
  627                    case  VFTP:
  628                             return  toStringV FTP();
  629                    case  RFC2141:
  630                             return  toStringR FC2141();
  631                    case  RAW:
  632                             return  toStringR aw();
  633                    defa ult:
  634                             return  toString( );
  635                    }
  636           }
  637           
  638           /* *
  639            *  Serialize  the names pace speci fic string  and the a dditional  identifier s, encode  the entire
  640            *  NSS using  RFC2141 c ompliant e scaping.
  641            *  
  642            *  @return
  643            * /
  644           pr otected St ring toStr ingVFTP()
  645           {
  646                    Octe tSequenceE scaping rf c2141Escap ing = Octe tSequenceE scaping.cr eateRFC214 1EscapeEng ine();
  647                    
  648                    Stri ngBuilder  ahnold = n ew StringB uilder();
  649                    
  650                    // b uild the s cheme iden tifier
  651                    ahno ld.append( urnSchemaI dentifier) ;
  652                    ahno ld.append( urnCompone ntDelimite r);
  653  
  654                    // b uild the n amespace i dentifier
  655                    ahno ld.append( this.getNa mespaceIde ntifier()) ;
  656                    ahno ld.append( urnCompone ntDelimite r);
  657                    
  658                    Stri ngBuilder  sbNss = ne w StringBu ilder();
  659                    sbNs s.append(  this.getNa mespaceSpe cificStrin g() );
  660                    
  661                    sbNs s.append(  URN.buildA dditionalI dentifiers String(SER IALIZATION _FORMAT.VF TP, getAdd itionalIde ntifiers() ) );
  662                    //if (getAdditi onalIdenti fiers() !=  null)
  663                    //       for(St ring addit ionalIdent ifier : ge tAdditiona lIdentifie rs())
  664                    //       {
  665                    //                sbNss.ap pend(URN.a ppendedIde ntifierSta rtDelimite r);
  666                    //                sbNss.ap pend(addit ionalIdent ifier);
  667                    //                sbNss.ap pend(URN.a ppendedIde ntifierEnd Delimiter) ;
  668                    //       }
  669                    ahno ld.append(  rfc2141Es caping.esc apeIllegal Characters (sbNss.toS tring()) ) ;
  670                    retu rn ahnold. toString() ;
  671           }
  672  
  673           /* *
  674            *  
  675            *  @return
  676            * /
  677           pr otected St ring toStr ingRaw()
  678           {
  679                    Stri ngBuilder  ahnold = n ew StringB uilder();
  680                    
  681                    // b uild the s cheme iden tifier
  682                    ahno ld.append( urnSchemaI dentifier) ;
  683                    ahno ld.append( urnCompone ntDelimite r);
  684  
  685                    // b uild the n amespace i dentifier
  686                    ahno ld.append( this.getNa mespaceIde ntifier()) ;
  687                    ahno ld.append( urnCompone ntDelimite r);
  688                    
  689                    ahno ld.append(  this.getN amespaceSp ecificStri ng(SERIALI ZATION_FOR MAT.RAW) ) ;
  690                    ahno ld.append(  URN.build Additional Identifier sString(SE RIALIZATIO N_FORMAT.R AW, additi onalIdenti fiers) );
  691                    //if (getAdditi onalIdenti fiers() !=  null)
  692                             //for( String add itionalIde ntifier :  getAdditio nalIdentif iers())
  693                             //{
  694                             //       ahnold.a ppend(URN. appendedId entifierSt artDelimit er);
  695                             //       ahnold.a ppend(addi tionalIden tifier);
  696                             //       ahnold.a ppend(URN. appendedId entifierEn dDelimiter );
  697                             //}
  698                    retu rn ahnold. toString() ;
  699           }
  700           
  701           /* *
  702            *  Build an  RFC-2141 c ompliant,  stringifie d form of  the URN. T his form
  703            *  may inclu de escaped  octet seq uences whe re the ori ginal stri ng had cha racters th at
  704            *  are illeg al accordi ng to RFC  2141.
  705            *  
  706            *  NOTE: thi s method m ay produce  a value t hat is not  equal to  the origin al string
  707            *  passed to  URNFactor y to build  the URN.
  708            *  
  709            *  @see #toS tringNativ e()
  710            *  @see #toS tringCDTP( )
  711            * /
  712           pu blic Strin g toString RFC2141()
  713           {
  714                    Stri ngBuilder  ahnold = n ew StringB uilder();
  715                    
  716                    // b uild the s cheme iden tifier
  717                    ahno ld.append( urnSchemaI dentifier) ;
  718                    ahno ld.append( urnCompone ntDelimite r);
  719  
  720                    // b uild the n amespace i dentifier
  721                    ahno ld.append( this.getNa mespaceIde ntifier()) ;
  722                    ahno ld.append( urnCompone ntDelimite r);
  723                    
  724                    ahno ld.append(  SERIALIZA TION_FORMA T.RFC2141. serialize( this.getNa mespaceSpe cificStrin g(SERIALIZ ATION_FORM AT.RFC2141 )) );
  725                    
  726                    retu rn ahnold. toString() ;
  727           }
  728           
  729           /* *
  730            *  @return
  731            * /
  732           pr otected St ring toStr ingPatch83 VFTP()
  733           {
  734                    Stri ngBuilder  ahnold = n ew StringB uilder();
  735                    
  736                    // b uild the s cheme iden tifier
  737                    ahno ld.append( urnSchemaI dentifier) ;
  738                    ahno ld.append( urnCompone ntDelimite r);
  739  
  740                    // b uild the n amespace i dentifier
  741                    ahno ld.append( this.getNa mespaceIde ntifier()) ;
  742                    ahno ld.append( urnCompone ntDelimite r);
  743                    
  744                    // r estore any  RFC2141 i llegal cha racters an d then Bas e32 encode  the NSS
  745                    ahno ld.append(  this.getN amespaceSp ecificStri ng(SERIALI ZATION_FOR MAT.PATCH8 3_VFTP) );
  746                    
  747                    retu rn ahnold. toString() ;
  748           }
  749  
  750           /* *
  751            *  This meth od is requ ired to ge nerate a S tring that  is equal  to the ori ginal
  752            *  value use d to creat e the URN.
  753            *  
  754            *  This meth od returns  a stringi fied view  of the URN  with octe t sequence s in the N SS 
  755            *  (and in t he form %x x) represe nting char acters tha t are not  legal RFC  2141 chara cters 
  756            *  converted  to the eq uivalent c haracter u sing the U TF-8 chara cter set.
  757            *  
  758            *  By defaul t this is  equivalent  to toStri ngUnescape d().  Deri ved classe s must ove rride
  759            *  this meth od when th e toString ToUnescape d() method  does not  return the  original  value beca use
  760            *  of intern al encodin g, additio nal identi fiers or f or any oth er reason.
  761            *
  762            *  NOTE: The  result of  this meth od may not  be a lega l RFC 2141  represent ation of a  URN.
  763            *  NOTE: The  URNFactor y recogniz es and enc odes illeg al charact ers.
  764            *  NOTE: Add itional id entifiers  are not in cluded.  
  765            *  
  766            *  @see #toS tring()
  767            *  @see #toS tringCDTP( )
  768            *  @return
  769            * /
  770           pr otected St ring toStr ingNative( )
  771           {
  772                    Stri ngBuilder  ahnold = n ew StringB uilder();
  773                    
  774                    // b uild the s cheme iden tifier
  775                    ahno ld.append( urnSchemaI dentifier) ;
  776                    ahno ld.append( urnCompone ntDelimite r);
  777  
  778                    // b uild the n amespace i dentifier
  779                    ahno ld.append( this.getNa mespaceIde ntifier()) ;
  780                    ahno ld.append( urnCompone ntDelimite r);
  781                    
  782                    // r estore any  RFC2141 i llegal cha racters
  783                    ahno ld.append(  RFC2141_E SCAPING.un escapeIlle galCharact ers(this.g etNamespac eSpecificS tring(SERI ALIZATION_ FORMAT.NAT IVE)) );
  784                    
  785                    retu rn ahnold. toString() ;
  786           }
  787           
  788           /* *
  789            *  The VA in ternal for m of a str ingified U RN include s any addi tional
  790            *  data such  that the  identifier s can be p arsed from  the Strin g.  For 
  791            *  example t his includ es the Stu dy and Pat ient ident ifiers in  an ImageUR N
  792            *  and the P atient ID  in a Study URN.
  793            *  
  794            *  Using thi s implemen tation of  toStringAs VAInternal , any URN  derivation  that 
  795            *  returns a  non-null  value from  getAdditi onalIdenti fiers() wi ll have th ose values
  796            *  tacked on to the res ulting str ing delimi ted by squ are bracke ts.  BHIE  derivation s of 
  797            *  ImageURN  and StudyU RN encode  the additi onal infor mation usi ng this me thod.
  798            *  It is sug gested tha t this enc oding alwa ys be used  because t he URNFact ory recogn izes it.
  799            *  
  800            *  The VAInt ernal stri ngified fo rm is not  required t o include  an RFC2141  compliant
  801            *  namespace  specific  string.  T he schema  must still  be "urn"  and the na mespace
  802            *  identifie r must be  valid acco rding to R FC 2141.
  803            *  
  804            *  NOTE: The  result of  this meth od may not  be a lega l RFC 2141  represent ation of a  URN.
  805            *  NOTE: The  URNFactor y recogniz es and enc odes illeg al charact ers.
  806            *  NOTE: Add itional id entifiers  are includ ed.
  807            *  NOTE: The  NSS porti on in the  resulting  String is  guaranteed  to consis t of only  legal file name
  808            *  character s.
  809            *  
  810            *  @see #FIL ENAME_SAFE _CHARS
  811            *  @return
  812            * /
  813           pu blic Strin g toString CDTP()
  814           {
  815                    Stri ngBuilder  ahnold = n ew StringB uilder();
  816                    
  817                    // b uild the s cheme iden tifier
  818                    ahno ld.append( urnSchemaI dentifier) ;
  819                    ahno ld.append( urnCompone ntDelimite r);
  820  
  821                    // b uild the n amespace i dentifier
  822                    ahno ld.append( this.getNa mespaceIde ntifier()) ;
  823                    ahno ld.append( urnCompone ntDelimite r);
  824                    
  825                    Stri ng nss = t his.getNam espaceSpec ificString ();
  826                    // e scape any  filename i llegal cha racters
  827                    nss  = FILENAME _ESCAPING. escapeIlle galCharact ers(nss);
  828                    ahno ld.append( nss);
  829                    
  830                    // ! !! JULIAN,  READ THIS  !!!!!!
  831                    // y ou could p robably re place the  next three  lines wit h this one
  832                    // a hnold.appe nd( URN.bu ildAdditio nalIdentif iersString (SERIALIZA TION_FORMA T.CDTP, ad ditionalId entifiers)  );
  833                    // b ut I figur ed this wa sn't the k ind of thi ng you wan ted change d in the l ast couple  of weeks
  834                    // b efore I le ft the pro ject.
  835                    Stri ng additio nalIdentif iers = thi s.getAddit ionalIdent ifiersStri ng();
  836                    // e scape any  filename i llegal cha racters
  837                    addi tionalIden tifiers =  FILENAME_E SCAPING.es capeIllega lCharacter s(addition alIdentifi ers);
  838                    ahno ld.append( additional Identifier s);
  839                    
  840                    retu rn ahnold. toString() ;
  841           }
  842  
  843           /* *
  844            *  
  845            *  @param se rializatio nFormat
  846            *  @param ad ditionalId entifiers
  847            *  @return
  848            * /
  849           st atic publi c String b uildAdditi onalIdenti fiersStrin g(SERIALIZ ATION_FORM AT seriali zationForm at, String ... additi onalIdenti fiers)
  850           {
  851                    if(a dditionalI dentifiers  == null)
  852                             return  "";
  853                    
  854                    Stri ngBuilder  stringifie dIdentifie rs = new S tringBuild er();
  855                    
  856                    int  preceeding Identifier s = 0;
  857                    for( String add itionalIde ntifier :  additional Identifier s)
  858                    {
  859                             // don 't write b lank unles s they are  needed fo r fill
  860                             // not e that if  the caller  sends a z ero-length  string th en that wi ll get wri tten
  861                             if(add itionalIde ntifier ==  null)
  862                             {
  863                                      ++precee dingIdenti fiers;
  864                                      continue ;
  865                             }
  866  
  867                             // wri te any bla nk additio nal identi fiers need ed as fill er
  868                             for(;  preceeding Identifier s > 0; pre ceedingIde ntifiers-- )
  869                                      stringif iedIdentif iers.appen d("" + URN .appendedI dentifierS tartDelimi ter + URN. appendedId entifierEn dDelimiter );
  870                             
  871                             string ifiedIdent ifiers.app end(URN.ap pendedIden tifierStar tDelimiter );
  872                             string ifiedIdent ifiers.app end( addit ionalIdent ifier == n ull ? "" :  serializa tionFormat .serialize (additiona lIdentifie r) );
  873                             string ifiedIdent ifiers.app end(URN.ap pendedIden tifierEndD elimiter);
  874                    }
  875                    
  876                    retu rn stringi fiedIdenti fiers.toSt ring();
  877           }
  878           
  879           /* *
  880            *  Create a  URI that r epresents  this URN i n its defa ult form,
  881            *  that is w ithout add itional id entifiers.
  882            *  
  883            *  @return
  884            *  @throws U RISyntaxEx ception
  885            * /
  886           pu blic URI t oURI() 
  887           th rows URISy ntaxExcept ion
  888           {
  889                    retu rn new URI (this.toSt ring());
  890           }
  891  
  892           
  893           @O verride
  894           pu blic int h ashCode()
  895           {
  896                    fina l int prim e = 31;
  897                    int  result = 1 ;
  898                    resu lt = prime  * result  + Arrays.h ashCode(th is.getAddi tionalIden tifiers()) ;
  899                    resu lt = prime  * result  + ((this.g etNamespac eIdentifie r() == nul l) ? 0 : t his.getNam espaceIden tifier().h ashCode()) ;
  900                    resu lt = prime  * result
  901                             + ((th is.getName spaceSpeci ficString( ) == null)  ? 0 : thi s.getNames paceSpecif icString() .hashCode( ));
  902                    retu rn result;
  903           }
  904  
  905           @O verride
  906           pu blic boole an equals( Object obj )
  907           {
  908                    if ( this == ob j)
  909                             return  true;
  910                    if ( obj == nul l)
  911                             return  false;
  912                    if ( getClass()  != obj.ge tClass())
  913                             return  false;
  914                    URN  other = (U RN) obj;
  915                    if ( !Arrays.eq uals(this. getAdditio nalIdentif iers(), ot her.getAdd itionalIde ntifiers() ))
  916                             return  false;
  917                    if ( this.getNa mespaceIde ntifier()  == null)
  918                    {
  919                             if (ot her.getNam espaceIden tifier() ! = null)
  920                                      return f alse;
  921                    }
  922                    else  if (!this .getNamesp aceIdentif ier().equa ls(other.g etNamespac eIdentifie r()))
  923                             return  false;
  924                    if ( this.getNa mespaceSpe cificStrin g() == nul l)
  925                    {
  926                             if (ot her.getNam espaceSpec ificString () != null )
  927                                      return f alse;
  928                    }
  929                    else  if (!this .getNamesp aceSpecifi cString(). equals(oth er.getName spaceSpeci ficString( )))
  930                             return  false;
  931                    retu rn true;
  932           }
  933   }