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>&lt;domain></i>.][<i>&lt;namespace></i>]:] [<i>&lt;object-name></i>][&#64;[<i>&lt;repository-name></i>]]
061     * <p>
062     * The <i>&lt;object-name></i>, and <i>&lt;repository-name></i> fields are
063     * segmented names where the segments are separated by '/'s or '\'s. The
064     * permitted <i>&lt;namespace></i>s are defined by
065     * {@link StpLocation.Namespace} and the permitted <i>&lt;domain></i>s are
066     * defined by {@link StpProvider.Domain}.
067     * <p>
068     * The character '&#64;' 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>&lt;domain></i>.][<i>&lt;namespace></i>]:] [<i>&lt;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 "&lt;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      | &lt;null&gt; 
1306         *      file://author      | &lt;null&gt; 
1307         *      pname:path         | &lt;null&gt;      
1308         *      file:/             | &lt;null&gt;      
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 &lt;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         *      /                  |  &lt;empty&gt;    | &lt;null&gt;       
1378         *      pname:/food        |   food      | pname:/
1379         *      http://server/path |   path      | http://server
1380         *      file://author/path |   path      | file://author
1381         *      http://server      |  &lt;empty&gt;    | &lt;null&gt;
1382         *      file://author      |  &lt;empty&gt;    | &lt;null&gt;
1383         *      pname:path         |   path      | &lt;null&gt;
1384         *      pname:/            |  &lt;empty&gt;    | &lt;null&gt;
1385         *      pname:\            |  &lt;empty&gt;    | &lt;null&gt;
1386         *      record:food@cq:s/u |   food      | record:@cq:s/u
1387         *      record:@cq:s/u     |  &lt;empty&gt;    | &lt;null&gt;
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    }