Skip to content

Commit

Permalink
Retry DateTimeTextProvider change
Browse files Browse the repository at this point in the history
Redesign and make public
Single threading tests
Update TestNG version
  • Loading branch information
jodastephen committed Jun 7, 2017
1 parent 9545198 commit e81cdb0
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Expand Up @@ -117,7 +117,7 @@
</includes>
<argLine>-Xmx2G</argLine>
<parallel>classes</parallel>
<threadCount>4</threadCount>
<threadCount>1</threadCount>
<!-- remove slow SuiteHTMLReporter -->
<properties>
<property>
Expand Down Expand Up @@ -441,7 +441,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8</version><!-- Later versions need JDK 7 -->
<version>6.8.21</version><!-- Later versions need JDK 7 -->
<scope>test</scope>
<exclusions>
<exclusion>
Expand Down
4 changes: 4 additions & 0 deletions src/changes/changes.xml
Expand Up @@ -9,6 +9,10 @@

<!-- types are add, fix, remove, update -->
<release version="1.3.5" date="SNAPSHOT" description="v1.3.5">
<action dev="pamalyshev" type="add" >
Add DateTimeTextProvider.setInstance() to allow the provider to be replaced.
See #69 and #70.
</action>
<action dev="jodastephen" type="update" >
Update to time-zone data 2017b.
</action>
Expand Down
37 changes: 30 additions & 7 deletions src/main/java/org/threeten/bp/format/DateTimeTextProvider.java
Expand Up @@ -36,7 +36,6 @@
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;

import org.threeten.bp.jdk8.Jdk8Methods;
import org.threeten.bp.temporal.TemporalField;

/**
Expand All @@ -47,27 +46,38 @@
* This interface is a service provider that can be called by multiple threads.
* Implementations must be thread-safe.
* Implementations should cache the textual information.
* <p>
* This class has been made pubilc primarily for the benefit of Android.
*/
abstract class DateTimeTextProvider {
public abstract class DateTimeTextProvider {

private static final AtomicReference<DateTimeTextProvider> MUTABLE_PROVIDER = new AtomicReference<DateTimeTextProvider>();

/**
* Gets the provider.
*
* @return the provider, not null
*/
static DateTimeTextProvider getInstance() {
return new SimpleDateTimeTextProvider();
return ProviderSingleton.PROVIDER;
}

/**
* Gets the available locales.
* Sets the provider to use.
* <p>
* This can only be invoked before {@link DateTimeTextProvider} class is used for formatting/parsing.
* Invoking this method at a later point will throw an exception.
*
* @return the locales
* @param provider the provider to use
* @throws IllegalStateException if initialization has already occurred or another provider has been set
*/
public Locale[] getAvailableLocales() {
throw new UnsupportedOperationException();
public static void setInitializer(DateTimeTextProvider provider) {
if (!MUTABLE_PROVIDER.compareAndSet(null, provider)) {
throw new IllegalStateException("Provider was already set, possibly with a default during initialization");
}
}

//-----------------------------------------------------------------------
/**
* Gets the text for the specified field, locale and style
* for the purpose of printing.
Expand Down Expand Up @@ -102,4 +112,17 @@ public Locale[] getAvailableLocales() {
*/
public abstract Iterator<Entry<String, Long>> getTextIterator(TemporalField field, TextStyle style, Locale locale);

//-----------------------------------------------------------------------
// use JVM class initializtion to lock the singleton without additional synchronization
static class ProviderSingleton {
static final DateTimeTextProvider PROVIDER = initialize();

// initialize the provider
static DateTimeTextProvider initialize() {
// Set the default initializer if none has been provided yet
MUTABLE_PROVIDER.compareAndSet(null, new SimpleDateTimeTextProvider());
return MUTABLE_PROVIDER.get();
}
}

}
Expand Up @@ -78,13 +78,6 @@ public int compare(Entry<String, Long> obj1, Entry<String, Long> obj2) {
private final ConcurrentMap<Entry<TemporalField, Locale>, Object> cache =
new ConcurrentHashMap<Entry<TemporalField, Locale>, Object>(16, 0.75f, 2);

//-----------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public Locale[] getAvailableLocales() {
return DateFormatSymbols.getAvailableLocales();
}

//-----------------------------------------------------------------------
@Override
public String getText(TemporalField field, long value, TextStyle style, Locale locale) {
Expand Down

0 comments on commit e81cdb0

Please sign in to comment.