Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/naming/CompositeName.java
38829 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.naming;2627import java.util.Enumeration;28import java.util.Properties;2930/**31* This class represents a composite name -- a sequence of32* component names spanning multiple namespaces.33* Each component is a string name from the namespace of a34* naming system. If the component comes from a hierarchical35* namespace, that component can be further parsed into36* its atomic parts by using the CompoundName class.37*<p>38* The components of a composite name are numbered. The indexes of a39* composite name with N components range from 0 up to, but not including, N.40* This range may be written as [0,N).41* The most significant component is at index 0.42* An empty composite name has no components.43*44* <h1>JNDI Composite Name Syntax</h1>45* JNDI defines a standard string representation for composite names. This46* representation is the concatenation of the components of a composite name47* from left to right using the component separator (a forward48* slash character (/)) to separate each component.49* The JNDI syntax defines the following meta characters:50* <ul>51* <li>escape (backward slash \),52* <li>quote characters (single (') and double quotes (")), and53* <li>component separator (forward slash character (/)).54* </ul>55* Any occurrence of a leading quote, an escape preceding any meta character,56* an escape at the end of a component, or a component separator character57* in an unquoted component must be preceded by an escape character when58* that component is being composed into a composite name string.59* Alternatively, to avoid adding escape characters as described,60* the entire component can be quoted using matching single quotes61* or matching double quotes. A single quote occurring within a double-quoted62* component is not considered a meta character (and need not be escaped),63* and vice versa.64*<p>65* When two composite names are compared, the case of the characters66* is significant.67*<p>68* A leading component separator (the composite name string begins with69* a separator) denotes a leading empty component (a component consisting70* of an empty string).71* A trailing component separator (the composite name string ends with72* a separator) denotes a trailing empty component.73* Adjacent component separators denote an empty component.74*75*<h1>Composite Name Examples</h1>76*This table shows examples of some composite names. Each row shows77*the string form of a composite name and its corresponding structural form78*(<tt>CompositeName</tt>).79*80<table border="1" cellpadding=3 summary="examples showing string form of composite name and its corresponding structural form (CompositeName)">8182<tr>83<th>String Name</th>84<th>CompositeName</th>85</tr>8687<tr>88<td>89""90</td>91<td>{} (the empty name == new CompositeName("") == new CompositeName())92</td>93</tr>9495<tr>96<td>97"x"98</td>99<td>{"x"}100</td>101</tr>102103<tr>104<td>105"x/y"106</td>107<td>{"x", "y"}</td>108</tr>109110<tr>111<td>"x/"</td>112<td>{"x", ""}</td>113</tr>114115<tr>116<td>"/x"</td>117<td>{"", "x"}</td>118</tr>119120<tr>121<td>"/"</td>122<td>{""}</td>123</tr>124125<tr>126<td>"//"</td>127<td>{"", ""}</td>128</tr>129130<tr><td>"/x/"</td>131<td>{"", "x", ""}</td>132</tr>133134<tr><td>"x//y"</td>135<td>{"x", "", "y"}</td>136</tr>137</table>138*139*<h1>Composition Examples</h1>140* Here are some composition examples. The right column shows composing141* string composite names while the left column shows composing the142* corresponding <tt>CompositeName</tt>s. Notice that composing the143* string forms of two composite names simply involves concatenating144* their string forms together.145146<table border="1" cellpadding=3 summary="composition examples showing string names and composite names">147148<tr>149<th>String Names</th>150<th>CompositeNames</th>151</tr>152153<tr>154<td>155"x/y" + "/" = x/y/156</td>157<td>158{"x", "y"} + {""} = {"x", "y", ""}159</td>160</tr>161162<tr>163<td>164"" + "x" = "x"165</td>166<td>167{} + {"x"} = {"x"}168</td>169</tr>170171<tr>172<td>173"/" + "x" = "/x"174</td>175<td>176{""} + {"x"} = {"", "x"}177</td>178</tr>179180<tr>181<td>182"x" + "" + "" = "x"183</td>184<td>185{"x"} + {} + {} = {"x"}186</td>187</tr>188189</table>190*191*<h1>Multithreaded Access</h1>192* A <tt>CompositeName</tt> instance is not synchronized against concurrent193* multithreaded access. Multiple threads trying to access and modify a194* <tt>CompositeName</tt> should lock the object.195*196* @author Rosanna Lee197* @author Scott Seligman198* @since 1.3199*/200201202public class CompositeName implements Name {203204private transient NameImpl impl;205/**206* Constructs a new composite name instance using the components207* specified by 'comps'. This protected method is intended to be208* to be used by subclasses of CompositeName when they override209* methods such as clone(), getPrefix(), getSuffix().210*211* @param comps A non-null enumeration containing the components for the new212* composite name. Each element is of class String.213* The enumeration will be consumed to extract its214* elements.215*/216protected CompositeName(Enumeration<String> comps) {217impl = new NameImpl(null, comps); // null means use default syntax218}219220/**221* Constructs a new composite name instance by parsing the string n222* using the composite name syntax (left-to-right, slash separated).223* The composite name syntax is described in detail in the class224* description.225*226* @param n The non-null string to parse.227* @exception InvalidNameException If n has invalid composite name syntax.228*/229public CompositeName(String n) throws InvalidNameException {230impl = new NameImpl(null, n); // null means use default syntax231}232233/**234* Constructs a new empty composite name. Such a name returns true235* when <code>isEmpty()</code> is invoked on it.236*/237public CompositeName() {238impl = new NameImpl(null); // null means use default syntax239}240241/**242* Generates the string representation of this composite name.243* The string representation consists of enumerating in order244* each component of the composite name and separating245* each component by a forward slash character. Quoting and246* escape characters are applied where necessary according to247* the JNDI syntax, which is described in the class description.248* An empty component is represented by an empty string.249*250* The string representation thus generated can be passed to251* the CompositeName constructor to create a new equivalent252* composite name.253*254* @return A non-null string representation of this composite name.255*/256public String toString() {257return impl.toString();258}259260/**261* Determines whether two composite names are equal.262* If obj is null or not a composite name, false is returned.263* Two composite names are equal if each component in one is equal264* to the corresponding component in the other. This implies265* both have the same number of components, and each component's266* equals() test against the corresponding component in the other name267* returns true.268*269* @param obj The possibly null object to compare against.270* @return true if obj is equal to this composite name, false otherwise.271* @see #hashCode272*/273public boolean equals(Object obj) {274return (obj != null &&275obj instanceof CompositeName &&276impl.equals(((CompositeName)obj).impl));277}278279/**280* Computes the hash code of this composite name.281* The hash code is the sum of the hash codes of individual components282* of this composite name.283*284* @return An int representing the hash code of this name.285* @see #equals286*/287public int hashCode() {288return impl.hashCode();289}290291292/**293* Compares this CompositeName with the specified Object for order.294* Returns a295* negative integer, zero, or a positive integer as this Name is less296* than, equal to, or greater than the given Object.297* <p>298* If obj is null or not an instance of CompositeName, ClassCastException299* is thrown.300* <p>301* See equals() for what it means for two composite names to be equal.302* If two composite names are equal, 0 is returned.303* <p>304* Ordering of composite names follows the lexicographical rules for305* string comparison, with the extension that this applies to all306* the components in the composite name. The effect is as if all the307* components were lined up in their specified ordered and the308* lexicographical rules applied over the two line-ups.309* If this composite name is "lexicographically" lesser than obj,310* a negative number is returned.311* If this composite name is "lexicographically" greater than obj,312* a positive number is returned.313* @param obj The non-null object to compare against.314*315* @return a negative integer, zero, or a positive integer as this Name316* is less than, equal to, or greater than the given Object.317* @exception ClassCastException if obj is not a CompositeName.318*/319public int compareTo(Object obj) {320if (!(obj instanceof CompositeName)) {321throw new ClassCastException("Not a CompositeName");322}323return impl.compareTo(((CompositeName)obj).impl);324}325326/**327* Generates a copy of this composite name.328* Changes to the components of this composite name won't329* affect the new copy and vice versa.330*331* @return A non-null copy of this composite name.332*/333public Object clone() {334return (new CompositeName(getAll()));335}336337/**338* Retrieves the number of components in this composite name.339*340* @return The nonnegative number of components in this composite name.341*/342public int size() {343return (impl.size());344}345346/**347* Determines whether this composite name is empty. A composite name348* is empty if it has zero components.349*350* @return true if this composite name is empty, false otherwise.351*/352public boolean isEmpty() {353return (impl.isEmpty());354}355356/**357* Retrieves the components of this composite name as an enumeration358* of strings.359* The effects of updates to this composite name on this enumeration360* is undefined.361*362* @return A non-null enumeration of the components of363* this composite name. Each element of the enumeration is of364* class String.365*/366public Enumeration<String> getAll() {367return (impl.getAll());368}369370/**371* Retrieves a component of this composite name.372*373* @param posn The 0-based index of the component to retrieve.374* Must be in the range [0,size()).375* @return The non-null component at index posn.376* @exception ArrayIndexOutOfBoundsException if posn is outside the377* specified range.378*/379public String get(int posn) {380return (impl.get(posn));381}382383/**384* Creates a composite name whose components consist of a prefix of the385* components in this composite name. Subsequent changes to386* this composite name does not affect the name that is returned.387*388* @param posn The 0-based index of the component at which to stop.389* Must be in the range [0,size()].390* @return A composite name consisting of the components at indexes in391* the range [0,posn).392* @exception ArrayIndexOutOfBoundsException393* If posn is outside the specified range.394*/395public Name getPrefix(int posn) {396Enumeration<String> comps = impl.getPrefix(posn);397return (new CompositeName(comps));398}399400/**401* Creates a composite name whose components consist of a suffix of the402* components in this composite name. Subsequent changes to403* this composite name does not affect the name that is returned.404*405* @param posn The 0-based index of the component at which to start.406* Must be in the range [0,size()].407* @return A composite name consisting of the components at indexes in408* the range [posn,size()). If posn is equal to409* size(), an empty composite name is returned.410* @exception ArrayIndexOutOfBoundsException411* If posn is outside the specified range.412*/413public Name getSuffix(int posn) {414Enumeration<String> comps = impl.getSuffix(posn);415return (new CompositeName(comps));416}417418/**419* Determines whether a composite name is a prefix of this composite name.420* A composite name 'n' is a prefix if it is equal to421* getPrefix(n.size())--in other words, this composite name422* starts with 'n'. If 'n' is null or not a composite name, false is returned.423*424* @param n The possibly null name to check.425* @return true if n is a CompositeName and426* is a prefix of this composite name, false otherwise.427*/428public boolean startsWith(Name n) {429if (n instanceof CompositeName) {430return (impl.startsWith(n.size(), n.getAll()));431} else {432return false;433}434}435436/**437* Determines whether a composite name is a suffix of this composite name.438* A composite name 'n' is a suffix if it it is equal to439* getSuffix(size()-n.size())--in other words, this440* composite name ends with 'n'.441* If n is null or not a composite name, false is returned.442*443* @param n The possibly null name to check.444* @return true if n is a CompositeName and445* is a suffix of this composite name, false otherwise.446*/447public boolean endsWith(Name n) {448if (n instanceof CompositeName) {449return (impl.endsWith(n.size(), n.getAll()));450} else {451return false;452}453}454455/**456* Adds the components of a composite name -- in order -- to the end of457* this composite name.458*459* @param suffix The non-null components to add.460* @return The updated CompositeName, not a new one. Cannot be null.461* @exception InvalidNameException If suffix is not a composite name.462*/463public Name addAll(Name suffix)464throws InvalidNameException465{466if (suffix instanceof CompositeName) {467impl.addAll(suffix.getAll());468return this;469} else {470throw new InvalidNameException("Not a composite name: " +471suffix.toString());472}473}474475/**476* Adds the components of a composite name -- in order -- at a specified477* position within this composite name.478* Components of this composite name at or after the index of the first479* new component are shifted up (away from index 0)480* to accommodate the new components.481*482* @param n The non-null components to add.483* @param posn The index in this name at which to add the new484* components. Must be in the range [0,size()].485* @return The updated CompositeName, not a new one. Cannot be null.486* @exception InvalidNameException If n is not a composite name.487* @exception ArrayIndexOutOfBoundsException488* If posn is outside the specified range.489*/490public Name addAll(int posn, Name n)491throws InvalidNameException492{493if (n instanceof CompositeName) {494impl.addAll(posn, n.getAll());495return this;496} else {497throw new InvalidNameException("Not a composite name: " +498n.toString());499}500}501502/**503* Adds a single component to the end of this composite name.504*505* @param comp The non-null component to add.506* @return The updated CompositeName, not a new one. Cannot be null.507* @exception InvalidNameException If adding comp at end of the name508* would violate the name's syntax.509*/510public Name add(String comp) throws InvalidNameException {511impl.add(comp);512return this;513}514515/**516* Adds a single component at a specified position within this517* composite name.518* Components of this composite name at or after the index of the new519* component are shifted up by one (away from index 0) to accommodate520* the new component.521*522* @param comp The non-null component to add.523* @param posn The index at which to add the new component.524* Must be in the range [0,size()].525* @return The updated CompositeName, not a new one. Cannot be null.526* @exception ArrayIndexOutOfBoundsException527* If posn is outside the specified range.528* @exception InvalidNameException If adding comp at the specified position529* would violate the name's syntax.530*/531public Name add(int posn, String comp)532throws InvalidNameException533{534impl.add(posn, comp);535return this;536}537538/**539* Deletes a component from this composite name.540* The component of this composite name at position 'posn' is removed,541* and components at indices greater than 'posn'542* are shifted down (towards index 0) by one.543*544* @param posn The index of the component to delete.545* Must be in the range [0,size()).546* @return The component removed (a String).547* @exception ArrayIndexOutOfBoundsException548* If posn is outside the specified range (includes case where549* composite name is empty).550* @exception InvalidNameException If deleting the component551* would violate the name's syntax.552*/553public Object remove(int posn) throws InvalidNameException{554return impl.remove(posn);555}556557/**558* Overridden to avoid implementation dependency.559* @serialData The number of components (an <tt>int</tt>) followed by560* the individual components (each a <tt>String</tt>).561*/562private void writeObject(java.io.ObjectOutputStream s)563throws java.io.IOException {564s.writeInt(size());565Enumeration<String> comps = getAll();566while (comps.hasMoreElements()) {567s.writeObject(comps.nextElement());568}569}570571/**572* Overridden to avoid implementation dependency.573*/574private void readObject(java.io.ObjectInputStream s)575throws java.io.IOException, ClassNotFoundException {576impl = new NameImpl(null); // null means use default syntax577int n = s.readInt(); // number of components578try {579while (--n >= 0) {580add((String)s.readObject());581}582} catch (InvalidNameException e) {583throw (new java.io.StreamCorruptedException("Invalid name"));584}585}586587/**588* Use serialVersionUID from JNDI 1.1.1 for interoperability589*/590private static final long serialVersionUID = 1667768148915813118L;591592/*593// %%% Test code for serialization.594public static void main(String[] args) throws Exception {595CompositeName c = new CompositeName("aaa/bbb");596java.io.FileOutputStream f1 = new java.io.FileOutputStream("/tmp/ser");597java.io.ObjectOutputStream s1 = new java.io.ObjectOutputStream(f1);598s1.writeObject(c);599s1.close();600java.io.FileInputStream f2 = new java.io.FileInputStream("/tmp/ser");601java.io.ObjectInputStream s2 = new java.io.ObjectInputStream(f2);602c = (CompositeName)s2.readObject();603604System.out.println("Size: " + c.size());605System.out.println("Size: " + c.snit);606}607*/608609/*610%%% Testing code611public static void main(String[] args) {612try {613for (int i = 0; i < args.length; i++) {614Name name;615Enumeration e;616System.out.println("Given name: " + args[i]);617name = new CompositeName(args[i]);618e = name.getComponents();619while (e.hasMoreElements()) {620System.out.println("Element: " + e.nextElement());621}622System.out.println("Constructed name: " + name.toString());623}624} catch (Exception ne) {625ne.printStackTrace();626}627}628*/629}630631632