1 /*
2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug     6253413 8059361
27  * @summary Test for Properties.stringPropertyNames() if the system
28  *          properties contain another list of properties as the defaults.
29  * @author  Mandy Chung
30  *
31  * @run build StringPropertyNames
32  * @run main  StringPropertyNames
33  */
34 
35 package test.java.util.Properties;
36 
37 import java.util.Properties;
38 import java.util.Enumeration;
39 import java.util.Iterator;
40 import java.util.Set;
41 
42 public class StringPropertyNames {
43     private static int NUM_SHARE_PROPS = 2;
44     private static int NUM_PROPS1 = 3;
45     private static int NUM_PROPS2 = 5;
46     private static String KEY = "good.property.";
47     private static String VALUE = "good.value.";
main(String[] argv)48     public static void main(String[] argv) throws Exception {
49         Properties props1 = new Properties();
50         Properties props2 = new Properties(props1);
51 
52         // add several new properties
53         for (int i = 0; i < NUM_PROPS1; i++) {
54             props1.put(KEY + "1." + i, VALUE + "1." + i);
55         }
56         for (int i = 0; i < NUM_PROPS2; i++) {
57             props2.put(KEY + "2." + i, VALUE + "2." + i);
58         }
59 
60         // add the same properties in both props1 and props2
61         for (int i = 0; i < NUM_SHARE_PROPS; i++) {
62             props1.put(KEY + i, VALUE + "1." + i);
63             props2.put(KEY + i, VALUE + "2." + i);
64         }
65         checkProperties(props1,
66                         NUM_PROPS1 + NUM_SHARE_PROPS, // size of props1
67                         NUM_PROPS1 + NUM_SHARE_PROPS, // num of string keys
68                         NUM_PROPS1 + NUM_SHARE_PROPS, // num of keys in propertyName(),
69                         false);
70         checkProperties(props2,
71                         NUM_PROPS2 + NUM_SHARE_PROPS, // size of props2
72                         NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of string keys
73                         NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of keys in propertyName(),
74                         false);
75 
76         // Add non-String value
77         props1.put(KEY + "9", new Integer(4));
78         checkProperties(props1,
79                         NUM_PROPS1 + NUM_SHARE_PROPS + 1, // size of props1
80                         NUM_PROPS1 + NUM_SHARE_PROPS, // num of string keys
81                         NUM_PROPS1 + NUM_SHARE_PROPS + 1, // num of keys in propertyName(),
82                         false);
83         checkProperties(props2,
84                         NUM_PROPS2 + NUM_SHARE_PROPS, // size of props2
85                         NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of string keys
86                         NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS + 1, // num of keys in propertyName(),
87                         false);
88         Object v = props1.remove(KEY + "9");
89         if (v == null) {
90             throw new RuntimeException("Test Failed: " +
91                 "Key " + KEY + "9" + " not found");
92         }
93 
94         // Add a non-String key
95         props1.put(new Integer(5), "good.value.5");
96         props2.put(new Object(), new Object());
97         checkProperties(props1,
98                         NUM_PROPS1 + NUM_SHARE_PROPS + 1, // size of props1
99                         NUM_PROPS1 + NUM_SHARE_PROPS, // num of string keys
100                         NUM_PROPS1 + NUM_SHARE_PROPS + 1, // num of keys in propertyName(),
101                         true);
102         checkProperties(props2,
103                         NUM_PROPS2 + NUM_SHARE_PROPS + 1, // size of props2
104                         NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of string keys
105                         NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS + 2, // num of keys in propertyName(),
106                         true);
107         System.out.println("Test passed.");
108     }
109 
checkProperties(Properties props, int propSize, int numStringKeys, int enumerateSize, boolean hasNonStringKeys)110     private static void checkProperties(Properties props,
111                                         int propSize,
112                                         int numStringKeys,
113                                         int enumerateSize,
114                                         boolean hasNonStringKeys) {
115         // check the size of the properties
116         if (props.size() != propSize) {
117             throw new RuntimeException("Test Failed: " +
118                 "Expected number of properties = " +
119                 propSize + " but found = " + props.size());
120         }
121 
122         // check the number of properties whose key and value
123         // are both strings
124         Set<String> keys = props.stringPropertyNames();
125         if (keys.size() != numStringKeys) {
126             throw new RuntimeException("Test Failed: " +
127                 "Expected number of String keys = " +
128                 numStringKeys + " but found = " + keys.size());
129         }
130         boolean cceThrown = false;
131         try {
132             // check the number of properties whose key are strings
133             // but its value can be anything in the current impl
134             int count = 0;
135             Enumeration<?> e = props.propertyNames();
136             for (;e.hasMoreElements(); e.nextElement()) {
137                 count++;
138             }
139             if (count != enumerateSize) {
140                 throw new RuntimeException("Test Failed: " +
141                     "Expected number of enumerated keys = " +
142                     enumerateSize + " but found = " + count);
143             }
144         } catch (ClassCastException e) {
145             if (!hasNonStringKeys) {
146                 RuntimeException re = new RuntimeException("Test Failed: " +
147                     "ClassCastException is expected not to be thrown");
148                 re.initCause(e);
149                 throw re;
150             }
151             cceThrown = true;
152         }
153 
154         if ((hasNonStringKeys && !cceThrown)) {
155             throw new RuntimeException("Test Failed: " +
156                 "ClassCastException is expected to be thrown");
157         }
158 
159         // make sure the set cannot be modified
160         try {
161             keys.add("xyzzy");
162             throw new RuntimeException("Test Failed: " +
163                 "add() should have thrown UnsupportedOperationException");
164         } catch (UnsupportedOperationException ignore) { }
165 
166         Iterator<String> it = keys.iterator();
167         if (it.hasNext()) {
168             try {
169                 keys.remove(it.next());
170                 throw new RuntimeException("Test Failed: " +
171                     "remove() should have thrown UnsupportedOperationException");
172             } catch (UnsupportedOperationException ignore) { }
173         }
174     }
175 }
176