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