Merge branch 'date' into date2

Conflicts:
	teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java
This commit is contained in:
konsoletyper 2014-05-29 18:37:24 +04:00
commit 2cab17dee4
14 changed files with 1754 additions and 1 deletions

View File

@ -39,4 +39,20 @@ public class CLDRHelper {
@GeneratedBy(CLDRHelperNativeGenerator.class) @GeneratedBy(CLDRHelperNativeGenerator.class)
@PluggableDependency(CLDRHelperNativeGenerator.class) @PluggableDependency(CLDRHelperNativeGenerator.class)
private static native String getLikelySubtagsImpl(String localeCode); private static native String getLikelySubtagsImpl(String localeCode);
public static String[] resolveEras(String localeCode) {
readErasFromCLDR();
String[] eras = getEras(localeCode);
if (eras == null) {
eras = getEras("root");
}
return eras;
}
// Defined by JCLPlugin
private static native void readErasFromCLDR();
@GeneratedBy(CLDRHelperNativeGenerator.class)
@PluggableDependency(CLDRHelperNativeGenerator.class)
private static native String[] getEras(String localeCode);
} }

View File

@ -35,6 +35,10 @@ public class CLDRHelperNativeGenerator implements Generator, DependencyPlugin {
case "getLikelySubtagsImpl": case "getLikelySubtagsImpl":
method.getResult().propagate("java.lang.String"); method.getResult().propagate("java.lang.String");
break; break;
case "getEras":
method.getResult().propagate("[java.lang.String;");
method.getResult().getArrayItem().propagate("java.lang.String");
break;
} }
} }
@ -46,6 +50,23 @@ public class CLDRHelperNativeGenerator implements Generator, DependencyPlugin {
.append(context.getParameterName(1)).append(")];").softNewLine(); .append(context.getParameterName(1)).append(")];").softNewLine();
writer.append("return data ? $rt_str(data) : null;").softNewLine(); writer.append("return data ? $rt_str(data) : null;").softNewLine();
break; break;
case "getEras":
generateGetArray(context, writer, "eras");
break;
} }
} }
private void generateGetArray(GeneratorContext context, SourceWriter writer, String name) throws IOException {
writer.append("var data = ").appendClass("java.util.Locale").append(".$CLDR.").append(name)
.append("[$rt_ustr(").append(context.getParameterName(1)).append(")];").softNewLine();
writer.append("if (!data) {").indent().softNewLine();
writer.append("return null;");
writer.outdent().append("}").softNewLine();
writer.append("var result = $rt_createArray(").appendClass("java.lang.String)")
.append(", data.length);").softNewLine();
writer.append("for (var i = 0; i < data.length; ++i) {").indent().softNewLine();
writer.append("result.data[i] = $rt_str(data[i])").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return result;").softNewLine();
}
} }

View File

@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
public class Annotation {
private Object value;
public Annotation(Object attribute) {
value = attribute;
}
public Object getValue() {
return value;
}
@Override
public String toString() {
return getClass().getName() + "[value=" + value + ']';
}
}

View File

@ -0,0 +1,144 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.util.TMap;
import org.teavm.classlib.java.util.TSet;
public interface AttributedCharacterIterator extends CharacterIterator {
public static class Attribute implements TSerializable {
public static final Attribute INPUT_METHOD_SEGMENT = new Attribute(
"input_method_segment");
public static final Attribute LANGUAGE = new Attribute("language");
public static final Attribute READING = new Attribute("reading");
private String name;
protected Attribute(String name) {
this.name = name;
}
@Override
public final boolean equals(Object object) {
return this == object;
}
protected String getName() {
return name;
}
@Override
public final int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
return getClass().getName() + '(' + getName() + ')';
}
}
/**
* Returns a set of attributes present in the {@code
* AttributedCharacterIterator}. An empty set is returned if no attributes
* were defined.
*
* @return a set of attribute keys; may be empty.
*/
public TSet<Attribute> getAllAttributeKeys();
/**
* Returns the value stored in the attribute for the current character. If
* the attribute was not defined then {@code null} is returned.
*
* @param attribute the attribute for which the value should be returned.
* @return the value of the requested attribute for the current character or
* {@code null} if it was not defined.
*/
public Object getAttribute(Attribute attribute);
/**
* Returns a map of all attributes of the current character. If no
* attributes were defined for the current character then an empty map is
* returned.
*
* @return a map of all attributes for the current character or an empty
* map.
*/
public TMap<Attribute, Object> getAttributes();
/**
* Returns the index of the last character in the run having the same
* attributes as the current character.
*
* @return the index of the last character of the current run.
*/
public int getRunLimit();
/**
* Returns the index of the last character in the run that has the same
* attribute value for the given attribute as the current character.
*
* @param attribute
* the attribute which the run is based on.
* @return the index of the last character of the current run.
*/
public int getRunLimit(Attribute attribute);
/**
* Returns the index of the last character in the run that has the same
* attribute values for the attributes in the set as the current character.
*
* @param attributes
* the set of attributes which the run is based on.
* @return the index of the last character of the current run.
*/
public int getRunLimit(TSet<? extends Attribute> attributes);
/**
* Returns the index of the first character in the run that has the same
* attributes as the current character.
*
* @return the index of the last character of the current run.
*/
public int getRunStart();
/**
* Returns the index of the first character in the run that has the same
* attribute value for the given attribute as the current character.
*
* @param attribute
* the attribute which the run is based on.
* @return the index of the last character of the current run.
*/
public int getRunStart(Attribute attribute);
/**
* Returns the index of the first character in the run that has the same
* attribute values for the attributes in the set as the current character.
*
* @param attributes
* the set of attributes which the run is based on.
* @return the index of the last character of the current run.
*/
public int getRunStart(TSet<? extends Attribute> attributes);
}

