Permalink
Browse files

Make zone rules initialization configurable and pluggable

Preserves the default behavior of obtaining a ZoneRulesProvider instance from ServiceLoader, but adds the
ability to substitute in different initialization code that will be executed in the static block of
ZoneRulesProvider the first time that time zone rules are needed.
  • Loading branch information...
mmallozzi authored and jodastephen committed May 1, 2017
1 parent ecf5991 commit a6a3fa3202dbba06e7de3bb53c4d923effcfa637
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of JSR-310 nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.threeten.bp.zone;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
/**
* Try to load time zone rules from implementations provided by {@link ServiceLoader}.
*/
class ServiceLoaderZoneRulesInitializer extends ZoneRulesInitializer {
@Override
protected void initializeZoneProviders() {
ServiceLoader<ZoneRulesProvider> loader = ServiceLoader.load(ZoneRulesProvider.class, ZoneRulesProvider.class.getClassLoader());
for (ZoneRulesProvider provider : loader) {
try {
ZoneRulesProvider.registerProvider(provider);
} catch (ServiceConfigurationError ex) {
if (!(ex.getCause() instanceof SecurityException)) {
throw ex;
}
}
}
}
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of JSR-310 nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.threeten.bp.zone;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
/**
* Provides instructions on how to initialize {@link ZoneRulesProvider}. If you need to override the default behavior
* of how to load time zone data, you should set this up before any other usage of the library.
*/
public abstract class ZoneRulesInitializer {
private static final AtomicBoolean INITIALIZED = new AtomicBoolean(false);
private static final AtomicReference<ZoneRulesInitializer> initializer = new AtomicReference<ZoneRulesInitializer>();
public static void setInitializer(final ZoneRulesInitializer newInitializer) {
if (!initializer.compareAndSet(null, newInitializer)) {
throw new IllegalStateException("Initializer was already set, possibly with a default during initialization");
}
}
static void initialize() {
if (INITIALIZED.getAndSet(true)) {
throw new IllegalStateException("Already initialized");
}
// Set the default initializer if none has been provided yet.
initializer.compareAndSet(null, new ServiceLoaderZoneRulesInitializer());
initializer.get().initializeZoneProviders();
}
protected abstract void initializeZoneProviders();
}
@@ -32,10 +32,7 @@
package org.threeten.bp.zone;
import java.util.Collections;
import java.util.HashSet;
import java.util.NavigableMap;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -82,16 +79,7 @@
*/
private static final ConcurrentMap<String, ZoneRulesProvider> ZONES = new ConcurrentHashMap<String, ZoneRulesProvider>(512, 0.75f, 2);
static {
ServiceLoader<ZoneRulesProvider> loader = ServiceLoader.load(ZoneRulesProvider.class, ZoneRulesProvider.class.getClassLoader());
for (ZoneRulesProvider provider : loader) {
try {
registerProvider0(provider);
} catch (ServiceConfigurationError ex) {
if (!(ex.getCause() instanceof SecurityException)) {
throw ex;
}
}
}
ZoneRulesInitializer.initialize();
}
//-------------------------------------------------------------------------

0 comments on commit a6a3fa3

Please sign in to comment.