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