1 /*
2  * Copyright (c) 2012, 2016, 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  * This file is available under and governed by the GNU General Public
26  * License version 2 only, as published by the Free Software Foundation.
27  * However, the following notice accompanied the original version of this
28  * file:
29  *
30  * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
31  *
32  * All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions are met:
36  *
37  *  * Redistributions of source code must retain the above copyright notice,
38  *    this list of conditions and the following disclaimer.
39  *
40  *  * Redistributions in binary form must reproduce the above copyright notice,
41  *    this list of conditions and the following disclaimer in the documentation
42  *    and/or other materials provided with the distribution.
43  *
44  *  * Neither the name of JSR-310 nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  */
60 package tck.java.time.zone;
61 
62 import static org.testng.Assert.assertEquals;
63 import static org.testng.Assert.assertNotNull;
64 import static org.testng.Assert.assertTrue;
65 
66 import java.time.ZoneId;
67 import java.time.ZoneOffset;
68 import java.time.zone.ZoneRules;
69 import java.time.zone.ZoneRulesException;
70 import java.time.zone.ZoneRulesProvider;
71 import java.util.Collections;
72 import java.util.HashSet;
73 import java.util.NavigableMap;
74 import java.util.Set;
75 import java.util.TreeMap;
76 
77 import org.testng.annotations.Test;
78 
79 /**
80  * Test ZoneRulesProvider.
81  */
82 @Test
83 public class TCKZoneRulesProvider {
84 
85     private static String TZDB_VERSION = "2012i";
86 
87     //-----------------------------------------------------------------------
88     // getAvailableZoneIds()
89     //-----------------------------------------------------------------------
90     @Test
test_getAvailableGroupIds()91     public void test_getAvailableGroupIds() {
92         Set<String> zoneIds = ZoneRulesProvider.getAvailableZoneIds();
93         assertEquals(zoneIds.contains("Europe/London"), true);
94     }
95 
96     @Test(expectedExceptions=UnsupportedOperationException.class)
test_getAvailableGroupIds_modifyZoneId()97     public void test_getAvailableGroupIds_modifyZoneId() {
98         ZoneRulesProvider.getAvailableZoneIds().clear();
99     }
100 
101     //-----------------------------------------------------------------------
102     // getRules(String, boolean)
103     //-----------------------------------------------------------------------
104     @Test
test_getRules_StringBoolean()105     public void test_getRules_StringBoolean() {
106         ZoneRules rules = ZoneRulesProvider.getRules("Europe/London", false);
107         assertNotNull(rules);
108         ZoneRules rules2 = ZoneRulesProvider.getRules("Europe/London", false);
109         assertEquals(rules2, rules);
110     }
111 
112     @Test(expectedExceptions=ZoneRulesException.class)
test_getRules_StringBoolean_unknownId()113     public void test_getRules_StringBoolean_unknownId() {
114         ZoneRulesProvider.getRules("Europe/Lon", false);
115     }
116 
117     @Test(expectedExceptions=NullPointerException.class)
test_getRules_StringBoolean_null()118     public void test_getRules_StringBoolean_null() {
119         ZoneRulesProvider.getRules(null, false);
120     }
121 
122     @Test
test_getRules_StringBoolean_dynamic()123     public void test_getRules_StringBoolean_dynamic() {
124         MockDynamicProvider dynamicProvider = new MockDynamicProvider();
125         ZoneRulesProvider.registerProvider(dynamicProvider);
126 
127         assertEquals(dynamicProvider.count, 0);
128         ZoneRules rules1 = ZoneId.of("DynamicLocation").getRules();
129         assertEquals(dynamicProvider.count, 2);
130         assertEquals(rules1, dynamicProvider.BASE);
131         ZoneRules rules2 = ZoneId.of("DynamicLocation").getRules();
132         assertEquals(dynamicProvider.count, 4);
133         assertEquals(rules2, dynamicProvider.ALTERNATE);
134     }
135 
136     //-----------------------------------------------------------------------
137     // getVersions(String)
138     //-----------------------------------------------------------------------
139     @Test
test_getVersions_String()140     public void test_getVersions_String() {
141         NavigableMap<String, ZoneRules> versions = ZoneRulesProvider.getVersions("Europe/London");
142         assertTrue(versions.size() >= 1);
143         ZoneRules rules = ZoneRulesProvider.getRules("Europe/London", false);
144         assertEquals(versions.lastEntry().getValue(), rules);
145 
146         NavigableMap<String, ZoneRules> copy = new TreeMap<>(versions);
147         versions.clear();
148         assertEquals(versions.size(), 0);
149         NavigableMap<String, ZoneRules> versions2 = ZoneRulesProvider.getVersions("Europe/London");
150         assertEquals(versions2, copy);
151     }
152 
153     @Test(expectedExceptions=ZoneRulesException.class)
test_getVersions_String_unknownId()154     public void test_getVersions_String_unknownId() {
155         ZoneRulesProvider.getVersions("Europe/Lon");
156     }
157 
158     @Test(expectedExceptions=NullPointerException.class)
test_getVersions_String_null()159     public void test_getVersions_String_null() {
160         ZoneRulesProvider.getVersions(null);
161     }
162 
163     //-----------------------------------------------------------------------
164     // refresh()
165     //-----------------------------------------------------------------------
166     @Test
test_refresh()167     public void test_refresh() {
168         assertEquals(ZoneRulesProvider.refresh(), false);
169     }
170 
171     //-----------------------------------------------------------------------
172     // registerProvider()
173     //-----------------------------------------------------------------------
174     @Test
test_registerProvider()175     public void test_registerProvider() {
176         Set<String> pre = ZoneRulesProvider.getAvailableZoneIds();
177         assertEquals(pre.contains("FooLocation"), false);
178         ZoneRulesProvider.registerProvider(new MockTempProvider());
179         assertEquals(pre.contains("FooLocation"), false);
180         Set<String> post = ZoneRulesProvider.getAvailableZoneIds();
181         assertEquals(post.contains("FooLocation"), true);
182         assertEquals(ZoneRulesProvider.getRules("FooLocation", false), ZoneOffset.of("+01:45").getRules());
183     }
184 
185     static class MockTempProvider extends ZoneRulesProvider {
186         final ZoneRules rules = ZoneOffset.of("+01:45").getRules();
187         @Override
provideZoneIds()188         public Set<String> provideZoneIds() {
189             return new HashSet<String>(Collections.singleton("FooLocation"));
190         }
191         @Override
provideVersions(String zoneId)192         protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
193             NavigableMap<String, ZoneRules> result = new TreeMap<>();
194             result.put("BarVersion", rules);
195             return result;
196         }
197         @Override
provideRules(String zoneId, boolean forCaching)198         protected ZoneRules provideRules(String zoneId, boolean forCaching) {
199             if (zoneId.equals("FooLocation")) {
200                 return rules;
201             }
202             throw new ZoneRulesException("Invalid");
203         }
204     }
205 
206     static class MockDynamicProvider extends ZoneRulesProvider {
207         final ZoneRules BASE = ZoneOffset.of("+01:15").getRules();
208         final ZoneRules ALTERNATE = ZoneOffset.of("+01:30").getRules();
209         int count = 0;
210         @Override
provideZoneIds()211         public Set<String> provideZoneIds() {
212             return new HashSet<>(Collections.singleton("DynamicLocation"));
213         }
214         @Override
provideVersions(String zoneId)215         protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
216             NavigableMap<String, ZoneRules> result = new TreeMap<>();
217             result.put("DynamicVersion1", BASE);
218             if (count > 2) {
219                 result.put("DynamicVersion2", ALTERNATE);
220             }
221             return result;
222         }
223         @Override
provideRules(String zoneId, boolean forCaching)224         protected ZoneRules provideRules(String zoneId, boolean forCaching) {
225             count++;
226             if (zoneId.equals("DynamicLocation")) {
227                 return (forCaching ? null : (count > 2 ? ALTERNATE : BASE));
228             }
229             throw new ZoneRulesException("Invalid");
230         }
231     }
232 
233 }
234