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