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
014 package com.ibm.rational.wvcm.stp;
015
016 import java.io.File;
017 import java.io.Serializable;
018 import java.net.MalformedURLException;
019 import java.util.EnumSet;
020 import java.util.Hashtable;
021 import java.util.Map;
022
023 import javax.wvcm.Location;
024 import javax.wvcm.Resource;
025 import javax.wvcm.WvcmException;
026
027 import com.ibm.rational.wvcm.stpex.StpExEnumeration;
028 import 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><domain></i>.][<i><namespace></i>]:] [<i><object-name></i>][@[<i><repository-name></i>]]
062 * <p>
063 * The <i><object-name></i>, and <i><repository-name></i> fields are
064 * segmented names where the segments are separated by '/'s or '\'s. The
065 * permitted <i><namespace></i>s are defined by
066 * {@link StpLocation.Namespace} and the permitted <i><domain></i>s are
067 * defined by {@link StpProvider.Domain}.
068 * <p>
069 * The character '@' 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><domain></i>.][<i><namespace></i>]:] [<i><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 */
107 public 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 "<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 | <null>
1378 * file://author | <null>
1379 * pname:path | <null>
1380 * file:/ | <null>
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 <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 * / | <empty> | <null>
1450 * pname:/food | food | pname:/
1451 * http://server/path | path | http://server
1452 * file://author/path | path | file://author
1453 * http://server | <empty> | <null>
1454 * file://author | <empty> | <null>
1455 * pname:path | path | <null>
1456 * pname:/ | <empty> | <null>
1457 * pname:\ | <empty> | <null>
1458 * record:food@cq:s/u | food | record:@cq:s/u
1459 * record:@cq:s/u | <empty> | <null>
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 }