View File

@ -0,0 +1,630 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.teavm.classlib.java.text;
import org.teavm.classlib.java.text.AttributedCharacterIterator.Attribute;
import org.teavm.classlib.java.util.*;
public class AttributedString {
String text;
TMap<AttributedCharacterIterator.Attribute, TList<Range>> attributeMap;
static class Range {
int start;
int end;
Object value;
Range(int s, int e, Object v) {
start = s;
end = e;
value = v;
}
}
static class AttributedIterator implements AttributedCharacterIterator {
private int begin, end, offset;
private AttributedString attrString;
private THashSet<Attribute> attributesAllowed;
AttributedIterator(AttributedString attrString) {
this.attrString = attrString;
begin = 0;
end = attrString.text.length();
offset = 0;
}
AttributedIterator(AttributedString attrString, AttributedCharacterIterator.Attribute[] attributes, int begin,
int end) {
if (begin < 0 || end > attrString.text.length() || begin > end) {
throw new IllegalArgumentException();
}
this.begin = begin;
this.end = end;
offset = begin;
this.attrString = attrString;
if (attributes != null) {
THashSet<Attribute> set = new THashSet<>((attributes.length * 4 / 3) + 1);
for (int i = attributes.length; --i >= 0;) {
set.add(attributes[i]);
}
attributesAllowed = set;
}
}
@Override
@SuppressWarnings("unchecked")
public Object clone() {
try {
AttributedIterator clone = (AttributedIterator) super.clone();
if (attributesAllowed != null) {
clone.attributesAllowed = (THashSet<Attribute>) attributesAllowed.clone();
}
return clone;
} catch (CloneNotSupportedException e) {
return null;
}
}
@Override
public char current() {
if (offset == end) {
return DONE;
}
return attrString.text.charAt(offset);
}
@Override
public char first() {
if (begin == end) {
return DONE;
}
offset = begin;
return attrString.text.charAt(offset);
}
@Override
public int getBeginIndex() {
return begin;
}
@Override
public int getEndIndex() {
return end;
}
@Override
public int getIndex() {
return offset;
}
private boolean inRange(Range range) {
if (!(range.value instanceof Annotation)) {
return true;
}
return range.start >= begin && range.start < end && range.end > begin && range.end <= end;
}
private boolean inRange(TList<Range> ranges) {
TIterator<Range> it = ranges.iterator();
while (it.hasNext()) {
Range range = it.next();
if (range.start >= begin && range.start < end) {
return !(range.value instanceof Annotation) || (range.end > begin && range.end <= end);
} else if (range.end > begin && range.end <= end) {
return !(range.value instanceof Annotation) || (range.start >= begin && range.start < end);
}
}
return false;
}
@Override
public TSet<AttributedIterator.Attribute> getAllAttributeKeys() {
if (begin == 0 && end == attrString.text.length() && attributesAllowed == null) {
return attrString.attributeMap.keySet();
}
TSet<AttributedIterator.Attribute> result = new THashSet<>((attrString.attributeMap.size() * 4 / 3) + 1);
TIterator<TMap.Entry<Attribute, TList<Range>>> it = attrString.attributeMap.entrySet().iterator();
while (it.hasNext()) {
TMap.Entry<Attribute, TList<Range>> entry = it.next();
if (attributesAllowed == null || attributesAllowed.contains(entry.getKey())) {
TList<Range> ranges = entry.getValue();
if (inRange(ranges)) {
result.add(entry.getKey());
}
}
}
return result;
}
private Object currentValue(TList<Range> ranges) {
TIterator<Range> it = ranges.iterator();
while (it.hasNext()) {
Range range = it.next();
if (offset >= range.start && offset < range.end) {
return inRange(range) ? range.value : null;
}
}
return null;
}
@Override
public Object getAttribute(AttributedCharacterIterator.Attribute attribute) {
if (attributesAllowed != null && !attributesAllowed.contains(attribute)) {
return null;
}
TArrayList<Range> ranges = (TArrayList<Range>) attrString.attributeMap.get(attribute);
if (ranges == null) {
return null;
}
return currentValue(ranges);
}
@Override
public TMap<Attribute, Object> getAttributes() {
TMap<Attribute, Object> result = new THashMap<>((attrString.attributeMap.size() * 4 / 3) + 1);
TIterator<TMap.Entry<Attribute, TList<Range>>> it = attrString.attributeMap.entrySet().iterator();
while (it.hasNext()) {
TMap.Entry<Attribute, TList<Range>> entry = it.next();
if (attributesAllowed == null || attributesAllowed.contains(entry.getKey())) {
Object value = currentValue(entry.getValue());
if (value != null) {
result.put(entry.getKey(), value);
}
}
}
return result;
}
@Override
public int getRunLimit() {
return getRunLimit(getAllAttributeKeys());
}
private int runLimit(TList<Range> ranges) {
int result = end;
TListIterator<Range> it = ranges.listIterator(ranges.size());
while (it.hasPrevious()) {
Range range = it.previous();
if (range.end <= begin) {
break;
}
if (offset >= range.start && offset < range.end) {
return inRange(range) ? range.end : result;
} else if (offset >= range.end) {
break;
}
result = range.start;
}
return result;
}
@Override
public int getRunLimit(AttributedCharacterIterator.Attribute attribute) {
if (attributesAllowed != null && !attributesAllowed.contains(attribute)) {
return end;
}
TArrayList<Range> ranges = (TArrayList<Range>) attrString.attributeMap.get(attribute);
if (ranges == null) {
return end;
}
return runLimit(ranges);
}
@Override
public int getRunLimit(TSet<? extends Attribute> attributes) {
int limit = end;
TIterator<? extends Attribute> it = attributes.iterator();
while (it.hasNext()) {
AttributedCharacterIterator.Attribute attribute = it.next();
int newLimit = getRunLimit(attribute);
if (newLimit < limit) {
limit = newLimit;
}
}
return limit;
}
@Override
public int getRunStart() {
return getRunStart(getAllAttributeKeys());
}
private int runStart(TList<Range> ranges) {
int result = begin;
TIterator<Range> it = ranges.iterator();
while (it.hasNext()) {
Range range = it.next();
if (range.start >= end) {
break;
}
if (offset >= range.start && offset < range.end) {
return inRange(range) ? range.start : result;
} else if (offset < range.start) {
break;
}
result = range.end;
}
return result;
}
@Override
public int getRunStart(AttributedCharacterIterator.Attribute attribute) {
if (attributesAllowed != null && !attributesAllowed.contains(attribute)) {
return begin;
}
TArrayList<Range> ranges = (TArrayList<Range>) attrString.attributeMap.get(attribute);
if (ranges == null) {
return begin;
}
return runStart(ranges);
}
@Override
public int getRunStart(TSet<? extends Attribute> attributes) {
int start = begin;
TIterator<? extends Attribute> it = attributes.iterator();
while (it.hasNext()) {
AttributedCharacterIterator.Attribute attribute = it.next();
int newStart = getRunStart(attribute);
if (newStart > start) {
start = newStart;
}
}
return start;
}
@Override
public char last() {
if (begin == end) {
return DONE;
}
offset = end - 1;
return attrString.text.charAt(offset);
}
@Override
public char next() {
if (offset >= (end - 1)) {
offset = end;
return DONE;
}
return attrString.text.charAt(++offset);
}
@Override
public char previous() {
if (offset == begin) {
return DONE;
}
return attrString.text.charAt(--offset);
}
@Override
public char setIndex(int location) {
if (location < begin || location > end) {
throw new IllegalArgumentException();
}
offset = location;
if (offset == end) {
return DONE;
}
return attrString.text.charAt(offset);
}
}
public AttributedString(AttributedCharacterIterator iterator) {
if (iterator.getBeginIndex() > iterator.getEndIndex()) {
throw new IllegalArgumentException("Invalid substring range");
}
StringBuilder buffer = new StringBuilder();
for (int i = iterator.getBeginIndex(); i < iterator.getEndIndex(); i++) {
buffer.append(iterator.current());
iterator.next();
}
text = buffer.toString();
TSet<AttributedCharacterIterator.Attribute> attributes = iterator.getAllAttributeKeys();
if (attributes == null) {
return;
}
attributeMap = new THashMap<>((attributes.size() * 4 / 3) + 1);
TIterator<Attribute> it = attributes.iterator();
while (it.hasNext()) {
AttributedCharacterIterator.Attribute attribute = it.next();
iterator.setIndex(0);
while (iterator.current() != CharacterIterator.DONE) {
int start = iterator.getRunStart(attribute);
int limit = iterator.getRunLimit(attribute);
Object value = iterator.getAttribute(attribute);
if (value != null) {
addAttribute(attribute, value, start, limit);
}
iterator.setIndex(limit);
}
}
}
private AttributedString(AttributedCharacterIterator iterator, int start, int end, TSet<Attribute> attributes) {
if (start < iterator.getBeginIndex() || end > iterator.getEndIndex() || start > end) {
throw new IllegalArgumentException();
}
if (attributes == null) {
return;
}
StringBuilder buffer = new StringBuilder();
iterator.setIndex(start);
while (iterator.getIndex() < end) {
buffer.append(iterator.current());
iterator.next();
}
text = buffer.toString();
attributeMap = new THashMap<>((attributes.size() * 4 / 3) + 1);
TIterator<Attribute> it = attributes.iterator();
while (it.hasNext()) {
AttributedCharacterIterator.Attribute attribute = it.next();
iterator.setIndex(start);
while (iterator.getIndex() < end) {
Object value = iterator.getAttribute(attribute);
int runStart = iterator.getRunStart(attribute);
int limit = iterator.getRunLimit(attribute);
if ((value instanceof Annotation && runStart >= start && limit <= end) ||
(value != null && !(value instanceof Annotation))) {
addAttribute(attribute, value, (runStart < start ? start : runStart) - start, (limit > end ? end
: limit) - start);
}
iterator.setIndex(limit);
}
}
}
public AttributedString(AttributedCharacterIterator iterator, int start, int end) {
this(iterator, start, end, iterator.getAllAttributeKeys());
}
public AttributedString(AttributedCharacterIterator iterator, int start, int end,
AttributedCharacterIterator.Attribute[] attributes) {
this(iterator, start, end, new THashSet<>(TArrays.asList(attributes)));
}
public AttributedString(String value) {
if (value == null) {
throw new NullPointerException();
}
text = value;
attributeMap = new THashMap<>(11);
}
public AttributedString(String value, TMap<? extends AttributedCharacterIterator.Attribute, ?> attributes) {
if (value == null) {
throw new NullPointerException();
}
if (value.length() == 0 && !attributes.isEmpty()) {
throw new IllegalArgumentException("Cannot add attributes to empty string");
}
text = value;
attributeMap = new THashMap<>((attributes.size() * 4 / 3) + 1);
TIterator<?> it = attributes.entrySet().iterator();
while (it.hasNext()) {
TMap.Entry<?, ?> entry = (TMap.Entry<?, ?>) it.next();
TArrayList<Range> ranges = new TArrayList<>(1);
ranges.add(new Range(0, text.length(), entry.getValue()));
attributeMap.put((AttributedCharacterIterator.Attribute) entry.getKey(), ranges);
}
}
/**
* Applies a given attribute to this string.
*
* @param attribute
* the attribute that will be applied to this string.
* @param value
* the value of the attribute that will be applied to this
* string.
* @throws IllegalArgumentException
* if the length of this attributed string is 0.
* @throws NullPointerException
* if {@code attribute} is {@code null}.
*/
public void addAttribute(AttributedCharacterIterator.Attribute attribute, Object value) {
if (null == attribute) {
throw new NullPointerException();
}
if (text.length() == 0) {
throw new IllegalArgumentException();
}
TList<Range> ranges = attributeMap.get(attribute);
if (ranges == null) {
ranges = new TArrayList<>(1);
attributeMap.put(attribute, ranges);
} else {
ranges.clear();
}
ranges.add(new Range(0, text.length(), value));
}
/**
* Applies a given attribute to the given range of this string.
*
* @param attribute
* the attribute that will be applied to this string.
* @param value
* the value of the attribute that will be applied to this
* string.
* @param start
* the start of the range where the attribute will be applied.
* @param end
* the end of the range where the attribute will be applied.
* @throws IllegalArgumentException
* if {@code start < 0}, {@code end} is greater than the length
* of this string, or if {@code start >= end}.
* @throws NullPointerException
* if {@code attribute} is {@code null}.
*/
public void addAttribute(AttributedCharacterIterator.Attribute attribute, Object value, int start, int end) {
if (null == attribute) {
throw new NullPointerException();
}
if (start < 0 || end > text.length() || start >= end) {
throw new IllegalArgumentException();
}
if (value == null) {
return;
}
TList<Range> ranges = attributeMap.get(attribute);
if (ranges == null) {
ranges = new TArrayList<>(1);
ranges.add(new Range(start, end, value));
attributeMap.put(attribute, ranges);
return;
}
TListIterator<Range> it = ranges.listIterator();
while (it.hasNext()) {
Range range = it.next();
if (end <= range.start) {
it.previous();
break;
} else if (start < range.end || (start == range.end && value.equals(range.value))) {
Range r1 = null, r3;
it.remove();
r1 = new Range(range.start, start, range.value);
r3 = new Range(end, range.end, range.value);
while (end > range.end && it.hasNext()) {
range = it.next();
if (end <= range.end) {
if (end > range.start || (end == range.start && value.equals(range.value))) {
it.remove();
r3 = new Range(end, range.end, range.value);
break;
}
} else {
it.remove();
}
}
if (value.equals(r1.value)) {
if (value.equals(r3.value)) {
it.add(new Range(r1.start < start ? r1.start : start, r3.end > end ? r3.end : end, r1.value));
} else {
it.add(new Range(r1.start < start ? r1.start : start, end, r1.value));
if (r3.start < r3.end) {
it.add(r3);
}
}
} else {
if (value.equals(r3.value)) {
if (r1.start < r1.end) {
it.add(r1);
}
it.add(new Range(start, r3.end > end ? r3.end : end, r3.value));
} else {
if (r1.start < r1.end) {
it.add(r1);
}
it.add(new Range(start, end, value));
if (r3.start < r3.end) {
it.add(r3);
}
}
}
return;
}
}
it.add(new Range(start, end, value));
}
/**
* Applies a given set of attributes to the given range of the string.
*
* @param attributes
* the set of attributes that will be applied to this string.
* @param start
* the start of the range where the attribute will be applied.
* @param end
* the end of the range where the attribute will be applied.
* @throws IllegalArgumentException
* if {@code start < 0}, {@code end} is greater than the length
* of this string, or if {@code start >= end}.
*/
public void addAttributes(TMap<? extends AttributedCharacterIterator.Attribute, ?> attributes, int start, int end) {
TIterator<?> it = attributes.entrySet().iterator();
while (it.hasNext()) {
TMap.Entry<?, ?> entry = (TMap.Entry<?, ?>) it.next();
addAttribute((AttributedCharacterIterator.Attribute) entry.getKey(), entry.getValue(), start, end);
}
}
/**
* Returns an {@code AttributedCharacterIterator} that gives access to the
* complete content of this attributed string.
*
* @return the newly created {@code AttributedCharacterIterator}.
*/
public AttributedCharacterIterator getIterator() {
return new AttributedIterator(this);
}
/**
* Returns an {@code AttributedCharacterIterator} that gives access to the
* complete content of this attributed string. Only attributes contained in
* {@code attributes} are available from this iterator if they are defined
* for this text.
*
* @param attributes
* the array containing attributes that will be in the new
* iterator if they are defined for this text.
* @return the newly created {@code AttributedCharacterIterator}.
*/
public AttributedCharacterIterator getIterator(AttributedCharacterIterator.Attribute[] attributes) {
return new AttributedIterator(this, attributes, 0, text.length());
}
/**
* Returns an {@code AttributedCharacterIterator} that gives access to the
* contents of this attributed string starting at index {@code start} up to
* index {@code end}. Only attributes contained in {@code attributes} are
* available from this iterator if they are defined for this text.
*
* @param attributes
* the array containing attributes that will be in the new
* iterator if they are defined for this text.
* @param start
* the start index of the iterator on the underlying text.
* @param end
* the end index of the iterator on the underlying text.
* @return the newly created {@code AttributedCharacterIterator}.
*/
public AttributedCharacterIterator getIterator(AttributedCharacterIterator.Attribute[] attributes, int start,
int end) {
return new AttributedIterator(this, attributes, start, end);
}
}

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
public interface CharacterIterator extends Cloneable {
public static final char DONE = '\uffff';
public Object clone();
public char current();
public char first();
public int getBeginIndex();
public int getEndIndex();
public int getIndex();
public char last();
public char next();
public char previous();
public char setIndex(int location);
}

