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 }