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