001 /* 002 * file StpLocation.java 003 * 004 * Licensed Materials - Property of IBM 005 * Restricted Materials of IBM 006 * 007 * com.ibm.rational.wvcm.stp.StpLocation 008 * 009 * © Copyright IBM Corporation 2004, 2008. All Rights Reserved. 010 * Note to U.S. Government Users Restricted Rights: Use, duplication or 011 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 012 */ 013 014 package com.ibm.rational.wvcm.stp; 015 016 import java.io.File; 017 import java.io.Serializable; 018 import java.net.MalformedURLException; 019 import java.util.EnumSet; 020 import java.util.Hashtable; 021 import java.util.Map; 022 023 import javax.wvcm.Location; 024 import javax.wvcm.Provider; 025 import javax.wvcm.Resource; 026 import javax.wvcm.WvcmException; 027 028 import com.ibm.rational.wvcm.stpex.StpExEnumeration; 029 import com.ibm.rational.wvcm.stpex.StpExEnumerationBase; 030 031 /** 032 * An extension of the javax.wvcm Location interface that provides a 033 * programmatic representation for the location of a resource. 034 * 035 * <p> 036 * An StpLocation instance represents a location specification that has been 037 * parsed into its various component fields. A number of different formats or 038 * <i>schemes</i> are used to express the location of various resources as a 039 * string. These schemes consist of one or more of the following fields: 040 * <i>domain</i>, <i>repository name</i>, <i>namespace</i>, and <i>object 041 * name</i>. It is the namespace field that determines the scheme being used. 042 * <p> 043 * Locations are hierarchical, with the domain field specifying the top level of 044 * the hierarchy. Within a domain, resources are partitioned into repositories. 045 * Within a repository, resources are first partitioned into namespaces, and 046 * then uniquely identified by segmented pathnames within that namespace. 047 * <p> 048 * Each scheme requires certain of the above fields to be specified. If required 049 * fields are not present, the StpLocation object will have a non-OK Status. 050 * Individual field values can be queried to determine which fields aren't 051 * present. 052 * <p> 053 * To use this StpLocation to construct a proxy, its Status must be OK. 054 * <p> 055 * When a proxy is constructed, a new StpLocation may need to be constructed, so 056 * clients must not assume that the object returned by Resource.location() 057 * or any of the StpLocation factory methods defined in StpProvider is 058 * the same object passed to the proxy factory that created the proxy. 059 * <p> 060 * The preferred scheme for specifying an object is the <i>object selector 061 * scheme</i>, which has the following structure 062 * <p> [[<i><domain></i>.][<i><namespace></i>]:] [<i><object-name></i>][@[<i><repository-name></i>]] 063 * <p> 064 * The <i><object-name></i>, and <i><repository-name></i> fields are 065 * segmented names where the segments are separated by '/'s or '\'s. The 066 * permitted <i><namespace></i>s are defined by 067 * {@link StpLocation.Namespace} and the permitted <i><domain></i>s are 068 * defined by {@link StpProvider.Domain}. 069 * <p> 070 * The character '@' is reserved for use as the repository field delimiter 071 * as defined above. If it is to be part of the name field, it must be escaped 072 * by preceding it with a percent sign '%'. Similarly, the characters '/' and 073 * '\' are reserved in both the name and repository fields to be used as 074 * pathname segment separators. To use them as part of a segment they, too, must 075 * be escaped using a percent sign. Use two percent signs, '%%', to include a 076 * percent sign in the name or repository field. Note that escaped characters 077 * within a field are <i>not</i> unescaped when parsed into a StpLocation. 078 * Utility methods are provided by the StpProvider class for unescaping the 079 * fields, should a client need the unadulterated image. 080 * <p> 081 * Some resources can also be referenced directly or indirectly by an absolute or 082 * relative file system pathname. As an StpLocation image, such 083 * representations are called <i>path-scheme</i> locations, which have the 084 * following structure 085 * <p> [[<i><domain></i>.][<i><namespace></i>]:] [<i><path-name></i>] 086 * <p> 087 * The path-scheme locations are further categorized by their namespace as 088 * indicated in this enumeration... 089 * <ul> 090 * <li>{@linkplain #isOk() <i>invalid</i>} namespaces: NONE, DEFAULT, INVALID, 091 * <li>{@linkplain #isFilePathScheme() <i>file path scheme</i>} namespaces: 092 * PNAME, PNAME_IMPLIED, FILE, 093 * <li>{@linkplain #isRepositoryPathScheme() <i>repository path scheme</i>} 094 * namespaces: VOB, VIEW_UUID, REPLICA_UUID, PROJ_DB, USER_DB, DB_SET, SERVER, 095 * <li>WORKSPACE, 096 * <li>{@linkplain #isUrlPathScheme() <i>URL path scheme</i>} namespaces: FILE, 097 * HTTP, HTTPS, 098 * </ul> 099 * This interface defines a predicate for each of these categories. The reader 100 * is referred to the documentation for those predicates for more information on 101 * the formation and meaning of each type of path-scheme location. Note that if 102 * a namespace is <i>not</i> one of the above path-scheme namespaces, it is an 103 * {@linkplain #isObjectSelectorScheme() <i>object selector scheme</i>} 104 * namespace. 105 * <p> 106 * %-escaping is not used in path-scheme locations. 107 */ 108 public interface StpLocation extends javax.wvcm.Location 109 { 110 /** 111 * Returns the StpProvider object that created this StpLocation object 112 * 113 * @return The StpProvider object that instantiated this instance of 114 * StpLocation 115 */ 116 StpProvider stpProvider(); 117 118 /** 119 * This class enumerates the namespaces that may appear in a location 120 * specification. Instances of the class are used to represent the namespace 121 * of the location represented by an StpLocation object. 122 * 123 * The Namespace maps directly to the word token used in a location 124 * specification to denote the namespace of the resource named by the 125 * location. Each resource may appear in multiple namespaces. 126 */ 127 public static enum Namespace implements StpExEnumeration, Serializable 128 { 129 /** 130 * A special path-scheme Namespace indicating that the namespace field 131 * of a location is unknown. 132 */ 133 INVALID("INVALID" /* NOI18N */), 134 135 /** 136 * A special path-scheme Namespace indicating that no namespace was 137 * specified in the location specification. 138 */ 139 NONE("NONE" /* NOI18N */), 140 141 /** 142 * A special path-scheme Namespace indicating that the namespace field 143 * in the location specification was empty, which is the convention for 144 * specifying the default namespace of a repository. 145 */ 146 DEFAULT("DEFAULT" /* NOI18N */), 147 148 /** 149 * The special, compound namespace used in stable selector schemes. To 150 * fully specify the stable selector scheme namespace, a resource-type 151 * string must follow the REPO word token in the location specification. 152 */ 153 REPO("repo" /* NOI18N */), 154 155 /** 156 * The special, compound namespace used in the selector scheme for 157 * specification of efficiently-accessed locations. To fully specify the 158 * efficient selector scheme namespace, a resource-type string must 159 * follow the FAST word token in the location specification. 160 */ 161 FAST("fast" /* NOI18N */), 162 163 /** 164 * A special file-path-scheme namespace that forces the rest of the 165 * location to be interpreted as a ClearCase P-name, a file system 166 * pathname with an optional history-mode extension. 167 */ 168 PNAME("pname" /* NOI18N */), 169 170 /** 171 * A special file-path-scheme Namespace indicating a pname without an 172 * explicit PNAME prefix. Locations in the PNAME_IMPLIED namespace 173 * display simply as P-names. 174 */ 175 PNAME_IMPLIED("implicit" /* NOI18N */), 176 177 /** 178 * A repository-path-scheme Namespace for a ClearCase VOB specified 179 * directly by tag or indirectly by an entity within the VOB. 180 */ 181 VOB("vob" /* NOI18N */), 182 183 /** 184 * A repository-path-scheme Namespace for a ClearCase VOB specified by 185 * its replica UUID 186 */ 187 REPLICA_UUID("replicauuid" /* NOI18N */), 188 189 /** 190 * A repository-path-scheme Namespace for a ClearCase view specified by 191 * its UUID 192 */ 193 VIEW_UUID("viewuuid" /* NOI18N */), 194 195 /** 196 * A stable-selector-scheme Namespace for a ClearCase resource specified 197 * by its DBID 198 */ 199 DBID("dbid" /* NOI18N */), 200 201 /** A repository-path-scheme Namespace for a ClearQuest user database */ 202 USER_DB("userdb" /* NOI18N */), 203 204 /** 205 * A repository-path-scheme Namespace for a ClearQuest database known 206 * variously as a profile, connection, database-set, master database, or 207 * schema repository 208 */ 209 DB_SET("dbset" /* NOI18N */), 210 211 /** 212 * The user-friendly-selector-scheme Namespace for an action 213 */ 214 ACTION("action" /* NOI18N */), 215 216 /** 217 * The user-friendly-selector-scheme Namespace for an activity 218 */ 219 ACTIVITY("activity" /* NOI18N */), 220 221 /** 222 * The user-friendly-selector-scheme Namespace for an attribute type 223 */ 224 ATTYPE("attype" /* NOI18N */), 225 226 /** The user-friendly-selector-scheme Namespace for a baseline */ 227 BASELINE("baseline" /* NOI18N */), 228 229 /** The user-friendly-selector-scheme Namespace for a branch type */ 230 BRTYPE("brtype" /* NOI18N */), 231 232 /** The user-friendly-selector-scheme Namespace for a component */ 233 COMPONENT("component" /* NOI18N */), 234 235 /** 236 * The user-friendly-selector-scheme Namespace for a dynamic choice 237 * list. 238 */ 239 DYNAMIC_CHOICE_LIST("choicelist" /* NOI18N */), 240 241 /** The user-friendly-selector-scheme Namespace for an element type */ 242 ELTYPE("eltype" /* NOI18N */), 243 244 /** The user-friendly-selector-scheme Namespace for a field definition */ 245 FIELD_DEFINITION("field" /* NOI18N */), 246 247 /** The URL-path-scheme and file-path-scheme Namespace for a file URL */ 248 FILE("file" /* NOI18N */), 249 250 /** The user-friendly-selector-scheme Namespace for a folder */ 251 FOLDER("folder" /* NOI18N */), 252 253 /** The user-friendly-selector-scheme Namespace for a form */ 254 FORM("form" /* NOI18N */), 255 256 /** The user-friendly-selector-scheme Namespace for a group */ 257 GROUP("group" /* NOI18N */), 258 259 /** The user-friendly-selector-scheme Namespace for a hyperlink */ 260 HLINK("hlink" /* NOI18N */), 261 262 /** The user-friendly-selector-scheme Namespace for a hyperlink type */ 263 HLTYPE("hltype" /* NOI18N */), 264 265 /** The user-friendly-selector-scheme Namespace for a hook */ 266 HOOK("hook" /* NOI18N */), 267 268 /** The user-friendly-selector-scheme Namespace for a label type */ 269 LBTYPE("lbtype" /* NOI18N */), 270 271 /** 272 * A stable-selector-scheme Namespace for a ClearCase resource specified 273 * by its OID 274 */ 275 OID("oid" /* NOI18N */), 276 277 /** The user-friendly-selector-scheme Namespace for a pool */ 278 POOL("pool" /* NOI18N */), 279 280 /** The user-friendly-selector-scheme Namespace for a project. */ 281 PROJECT("project" /* NOI18N */), 282 283 /** 284 * The user-friendly-selector-scheme Namespace for a project 285 * configuration 286 */ 287 PROJECT_CONFIGURATION("projconfig" /* NOI18N */), 288 289 /** 290 * The user-friendly-selector-scheme Namespace for a query, chart, 291 * report, report format, or query folder. 292 */ 293 QUERY("query" /* NOI18N */), 294 295 /** 296 * The user-friendly-selector-scheme Namespace for a record, record 297 * type, attachment folder, or attachment 298 */ 299 RECORD("record" /* NOI18N */), 300 301 /** 302 * The user-friendly, efficient, and stable-scheme Namespace for a 303 * ClearCase registry region. 304 */ 305 REGISTRY_REGION("registryregion" /* NOI18N */), 306 307 /** The user-friendly-selector-scheme Namespace for a replica */ 308 REPLICA("replica" /* NOI18N */), 309 310 /** The user-friendly-selector-scheme Namespace for an rptype */ 311 RPTYPE("rptype" /* NOI18N */), 312 313 /** The user-friendly-selector-scheme Namespace for a stream */ 314 STREAM("stream" /* NOI18N */), 315 316 /** The user-friendly-selector-scheme Namespace for a trigger type */ 317 TRTYPE("trtype" /* NOI18N */), 318 319 /** 320 * The URL-path-scheme Namespace denoting a location presented in the 321 * form of an HTTP URI or URL 322 */ 323 HTTP("http" /* NOI18N */), 324 325 /** 326 * The URL-path-scheme Namespace denoting a location presented in the 327 * form of an HTTPS URI or URL 328 */ 329 HTTPS("https" /* NOI18N */), 330 331 /** The user-friendly-selector-scheme Namespace for a user */ 332 USER("user" /* NOI18N */), 333 334 /** 335 * The user-friendly, efficient, and stable-scheme Namespace for a view 336 * tag. 337 */ 338 VIEWTAG("viewtag" /* NOI18N */), 339 340 /** 341 * The user-friendly, efficient, and stable-scheme Namespace for a VOB 342 * tag. 343 */ 344 VOBTAG("vobtag" /* NOI18N */), 345 346 /** 347 * The path-scheme Namespace for a ClearCase VOB tag, treated in some 348 * senses as a directory. 349 * 350 * Note: This namespace is an implementation detail of the server, which 351 * unfortunately must be exposed to clients. 352 * 353 * It is not intended that clients should attempt to create resources 354 * within this namespace. Undefined behavior is guaranteed if clients 355 * attempt this. 356 * 357 * It is not expected that the server will return resources within this 358 * namespace. 359 */ 360 VOB_TAG_AS_DIRECTORY("vobtagasdirectory" /* NOI18N */), 361 362 /** The path-scheme Namespace for a workspace */ 363 WORKSPACE("workspace" /* NOI18N */), 364 365 /** 366 * The user-friendly-selector-scheme Namespace for a domain server; 367 * e.g. ClearCase or ClearQuest 368 */ 369 DOMAINSERVER("domainserver" /* NOI18N */), 370 371 /** The path-scheme for a CCRC (aka, "legacy") server */ 372 LEGACYSERVER("legacyserver" /* NOI18N */); 373 374 /** 375 * Returns the word token for this Namespace in the namespace field of a 376 * location specification. 377 * 378 * @return A String containing the namespace field value that denotes 379 * this Namespace. 380 */ 381 public String toNamespaceField() 382 { 383 return m_namespaceField; 384 } 385 386 /** 387 * Finds the Namespace enumerator from the identifier used in the 388 * namespace field of a location specification. 389 * 390 * @param field The word token as it appears in a location namespace 391 * field. 392 * 393 * @return The Namespace that the namespace field identifier denotes. 394 * Namespace.INVALID is returned if no Namespace enumerator 395 * matches the symbol exactly. 396 */ 397 public static final Namespace fromNamespaceField(String field) 398 { 399 // Force to lower case before consulting symbol map 400 String symbol = field.toLowerCase(); 401 402 Namespace namespace = g_symbolToNamespaceMap.get(symbol); 403 404 return namespace == null? Namespace.INVALID : namespace; 405 } 406 407 /** 408 * EnumSet definitions for the various classifications of Namespaces 409 */ 410 private static EnumSet<Namespace> invalid = EnumSet.of(INVALID, NONE); 411 private static EnumSet<Namespace> valid = EnumSet.complementOf(invalid); 412 private static EnumSet<Namespace> filePathSchemes = 413 EnumSet.of(PNAME, 414 PNAME_IMPLIED, 415 FILE); 416 private static EnumSet<Namespace> repositoryPathSchemes = 417 EnumSet.of(VOB, 418 VIEW_UUID, 419 REPLICA_UUID, 420 USER_DB, 421 DB_SET, 422 LEGACYSERVER); 423 private static EnumSet<Namespace> urlPathSchemes = EnumSet.of(FILE, 424 HTTP, 425 HTTPS); 426 private static EnumSet<Namespace> pathSchemes = 427 union(EnumSet.of(WORKSPACE, NONE, DEFAULT, INVALID), 428 filePathSchemes, 429 urlPathSchemes, 430 repositoryPathSchemes); 431 private static EnumSet<Namespace> escapeEncoded = 432 union(EnumSet.complementOf(union(pathSchemes, invalid)), 433 EnumSet.of(USER_DB, DB_SET)); 434 private static EnumSet<Namespace> extendedNamespaces = 435 EnumSet.of(REPO, FAST); 436 437 /** 438 * Computes the union of a set of EnumSets 439 * 440 * @param set Two or more EnumSet<Namespace> objects to be combined 441 * into one. 442 * @return The logical union of the given EnumSets. 443 */ 444 private static EnumSet<Namespace> union(EnumSet... set) 445 { 446 EnumSet<Namespace> result = EnumSet.noneOf(Namespace.class); 447 448 for (EnumSet s : set) 449 result.addAll(StpException.<EnumSet<Namespace>>unchecked_cast(s)); 450 451 return result; 452 } 453 454 /** 455 * Determines whether this namespace is valid (not NONE or INVALID). 456 * 457 * @return <b>true</b> if this Namespace represents a valid namespace; 458 * <b>false</b> otherwise. 459 */ 460 public boolean isValid() 461 { 462 return valid.contains(this); 463 } 464 465 /** 466 * @return <b>true</b> iff this namespace prefixes a path scheme 467 */ 468 public boolean isPathScheme() 469 { 470 return pathSchemes.contains(this); 471 } 472 473 /** 474 * @return <b>true</b> iff this namespace prefixes a file path scheme. 475 */ 476 public boolean isFilePathScheme() 477 { 478 return filePathSchemes.contains(this); 479 } 480 481 482 /** 483 * @return <b>true</b> iff this namespace prefixes a path scheme 484 * selector for the name of a repository (or repository-like 485 * entity not in a repository). Said path is the value of the 486 * Repo field rather than the Name field of an StpLocation. 487 */ 488 public boolean isRepositoryPathScheme() 489 { 490 return repositoryPathSchemes.contains(this); 491 } 492 493 494 /** 495 * @return <b>true</b> iff this namespace prefixes a path scheme 496 * selector expressed as a URL or URI. The complete URI, 497 * including this prefix is contained wholly within the Name 498 * field of the StpLocation 499 */ 500 public boolean isUrlPathScheme() 501 { 502 return urlPathSchemes.contains(this); 503 } 504 505 /** 506 * @return <b>true</b> iff this namespace requires additional segments 507 * to complete its specification. 508 */ 509 public boolean isExtendedNamespace() 510 { 511 return extendedNamespaces.contains(this); 512 } 513 514 /** 515 * @return Whether or not the name field of a location specification 516 * prefixed by this namespace should be %-escaped encoded. 517 */ 518 public boolean isEscapeEncoded() 519 { 520 return escapeEncoded.contains(this); 521 } 522 523 /** 524 * Creates a new Namespace object given its namespace field image. 525 * 526 * @param symbol The identifier used in the namespace field to denote 527 * this namespace. 528 */ 529 private Namespace(String symbol) 530 { 531 m_namespaceField = symbol; 532 } 533 534 /** A map from namespace Symbol to Namespace */ 535 private static Map<String, Namespace> g_symbolToNamespaceMap = 536 new Hashtable<String, Namespace>(); 537 538 static { 539 for (Namespace n : Namespace.values()) 540 if (null != g_symbolToNamespaceMap.put(n.m_namespaceField, 541 n)) { 542 throw new IllegalArgumentException 543 ("Duplicate Selector.Namespace symbol" /* NOI18N */); 544 } 545 } 546 547 /** The symbol used in a selector to denote this Namespace */ 548 private String m_namespaceField; 549 550 /** Serialization version UID */ 551 private static final long serialVersionUID = -3736971155548723312L; 552 } 553 554 /** 555 * The characters within a location specification that syntactically delimit 556 * the fields of the selector. 557 */ 558 static final String FIELD_DELIMITERS = "@" /* NOI18N */; 559 560 /** 561 * The characters within a selector field that syntactically delimit the 562 * segments of a field. 563 */ 564 static final String SEGMENT_DELIMITERS = "/\\" /* NOI18N */; 565 566 /** 567 * The characters within a selector that syntactically delimit the fields 568 * and segments embedded within the selector. 569 */ 570 static final String DELIMITERS = FIELD_DELIMITERS + SEGMENT_DELIMITERS; 571 572 /** 573 * If one of the characters of DELIMITERS is to be part of a name segment it 574 * must be protected from its syntactic interpretation by preceding it with 575 * this escape character. The escape character must also be escaped if it is 576 * to be part of a name segment. 577 */ 578 static final String ESCAPE_CHAR = "%" /* NOI18N */; 579 580 /** 581 * Overall status of this StpLocation 582 * 583 * @return <b>true</b> if all required fields were found in the given 584 * location specification. 585 */ 586 boolean isOk(); 587 588 /** 589 * Generates an StpException object that reports the state of this 590 * StpLocation. 591 * 592 * @return An StpException whose message reports the state of this 593 * StpLocation. Will be <b>null</b> if this StpLocation is valid. 594 */ 595 StpException status(); 596 597 /** 598 * Throws an INVALID_OBJECT_SELECTOR StpException if this StpLocation does 599 * not reflect a syntactically complete and correct location specification. 600 * 601 * @throws StpException if any required fields are missing from the 602 * StpLocation specification. 603 */ 604 void throwIfNotOk() throws StpException; 605 606 /** 607 * Returns whether or not this location is specified using a pathname 608 * format. Such locations specify a location as a segmented pathname 609 * following an explicit scheme prefix: 610 * <p>[<i>domain</i> .] <i>namespace</i> : <i>segmented-path</i>. 611 * <p> 612 * The segmented-path is the value of either the name field or the repo 613 * field of this StpLocation and the other field is not used and empty. The 614 * segmented path is stored in the name field unless the predicate 615 * {@link #isRepositoryPathScheme} is also <b>true</b>. 616 * <p> 617 * Included in this scheme classification are the location specifications 618 * that are not complete enough to classify more precisely; i.e. it includes 619 * the locations with the following special Namespace values. 620 * <ul> 621 * <li>NONE: The location specification did not include a scheme delimiter 622 * (":") (at least, not before the first occurrence of a character not 623 * allowed in a scheme prefix). The original input is in the name field of 624 * this StpLocation. 625 * <li>INVALID: The location specification began with a syntactically valid 626 * scheme prefix, but the spelling of the namespace subfield did not match 627 * any known namespace. The location was parsed as a path-scheme location 628 * with all text following the first ':' stored in the name field. The 629 * apparently misspelled namespace field is available from the 630 * ExtendedNamespace field of this StpLocation. 631 * <li>DEFAULT: The location specification began with a syntactically valid 632 * scheme prefix, but the namespace field was empty. The location was parsed 633 * as a path-scheme location, with all text following the first ':' stored 634 * in the name field. 635 * </ul> 636 * 637 * @return <b>true</b> if this is a path-scheme location; <b>false</b> otherwise 638 */ 639 boolean isPathScheme(); 640 641 /** 642 * Returns whether or not this location is specified using the URL path- 643 * scheme format. Such locations are formatted as standards-conforming URLs 644 * (URL-encoded). The entire URL, including the scheme-prefix of the URL, 645 * such as "http:" or "file:" is included in the name field of the 646 * StpLocation object. An optional domain field is permitted before the 647 * scheme-prefix, but it is not included in the name field. A URL path 648 * scheme is a specialized form of path scheme. The URL could designate a 649 * server, a repository, or a resource inside or outside of a repository. 650 * The URL is stored in the repo field if {@link #isRepositoryPathScheme} is 651 * <b>true</b>; otherwise it is stored in the name field. 652 * 653 * @return <b>true</b> if this is a URL path-location; <b>false</b> 654 * otherwise 655 */ 656 boolean isUrlPathScheme(); 657 658 /** 659 * Returns whether or not this location specifies a repository using a path- 660 * scheme format. Such locations have a repository field specified as a 661 * segmented pathname (un-encoded). A repository path-scheme is a 662 * specialized form of path-scheme in which the path is found in the repo 663 * field of the StpLocation object. For all other forms of path-location the 664 * path is found in the name field of the StpLocation object. 665 * 666 * @return <b>true</b> if this is a repository path-location; <b>false</b> 667 * otherwise 668 */ 669 boolean isRepositoryPathScheme(); 670 671 /** 672 * Returns whether or not this location is specified using the file path- 673 * scheme format. In this format, the resource location is specified in the 674 * name field of this StpLocation as a segmented pathname (using native file 675 * system encoding conventions) to a file system object, perhaps extended by 676 * a ClearCase history-mode selector. The variant of the file path location 677 * format used in the specification of this StpLocation is indicated by the 678 * value of getNamespace(). 679 * <ul> 680 * <li>FILE: The "file:" URL scheme prefix was used to specify this 681 * StpLocation. Since this is also a URL path-scheme, the file-scheme prefix 682 * is included in the name field of this object. Conversion of this location 683 * to a File via {@link #getFile()} or canonical path via 684 * {@link #getCanonicalPath()} will first use the java.net.URI class to 685 * parse the file URL. 686 * <li>PNAME: This location was specified with an explicit "pname:" prefix. 687 * The "pname:" prefix is <i>not</i> included in the name field of this 688 * object; it contains only the characters following "pname:" 689 * <li>PNAME_IMPLIED: This location was not specified with an explicit 690 * "pname:" prefix but is being treated as if it were a pname. The implied 691 * "pname:" prefix is <i>not</i> included in the name field of this object 692 * nor does it appear in the string image of this StpLocation. 693 * </ul> 694 * <p> 695 * Note that this and the other predicates are purely syntactic. The user 696 * may have intended to name a file, but if it so happens that its name 697 * looks exactly like a valid object selector, it will be parsed and 698 * classified as an object selector. {@link #isObjectSelectorScheme()} will 699 * be <b>true</b> not {@link #isFilePathScheme()}. Clients wishing to 700 * interpret a location as a file path location, may always use the 701 * {@link #getFile()} or {@link #getCanonicalPath()} methods to investigate 702 * that option further. If this StpLocation isn't in the FILE or PNAME 703 * namespace, these methods will use the original input in its entirety as 704 * the intended pathname. 705 * <p> 706 * Similarly, {@link #recomposeWithNamespace(StpLocation.Namespace) 707 * recomposeWithNamespace(Namespace.PNAME)} will "do the right thing" and 708 * force the original input into an explicit file path selector. Note, 709 * however, that in this case, the image of that StpLocation will include 710 * the "pname:" prefix. 711 * 712 * @return <code><b>true</b></code> if this selector is most likely a 713 * pathname to a file system object, <code><b>false</b></code> if 714 * there is a more likely interpretation. 715 */ 716 boolean isFilePathScheme(); 717 718 /** 719 * Returns whether or not this file-path scheme location uses the optional 720 * ClearCase history-mode naming syntax. 721 * 722 * @return <b>true</b> if the name segment of this location contains 723 * history-mode naming syntax. 724 */ 725 boolean isHistoryModeScheme(); 726 727 /** 728 * Returns whether or not this location uses either a stable, fast 729 * (efficient), or user-friendly object selector scheme. Locations using the 730 * object selector format have a pre-defined namespace and separate name and 731 * repository fields. 732 * 733 * @return <b>true</b> if this location uses the object selector format; 734 * <b>false</b> otherwise, in which case it uses either a path 735 * scheme. 736 */ 737 boolean isObjectSelectorScheme(); 738 739 /** 740 * Returns whether or not this location uses an object selector scheme with 741 * user-friendly namespace, name, and repository fields. 742 * 743 * @return <b>true</b> if this is an object name selector; <b>false</b> 744 * otherwise. 745 * 746 */ 747 boolean isUserFriendlySelectorScheme(); 748 749 /** 750 * Returns whether or not this location uses an object selector scheme with 751 * a compound REPO namespace. Its name and repository fields are densely 752 * encoded for greater stability and more efficient retrieval. 753 * 754 * @return <b>true</b> if the location uses the REPO namespace; <b> false</b> 755 * otherwise. 756 */ 757 boolean isRepoSelectorScheme(); 758 759 /** 760 * Returns whether or not this location uses an object selector scheme with 761 * a compound FAST namespace. Its name and repository fields are densely 762 * encoded for greater stability and more efficient retrieval. 763 * 764 * @return <b>true</b> if the location uses the FAST namespace; <b> false</b> 765 * otherwise. 766 */ 767 boolean isFastSelectorScheme(); 768 769 /** 770 * Returns whether or not this location uses an object selector scheme with 771 * a compound OID namespace. Its name and repository fields are densely 772 * encoded for greater stability and more efficient retrieval. 773 * 774 * @return <b>true</b> if the location uses the OID namespace; <b> false</b> 775 * otherwise. 776 */ 777 boolean isOidSelectorScheme(); 778 779 /** 780 * Returns the StpLocation.Namespace of this selector. 781 * <p> 782 * The special Namespace.INVALID indicates that the namespace field was 783 * present but spelled different from any namespace known to the library. 784 * <p> 785 * The special Namespace.DEFAULT indicates that the namespace field was 786 * present but empty, indicating that the default namespace ought to be 787 * used. 788 * <p> 789 * The special Namespace.NONE indicates that the namespace field was not 790 * present (i.e. there was no ':' in the specification before the first 791 * occurrence of a character not allowed in a scheme prefix), making it 792 * quite likely that this is a file selector. 793 * <p> 794 * Namespace.HTTP, Namespace.HTTPS, and Namespace.FILE indicate that the 795 * selector used the URI/URL syntax, the entirety of which is present in the 796 * name property. 797 * <p> 798 * Namespace.PNAME indicates that the selector used the PNAME namespace 799 * prefix. The file pathname following the PNAME prefix is the value of the 800 * name field. 801 * <p> 802 * See the complete list of possible namespaces in the Namespace enum 803 * specification. 804 * 805 * @return The namespace used in this location specification as a Namespace 806 * object. This will never be <b>null</b>. 807 */ 808 Namespace getNamespace(); 809 810 /** 811 * Returns the resource type field of a location specification if it used a 812 * compound namespace. 813 * 814 * @return The resource type segment of this StpLocation. This field is 815 * defined only for compound namespace locations (i.e. those that 816 * use Namespace.REPO, Namespace.FAST, or Namespace.OID). It will be 817 * an empty string otherwise. 818 */ 819 String getResourceType(); 820 821 /** 822 * An object containing additional information associated with certain 823 * Namespace enumerators. 824 */ 825 interface ExtendedNamespace 826 { 827 828 /** 829 * @return Returns the namespace. 830 */ 831 Namespace getNamespace(); 832 833 /** 834 * @return Returns the resource type portion of the compound REPO 835 * namespace field. Returns the empty string if the namespace is 836 * not REPO, FAST, or OID. 837 */ 838 String getResourceType(); 839 840 /** 841 * The image of the extended namespace field. For Namespace.REPO, FAST, 842 * or OID, this includes the resource type subfield; for 843 * Namespace.INVALID, this is the (misspelled) namespace field as 844 * entered. 845 * 846 * @return A String containing the image of the namespace field for this 847 * extended namespace (without the delimiting ':'). Will be 848 * empty if the namespace is DEFAULT and <b>null</b> if the 849 * location specification has no namespace field separate from 850 * the name field, i.e. if the namespace is NONE, PNAME_IMPLIED, 851 * HTTP, HTTPS, or FILE. 852 */ 853 String toNamespaceField(); 854 855 /** 856 * Generates a debug image for this ExtendedNamespace object 857 * 858 * @return Returns the value of {@link #toNamespaceField()}, 859 * substituting "<null>" for <b>null</b>. 860 */ 861 public String toString(); 862 } 863 864 /** 865 * Returns an ExtendedNamespace object that, for some namespaces, contains 866 * additional information about the namespace field beyond its Namespace 867 * value. 868 * 869 * @return For a REPO, FAST, or OID namespace, the ExtendedNamespace 870 * specifies the resource type segment that is associated with it; 871 * for an INVALID namespace, the ExtendedNamespace object specifies 872 * the misspelled namespace field; for other namespaces, no 873 * additional information is available. Will not be <b>null</b>. 874 */ 875 ExtendedNamespace getExtendedNamespace(); 876 877 /** 878 * Returns the object name field specified for this location. This field is 879 * relevant and meaningful in all schemes <i>except</i> the repository-path 880 * scheme. In a repository-path scheme, it will be an empty Sting. The 881 * encoding of the returned String is unchanged from the original input. 882 * 883 * @return An empty string for a repository-path-scheme location; otherwise 884 * the object name field of an object selector or the pathname of a 885 * path-scheme location. Will be never be <b> null</b>, but may be 886 * empty. 887 */ 888 String getName(); 889 890 /** 891 * The number of segments in the object name. 892 * 893 * @return The length of the Sting array returned by 894 * {@link #getNameSegments(int) getNameSegments(Integer.MAX_VALUE)}. 895 */ 896 int getNameSegmentCount(); 897 898 /** 899 * Returns the first N segments of the name field of this location 900 * specification. If the requested number of segments is greater than the 901 * number in the name field, the entire name is returned; if zero or less, 902 * an empty array is returned. 903 * <p> 904 * Constructs a String array containing the segments of the given field. The 905 * elements of the array are the character sequences that preceded each 906 * segment delimiter plus the character sequence at the end of the field not 907 * followed by a delimiter as long as it is not empty. Thus, the array is 908 * empty if the field is empty; otherwise, the array has N+1 segments, where 909 * N is the number of segment delimiters in the field not counting the last 910 * delimiter if it appears at the end of the field. 911 * <p> 912 * The following examples illustrate the way a field is segmented. 913 * 914 * <pre> 915 * "" ==> {} 916 * "fob/bar" ==> {"fob", "bar"} 917 * "fob/" ==> {"fob"} 918 * "fob" ==> {"fob"} 919 * "/fob" ==> {"", "fob"} 920 * "/" ==> {""} 921 * "//" ==> {"", ""} 922 * "fob//bar" ==> {"fob", "", "bar"} 923 * "http://server" ==> {"http:", "", "server"} 924 * "http://" ==> {"http:", ""} 925 * "file:///" ==> {"file", "", ""} 926 * </pre> 927 * 928 * Note that a trailing segment delimiter is "lost" only if it follows a 929 * non-empty segment. Consequently, when reconstructing the field from the 930 * array, segment delimiters should be inserted between each array element 931 * and a trailing delimiter should be added only if the last segment is 932 * empty. 933 * 934 * <p> 935 * Note: The returned segments are encoded just as they were on input to the 936 * constructor. Any escape characters present in the field on input remain 937 * in each returned segment. Only the unescaped segment delimiters have been 938 * removed from the input field. 939 * 940 * @param nSegs the number of segments to return 941 * 942 * @return a String array containing the first nSegs segments of the name 943 * field of this StpLocation. 944 */ 945 String[] getNameSegments(int nSegs); 946 947 /** 948 * Returns contiguous segments of the name field of this selector. Segments 949 * returned are in the intersection of the specified range and the actual 950 * range of name segments. The first segment is at index zero. 951 * 952 * <p> 953 * Note: The returned segments are encoded just as they were on input to the 954 * constructor. Any escape characters present in the field on input remain 955 * in each returned segment. Only the unescaped segment delimiters have been 956 * removed from the input field. 957 * 958 * @param firstSeg the first segment to include 959 * @param lastSeg the last segment to include 960 * 961 * @return the requested segments of the object name. Will never be null, 962 * but may be empty if the specified range includes none of the 963 * segments of the name field. 964 */ 965 String[] getNameSegments(int firstSeg, 966 int lastSeg); 967 968 /** 969 * Returns the repository field of this location specification. This field 970 * is irrelevant and empty in any path scheme location that does not have a 971 * repository field. Conversely, if this location specification specified a 972 * repository, it will be in this field. 973 * 974 * @return An empty string if there was no repository field found in the 975 * location specification; otherwise the image of the repository 976 * field (without a repository field delimiter). 977 */ 978 String getRepo(); 979 980 /** 981 * The number of segments in the repository name. 982 * 983 * @return The length of the String array returned by 984 * {@link #getRepoSegments(int) getRepoSegments(Integer.MAX_VALUE)}. 985 */ 986 int getRepoSegmentCount(); 987 988 /** 989 * Returns the first N segments of the repository field of this location. If 990 * the requested number of segments is greater than the number in the 991 * repository name, the entire repository name is returned; if zero or less, 992 * an empty array is returned. 993 * 994 * <p> 995 * Note: The returned segments are encoded just as they were on input to the 996 * constructor. Any escape characters present in the field on input remain 997 * in each returned segment. Only the unescaped segment delimiters have been 998 * removed from the input field. 999 * 1000 * @param nSegs the number of segments to return 1001 * 1002 * @return a String containing the first nSegs segments of the repository 1003 * name. 1004 * 1005 * @see #getNameSegments(int) for a description of how segments are parsed 1006 * and counted. 1007 */ 1008 String[] getRepoSegments(int nSegs); 1009 1010 /** 1011 * Returns contiguous segments of the repository name of this location. 1012 * Segments returned are in the intersection of the specified range and the 1013 * actual range of name segments. The first segment is at index zero. 1014 * 1015 * <p> 1016 * Note: The returned segments are encoded just as they were on input to the 1017 * constructor. Any escape characters present in the field on input remain 1018 * in each returned segment. Only the unescaped segment delimiters have been 1019 * removed from the input field. 1020 * 1021 * @param firstSeg the first segment to include 1022 * @param lastSeg the last segment to include 1023 * 1024 * @return the requested segments of the repository name. Will never be 1025 * null, but may be empty if the specified range includes none of 1026 * the segments of the name. 1027 */ 1028 String[] getRepoSegments(int firstSeg, 1029 int lastSeg); 1030 1031 /** 1032 * Returns the domain specified or implied by the selector. In 1033 * URL-path-scheme locations this field is optional and will be NONE if no 1034 * domain information is available. In the other formats, the value NONE 1035 * denotes the default domain. 1036 * 1037 * @return Returns the StpProvider.Domain. Will never be <b>null</b>, but 1038 * may be {@link StpProvider.Domain#NONE NONE} or {@link 1039 * StpProvider.Domain#INVALID INVALID}. 1040 */ 1041 StpProvider.Domain getDomain(); 1042 1043 /** 1044 * Reconstitutes the location specification from its component fields. 1045 * 1046 * @return For a valid StpLocation, a syntactically correct location 1047 * specification string composed from the current values for the 1048 * namespace, name, domain, and repo fields; otherwise the location 1049 * specification as passed to the constructor. 1050 * 1051 * @see java.lang.Object#toString() 1052 */ 1053 String toString(); 1054 1055 /** 1056 * As above, but returns a location string <i>without</i> the domain 1057 * prefix. 1058 */ 1059 String toStringWithoutDomain(); 1060 1061 /** 1062 * @see java.lang.Object#equals(java.lang.Object) 1063 */ 1064 boolean equals(Object arg0); 1065 1066 /** 1067 * Uses the hash code of the composed String image 1068 * 1069 * @see java.lang.Object#hashCode() 1070 */ 1071 int hashCode(); 1072 1073 /** 1074 * Constructs an StpLocation object based on the fields of this StpLocation 1075 * with optional replacements for some of the fields. A <b>null</b> 1076 * argument generally means to use the corresponding field of this 1077 * StpLocation in the new StpLocation. 1078 * <p> 1079 * NOTE: This method does not change the host StpLocation object. But 1080 * constructs and returns a new instance of StpLocation. 1081 * 1082 * @param namespace The namespace for the new location expressed either as 1083 * an ExtendedNamespace object, a Namespace enumeration or as a 1084 * String containing the resource type of a REPO namespace. If 1085 * namespace is Namespace.NONE no namespace prefix is generated 1086 * for the selector. If namespace is <b>null</b>, the current 1087 * value of getExtendedNamespace() is used. 1088 * @param name The name field of the new selector. If <b>null</b>, the 1089 * current value of getName() is used. 1090 * @param domain The StpProvider.Domain for the new selector. If null, the 1091 * current value of getDomain() is used. 1092 * @param repo The repository field for the new selector. If <b>null</b>, 1093 * the current value of getRepo() is used. Must be <b>null</b> 1094 * for path-path scheme locations that are not 1095 * repository-path-schemes. If empty, no repository field will be 1096 * generated for the selector. 1097 * 1098 * @return A new StpLocation composed from the current namespace, name, type 1099 * and repo fields, optionally overwritten by the given arguments. 1100 * 1101 * @throws StpException Thrown if the given selector String is not in the 1102 * correct form. StpReasonCode=INVALID_OBJECT_SELECTOR 1103 */ 1104 StpLocation recomposeWithMods(Object namespace, 1105 String name, 1106 StpProvider.Domain domain, 1107 String repo) throws StpException; 1108 1109 /** 1110 * Constructs new location based on this location but with a replacement for 1111 * its namespace field. 1112 * 1113 * @param namespace The namespace for the new StpLocation. If namespace is 1114 * Namespace.NONE, no namespace prefix is generated for the 1115 * selector. If namespace is <b>null</b>, the current value of 1116 * Namespace is used, effectively cloning this StpLocation 1117 * object. 1118 * 1119 * @return An StpLocation composed from the current name, domain and repo 1120 * fields and the specified namespace argument. 1121 * 1122 * @throws StpException if the given selector String is not in the 1123 * correct form. StpReasonCode=INVALID_OBJECT_SELECTOR 1124 */ 1125 StpLocation recomposeWithNamespace(StpLocation.Namespace namespace) 1126 throws StpException; 1127 1128 /** 1129 * Constructs a new location based on this location with a replacement for 1130 * its name field. 1131 * 1132 * @param name The new selector name field. If null, the current value of 1133 * name() is used. 1134 * 1135 * @return The selector composed from the current namespace, domain and repo 1136 * fields and the specified name argument. 1137 * 1138 * @throws StpException Thrown if the given selector String is not in the 1139 * correct form. StpReasonCode=INVALID_OBJECT_SELECTOR 1140 */ 1141 StpLocation recomposeWithName(String name) throws StpException; 1142 1143 /** 1144 * Constructs a new location based on this location with a replacement for 1145 * its repository field. 1146 * 1147 * @param repo The new repository field for the location. If <b>null</b>, 1148 * the current value of getRepo() is used. If empty, no 1149 * repository field will be generated for the location. 1150 * 1151 * @return An StpLocation composed from the current namespace, name, and 1152 * domain fields and the specified repo argument. 1153 * 1154 * @throws StpException Thrown if the given selector String is not in the 1155 * correct form. StpReasonCode=INVALID_OBJECT_SELECTOR 1156 */ 1157 StpLocation recomposeWithRepo(String repo) throws StpException; 1158 1159 /** 1160 * Constructs a new location based on this location with a replacement for 1161 * its domain field. 1162 * 1163 * @param domain The new domain for the selector. If <b>null</b>, the 1164 * current value of getDomain() is used. 1165 * 1166 * @return An StpLocation composed from the current namespace, name, and 1167 * repo fields and the specified domain argument. 1168 * 1169 * @throws StpException Thrown if the given selector String is not in the 1170 * correct form. StpReasonCode=INVALID_OBJECT_SELECTOR 1171 */ 1172 StpLocation recomposeWithDomain(StpProvider.Domain domain) 1173 throws StpException; 1174 1175 /** 1176 * Constructs an object selector with a replacement for its resource type 1177 * field, forcing the namespace to REPO. 1178 * 1179 * @param rType The resource type for the new location. If <b>null</b>, the 1180 * current value of getResourceType() is used. 1181 * 1182 * @return A stable-selector scheme StpLocation composed from the current 1183 * name, repo and domain fields and the specified resource type. 1184 * 1185 * @throws StpException Thrown if the given selector String is not in the 1186 * correct form. StpReasonCode=INVALID_OBJECT_SELECTOR 1187 */ 1188 StpLocation recomposeWithResourceType(String rType) throws StpException; 1189 1190 /** 1191 * Constructs an StpLocation for a pname based on the image of this 1192 * StpLocation. The StpLocation can be constructed with or without a pname 1193 * prefix and can be assigned a StpProvider.Domain. 1194 * <p> 1195 * In most cases, the entire image of this StpLocation (as returned by 1196 * toString()) becomes the value of the name field of the returned 1197 * StpLocation even if that image includes a namespace and/or a domain 1198 * prefix. The domain prefix can be elided from the name field of the new 1199 * location by using <b>null</b> for the domain argument to this method. 1200 * <p> 1201 * To convert any ill-formed selector to an implied pname, the following 1202 * logic might be used <code><pre> 1203 * if (!myLoc.isOk()) { 1204 * // Convert to an implied pname so that it prints as it was 1205 * // entered, but is treated internally as an OK file path selector 1206 * myLoc = myLoc.recomposeAsPname(false, MY_DOMAIN); 1207 * } 1208 * </pre></code> 1209 * <p> 1210 * To convert any input not already formatted as a file-path-scheme location 1211 * to an explicit pname, the following logic might be used <code><pre> 1212 * if (!(myLoc.isFilePathScheme() && myLoc.isOk())) { 1213 * myLoc = myLoc.recomposeAsPname(true, MY_DOMAIN); 1214 * } 1215 * </pre></code> 1216 * <p> 1217 * To convert all input to an implied pname, the following logic might be 1218 * used <code><pre> 1219 * if (myLoc.getNamespace() == Namespace.PNAME) { 1220 * // Keep the original "pname:" prefix out of the implied pname 1221 * // Preserve any domain data from the input. 1222 * myLoc = myLoc.recomposeWithNamespace(Namespace.PNAME_IMPLIED); 1223 * } else if (myLoc.getNamespace() == Namespace.FILE) { 1224 * // Remove any domain info from the "file:" prefix, but push the 1225 * // rest of the "file:" prefix into the pname. 1226 * myLoc = myLoc.recomposeAsPname(false, null); 1227 * } else { 1228 * // All other input not using an explicit pname: or file: prefix is 1229 * // treated as a raw pname. 1230 * myLoc = myLoc.recomposeAsPname(false, MY_DOMAIN); 1231 * } 1232 * 1233 * // Set the domain type if not already specified. 1234 * if (myLoc.getDomain() == Domain.NONE) 1235 * myLoc = recomposeWithType(MY_DOMAIN); 1236 * </pre></code> 1237 * 1238 * @param withPrefix if <b>true</b>, the namespace of the returned 1239 * StpLocation will be Namespace.PNAME; if <b>false</b>, the 1240 * namespace will be Namespace.PNAME_IMPLIED. 1241 * @param domain The StpProvider.Domain of the returned StpLocation. If 1242 * <b>null</b> the StpProvider.Domain of the current StpLocation 1243 * will be used <i>and the image of that domain will be elided 1244 * from the pname.</i> 1245 * @return An StpLocation reconfigured as a Pname instance, explicit or 1246 * implied as requested 1247 */ 1248 StpLocation recomposeAsPname(boolean withPrefix, 1249 StpProvider.Domain domain) throws StpException; 1250 1251 /** 1252 * Constructs a location suitable for addressing resources of the type 1253 * indicated by the supplied proxy class by filling in unspecified fields of 1254 * this location using provider-defined or resource-type-dependent defaults. 1255 * <p> 1256 * Note, when an StpLocation object is passed to a Provider proxy factory 1257 * method this forClass is implicitly invoked using the Class of the proxy 1258 * returned by the proxy factory method. Similarly, when an StpLocation is 1259 * passed to a method of a proxy, that method implicitly invokes forClass 1260 * using a proxy class deduced from the host proxy and the operation. 1261 * <p> 1262 * Clients need to use this method only if they want to complete/verify a 1263 * location used in some other context or more tightly than can be 1264 * determined from the proxy context. 1265 * 1266 * @param proxyClass The Class object for the proxy interface for which this 1267 * location is to be completed. 1268 * @return An StpLocation suitable for use with a proxy of the given class. 1269 * The result will be this location if it is already suitable and a 1270 * new StpLocation if not; will never be <b>null</b>. 1271 * @throws WvcmException if it is not possible to complete the location from 1272 * available defaults or if the completed location is 1273 * inappropriate in some other (obvious) way, such as having a 1274 * domain or namespace inconsistent with the given class. 1275 */ 1276 StpLocation forClass(Class<? extends Resource> proxyClass) throws WvcmException; 1277 1278 /** 1279 * Returns an StpLocation whose segmented name field is one segment shorter 1280 * than the name field of this StpLocation <i>provided</i> the name field 1281 * of the resulting StpLocation would be valid. All other fields of the 1282 * StpLocation are left unchanged. 1283 * <p> 1284 * NOTE: For repository-path scheme locations this method operates on the 1285 * segmented repo field rather than the name field. But in all other 1286 * respects the behavior is the same. 1287 * <p> 1288 * For object-selector scheme locations, an empty name field is valid, but 1289 * for path-scheme locations, the name/repo field is valid only if it 1290 * contains at least one segment of the original path (even if that segment 1291 * is empty). These examples illustrate the edge cases <code><pre> 1292 * StpLocation | Parent 1293 * -------------------+--------------- 1294 * /food | / 1295 * vob:/food | vob:/ 1296 * http://server/path | http://server 1297 * file://author/path | file://author 1298 * http://server | <null> 1299 * file://author | <null> 1300 * pname:path | <null> 1301 * file:/ | <null> 1302 * </pre></code> 1303 * 1304 * @return A new StpLocation instance; will be <b>null</b> if the name 1305 * field of this StpLocation has no segments that can be removed. 1306 */ 1307 Location parent(); 1308 1309 /** 1310 * Returns an StpLocation whose name field is the name field of this 1311 * StpLocation extended by the given child segment. All other fields are the 1312 * same as the fields of this StpLocation. For repository-path-scheme 1313 * locations, the repo field is extended rather than the name field. 1314 * <p> 1315 * Unlike most of the other methods of this class, the child() method 1316 * encodes the new child segment according to the requirements of the 1317 * scheme. Thus, this method may be used to add only one segment at a time 1318 * to the StpLocation. In any scheme, any embedded segment delimiters in the 1319 * child segment will be encoded to make them part of the segment. 1320 * <p> 1321 * Even if this method successfully returns an StpLocation, there is no 1322 * guarantee that the returned location is a valid resource location. The 1323 * returned location may be invalid even if the original location was valid. 1324 * Some resources simply do not have parents even though their location 1325 * suggests that they do. 1326 * <p> 1327 * For example, <b>field:Defect/Headline@7.0.0.0/SAMPL</b> is the location 1328 * for the description of the <b>Headline</b> field of the <b>Defect</b> 1329 * record type in the sample ClearQuest database. However, its parent 1330 * location, <b>field:Defect@7.0.0.0/SAMPL</b>, is <i>not</i> a valid 1331 * location. While this may seem to address the <b>Defect</b> record type 1332 * resource, it does not. The location for the <b>Defect</b> record type 1333 * resource is, in fact, <b><u>record</u>:Defect@7.0.0.0/SAMPL</b>, which 1334 * is in a different namespace from the parent of the field description 1335 * resource. 1336 * <p> 1337 * In general, clients are discouraged from manipulating locations to 1338 * traverse the object model. They should use the properties defined for 1339 * this purpose instead. If, for example, the client wants to traverse from 1340 * a field description to the record type of that field, then it should use 1341 * the RECORD_TYPE property of the field rather than taking the parent and 1342 * changing the namespace. Note that if the field location is a 1343 * stable-selector scheme location, simply changing the namespace of the 1344 * parent will not work. 1345 * 1346 * @param child The new segment to be appended to the name field of this 1347 * StpLocation. To be consistent with the Location.child method, 1348 * it is assumed that the String is not yet encoded. It will be 1349 * encoded as a single segment before adding it to the name 1350 * field. 1351 * 1352 * @return A new StpLocation with an extended name field. 1353 */ 1354 Location child(String child); 1355 1356 /** 1357 * Returns the last segment of the name field of this StpLocation. (Returns 1358 * the last segment of the repo field for repository-path-scheme locations.) 1359 * Any encoding used within the last segment is removed before returning a 1360 * value. Thus it's the case that 1361 * <b>loc.equals(loc.parent().child(loc.lastSegment()))</b> as long as 1362 * <b>loc.parent()</b> is not null. 1363 * <p> 1364 * At the root of the namespace (parent() returns <null>), returns either 1365 * the name of the root or the empty string if the root is unnamed. These 1366 * examples illustrate the edge cases <code><pre> 1367 * StpLocation | lastSegment | parent 1368 * -------------------+-------------+------------- 1369 * /food | food | / 1370 * / | <empty> | <null> 1371 * pname:/food | food | pname:/ 1372 * http://server/path | path | http://server 1373 * file://author/path | path | file://author 1374 * http://server | <empty> | <null> 1375 * file://author | <empty> | <null> 1376 * pname:path | path | <null> 1377 * pname:/ | <empty> | <null> 1378 * pname:\ | <empty> | <null> 1379 * record:food@cq:s/u | food | record:@cq:s/u 1380 * record:@cq:s/u | <empty> | <null> 1381 * </pre></code> 1382 * 1383 * @return A String containing the last segment of the name field of this 1384 * StpLocation stripped of all encodings. Will never be null, but 1385 * may be empty if the last segment is unnamed. 1386 */ 1387 String lastSegment(); 1388 1389 /** 1390 * Interprets this StpLocation as a file-path-scheme location and returns 1391 * the <i>canonical</i> pathname for the file. If this StpLocation is not a 1392 * file-path-scheme location, the original location specification used to 1393 * construct this StpLocation is used as the pathname to be canonicalized. 1394 * <p> 1395 * For a location in the FILE namespace, this method constructs a URI from 1396 * the given file-scheme URL and then constructs a java.io.File from that 1397 * URI. Whether or not this succeeds depends on the JVM. (IBM's JVM 1.4.2, 1398 * for example, requires that the authority portion be empty.) 1399 * 1400 * @see java.io.File#getCanonicalPath() 1401 * 1402 * @return The canonicalized pathname for this resource. Will never be 1403 * <b>null</b>. 1404 * 1405 * @throws StpException if IO errors are encountered while determining the 1406 * canonical path or converting the file-scheme URL to a File. 1407 */ 1408 String getCanonicalPath() throws StpException; 1409 1410 /** 1411 * Returns a File object that references the path defined by this 1412 * StpLocation. If this StpLocation is not a file-path-scheme location, the 1413 * original location specification used to construct this StpLocation is 1414 * used as the pathname from which the java.io.File object is constructed. 1415 * <p> 1416 * For a location in the FILE namespace, this method constructs a URI from 1417 * the given URL and then constructs a java.io.File from that URI. Whether 1418 * or not this succeeds depends on the JVM. (IBM's JVM 1.4.2, for example, 1419 * requires that the authority portion be undefined.) 1420 * 1421 * @return A File object for the path defined by this StpLocation; Will 1422 * never be <b>null</b>. 1423 * 1424 * @throws MalformedURLException if the selector is a file scheme URL for 1425 * which a File cannot be constructed. 1426 * @throws StpException 1427 * @throws IllegalStateException If {@link #isFilePathScheme()} is <b> false</b>. 1428 */ 1429 File getFile() throws MalformedURLException, StpException; 1430 1431 }