View File

@ -0,0 +1,283 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
import org.teavm.classlib.java.util.*;
public abstract class DateFormat extends Format {
protected TCalendar calendar;
//protected NumberFormat numberFormat;
public final static int DEFAULT = 2;
public final static int FULL = 0;
public final static int LONG = 1;
public final static int MEDIUM = 2;
public final static int SHORT = 3;
public final static int ERA_FIELD = 0;
public final static int YEAR_FIELD = 1;
public final static int MONTH_FIELD = 2;
public final static int DATE_FIELD = 3;
public final static int HOUR_OF_DAY1_FIELD = 4;
public final static int HOUR_OF_DAY0_FIELD = 5;
public final static int MINUTE_FIELD = 6;
public final static int SECOND_FIELD = 7;
public final static int MILLISECOND_FIELD = 8;
public final static int DAY_OF_WEEK_FIELD = 9;
public final static int DAY_OF_YEAR_FIELD = 10;
public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
public final static int WEEK_OF_YEAR_FIELD = 12;
public final static int WEEK_OF_MONTH_FIELD = 13;
public final static int AM_PM_FIELD = 14;
public final static int HOUR1_FIELD = 15;
public final static int HOUR0_FIELD = 16;
public final static int TIMEZONE_FIELD = 17;
protected DateFormat() {
}
@Override
public Object clone() {
DateFormat clone = (DateFormat) super.clone();
clone.calendar = (TCalendar) calendar.clone();
// TODO: implement
//clone.numberFormat = (NumberFormat) numberFormat.clone();
return clone;
}
@Override
public boolean equals(Object object) {
/*if (this == object) {
return true;
}
if (!(object instanceof DateFormat)) {
return false;
}
DateFormat dateFormat = (DateFormat) object;
return numberFormat.equals(dateFormat.numberFormat) &&
calendar.getFirstDayOfWeek() == dateFormat.calendar.getFirstDayOfWeek() &&
calendar.getMinimalDaysInFirstWeek() == dateFormat.calendar.getMinimalDaysInFirstWeek() &&
calendar.isLenient() == dateFormat.calendar.isLenient();*/
// TODO: implement
return false;
}
@Override
public final StringBuffer format(Object object, StringBuffer buffer, FieldPosition field) {
if (object instanceof TDate) {
return format((TDate) object, buffer, field);
}
if (object instanceof Number) {
return format(new TDate(((Number) object).longValue()), buffer, field);
}
throw new IllegalArgumentException();
}
public final String format(TDate date) {
return format(date, new StringBuffer(), new FieldPosition(0)).toString();
}
public abstract StringBuffer format(TDate date, StringBuffer buffer, FieldPosition field);
public static TLocale[] getAvailableLocales() {
return TLocale.getAvailableLocales();
}
public TCalendar getCalendar() {
return calendar;
}
public final static DateFormat getDateInstance() {
return getDateInstance(DEFAULT);
}
public final static DateFormat getDateInstance(int style) {
checkDateStyle(style);
return getDateInstance(style, TLocale.getDefault());
}
public final static DateFormat getDateInstance(int style, TLocale locale) {
/*checkDateStyle(style);
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateInstance(style, locale);
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
// TODO: implement
return null;
}
public final static DateFormat getDateTimeInstance() {
return getDateTimeInstance(DEFAULT, DEFAULT);
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
checkTimeStyle(timeStyle);
checkDateStyle(dateStyle);
return getDateTimeInstance(dateStyle, timeStyle, TLocale.getDefault());
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, TLocale locale) {
/*checkTimeStyle(timeStyle);
checkDateStyle(dateStyle);
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle,
locale);
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
// TODO: implement
return null;
}
public final static DateFormat getInstance() {
return getDateTimeInstance(SHORT, SHORT);
}
/*public NumberFormat getNumberFormat() {
return numberFormat;
}*/
static String getStyleName(int style) {
String styleName;
switch (style) {
case SHORT:
styleName = "SHORT";
break;
case MEDIUM:
styleName = "MEDIUM";
break;
case LONG:
styleName = "LONG";
break;
case FULL:
styleName = "FULL";
break;
default:
styleName = "";
}
return styleName;
}
public final static DateFormat getTimeInstance() {
return getTimeInstance(DEFAULT);
}
public final static DateFormat getTimeInstance(int style) {
checkTimeStyle(style);
return getTimeInstance(style, TLocale.getDefault());
}
public final static DateFormat getTimeInstance(int style, TLocale locale) {
/*checkTimeStyle(style);
com.ibm.icu.text.DateFormat icuFormat = com.ibm.icu.text.DateFormat.getTimeInstance(style, locale);
return new SimpleDateFormat(locale, (com.ibm.icu.text.SimpleDateFormat) icuFormat);*/
// TODO: implement
return null;
}
@Override
public int hashCode() {
/*return calendar.getFirstDayOfWeek() + calendar.getMinimalDaysInFirstWeek() +
(calendar.isLenient() ? 1231 : 1237) + numberFormat.hashCode();*/
// TODO: implement
return 0;
}
public boolean isLenient() {
return calendar.isLenient();
}
public TDate parse(String string) throws ParseException {
ParsePosition position = new ParsePosition(0);
TDate date = parse(string, position);
if (position.getIndex() == 0) {
throw new ParseException("Unparseable date" + string, position.getErrorIndex());
}
return date;
}
public abstract TDate parse(String string, ParsePosition position);
@Override
public Object parseObject(String string, ParsePosition position) {
return parse(string, position);
}
public void setCalendar(TCalendar cal) {
calendar = cal;
}
public void setLenient(boolean value) {
calendar.setLenient(value);
}
/*public void setNumberFormat(NumberFormat format) {
numberFormat = format;
}*/
public static class Field extends Format.Field {
private static THashMap<Integer, Field> table = new THashMap<>();
public final static Field ERA = new Field("era", TCalendar.ERA);
public final static Field YEAR = new Field("year", TCalendar.YEAR);
public final static Field MONTH = new Field("month", TCalendar.MONTH);
public final static Field HOUR_OF_DAY0 = new Field("hour of day", TCalendar.HOUR_OF_DAY);
public final static Field HOUR_OF_DAY1 = new Field("hour of day 1", -1);
public final static Field MINUTE = new Field("minute", TCalendar.MINUTE);
public final static Field SECOND = new Field("second", TCalendar.SECOND);
public final static Field MILLISECOND = new Field("millisecond", TCalendar.MILLISECOND);
public final static Field DAY_OF_WEEK = new Field("day of week", TCalendar.DAY_OF_WEEK);
public final static Field DAY_OF_MONTH = new Field("day of month", TCalendar.DAY_OF_MONTH);
public final static Field DAY_OF_YEAR = new Field("day of year", TCalendar.DAY_OF_YEAR);
public final static Field DAY_OF_WEEK_IN_MONTH = new Field("day of week in month",
TCalendar.DAY_OF_WEEK_IN_MONTH);
public final static Field WEEK_OF_YEAR = new Field("week of year", TCalendar.WEEK_OF_YEAR);
public final static Field WEEK_OF_MONTH = new Field("week of month", TCalendar.WEEK_OF_MONTH);
public final static Field AM_PM = new Field("am pm", TCalendar.AM_PM);
public final static Field HOUR0 = new Field("hour", TCalendar.HOUR);
public final static Field HOUR1 = new Field("hour 1", -1);
public final static Field TIME_ZONE = new Field("time zone", -1);
private int calendarField = -1;
protected Field(String fieldName, int calendarField) {
super(fieldName);
this.calendarField = calendarField;
if (calendarField != -1 && table.get(new Integer(calendarField)) == null) {
table.put(new Integer(calendarField), this);
}
}
public int getCalendarField() {
return calendarField;
}
public static Field ofCalendarField(int calendarField) {
if (calendarField < 0 || calendarField >= TCalendar.FIELD_COUNT) {
throw new IllegalArgumentException();
}
return table.get(new Integer(calendarField));
}
}
private static void checkDateStyle(int style) {
if (!(style == SHORT || style == MEDIUM || style == LONG || style == FULL || style == DEFAULT)) {
throw new IllegalArgumentException("Illegal date style: " + style);
}
}
private static void checkTimeStyle(int style) {
if (!(style == SHORT || style == MEDIUM || style == LONG || style == FULL || style == DEFAULT)) {
// text.0F=Illegal time style: {0}
throw new IllegalArgumentException("Illegal time style: " + style);
}
}
}

View File

@ -0,0 +1,226 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
import java.util.Arrays;
import org.teavm.classlib.impl.unicode.CLDRHelper;
import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.TCloneable;
import org.teavm.classlib.java.util.TLocale;
public class DateFormatSymbols implements TSerializable, TCloneable {
private TLocale locale;
private String localPatternChars;
String[] ampms, eras, months, shortMonths, shortWeekdays, weekdays;
String[][] zoneStrings;
public DateFormatSymbols() {
this(TLocale.getDefault());
}
public DateFormatSymbols(TLocale locale) {
this.locale = locale;
}
@Override
public Object clone() {
DateFormatSymbols symbols = new DateFormatSymbols(locale);
if (ampms != null) {
symbols.ampms = Arrays.copyOf(ampms, ampms.length);
}
if (eras != null) {
symbols.eras = Arrays.copyOf(eras, eras.length);
}
if (months != null) {
symbols.months = Arrays.copyOf(months, months.length);
}
if (shortMonths != null) {
symbols.shortMonths = Arrays.copyOf(shortMonths, shortMonths.length);
}
if (shortWeekdays != null) {
symbols.shortWeekdays = Arrays.copyOf(shortWeekdays.clone(), shortWeekdays.length);
}
if (weekdays != null) {
symbols.weekdays = Arrays.copyOf(weekdays, weekdays.length);
}
if (zoneStrings != null) {
symbols.zoneStrings = new String[zoneStrings.length][];
for (int i = 0; i < zoneStrings.length; i++) {
symbols.zoneStrings[i] = Arrays.copyOf(zoneStrings[i], zoneStrings[i].length);
}
}
return symbols;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof DateFormatSymbols)) {
return false;
}
DateFormatSymbols obj = (DateFormatSymbols) object;
if (!locale.equals(obj.locale)) {
return false;
}
if (!localPatternChars.equals(obj.localPatternChars)) {
return false;
}
if (!Arrays.equals(ampms, obj.ampms)) {
return false;
}
if (!Arrays.equals(eras, obj.eras)) {
return false;
}
if (!Arrays.equals(months, obj.months)) {
return false;
}
if (!Arrays.equals(shortMonths, obj.shortMonths)) {
return false;
}
if (!Arrays.equals(shortWeekdays, obj.shortWeekdays)) {
return false;
}
if (!Arrays.equals(weekdays, obj.weekdays)) {
return false;
}
if (zoneStrings.length != obj.zoneStrings.length) {
return false;
}
for (String[] element : zoneStrings) {
if (element.length != element.length) {
return false;
}
for (int j = 0; j < element.length; j++) {
if (element[j] != element[j] && !(element[j].equals(element[j]))) {
return false;
}
}
}
return true;
}
public String[] getAmPmStrings() {
return ampms.clone();
}
public String[] getEras() {
if (eras == null) {
eras = CLDRHelper.resolveEras(CLDRHelper.getCode(locale.getLanguage(), locale.getCountry()));
}
return eras.clone();
}
public String getLocalPatternChars() {
return localPatternChars;
}
public String[] getMonths() {
return months.clone();
}
public String[] getShortMonths() {
return shortMonths.clone();
}
public String[] getShortWeekdays() {
return shortWeekdays.clone();
}
public String[] getWeekdays() {
return weekdays.clone();
}
public String[][] getZoneStrings() {
String[][] clone = new String[zoneStrings.length][];
for (int i = zoneStrings.length; --i >= 0;) {
clone[i] = zoneStrings[i].clone();
}
return clone;
}
@Override
public int hashCode() {
int hashCode;
hashCode = localPatternChars.hashCode();
for (String element : ampms) {
hashCode += element.hashCode();
}
for (String element : eras) {
hashCode += element.hashCode();
}
for (String element : months) {
hashCode += element.hashCode();
}
for (String element : shortMonths) {
hashCode += element.hashCode();
}
for (String element : shortWeekdays) {
hashCode += element.hashCode();
}
for (String element : weekdays) {
hashCode += element.hashCode();
}
for (String[] element : zoneStrings) {
for (int j = 0; j < element.length; j++) {
if (element[j] != null) {
hashCode += element[j].hashCode();
}
}
}
return hashCode;
}
public void setAmPmStrings(String[] data) {
ampms = data.clone();
}
public void setEras(String[] data) {
eras = data.clone();
}
public void setLocalPatternChars(String data) {
if (data == null) {
throw new NullPointerException();
}
localPatternChars = data;
}
public void setMonths(String[] data) {
months = data.clone();
}
public void setShortMonths(String[] data) {
shortMonths = data.clone();
}
public void setShortWeekdays(String[] data) {
shortWeekdays = data.clone();
}
public void setWeekdays(String[] data) {
weekdays = data.clone();
}
public void setZoneStrings(String[][] data) {
zoneStrings = data.clone();
}
}

