View | Details | Raw Unified | Return to bug 56787
Collapse All | Expand All

(-)java/org/apache/naming/SimpleName.java (+448 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package org.apache.naming;
18
19
import javax.naming.InvalidNameException;
20
import java.util.*;
21
22
23
/**
24
 * Simplified name parsing
25
 *
26
 * Around 6 times faster than the CompositeName
27
 *
28
 * @author Sheldon Shao (xshao@ebay.com)
29
 */
30
class SimpleName {
31
32
    private List<String> comps;
33
34
    private static final char syntaxSeparator = '/';
35
    private static final char syntaxEscape = '\\';
36
    private static final char syntaxBeginQuote1 = '\"';
37
    private static final char syntaxEndQuote1 = '\"';
38
    private static final char syntaxBeginQuote2 = '\'';
39
    private static final char syntaxEndQuote2 = '\'';
40
41
    private boolean isMeta(String n, int i) {
42
        char ch = n.charAt(i);
43
        return (ch == syntaxEscape) ||
44
                (ch == syntaxBeginQuote1) ||
45
                (ch == syntaxBeginQuote2) ||
46
                 ch == syntaxSeparator;
47
    }
48
49
    SimpleName() {
50
        comps = new ArrayList<String>(5);
51
    }
52
53
    SimpleName(List<String> comps) {
54
        this();
55
56
        this.comps.addAll(comps);
57
    }
58
59
    SimpleName(String name) throws InvalidNameException {
60
        this();
61
62
        boolean compsAllEmpty = true;
63
        int len = name.length();
64
65
        int off;
66
67
        char endQuote;
68
        boolean start;
69
        boolean one;
70
        StringBuilder sb = null;
71
72
        char ch;
73
74
        String comp;
75
        for (int i = 0; i < len; ) {
76
            off = i;
77
            start = true;
78
            one = false;
79
            if (sb != null) {
80
                sb.setLength(0);
81
            }
82
            while (i < len) {
83
                ch = name.charAt(i);
84
85
                // handle quoted strings
86
                if (start && ((one = ch == syntaxBeginQuote1)) || ch == syntaxBeginQuote2) {
87
                    // record choice of quote chars being used
88
                    endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2;
89
90
                    if (sb == null) {
91
                        sb = new StringBuilder(len);
92
                    }
93
94
                    // consume string until matching quote
95
                    for (i += 1; ((i < len) && (ch = name.charAt(i)) != endQuote);i++) {
96
                        // skip escape character if it is escaping ending quote
97
                        // otherwise leave as is.
98
                        if (ch == syntaxEscape && (ch = name.charAt(i + 1)) == endQuote) {
99
                            i += 1;
100
                        }
101
                        sb.append(ch);  // copy char
102
                    }
103
104
                    // no ending quote found
105
                    if (i >= len)
106
                        throw new InvalidNameException(name + ": no close quote");
107
108
                    i += 1;
109
                    // verify that end-quote occurs at separator or end of string
110
                    if (i == len || name.charAt(i) == syntaxSeparator) {
111
                        break;
112
                    }
113
                    throw (new InvalidNameException(name + ": close quote appears before end of component"));
114
                } else if (ch == syntaxSeparator) {
115
                    break;
116
                } else if (ch == syntaxEscape) {
117
                    if (isMeta(name, i + 1)) {
118
                        // if escape precedes meta, consume escape and let
119
                        // meta through
120
                        if (sb == null) {
121
                            sb = new StringBuilder(len);
122
                            sb.append(name, off, i);
123
                        }
124
                        i += 1;
125
                        ch = name.charAt(i);
126
                        //The 'ch' will be appended in the following code
127
                    } else if (i + 1 >= len) {
128
                        throw (new InvalidNameException(name + ": unescaped " + syntaxEscape + " at end of component"));
129
                    }
130
                }
131
132
                if (sb != null) {
133
                    sb.append(ch);
134
                }
135
                i ++;
136
                start = false;
137
            }
138
139
            if (sb != null) {
140
                comp = sb.toString();
141
            }
142
            else {
143
                comp = name.substring(off, i);
144
            }
145
            comps.add(comp);
146
147
            if (!comp.isEmpty()) {
148
                compsAllEmpty = false;
149
            }
150
151
            if (i < len) {
152
                if (name.charAt(i) == syntaxSeparator) {
153
                    i ++;
154
                }
155
                if ((i == len) && !compsAllEmpty) {
156
                    // Trailing separator found.  Add an empty component.
157
                    comps.add("");
158
                }
159
            }
160
        }
161
    }
162
163
    private String escape(String comp) {
164
        int len = comp.length();
165
        boolean escapeSeparator = true;
166
        char beginQuote = 0, endQuote = 0;
167
        StringBuilder sb = new StringBuilder(len);
168
169
        // determine whether there are any separators; if so escape or quote them
170
        if (comp.indexOf(syntaxSeparator) >= 0) {
171
            beginQuote = syntaxBeginQuote1;
172
            endQuote = syntaxEndQuote1;
173
        }
174
175
        // if quoting component,
176
        if (beginQuote != 0) {
177
            // start string off with opening quote
178
            sb = sb.append(beginQuote);
179
180
            // component is being quoted, so we only need to worry about
181
            // escaping end quotes that occur in component
182
            for (int i = 0; i < len; ) {
183
                if (comp.charAt(i) == endQuote) {
184
                    // end-quotes must be escaped when inside a quoted string
185
                    sb.append(syntaxEscape).append(endQuote);
186
                    i += 1;
187
                } else {
188
                    // no special treatment required
189
                    sb.append(comp.charAt(i++));
190
                }
191
            }
192
193
            // end with closing quote
194
            sb.append(endQuote);
195
196
        } else {
197
            // When component is not quoted, add escape for:
198
            // 1. leading quote
199
            // 2. an escape preceding any meta char
200
            // 3. an escape at the end of a component
201
            // 4. separator
202
203
            // go through characters in component and escape where necessary
204
            boolean start = true;
205
            for (int i = 0; i < len; ) {
206
                // leading quote must be escaped
207
                if (start && comp.charAt(i) == syntaxBeginQuote1) {
208
                    sb.append(syntaxEscape).append(syntaxBeginQuote1);
209
                    i += 1;
210
                } else if (start && comp.charAt(i) == syntaxBeginQuote2) {
211
                    sb.append(syntaxEscape).append(syntaxBeginQuote2);
212
                    i += 1;
213
                } else
214
215
                    // Escape an escape preceding meta characters, or at end.
216
                    // Other escapes pass through.
217
                    if (comp.charAt(i) == syntaxEscape) {
218
                        if (i + 1 >= len) {
219
                            // escape an ending escape
220
                            sb.append(syntaxEscape);
221
                        } else if (isMeta(comp, i + 1)) {
222
                            // escape meta strings
223
                            sb.append(syntaxEscape);
224
                        }
225
                        sb.append(syntaxEscape);
226
                        i += 1;
227
                    } else
228
229
                        // escape unescaped separator
230
                        if (escapeSeparator && comp.charAt(i) == syntaxSeparator) {
231
                            // escape separator
232
                            sb.append(syntaxEscape).append(syntaxSeparator);
233
                            i += 1;
234
                        }else {
235
                            // no special treatment required
236
                            sb.append(comp.charAt(i++));
237
                        }
238
                start = false;
239
            }
240
        }
241
        return (sb.toString());
242
    }
243
244
245
246
    public String toString() {
247
        StringBuilder sb = new StringBuilder();
248
        String comp;
249
        boolean compsAllEmpty = true;
250
        int size = comps.size();
251
252
        for (int i = 0; i < size; i++) {
253
            comp = escape(comps.get(i));
254
            if ((i != 0))
255
                sb.append(syntaxSeparator);
256
            if (comp.length() >= 1)
257
                compsAllEmpty = false;
258
            sb = sb.append(comp);
259
        }
260
        if (compsAllEmpty && (size >= 1))
261
            sb = sb.append(syntaxSeparator);
262
        return (sb.toString());
263
    }
264
265
    public boolean equals(Object obj) {
266
        if ((obj != null) && (obj instanceof SimpleName)) {
267
            SimpleName target = (SimpleName)obj;
268
            int size = size();
269
            if (target.size() == size) {
270
                List<String> mycomps = comps;
271
                List<String> comps = target.comps;
272
273
                for(int i = 0; i < size; i ++) {
274
                    // %% comps could shrink in the middle.
275
                    String my = mycomps.get(i);
276
                    String his = comps.get(i);
277
                    if (!(my.equals(his)))
278
                        return false;
279
                }
280
                return true;
281
            }
282
        }
283
        return false;
284
    }
285
286
    /**
287
     * Compares obj to this SimpleName to determine ordering.
288
     * Takes into account syntactic properties such as
289
     * elimination of blanks, case-ignore, etc, if relevant.
290
     *
291
     * Note: using syntax of this NameImpl and ignoring
292
     * that of comparison target.
293
     */
294
    public int compareTo(SimpleName obj) {
295
        if (this == obj) {
296
            return 0;
297
        }
298
299
        int len1 = size();
300
        int len2 = obj.size();
301
        int n = Math.min(len1, len2);
302
303
        int index1 = 0, index2 = 0;
304
305
        while (n-- != 0) {
306
            String comp1 = get(index1++);
307
            String comp2 = obj.get(index2++);
308
309
            // normalize according to syntax
310
            int local = comp1.compareTo(comp2);
311
            if (local != 0) {
312
                return local;
313
            }
314
        }
315
316
        return len1 - len2;
317
    }
318
319
    public int size() {
320
        return (comps.size());
321
    }
322
323
    public List<String> getComponents() {
324
        return comps;
325
    }
326
327
    public String get(int pos) {
328
        return comps.get(pos);
329
    }
330
331
    public List<String> getPrefix(int pos) {
332
        int size = size();
333
        if (pos < 0 || pos > size) {
334
            throw new ArrayIndexOutOfBoundsException("Invalid position: " + pos + ", it should be [0, " + size + "].");
335
        }
336
        return comps.subList(0, pos);
337
    }
338
339
    public List<String> getSuffix(int pos) {
340
        int size = size();
341
        if (pos < 0 || pos > size) {
342
            throw new ArrayIndexOutOfBoundsException("Invalid position: " + pos + ", it should be [0, " + size + "].");
343
        }
344
        return comps.subList(pos, size);
345
    }
346
347
    public boolean isEmpty() {
348
        return (comps.isEmpty());
349
    }
350
351
    public boolean startsWith(int pos, Enumeration<String> prefix) {
352
        if (pos < 0 || pos > size()) {
353
            return false;
354
        }
355
        try {
356
            List<String> myComps = getPrefix(pos);
357
            for(String my : myComps) {
358
                String his = prefix.nextElement();
359
                if (!(my.equals(his)))
360
                    return false;
361
            }
362
        } catch (NoSuchElementException e) {
363
            return false;
364
        }
365
        return true;
366
    }
367
368
    public boolean endsWith(int pos, Enumeration<String> suffix) {
369
        int size = size();
370
        int startIndex = size - pos;
371
        if (startIndex < 0 || startIndex > size) {
372
            return false;
373
        }
374
        try {
375
            List<String> myComps = getSuffix(startIndex);
376
            for(String my: myComps) {
377
                String his = suffix.nextElement();
378
                if (!(my.equals(his)))
379
                    return false;
380
            }
381
        } catch (NoSuchElementException e) {
382
            return false;
383
        }
384
        return true;
385
    }
386
387
    public boolean addAll(Enumeration<String> comps) throws InvalidNameException {
388
        boolean added = false;
389
        while (comps.hasMoreElements()) {
390
            try {
391
                String comp = comps.nextElement();
392
                if (size() > 0) {
393
                    throw new InvalidNameException("A flat name can only have a single component");
394
                }
395
                this.comps.add(comp);
396
                added = true;
397
            } catch (NoSuchElementException e) {
398
                break;  // "comps" has shrunk.
399
            }
400
        }
401
        return added;
402
    }
403
404
    public boolean addAll(int pos, Enumeration<String> comps)
405
            throws InvalidNameException {
406
        boolean added = false;
407
        for (int i = pos; comps.hasMoreElements(); i++) {
408
            try {
409
                String comp = comps.nextElement();
410
                if (size() > 0) {
411
                    throw new InvalidNameException("A flat name can only have a single component");
412
                }
413
                this.comps.add(i, comp);
414
                added = true;
415
            } catch (NoSuchElementException e) {
416
                break;  // "comps" has shrunk.
417
            }
418
        }
419
        return added;
420
    }
421
422
    public void add(String comp) throws InvalidNameException {
423
        if (size() > 0) {
424
            throw new InvalidNameException("A flat name can only have a single component");
425
        }
426
        comps.add(comp);
427
    }
428
429
    public void add(int pos, String comp) throws InvalidNameException {
430
        if (size() > 0) {
431
            throw new InvalidNameException("A flat name can only zero or one component");
432
        }
433
        comps.add(pos, comp);
434
    }
435
436
    public Object remove(int pos) {
437
        return comps.remove(pos);
438
    }
439
440
    public int hashCode() {
441
        int hash = 0;
442
        for (String comp: comps) {
443
            hash += comp.hashCode();
444
        }
445
        return hash;
446
    }
447
}
448
native
(-)java/org/apache/naming/SimpleCompositeName.java (+409 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package org.apache.naming;
18
19
import javax.naming.InvalidNameException;
20
import javax.naming.Name;
21
import java.util.Collections;
22
import java.util.Enumeration;
23
import java.util.List;
24
25
public class SimpleCompositeName implements Name {
26
27
    private transient SimpleName impl;
28
    /**
29
     * Constructs a new composite name instance using the components
30
     * specified by 'comps'. This protected method is intended to be
31
     * to be used by subclasses of CompositeName when they override
32
     * methods such as clone(), getPrefix(), getSuffix().
33
     *
34
     * @param comps A non-null enumeration containing the components for the new
35
     *              composite name. Each element is of class String.
36
     *               The enumeration will be consumed to extract its
37
     *               elements.
38
     */
39
    protected SimpleCompositeName(List<String> comps) {
40
        impl = new SimpleName(comps); // null means use default syntax
41
    }
42
43
    /**
44
     * Constructs a new composite name instance by parsing the string n
45
     * using the composite name syntax (left-to-right, slash separated).
46
     * The composite name syntax is described in detail in the class
47
     * description.
48
     *
49
     * @param  n       The non-null string to parse.
50
     * @exception javax.naming.InvalidNameException If n has invalid composite name syntax.
51
     */
52
    public SimpleCompositeName(String n) throws InvalidNameException {
53
        impl = new SimpleName(n);  // null means use default syntax
54
    }
55
56
    /**
57
     * Constructs a new empty composite name. Such a name returns true
58
     * when <code>isEmpty()</code> is invoked on it.
59
     */
60
    public SimpleCompositeName() {
61
        impl = new SimpleName();  // null means use default syntax
62
    }
63
64
    /**
65
     * Generates the string representation of this composite name.
66
     * The string representation consists of enumerating in order
67
     * each component of the composite name and separating
68
     * each component by a forward slash character. Quoting and
69
     * escape characters are applied where necessary according to
70
     * the JNDI syntax, which is described in the class description.
71
     * An empty component is represented by an empty string.
72
     *
73
     * The string representation thus generated can be passed to
74
     * the CompositeName constructor to create a new equivalent
75
     * composite name.
76
     *
77
     * @return A non-null string representation of this composite name.
78
     */
79
    public String toString() {
80
        return impl.toString();
81
    }
82
83
    /**
84
     * Determines whether two composite names are equal.
85
     * If obj is null or not a composite name, false is returned.
86
     * Two composite names are equal if each component in one is equal
87
     * to the corresponding component in the other. This implies
88
     * both have the same number of components, and each component's
89
     * equals() test against the corresponding component in the other name
90
     * returns true.
91
     *
92
     * @param  obj     The possibly null object to compare against.
93
     * @return true if obj is equal to this composite name, false otherwise.
94
     * @see #hashCode
95
     */
96
    public boolean equals(Object obj) {
97
        return (obj != null &&
98
                obj instanceof SimpleCompositeName &&
99
                impl.equals(((SimpleCompositeName)obj).impl));
100
    }
101
102
    /**
103
     * Computes the hash code of this composite name.
104
     * The hash code is the sum of the hash codes of individual components
105
     * of this composite name.
106
     *
107
     * @return An int representing the hash code of this name.
108
     * @see #equals
109
     */
110
    public int hashCode() {
111
        return impl.hashCode();
112
    }
113
114
115
    /**
116
     * Compares this CompositeName with the specified Object for order.
117
     * Returns a
118
     * negative integer, zero, or a positive integer as this Name is less
119
     * than, equal to, or greater than the given Object.
120
     * <p>
121
     * If obj is null or not an instance of CompositeName, ClassCastException
122
     * is thrown.
123
     * <p>
124
     * See equals() for what it means for two composite names to be equal.
125
     * If two composite names are equal, 0 is returned.
126
     * <p>
127
     * Ordering of composite names follows the lexicographical rules for
128
     * string comparison, with the extension that this applies to all
129
     * the components in the composite name. The effect is as if all the
130
     * components were lined up in their specified ordered and the
131
     * lexicographical rules applied over the two line-ups.
132
     * If this composite name is "lexicographically" lesser than obj,
133
     * a negative number is returned.
134
     * If this composite name is "lexicographically" greater than obj,
135
     * a positive number is returned.
136
     * @param obj The non-null object to compare against.
137
     *
138
     * @return  a negative integer, zero, or a positive integer as this Name
139
     *          is less than, equal to, or greater than the given Object.
140
     * @exception ClassCastException if obj is not a CompositeName.
141
     */
142
    public int compareTo(Object obj) {
143
        if (!(obj instanceof SimpleCompositeName)) {
144
            throw new ClassCastException("Not a SimpleCompositeName");
145
        }
146
        return impl.compareTo(((SimpleCompositeName)obj).impl);
147
    }
148
149
    /**
150
     * Generates a copy of this composite name.
151
     * Changes to the components of this composite name won't
152
     * affect the new copy and vice versa.
153
     *
154
     * @return A non-null copy of this composite name.
155
     */
156
    public Object clone() {
157
        return (new SimpleCompositeName(impl.getComponents()));
158
    }
159
160
    /**
161
     * Retrieves the number of components in this composite name.
162
     *
163
     * @return The nonnegative number of components in this composite name.
164
     */
165
    public int size() {
166
        return (impl.size());
167
    }
168
169
    /**
170
     * Determines whether this composite name is empty. A composite name
171
     * is empty if it has zero components.
172
     *
173
     * @return true if this composite name is empty, false otherwise.
174
     */
175
    public boolean isEmpty() {
176
        return (impl.isEmpty());
177
    }
178
179
    /**
180
     * Retrieves the components of this composite name as an enumeration
181
     * of strings.
182
     * The effects of updates to this composite name on this enumeration
183
     * is undefined.
184
     *
185
     * @return A non-null enumeration of the components of
186
     *         this composite name. Each element of the enumeration is of
187
     *         class String.
188
     */
189
    public Enumeration<String> getAll() {
190
        return Collections.enumeration(impl.getComponents());
191
    }
192
193
    /**
194
     * Retrieves a component of this composite name.
195
     *
196
     * @param  posn    The 0-based index of the component to retrieve.
197
     *                 Must be in the range [0,size()).
198
     * @return The non-null component at index posn.
199
     * @exception ArrayIndexOutOfBoundsException if posn is outside the
200
     *         specified range.
201
     */
202
    public String get(int posn) {
203
        return (impl.get(posn));
204
    }
205
206
    /**
207
     * Creates a composite name whose components consist of a prefix of the
208
     * components in this composite name. Subsequent changes to
209
     * this composite name does not affect the name that is returned.
210
     *
211
     * @param  pos    The 0-based index of the component at which to stop.
212
     *                 Must be in the range [0,size()].
213
     * @return A composite name consisting of the components at indexes in
214
     *         the range [0,posn).
215
     * @exception ArrayIndexOutOfBoundsException
216
     *         If posn is outside the specified range.
217
     */
218
    public Name getPrefix(int pos) {
219
        List<String> comps = impl.getPrefix(pos);
220
        return (new SimpleCompositeName(comps));
221
    }
222
223
    /**
224
     * Creates a composite name whose components consist of a suffix of the
225
     * components in this composite name. Subsequent changes to
226
     * this composite name does not affect the name that is returned.
227
     *
228
     * @param  pos    The 0-based index of the component at which to start.
229
     *                 Must be in the range [0,size()].
230
     * @return A composite name consisting of the components at indexes in
231
     *         the range [posn,size()).  If posn is equal to
232
     *         size(), an empty composite name is returned.
233
     * @exception ArrayIndexOutOfBoundsException
234
     *         If posn is outside the specified range.
235
     */
236
    public Name getSuffix(int pos) {
237
        List<String> comps = impl.getSuffix(pos);
238
        return (new SimpleCompositeName(comps));
239
    }
240
241
    /**
242
     * Determines whether a composite name is a prefix of this composite name.
243
     * A composite name 'n' is a prefix if it is equal to
244
     * getPrefix(n.size())--in other words, this composite name
245
     * starts with 'n'. If 'n' is null or not a composite name, false is returned.
246
     *
247
     * @param  n       The possibly null name to check.
248
     * @return true if n is a CompositeName and
249
     *         is a prefix of this composite name, false otherwise.
250
     */
251
    public boolean startsWith(Name n) {
252
        if (n instanceof SimpleCompositeName) {
253
            return (impl.startsWith(n.size(), n.getAll()));
254
        } else {
255
            return false;
256
        }
257
    }
258
259
    /**
260
     * Determines whether a composite name is a suffix of this composite name.
261
     * A composite name 'n' is a suffix if it it is equal to
262
     * getSuffix(size()-n.size())--in other words, this
263
     * composite name ends with 'n'.
264
     * If n is null or not a composite name, false is returned.
265
     *
266
     * @param  n       The possibly null name to check.
267
     * @return true if n is a CompositeName and
268
     *         is a suffix of this composite name, false otherwise.
269
     */
270
    public boolean endsWith(Name n) {
271
        if (n instanceof SimpleCompositeName) {
272
            return (impl.endsWith(n.size(), n.getAll()));
273
        } else {
274
            return false;
275
        }
276
    }
277
278
    /**
279
     * Adds the components of a composite name -- in order -- to the end of
280
     * this composite name.
281
     *
282
     * @param suffix   The non-null components to add.
283
     * @return The updated CompositeName, not a new one. Cannot be null.
284
     * @exception InvalidNameException If suffix is not a composite name.
285
     */
286
    public Name addAll(Name suffix)
287
            throws InvalidNameException
288
    {
289
        if (suffix instanceof SimpleCompositeName) {
290
            impl.addAll(suffix.getAll());
291
            return this;
292
        } else {
293
            throw new InvalidNameException("Not a composite name: " + suffix.toString());
294
        }
295
    }
296
297
    /**
298
     * Adds the components of a composite name -- in order -- at a specified
299
     * position within this composite name.
300
     * Components of this composite name at or after the index of the first
301
     * new component are shifted up (away from index 0)
302
     * to accommodate the new components.
303
     *
304
     * @param n        The non-null components to add.
305
     * @param posn     The index in this name at which to add the new
306
     *                 components.  Must be in the range [0,size()].
307
     * @return The updated CompositeName, not a new one. Cannot be null.
308
     * @exception InvalidNameException If n is not a composite name.
309
     * @exception ArrayIndexOutOfBoundsException
310
     *         If posn is outside the specified range.
311
     */
312
    public Name addAll(int posn, Name n)
313
            throws InvalidNameException
314
    {
315
        if (n instanceof SimpleCompositeName) {
316
            impl.addAll(posn, n.getAll());
317
            return this;
318
        } else {
319
            throw new InvalidNameException("Not a composite name: " +
320
                    n.toString());
321
        }
322
    }
323
324
    /**
325
     * Adds a single component to the end of this composite name.
326
     *
327
     * @param comp     The non-null component to add.
328
     * @return The updated CompositeName, not a new one. Cannot be null.
329
     * @exception InvalidNameException If adding comp at end of the name
330
     *                         would violate the name's syntax.
331
     */
332
    public Name add(String comp) throws InvalidNameException {
333
        impl.add(comp);
334
        return this;
335
    }
336
337
    /**
338
     * Adds a single component at a specified position within this
339
     * composite name.
340
     * Components of this composite name at or after the index of the new
341
     * component are shifted up by one (away from index 0) to accommodate
342
     * the new component.
343
     *
344
     * @param  comp    The non-null component to add.
345
     * @param  posn    The index at which to add the new component.
346
     *                 Must be in the range [0,size()].
347
     * @return The updated CompositeName, not a new one. Cannot be null.
348
     * @exception ArrayIndexOutOfBoundsException
349
     *         If posn is outside the specified range.
350
     * @exception InvalidNameException If adding comp at the specified position
351
     *                         would violate the name's syntax.
352
     */
353
    public Name add(int posn, String comp)
354
            throws InvalidNameException
355
    {
356
        impl.add(posn, comp);
357
        return this;
358
    }
359
360
    /**
361
     * Deletes a component from this composite name.
362
     * The component of this composite name at position 'posn' is removed,
363
     * and components at indices greater than 'posn'
364
     * are shifted down (towards index 0) by one.
365
     *
366
     * @param  posn    The index of the component to delete.
367
     *                 Must be in the range [0,size()).
368
     * @return The component removed (a String).
369
     * @exception ArrayIndexOutOfBoundsException
370
     *         If posn is outside the specified range (includes case where
371
     *         composite name is empty).
372
     * @exception InvalidNameException If deleting the component
373
     *                         would violate the name's syntax.
374
     */
375
    public Object remove(int posn) throws InvalidNameException{
376
        return impl.remove(posn);
377
    }
378
379
    /**
380
     * Overridden to avoid implementation dependency.
381
     * @serialData The number of components (an <tt>int</tt>) followed by
382
     * the individual components (each a <tt>String</tt>).
383
     */
384
    private void writeObject(java.io.ObjectOutputStream s)
385
            throws java.io.IOException {
386
        s.writeInt(size());
387
        Enumeration<String> comps = getAll();
388
        while (comps.hasMoreElements()) {
389
            s.writeObject(comps.nextElement());
390
        }
391
    }
392
393
    /**
394
     * Overridden to avoid implementation dependency.
395
     */
396
    private void readObject(java.io.ObjectInputStream s)
397
            throws java.io.IOException, ClassNotFoundException {
398
        impl = new SimpleName();  // null means use default syntax
399
        int n = s.readInt();    // number of components
400
        try {
401
            while (--n >= 0) {
402
                add((String)s.readObject());
403
            }
404
        } catch (InvalidNameException e) {
405
            throw (new java.io.StreamCorruptedException("Invalid name"));
406
        }
407
    }
408
}
409
native
(-)test/org/apache/naming/TestSimpleName.java (+293 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
package org.apache.naming;
18
19
import org.junit.Test;
20
21
import javax.naming.CompositeName;
22
import javax.naming.InvalidNameException;
23
import javax.naming.Name;
24
import javax.naming.NamingException;
25
26
import static org.junit.Assert.assertEquals;
27
import static org.junit.Assert.fail;
28
29
/**
30
 * Test case for SimpleName
31
 */
32
public class TestSimpleName {
33
34
    @Test
35
    public void testSimpleName() throws NamingException {
36
37
        CompositeName cn = new CompositeName("/META-INF/javax.naming.Name");
38
39
        assertEquals(cn.size(), 3);
40
        assertEquals(cn.get(0), "");
41
        assertEquals(cn.get(1), "META-INF");
42
        assertEquals(cn.get(2), "javax.naming.Name");
43
44
        SimpleName name = new SimpleName("/META-INF/javax.naming.Name");
45
46
        assertEquals(name.size(), 3);
47
        assertEquals(name.get(0), "");
48
        assertEquals(name.get(1), "META-INF");
49
        assertEquals(name.get(2), "javax.naming.Name");
50
51
    }
52
53
    @Test
54
    public void testAB() throws NamingException {
55
56
        int warmupTimes = 1000;
57
58
        for(int i = 0; i < warmupTimes; i ++) {
59
            CompositeName cn = new CompositeName("/META-INF/javax.naming.Name");
60
            SimpleName name = new SimpleName("/META-INF/javax.naming.Name");
61
        }
62
63
        int invocation = 1000000;
64
65
        long start = System.currentTimeMillis();
66
        for(int i = 0; i < invocation; i ++) {
67
            CompositeName cn = new CompositeName("/META-INF/javax.naming.Name");
68
        }
69
        long end = System.currentTimeMillis();
70
        System.out.println("CompositeName:" + (end-start));
71
        start = System.currentTimeMillis();
72
        for(int i = 0; i < invocation; i ++) {
73
            SimpleCompositeName cn = new SimpleCompositeName("/META-INF/javax.naming.Name");
74
        }
75
        end = System.currentTimeMillis();
76
        System.out.println("SimpleCompositeName:" + (end-start));
77
78
        start = System.currentTimeMillis();
79
        for(int i = 0; i < invocation; i ++) {
80
            SimpleCompositeName cn = new SimpleCompositeName("/META-INF/javax.naming.Name");
81
        }
82
        end = System.currentTimeMillis();
83
        System.out.println("SimpleCompositeName:" + (end-start));
84
        start = System.currentTimeMillis();
85
        for(int i = 0; i < invocation; i ++) {
86
            CompositeName cn = new CompositeName("/META-INF/javax.naming.Name");
87
        }
88
        end = System.currentTimeMillis();
89
        System.out.println("CompositeName:" + (end-start));
90
91
    }
92
93
94
    @Test
95
    public void testEscape1() throws Exception {
96
        CompositeName cn = new CompositeName("/META-INF/'javax\\'.naming.Name'");
97
98
        assertEquals(cn.size(), 3);
99
        assertEquals(cn.get(0), "");
100
        assertEquals(cn.get(1), "META-INF");
101
        assertEquals(cn.get(2), "javax'.naming.Name");
102
103
        SimpleName name = new SimpleName("/META-INF/'javax\\'.naming.Name'");
104
105
        assertEquals(name.size(), 3);
106
        assertEquals(name.get(0), "");
107
        assertEquals(name.get(1), "META-INF");
108
        assertEquals(name.get(2), "javax'.naming.Name");
109
    }
110
111
    @Test
112
    public void testEscape2() throws Exception {
113
        CompositeName cn = new CompositeName("/\"META'-INF\\\"\"/'javax\\'.naming.Name'");
114
115
        assertEquals(cn.size(), 3);
116
        assertEquals(cn.get(0), "");
117
        assertEquals(cn.get(1), "META'-INF\"");
118
        assertEquals(cn.get(2), "javax'.naming.Name");
119
120
        SimpleName name = new SimpleName("/\"META'-INF\\\"\"/'javax\\'.naming.Name'");
121
122
        assertEquals(name.size(), 3);
123
        assertEquals(name.get(0), "");
124
        assertEquals(name.get(1), "META'-INF\"");
125
        assertEquals(name.get(2), "javax'.naming.Name");
126
    }
127
128
    @Test
129
    public void testEscape3() throws Exception {
130
        CompositeName cn = new CompositeName("/META\\'-INF\\\"/'javax\\'.naming.Name'");
131
132
        assertEquals(cn.size(), 3);
133
        assertEquals(cn.get(0), "");
134
        assertEquals(cn.get(1), "META'-INF\"");
135
        assertEquals(cn.get(2), "javax'.naming.Name");
136
137
        SimpleName name = new SimpleName("/META\\'-INF\\\"/'javax\\'.naming.Name'");
138
139
        assertEquals(name.size(), 3);
140
        assertEquals(name.get(0), "");
141
        assertEquals(name.get(1), "META'-INF\"");
142
        assertEquals(name.get(2), "javax'.naming.Name");
143
    }
144
145
    @Test
146
     public void testEscape4() throws Exception {
147
        CompositeName cn = new CompositeName("/\\/META\\'-INF\\\"/'javax\\'.naming.Name'");
148
149
        assertEquals(cn.size(), 3);
150
        assertEquals(cn.get(0), "");
151
        assertEquals(cn.get(1), "/META'-INF\"");
152
        assertEquals(cn.get(2), "javax'.naming.Name");
153
154
        SimpleName name = new SimpleName("/\\/META\\'-INF\\\"/'javax\\'.naming.Name'");
155
156
        assertEquals(name.size(), 3);
157
        assertEquals(name.get(0), "");
158
        assertEquals(name.get(1), "/META'-INF\"");
159
        assertEquals(name.get(2), "javax'.naming.Name");
160
    }
161
162
    @Test
163
    public void testToString() throws Exception {
164
        CompositeName cn = new CompositeName("/\\/META\\'-INF\\\"/'javax\\'.naming.Name'");
165
166
        assertEquals(cn.size(), 3);
167
        assertEquals(cn.get(0), "");
168
        assertEquals(cn.get(1), "/META'-INF\"");
169
        assertEquals(cn.get(2), "javax'.naming.Name");
170
171
        assertEquals("/\"/META'-INF\\\"\"/javax'.naming.Name", cn.toString());
172
173
        SimpleName name = new SimpleName("/\\/META\\'-INF\\\"/'javax\\'.naming.Name'");
174
175
        assertEquals(name.size(), 3);
176
        assertEquals(name.get(0), "");
177
        assertEquals(name.get(1), "/META'-INF\"");
178
        assertEquals(name.get(2), "javax'.naming.Name");
179
        assertEquals("/\"/META'-INF\\\"\"/javax'.naming.Name", name.toString());
180
181
        //Make sure the result is same as CompositeName
182
        assertEquals(cn.toString(), name.toString());
183
    }
184
185
    @Test
186
    public void testEscape5() throws Exception {
187
        CompositeName cn = new CompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name'");
188
189
        assertEquals(cn.size(), 4);
190
        assertEquals(cn.get(0), "");
191
        assertEquals(cn.get(1), "/META'-INF\"");
192
        assertEquals(cn.get(2), "");
193
        assertEquals(cn.get(3), "javax'.naming.Name");
194
195
        SimpleName name = new SimpleName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name'");
196
197
        assertEquals(name.size(), 4);
198
        assertEquals(name.get(0), "");
199
        assertEquals(name.get(1), "/META'-INF\"");
200
        assertEquals(name.get(2), "");
201
        assertEquals(name.get(3), "javax'.naming.Name");
202
    }
203
204
205
    private void testPrefix(Name name) {
206
207
        assertEquals(name.size(), 4);
208
209
        Name prefix1 = name.getPrefix(4);
210
        assertEquals(prefix1.get(0), "");
211
        assertEquals(prefix1.get(1), "/META'-INF\"");
212
        assertEquals(prefix1.get(2), "");
213
        assertEquals(prefix1.get(3), "javax'.naming.Name");
214
215
        Name prefix2 = name.getPrefix(3);
216
        assertEquals(prefix2.get(0), "");
217
        assertEquals(prefix2.get(1), "/META'-INF\"");
218
        assertEquals(prefix2.get(2), "");
219
220
221
        Name prefix3 = name.getPrefix(2);
222
        assertEquals(prefix3.get(0), "");
223
        assertEquals(prefix3.get(1), "/META'-INF\"");
224
225
        Name prefix4 = name.getPrefix(1);
226
        assertEquals(prefix4.get(0), "");
227
228
        Name prefix5 = name.getPrefix(0);
229
        assertEquals(prefix5.size(), 0);
230
    }
231
232
    @Test
233
    public void testPrefix() throws Exception {
234
        Name name = new CompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name'");
235
        testPrefix(name);
236
237
        name = new SimpleCompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name'");
238
        testPrefix(name);
239
    }
240
241
    private void testSuffix(Name name) {
242
        assertEquals(name.size(), 4);
243
244
        Name suffix1 = name.getSuffix(0);
245
        assertEquals(suffix1.get(0), "");
246
        assertEquals(suffix1.get(1), "/META'-INF\"");
247
        assertEquals(suffix1.get(2), "");
248
        assertEquals(suffix1.get(3), "javax'.naming.Name");
249
250
        Name suffix2 = name.getSuffix(1);
251
        assertEquals(suffix2.get(0), "/META'-INF\"");
252
        assertEquals(suffix2.get(1), "");
253
        assertEquals(suffix2.get(2), "javax'.naming.Name");
254
255
256
        Name suffix3 = name.getSuffix(2);
257
        assertEquals(suffix3.get(0), "");
258
        assertEquals(suffix3.get(1), "javax'.naming.Name");
259
260
        Name suffix4 = name.getSuffix(3);
261
        assertEquals(suffix4.get(0), "javax'.naming.Name");
262
263
        Name suffix5 = name.getSuffix(4);
264
        assertEquals(suffix5.size(), 0);
265
    }
266
267
    @Test
268
    public void testSuffix() throws Exception {
269
        Name name = new CompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name'");
270
        testSuffix(name);
271
272
        name = new SimpleCompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name'");
273
        testSuffix(name);
274
    }
275
276
    @Test
277
    public void testException() throws Exception {
278
        try {
279
            new CompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name");
280
            fail("Invalid name parsing");
281
        }
282
        catch(InvalidNameException ine) {
283
        }
284
285
        try {
286
            new SimpleCompositeName("/\\/META\\'-INF\\\"//'javax\\'.naming.Name");
287
            fail("Invalid name parsing");
288
        }
289
        catch(InvalidNameException ine) {
290
        }
291
    }
292
}
293
native
(-)java/org/apache/naming/NameParserImpl.java (-2 / +1 lines)
Lines 18-24 Link Here
18
18
19
package org.apache.naming;
19
package org.apache.naming;
20
20
21
import javax.naming.CompositeName;
22
import javax.naming.Name;
21
import javax.naming.Name;
23
import javax.naming.NameParser;
22
import javax.naming.NameParser;
24
import javax.naming.NamingException;
23
import javax.naming.NamingException;
Lines 48-54 Link Here
48
    @Override
47
    @Override
49
    public Name parse(String name)
48
    public Name parse(String name)
50
        throws NamingException {
49
        throws NamingException {
51
        return new CompositeName(name);
50
        return new SimpleCompositeName(name);
52
    }
51
    }
53
52
54
53
(-)java/org/apache/naming/NamingContext.java (-12 / +11 lines)
Lines 23-29 Link Here
23
import java.util.Hashtable;
23
import java.util.Hashtable;
24
24
25
import javax.naming.Binding;
25
import javax.naming.Binding;
26
import javax.naming.CompositeName;
27
import javax.naming.Context;
26
import javax.naming.Context;
28
import javax.naming.InitialContext;
27
import javax.naming.InitialContext;
29
import javax.naming.LinkRef;
28
import javax.naming.LinkRef;
Lines 164-170 Link Here
164
    @Override
163
    @Override
165
    public Object lookup(String name)
164
    public Object lookup(String name)
166
        throws NamingException {
165
        throws NamingException {
167
        return lookup(new CompositeName(name), true);
166
        return lookup(new SimpleCompositeName(name), true);
168
    }
167
    }
169
168
170
169
Lines 200-206 Link Here
200
    @Override
199
    @Override
201
    public void bind(String name, Object obj)
200
    public void bind(String name, Object obj)
202
        throws NamingException {
201
        throws NamingException {
203
        bind(new CompositeName(name), obj);
202
        bind(new SimpleCompositeName(name), obj);
204
    }
203
    }
205
204
206
205
Lines 238-244 Link Here
238
    @Override
237
    @Override
239
    public void rebind(String name, Object obj)
238
    public void rebind(String name, Object obj)
240
        throws NamingException {
239
        throws NamingException {
241
        rebind(new CompositeName(name), obj);
240
        rebind(new SimpleCompositeName(name), obj);
242
    }
241
    }
243
242
244
243
Lines 301-307 Link Here
301
    @Override
300
    @Override
302
    public void unbind(String name)
301
    public void unbind(String name)
303
        throws NamingException {
302
        throws NamingException {
304
        unbind(new CompositeName(name));
303
        unbind(new SimpleCompositeName(name));
305
    }
304
    }
306
305
307
306
Lines 337-343 Link Here
337
    @Override
336
    @Override
338
    public void rename(String oldName, String newName)
337
    public void rename(String oldName, String newName)
339
        throws NamingException {
338
        throws NamingException {
340
        rename(new CompositeName(oldName), new CompositeName(newName));
339
        rename(new SimpleCompositeName(oldName), new SimpleCompositeName(newName));
341
    }
340
    }
342
341
343
342
Lines 391-397 Link Here
391
    @Override
390
    @Override
392
    public NamingEnumeration<NameClassPair> list(String name)
391
    public NamingEnumeration<NameClassPair> list(String name)
393
        throws NamingException {
392
        throws NamingException {
394
        return list(new CompositeName(name));
393
        return list(new SimpleCompositeName(name));
395
    }
394
    }
396
395
397
396
Lines 445-451 Link Here
445
    @Override
444
    @Override
446
    public NamingEnumeration<Binding> listBindings(String name)
445
    public NamingEnumeration<Binding> listBindings(String name)
447
        throws NamingException {
446
        throws NamingException {
448
        return listBindings(new CompositeName(name));
447
        return listBindings(new SimpleCompositeName(name));
449
    }
448
    }
450
449
451
450
Lines 526-532 Link Here
526
    @Override
525
    @Override
527
    public void destroySubcontext(String name)
526
    public void destroySubcontext(String name)
528
        throws NamingException {
527
        throws NamingException {
529
        destroySubcontext(new CompositeName(name));
528
        destroySubcontext(new SimpleCompositeName(name));
530
    }
529
    }
531
530
532
531
Lines 571-577 Link Here
571
    @Override
570
    @Override
572
    public Context createSubcontext(String name)
571
    public Context createSubcontext(String name)
573
        throws NamingException {
572
        throws NamingException {
574
        return createSubcontext(new CompositeName(name));
573
        return createSubcontext(new SimpleCompositeName(name));
575
    }
574
    }
576
575
577
576
Lines 604-610 Link Here
604
    @Override
603
    @Override
605
    public Object lookupLink(String name)
604
    public Object lookupLink(String name)
606
        throws NamingException {
605
        throws NamingException {
607
        return lookup(new CompositeName(name), false);
606
        return lookup(new SimpleCompositeName(name), false);
608
    }
607
    }
609
608
610
609
Lines 657-663 Link Here
657
    @Override
656
    @Override
658
    public NameParser getNameParser(String name)
657
    public NameParser getNameParser(String name)
659
        throws NamingException {
658
        throws NamingException {
660
        return getNameParser(new CompositeName(name));
659
        return getNameParser(new SimpleCompositeName(name));
661
    }
660
    }
662
661
663
662
(-)java/org/apache/naming/NamingContextBindingsEnumeration.java (-2 / +1 lines)
Lines 21-27 Link Here
21
import java.util.Iterator;
21
import java.util.Iterator;
22
22
23
import javax.naming.Binding;
23
import javax.naming.Binding;
24
import javax.naming.CompositeName;
25
import javax.naming.Context;
24
import javax.naming.Context;
26
import javax.naming.NamingEnumeration;
25
import javax.naming.NamingEnumeration;
27
import javax.naming.NamingException;
26
import javax.naming.NamingException;
Lines 114-120 Link Here
114
        if (entry.type == NamingEntry.REFERENCE
113
        if (entry.type == NamingEntry.REFERENCE
115
                || entry.type == NamingEntry.LINK_REF) {
114
                || entry.type == NamingEntry.LINK_REF) {
116
            try {
115
            try {
117
                value = ctx.lookup(new CompositeName(entry.name));
116
                value = ctx.lookup(new SimpleCompositeName(entry.name));
118
            } catch (NamingException e) {
117
            } catch (NamingException e) {
119
                throw e;
118
                throw e;
120
            } catch (Exception e) {
119
            } catch (Exception e) {

Return to bug 56787