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