View File

@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
public class FieldPosition {
private int myField, beginIndex, endIndex;
private Format.Field myAttribute;
public FieldPosition(int field) {
myField = field;
}
public FieldPosition(Format.Field attribute) {
myAttribute = attribute;
myField = -1;
}
public FieldPosition(Format.Field attribute, int field) {
myAttribute = attribute;
myField = field;
}
void clear() {
beginIndex = endIndex = 0;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof FieldPosition)) {
return false;
}
FieldPosition pos = (FieldPosition) object;
return myField == pos.myField && myAttribute == pos.myAttribute && beginIndex == pos.beginIndex &&
endIndex == pos.endIndex;
}
public int getBeginIndex() {
return beginIndex;
}
public int getEndIndex() {
return endIndex;
}
public int getField() {
return myField;
}
public Format.Field getFieldAttribute() {
return myAttribute;
}
@Override
public int hashCode() {
int attributeHash = (myAttribute == null) ? 0 : myAttribute.hashCode();
return attributeHash + myField * 10 + beginIndex * 100 + endIndex;
}
public void setBeginIndex(int index) {
beginIndex = index;
}
public void setEndIndex(int index) {
endIndex = index;
}
@Override
public String toString() {
return getClass().getName() + "[attribute=" + myAttribute + ", field=" + myField + ", beginIndex=" +
beginIndex + ", endIndex=" + endIndex + "]";
}
}

