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