/projects/eclipse_SDK-3.7.1/plugins/com.ibm.icu.source_4.4.2.v20110208/com/ibm/icu/impl/duration/BasicPeriodBuilderFactory.java
https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 514 lines · 405 code · 67 blank · 42 comment · 89 complexity · c5c9cf2c8bed93324728b9e1c70fce0f MD5 · raw file
- /*
- ******************************************************************************
- * Copyright (C) 2007-2009, International Business Machines Corporation and *
- * others. All Rights Reserved. *
- ******************************************************************************
- */
-
- package com.ibm.icu.impl.duration;
-
- import com.ibm.icu.impl.duration.impl.DataRecord;
- import com.ibm.icu.impl.duration.impl.PeriodFormatterData;
- import com.ibm.icu.impl.duration.impl.PeriodFormatterDataService;
-
- import java.util.TimeZone;
-
- /**
- * Default implementation of PeriodBuilderFactory. This creates builders that
- * use approximate durations.
- */
- class BasicPeriodBuilderFactory implements PeriodBuilderFactory {
- private PeriodFormatterDataService ds;
- private Settings settings;
-
- private static final short allBits = 0xff;
-
- BasicPeriodBuilderFactory(PeriodFormatterDataService ds) {
- this.ds = ds;
- this.settings = new Settings();
- }
-
- static long approximateDurationOf(TimeUnit unit) {
- return TimeUnit.approxDurations[unit.ordinal];
- }
-
- class Settings {
- boolean inUse;
- short uset = allBits;
- TimeUnit maxUnit = TimeUnit.YEAR;
- TimeUnit minUnit = TimeUnit.MILLISECOND;
- int maxLimit;
- int minLimit;
- boolean allowZero = true;
- boolean weeksAloneOnly;
- boolean allowMillis = true;
-
- Settings setUnits(int uset) {
- if (this.uset == uset) {
- return this;
- }
- Settings result = inUse ? copy() : this;
-
- result.uset = (short)uset;
-
- if ((uset & allBits) == allBits) {
- result.uset = allBits;
- result.maxUnit = TimeUnit.YEAR;
- result.minUnit = TimeUnit.MILLISECOND;
- } else {
- int lastUnit = -1;
- for (int i = 0; i < TimeUnit.units.length; ++i) {
- if (0 != (uset & (1 << i))) {
- if (lastUnit == -1) {
- result.maxUnit = TimeUnit.units[i];
- }
- lastUnit = i;
- }
- }
- if (lastUnit == -1) {
- // currently empty, but this might be transient so no fail
- result.minUnit = result.maxUnit = null;
- } else {
- result.minUnit = TimeUnit.units[lastUnit];
- }
- }
-
- return result;
- }
-
- short effectiveSet() {
- if (allowMillis) {
- return uset;
- }
- return (short)(uset & ~(1 << TimeUnit.MILLISECOND.ordinal));
- }
-
- TimeUnit effectiveMinUnit() {
- if (allowMillis || minUnit != TimeUnit.MILLISECOND) {
- return minUnit;
- }
- // -1 to skip millisecond
- for (int i = TimeUnit.units.length - 1; --i >= 0;) {
- if (0 != (uset & (1 << i))) {
- return TimeUnit.units[i];
- }
- }
- return TimeUnit.SECOND; // default for pathological case
- }
-
- Settings setMaxLimit(float maxLimit) {
- int val = maxLimit <= 0 ? 0 : (int)(maxLimit*1000);
- if (maxLimit == val) {
- return this;
- }
- Settings result = inUse ? copy() : this;
- result.maxLimit = val;
- return result;
- }
-
- Settings setMinLimit(float minLimit) {
- int val = minLimit <= 0 ? 0 : (int)(minLimit*1000);
- if (minLimit == val) {
- return this;
- }
- Settings result = inUse ? copy() : this;
- result.minLimit = val;
- return result;
- }
-
- Settings setAllowZero(boolean allow) {
- if (this.allowZero == allow) {
- return this;
- }
- Settings result = inUse ? copy() : this;
- result.allowZero = allow;
- return result;
- }
-
- Settings setWeeksAloneOnly(boolean weeksAlone) {
- if (this.weeksAloneOnly == weeksAlone) {
- return this;
- }
- Settings result = inUse ? copy() : this;
- result.weeksAloneOnly = weeksAlone;
- return result;
- }
-
- Settings setAllowMilliseconds(boolean allowMillis) {
- if (this.allowMillis == allowMillis) {
- return this;
- }
- Settings result = inUse ? copy() : this;
- result.allowMillis = allowMillis;
- return result;
- }
-
- Settings setLocale(String localeName) {
- PeriodFormatterData data = ds.get(localeName);
- return this
- .setAllowZero(data.allowZero())
- .setWeeksAloneOnly(data.weeksAloneOnly())
- .setAllowMilliseconds(data.useMilliseconds() != DataRecord.EMilliSupport.NO);
- }
-
- Settings setInUse() {
- inUse = true;
- return this;
- }
-
- Period createLimited(long duration, boolean inPast) {
- if (maxLimit > 0) {
- long maxUnitDuration = approximateDurationOf(maxUnit);
- if (duration * 1000 > maxLimit * maxUnitDuration) {
- return Period.moreThan(maxLimit/1000f, maxUnit).inPast(inPast);
- }
- }
-
- if (minLimit > 0) {
- TimeUnit emu = effectiveMinUnit();
- long emud = approximateDurationOf(emu);
- long eml = (emu == minUnit) ? minLimit :
- Math.max(1000, (approximateDurationOf(minUnit) * minLimit) / emud);
- if (duration * 1000 < eml * emud) {
- return Period.lessThan(eml/1000f, emu).inPast(inPast);
- }
- }
- return null;
- }
-
- public Settings copy() {
- Settings result = new Settings();
- result.inUse = inUse;
- result.uset = uset;
- result.maxUnit = maxUnit;
- result.minUnit = minUnit;
- result.maxLimit = maxLimit;
- result.minLimit = minLimit;
- result.allowZero = allowZero;
- result.weeksAloneOnly = weeksAloneOnly;
- result.allowMillis = allowMillis;
- return result;
- }
- }
-
- public PeriodBuilderFactory setAvailableUnitRange(TimeUnit minUnit,
- TimeUnit maxUnit) {
- int uset = 0;
- for (int i = maxUnit.ordinal; i <= minUnit.ordinal; ++i) {
- uset |= 1 << i;
- }
- if (uset == 0) {
- throw new IllegalArgumentException("range " + minUnit + " to " + maxUnit + " is empty");
- }
- settings = settings.setUnits(uset);
- return this;
- }
-
- public PeriodBuilderFactory setUnitIsAvailable(TimeUnit unit,
- boolean available) {
- int uset = settings.uset;
- if (available) {
- uset |= 1 << unit.ordinal;
- } else {
- uset &= ~(1 << unit.ordinal);
- }
- settings = settings.setUnits(uset);
- return this;
- }
-
- public PeriodBuilderFactory setMaxLimit(float maxLimit) {
- settings = settings.setMaxLimit(maxLimit);
- return this;
- }
-
- public PeriodBuilderFactory setMinLimit(float minLimit) {
- settings = settings.setMinLimit(minLimit);
- return this;
- }
-
- public PeriodBuilderFactory setAllowZero(boolean allow) {
- settings = settings.setAllowZero(allow);
- return this;
- }
-
- public PeriodBuilderFactory setWeeksAloneOnly(boolean aloneOnly) {
- settings = settings.setWeeksAloneOnly(aloneOnly);
- return this;
- }
-
- public PeriodBuilderFactory setAllowMilliseconds(boolean allow) {
- settings = settings.setAllowMilliseconds(allow);
- return this;
- }
-
- public PeriodBuilderFactory setLocale(String localeName) {
- settings = settings.setLocale(localeName);
- return this;
- }
-
- public PeriodBuilderFactory setTimeZone(TimeZone timeZone) {
- // ignore this
- return this;
- }
-
- private Settings getSettings() {
- if (settings.effectiveSet() == 0) {
- return null;
- }
- return settings.setInUse();
- }
-
- /**
- * Return a builder that represents relative time in terms of the single
- * given TimeUnit
- *
- * @param unit the single TimeUnit with which to represent times
- * @return a builder
- */
- public PeriodBuilder getFixedUnitBuilder(TimeUnit unit) {
- return FixedUnitBuilder.get(unit, getSettings());
- }
-
- /**
- * Return a builder that represents relative time in terms of the
- * largest period less than or equal to the duration.
- *
- * @return a builder
- */
- public PeriodBuilder getSingleUnitBuilder() {
- return SingleUnitBuilder.get(getSettings());
- }
-
- /**
- * Return a builder that formats the largest one or two periods,
- * Starting with the largest period less than or equal to the duration.
- * It formats two periods if the first period has a count < 2
- * and the next period has a count >= 1.
- *
- * @return a builder
- */
- public PeriodBuilder getOneOrTwoUnitBuilder() {
- return OneOrTwoUnitBuilder.get(getSettings());
- }
-
- /**
- * Return a builder that formats the given number of periods,
- * starting with the largest period less than or equal to the
- * duration.
- *
- * @return a builder
- */
- public PeriodBuilder getMultiUnitBuilder(int periodCount) {
- return MultiUnitBuilder.get(periodCount, getSettings());
- }
- }
-
- abstract class PeriodBuilderImpl implements PeriodBuilder {
-
- protected BasicPeriodBuilderFactory.Settings settings;
-
- public Period create(long duration) {
- return createWithReferenceDate(duration, System.currentTimeMillis());
- }
-
- public long approximateDurationOf(TimeUnit unit) {
- return BasicPeriodBuilderFactory.approximateDurationOf(unit);
- }
-
- public Period createWithReferenceDate(long duration, long referenceDate) {
- boolean inPast = duration < 0;
- if (inPast) {
- duration = -duration;
- }
- Period ts = settings.createLimited(duration, inPast);
- if (ts == null) {
- ts = handleCreate(duration, referenceDate, inPast);
- if (ts == null) {
- ts = Period.lessThan(1, settings.effectiveMinUnit()).inPast(inPast);
- }
- }
- return ts;
- }
-
- public PeriodBuilder withTimeZone(TimeZone timeZone) {
- // ignore the time zone
- return this;
- }
-
- public PeriodBuilder withLocale(String localeName) {
- BasicPeriodBuilderFactory.Settings newSettings = settings.setLocale(localeName);
- if (newSettings != settings) {
- return withSettings(newSettings);
- }
- return this;
- }
-
- protected abstract PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse);
-
- protected abstract Period handleCreate(long duration, long referenceDate,
- boolean inPast);
-
- protected PeriodBuilderImpl(BasicPeriodBuilderFactory.Settings settings) {
- this.settings = settings;
- }
- }
-
- class FixedUnitBuilder extends PeriodBuilderImpl {
- private TimeUnit unit;
-
- public static FixedUnitBuilder get(TimeUnit unit, BasicPeriodBuilderFactory.Settings settingsToUse) {
- if (settingsToUse != null && (settingsToUse.effectiveSet() & (1 << unit.ordinal)) != 0) {
- return new FixedUnitBuilder(unit, settingsToUse);
- }
- return null;
- }
-
- FixedUnitBuilder(TimeUnit unit, BasicPeriodBuilderFactory.Settings settings) {
- super(settings);
- this.unit = unit;
- }
-
- protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) {
- return get(unit, settingsToUse);
- }
-
- protected Period handleCreate(long duration, long referenceDate,
- boolean inPast) {
- if (unit == null) {
- return null;
- }
- long unitDuration = approximateDurationOf(unit);
- return Period.at((float)((double)duration/unitDuration), unit)
- .inPast(inPast);
- }
- }
-
- class SingleUnitBuilder extends PeriodBuilderImpl {
- SingleUnitBuilder(BasicPeriodBuilderFactory.Settings settings) {
- super(settings);
- }
-
- public static SingleUnitBuilder get(BasicPeriodBuilderFactory.Settings settings) {
- if (settings == null) {
- return null;
- }
- return new SingleUnitBuilder(settings);
- }
-
- protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) {
- return SingleUnitBuilder.get(settingsToUse);
- }
-
- protected Period handleCreate(long duration, long referenceDate,
- boolean inPast) {
- short uset = settings.effectiveSet();
- for (int i = 0; i < TimeUnit.units.length; ++i) {
- if (0 != (uset & (1 << i))) {
- TimeUnit unit = TimeUnit.units[i];
- long unitDuration = approximateDurationOf(unit);
- if (duration >= unitDuration) {
- return Period.at((float)((double)duration/unitDuration), unit)
- .inPast(inPast);
- }
- }
- }
- return null;
- }
- }
-
- class OneOrTwoUnitBuilder extends PeriodBuilderImpl {
- OneOrTwoUnitBuilder(BasicPeriodBuilderFactory.Settings settings) {
- super(settings);
- }
-
- public static OneOrTwoUnitBuilder get(BasicPeriodBuilderFactory.Settings settings) {
- if (settings == null) {
- return null;
- }
- return new OneOrTwoUnitBuilder(settings);
- }
-
- protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) {
- return OneOrTwoUnitBuilder.get(settingsToUse);
- }
-
- protected Period handleCreate(long duration, long referenceDate,
- boolean inPast) {
- Period period = null;
- short uset = settings.effectiveSet();
- for (int i = 0; i < TimeUnit.units.length; ++i) {
- if (0 != (uset & (1 << i))) {
- TimeUnit unit = TimeUnit.units[i];
- long unitDuration = approximateDurationOf(unit);
- if (duration >= unitDuration || period != null) {
- double count = (double)duration/unitDuration;
- if (period == null) {
- if (count >= 2) {
- period = Period.at((float)count, unit);
- break;
- }
- period = Period.at(1, unit).inPast(inPast);
- duration -= unitDuration;
- } else {
- if (count >= 1) {
- period.and((float)count, unit);
- }
- break;
- }
- }
- }
- }
- return period;
- }
- }
-
- class MultiUnitBuilder extends PeriodBuilderImpl {
- private int nPeriods;
-
- MultiUnitBuilder(int nPeriods, BasicPeriodBuilderFactory.Settings settings) {
- super(settings);
- this.nPeriods = nPeriods;
- }
-
- public static MultiUnitBuilder get(int nPeriods, BasicPeriodBuilderFactory.Settings settings) {
- if (nPeriods > 0 && settings != null) {
- return new MultiUnitBuilder(nPeriods, settings);
- }
- return null;
- }
-
- protected PeriodBuilder withSettings(BasicPeriodBuilderFactory.Settings settingsToUse) {
- return MultiUnitBuilder.get(nPeriods, settingsToUse);
- }
-
- protected Period handleCreate(long duration, long referenceDate,
- boolean inPast) {
- Period period = null;
- int n = 0;
- short uset = settings.effectiveSet();
- for (int i = 0; i < TimeUnit.units.length; ++i) {
- if (0 != (uset & (1 << i))) {
- TimeUnit unit = TimeUnit.units[i];
- if (n == nPeriods) {
- break;
- }
- long unitDuration = approximateDurationOf(unit);
- if (duration >= unitDuration || n > 0) {
- ++n;
- double count = (double)duration / unitDuration;
- if (n < nPeriods) {
- count = Math.floor(count);
- duration -= (long)(count * unitDuration);
- }
- if (period == null) {
- period = Period.at((float)count, unit).inPast(inPast);
- } else {
- period.and((float)count, unit);
- }
- }
- }
- }
- return period;
- }
- }