View File

@ -0,0 +1,137 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.TCloneable;
public abstract class Format implements TSerializable, TCloneable {
public Format() {
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
String convertPattern(String template, String fromChars, String toChars, boolean check) {
if (!check && fromChars.equals(toChars)) {
return template;
}
boolean quote = false;
StringBuilder output = new StringBuilder();
int length = template.length();
for (int i = 0; i < length; i++) {
int index;
char next = template.charAt(i);
if (next == '\'') {
quote = !quote;
}
if (!quote && (index = fromChars.indexOf(next)) != -1) {
output.append(toChars.charAt(index));
} else if (check && !quote && ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) {
throw new IllegalArgumentException("Invalid pattern char" + next + " in " + template);
} else {
output.append(next);
}
}
if (quote) {
throw new IllegalArgumentException("Unterminated quote");
}
return output.toString();
}
public final String format(Object object) {
return format(object, new StringBuffer(), new FieldPosition(0)).toString();
}
public abstract StringBuffer format(Object object, StringBuffer buffer, FieldPosition field);
public AttributedCharacterIterator formatToCharacterIterator(Object object) {
return new AttributedString(format(object)).getIterator();
}
public Object parseObject(String string) throws ParseException {
ParsePosition position = new ParsePosition(0);
Object result = parseObject(string, position);
if (position.getIndex() == 0) {
throw new ParseException("Format.parseObject(String) parse failure", position.getErrorIndex());
}
return result;
}
public abstract Object parseObject(String string, ParsePosition position);
static boolean upTo(String string, ParsePosition position, StringBuffer buffer, char stop) {
int index = position.getIndex(), length = string.length();
boolean lastQuote = false, quote = false;
while (index < length) {
char ch = string.charAt(index++);
if (ch == '\'') {
if (lastQuote) {
buffer.append('\'');
}
quote = !quote;
lastQuote = true;
} else if (ch == stop && !quote) {
position.setIndex(index);
return true;
} else {
lastQuote = false;
buffer.append(ch);
}
}
position.setIndex(index);
return false;
}
static boolean upToWithQuotes(String string, ParsePosition position, StringBuffer buffer, char stop, char start) {
int index = position.getIndex(), length = string.length(), count = 1;
boolean quote = false;
while (index < length) {
char ch = string.charAt(index++);
if (ch == '\'') {
quote = !quote;
}
if (!quote) {
if (ch == stop) {
count--;
}
if (count == 0) {
position.setIndex(index);
return true;
}
if (ch == start) {
count++;
}
}
buffer.append(ch);
}
throw new IllegalArgumentException("Unmatched braces in the pattern");
}
public static class Field extends AttributedCharacterIterator.Attribute {
protected Field(String fieldName) {
super(fieldName);
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
/**
* Thrown when the string being parsed is not in the correct form.
*/
public class ParseException extends Exception {
private static final long serialVersionUID = 2703218443322787634L;
private int errorOffset;
/**
* Constructs a new instance of this class with its stack trace, detail
* message and the location of the error filled in.
*
* @param detailMessage
* the detail message for this exception.
* @param location
* the index at which the parse exception occurred.
*/
public ParseException(String detailMessage, int location) {
super(detailMessage);
errorOffset = location;
}
/**
* Returns the index at which this parse exception occurred.
*
* @return the location of this exception in the parsed string.
*/
public int getErrorOffset() {
return errorOffset;
}
}

View File

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.text;
public class ParsePosition {
private int currentPosition, errorIndex = -1;
public ParsePosition(int index) {
currentPosition = index;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof ParsePosition)) {
return false;
}
ParsePosition pos = (ParsePosition) object;
return currentPosition == pos.currentPosition && errorIndex == pos.errorIndex;
}
public int getErrorIndex() {
return errorIndex;
}
public int getIndex() {
return currentPosition;
}
@Override
public int hashCode() {
return currentPosition + errorIndex;
}
public void setErrorIndex(int index) {
errorIndex = index;
}
public void setIndex(int index) {
currentPosition = index;
}
@Override
public String toString() {
return getClass().getName() + "[index=" + currentPosition + ", errorIndex=" + errorIndex + "]";
}
}

View File

@ -100,7 +100,7 @@ public class LocaleSettingsNativeGenerator implements Generator {
if (localeName.startsWith("/")) { if (localeName.startsWith("/")) {
localeName = localeName.substring(1); localeName = localeName.substring(1);
} }
if (!availableLocales.contains(localeName)) { if (!localeName.equals("root") && !availableLocales.contains(localeName)) {
continue; continue;
} }
LocaleInfo localeInfo = knownLocales.get(localeName); LocaleInfo localeInfo = knownLocales.get(localeName);
@ -115,6 +115,9 @@ public class LocaleSettingsNativeGenerator implements Generator {
case "territories.json": case "territories.json":
readCountries(localeName, localeInfo, input); readCountries(localeName, localeInfo, input);
break; break;
case "ca-gregorian.json":
readEras(localeName, localeInfo, input);
break;
} }
} }
} catch (IOException e) { } catch (IOException e) {
@ -146,6 +149,16 @@ public class LocaleSettingsNativeGenerator implements Generator {
} }
} }
private void readEras(String localeCode, LocaleInfo locale, InputStream input) {
JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input));
JsonObject erasJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject()
.get("calendars").getAsJsonObject().get("gregorian").getAsJsonObject()
.get("eras").getAsJsonObject().get("eraNames").getAsJsonObject();
String am = erasJson.get("0").getAsString();
String pm = erasJson.get("1").getAsString();
locale.eras = new String[] { am, pm };
}
private void readWeekData(InputStream input) { private void readWeekData(InputStream input) {
JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input));
JsonObject weekJson = root.get("supplemental").getAsJsonObject().get("weekData").getAsJsonObject(); JsonObject weekJson = root.get("supplemental").getAsJsonObject().get("weekData").getAsJsonObject();
@ -338,5 +351,6 @@ public class LocaleSettingsNativeGenerator implements Generator {
static class LocaleInfo { static class LocaleInfo {
Map<String, String> languages = new LinkedHashMap<>(); Map<String, String> languages = new LinkedHashMap<>();
Map<String, String> territories = new LinkedHashMap<>(); Map<String, String> territories = new LinkedHashMap<>();
String[] eras;
} }
} }

View File

@ -181,4 +181,9 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) { THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) {
return new THashMap<>(capacity, loadFactor); return new THashMap<>(capacity, loadFactor);
} }
@Override
public Object clone() {
return new THashSet<>(this);
}
} }