diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java new file mode 100644 index 000000000..ff51e5ceb --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed 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.impl; + +import java.util.Map; +import org.teavm.classlib.impl.unicode.CLDRReader; + +/** + * + * @author Alexey Andreev + */ +public class FirstDayOfWeekMetadataGenerator extends WeekMetadataGenerator { + @Override + protected Map getWeekData(CLDRReader reader) { + return reader.getFirstDayMap(); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java index 0fcb68aed..e03445ded 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLPlugin.java @@ -15,10 +15,7 @@ */ package org.teavm.classlib.impl; -import org.teavm.classlib.impl.unicode.CLDRHelper; import org.teavm.classlib.impl.unicode.CLDRReader; -import org.teavm.classlib.java.util.LocaleSettingsNativeGenerator; -import org.teavm.javascript.ni.Generator; import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReference; import org.teavm.model.ValueType; @@ -46,12 +43,5 @@ public class JCLPlugin implements TeaVMPlugin { host.add(javacSupport); host.registerService(CLDRReader.class, new CLDRReader(host.getProperties(), host.getClassLoader())); - Generator localeGen = new LocaleSettingsNativeGenerator(host.getClassLoader(), host.getProperties()); - host.add(new MethodReference("java.util.Calendar", "readWeeksFromCDLR", ValueType.VOID), localeGen); - host.add(new MethodReference(CLDRHelper.class.getName(), "readLikelySubtagsFromCLDR", ValueType.VOID), - localeGen); - host.add(new MethodReference("java.util.Locale", "getDefaultLocale", ValueType.object("java.lang.String")), - localeGen); - host.add(new MethodReference("java.util.Locale", "readAvailableLocales", ValueType.VOID), localeGen); } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java new file mode 100644 index 000000000..3ed52e5a1 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed 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.impl; + +import java.util.Map; +import org.teavm.classlib.impl.unicode.CLDRReader; + +/** + * + * @author Alexey Andreev + */ +public class MinimalDaysInFirstWeekMetadataGenerator extends WeekMetadataGenerator { + @Override + protected Map getWeekData(CLDRReader reader) { + return reader.getMinDaysMap(); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java new file mode 100644 index 000000000..0ecf0c00c --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed 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.impl; + +import java.util.Map; +import org.teavm.classlib.impl.unicode.CLDRReader; +import org.teavm.model.MethodReference; +import org.teavm.platform.metadata.*; + +/** + * + * @author Alexey Andreev + */ +public abstract class WeekMetadataGenerator implements MetadataGenerator { + @Override + public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { + ResourceMap map = context.createResourceMap(); + for (Map.Entry entry : getWeekData(context.getService(CLDRReader.class)).entrySet()) { + IntResource valueRes = context.createResource(IntResource.class); + valueRes.setValue(entry.getValue()); + map.put(entry.getKey(), valueRes); + } + return map; + } + + protected abstract Map getWeekData(CLDRReader reader); +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java new file mode 100644 index 000000000..713cc88d7 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed 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.impl.unicode; + +import org.teavm.model.MethodReference; +import org.teavm.platform.metadata.*; + +/** + * + * @author Alexey Andreev + */ +public class AvailableLocalesMetadataGenerator implements MetadataGenerator { + @Override + public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { + CLDRReader reader = context.getService(CLDRReader.class); + ResourceArray result = context.createResourceArray(); + for (String locale : reader.getAvailableLocales()) { + StringResource localeRes = context.createResource(StringResource.class); + localeRes.setValue(locale); + result.add(localeRes); + } + return result; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java index 5f579335c..ce0effd41 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java @@ -15,11 +15,9 @@ */ package org.teavm.classlib.impl.unicode; -import org.teavm.dependency.PluggableDependency; -import org.teavm.javascript.ni.GeneratedBy; -import org.teavm.platform.metadata.MetadataProvider; -import org.teavm.platform.metadata.ResourceMap; -import org.teavm.platform.metadata.StringResource; +import org.teavm.classlib.impl.FirstDayOfWeekMetadataGenerator; +import org.teavm.classlib.impl.MinimalDaysInFirstWeekMetadataGenerator; +import org.teavm.platform.metadata.*; /** * @@ -31,33 +29,20 @@ public class CLDRHelper { } public static String getLikelySubtags(String localeCode) { - readLikelySubtagsFromCLDR(); - String subtags = getLikelySubtagsImpl(localeCode); - return subtags != null ? subtags : localeCode; + ResourceMap map = getLikelySubtagsMap(); + return map.has(localeCode) ? map.get(localeCode).getValue() : localeCode; } - // Defined by JCLPlugin - private static native void readLikelySubtagsFromCLDR(); - - @GeneratedBy(CLDRHelperNativeGenerator.class) - @PluggableDependency(CLDRHelperNativeGenerator.class) - private static native String getLikelySubtagsImpl(String localeCode); + @MetadataProvider(LikelySubtagsMetadataGenerator.class) + private static native ResourceMap getLikelySubtagsMap(); public static String[] resolveEras(String localeCode) { - readErasFromCLDR(); - String[] eras = getEras(localeCode); - if (eras == null) { - eras = getEras("root"); - } - return eras; + ResourceMap> map = getErasMap(); + ResourceArray arrayRes = map.has(localeCode) ? map.get(localeCode) : map.get("root"); + return new String[] { arrayRes.get(0).getValue(), arrayRes.get(1).getValue() }; } - // Defined by JCLPlugin - private static native void readErasFromCLDR(); - - @GeneratedBy(CLDRHelperNativeGenerator.class) - @PluggableDependency(CLDRHelperNativeGenerator.class) - private static native String[] getEras(String localeCode); + private static native ResourceMap> getErasMap(); @MetadataProvider(LanguageMetadataGenerator.class) public static native ResourceMap> getLanguagesMap(); @@ -67,4 +52,13 @@ public class CLDRHelper { @MetadataProvider(DefaultLocaleMetadataGenerator.class) public static native StringResource getDefaultLocale(); + + @MetadataProvider(AvailableLocalesMetadataGenerator.class) + public static native ResourceArray getAvailableLocales(); + + @MetadataProvider(MinimalDaysInFirstWeekMetadataGenerator.class) + public static native ResourceMap getMinimalDaysInFirstWeek(); + + @MetadataProvider(FirstDayOfWeekMetadataGenerator.class) + public static native ResourceMap getFirstDayOfWeek(); } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelperNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelperNativeGenerator.java deleted file mode 100644 index 63ec3fd5d..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelperNativeGenerator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed 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.impl.unicode; - -import java.io.IOException; -import org.teavm.codegen.SourceWriter; -import org.teavm.dependency.DependencyAgent; -import org.teavm.dependency.DependencyPlugin; -import org.teavm.dependency.MethodDependency; -import org.teavm.javascript.ni.Generator; -import org.teavm.javascript.ni.GeneratorContext; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class CLDRHelperNativeGenerator implements Generator, DependencyPlugin { - @Override - public void methodAchieved(DependencyAgent agent, MethodDependency method) { - switch (method.getMethod().getName()) { - case "getLikelySubtagsImpl": - method.getResult().propagate("java.lang.String"); - break; - case "getEras": - method.getResult().propagate("[java.lang.String;"); - method.getResult().getArrayItem().propagate("java.lang.String"); - break; - } - } - - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "getLikelySubtagsImpl": - writer.append("var data = ").appendClass("java.util.Locale").append(".$CLDR.likelySubtags[$rt_ustr(") - .append(context.getParameterName(1)).append(")];").softNewLine(); - writer.append("return data ? $rt_str(data) : null;").softNewLine(); - 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(); - } -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java index 4755e0698..17ed965f5 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java @@ -201,4 +201,16 @@ public class CLDRReader { public Set getAvailableCountries() { return Collections.unmodifiableSet(availableCountries); } + + public Map getMinDaysMap() { + return Collections.unmodifiableMap(minDaysMap); + } + + public Map getFirstDayMap() { + return Collections.unmodifiableMap(firstDayMap); + } + + public Map getLikelySubtags() { + return Collections.unmodifiableMap(likelySubtags); + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java new file mode 100644 index 000000000..d4468d464 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed 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.impl.unicode; + +import java.util.Map; +import org.teavm.model.MethodReference; +import org.teavm.platform.metadata.*; + +/** + * + * @author Alexey Andreev + */ +public class LikelySubtagsMetadataGenerator implements MetadataGenerator { + @Override + public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { + CLDRReader reader = context.getService(CLDRReader.class); + ResourceMap map = context.createResourceMap(); + for (Map.Entry entry : reader.getLikelySubtags().entrySet()) { + StringResource subtagRes = context.createResource(StringResource.class); + subtagRes.setValue(entry.getValue()); + map.put(entry.getKey(), subtagRes); + } + return map; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/CalendarNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/CalendarNativeGenerator.java deleted file mode 100644 index 78ea92407..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/CalendarNativeGenerator.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed 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.util; - -import java.io.IOException; -import org.teavm.codegen.SourceWriter; -import org.teavm.javascript.ni.Generator; -import org.teavm.javascript.ni.GeneratorContext; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class CalendarNativeGenerator implements Generator { - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "getFirstDayOfWeek": - generateWeekMethod(context, writer, "firstDay"); - break; - case "getMinimalDaysInFirstWeek": - generateWeekMethod(context, writer, "minDays"); - break; - } - } - - private void generateWeekMethod(GeneratorContext context, SourceWriter writer, String property) - throws IOException { - writer.append("var result = ").appendClass("java.util.Locale").append(".$CLDR.").append(property) - .append("[$rt_ustr(").append(context.getParameterName(1)).append(")];").softNewLine(); - writer.append("return result ? result : -1;").softNewLine(); - } -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/LocaleNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/LocaleNativeGenerator.java deleted file mode 100644 index 8ad145288..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/LocaleNativeGenerator.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed 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.util; - -import java.io.IOException; -import org.teavm.codegen.SourceWriter; -import org.teavm.dependency.DependencyAgent; -import org.teavm.dependency.DependencyPlugin; -import org.teavm.dependency.MethodDependency; -import org.teavm.javascript.ni.Generator; -import org.teavm.javascript.ni.GeneratorContext; -import org.teavm.model.MethodReference; - -/** - * - * @author Alexey Andreev - */ -public class LocaleNativeGenerator implements Generator, DependencyPlugin { - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - switch (methodRef.getName()) { - case "getAvailableLocaleStrings": - generateAvailableLocales(writer); - break; - } - } - - private void generateAvailableLocales(SourceWriter writer) throws IOException { - writer.append("var locales = ").appendClass("java.util.Locale").append(".$CLDR.availableLocales;") - .softNewLine(); - writer.append("var array = $rt_createArray(").appendClass("java.lang.String").append(", locales);") - .softNewLine(); - writer.append("for (var i = 0; i < locales.length; ++i) {").indent().softNewLine(); - writer.append("array.data[i] = $rt_str(locales[i]);").softNewLine(); - writer.outdent().append("}").softNewLine(); - writer.append("return array;").softNewLine(); - } - - @Override - public void methodAchieved(DependencyAgent agent, MethodDependency method) { - switch (method.getMethod().getName()) { - case "getDisplayCountry": - case "getDisplayLanguage": - method.getResult().propagate("java.lang.String"); - break; - case "getAvailableLocaleStrings": - method.getResult().propagate("[java.lang.String"); - method.getResult().getArrayItem().propagate("java.lang.String"); - break; - } - } -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/LocaleSettingsNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/LocaleSettingsNativeGenerator.java deleted file mode 100644 index a161ffc94..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/LocaleSettingsNativeGenerator.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed 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.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import org.teavm.codegen.SourceWriter; -import org.teavm.javascript.Renderer; -import org.teavm.javascript.ni.Generator; -import org.teavm.javascript.ni.GeneratorContext; -import org.teavm.model.MethodReference; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -/** - * - * @author Alexey Andreev - */ -public class LocaleSettingsNativeGenerator implements Generator { - private ClassLoader classLoader; - private Properties properties; - private Map knownLocales = new LinkedHashMap<>(); - private Map minDaysMap = new LinkedHashMap<>(); - private Map firstDayMap = new LinkedHashMap<>(); - private Map likelySubtags = new LinkedHashMap<>(); - private Set availableLocales = new LinkedHashSet<>(); - private Set availableLanguages = new LinkedHashSet<>(); - private Set availableCountries = new LinkedHashSet<>(); - private boolean initialized; - - public LocaleSettingsNativeGenerator(ClassLoader classLoader, Properties properties) { - this.classLoader = classLoader; - this.properties = properties; - } - - private synchronized void init() { - if (!initialized) { - initialized = true; - findAvailableLocales(); - readCLDR(); - } - } - - private void findAvailableLocales() { - String availableLocalesString = properties.getProperty("java.util.Locale.available", "en_EN").trim(); - for (String locale : Arrays.asList(availableLocalesString.split(" *, *"))) { - int countryIndex = locale.indexOf('_'); - if (countryIndex > 0) { - String language = locale.substring(0, countryIndex); - String country = locale.substring(countryIndex + 1); - availableLocales.add(language + "-" + country); - availableLocales.add(language); - availableLanguages.add(language); - availableCountries.add(country); - } else { - availableLocales.add(locale); - availableLanguages.add(locale); - } - } - } - - private void readCLDR() { - try (ZipInputStream input = new ZipInputStream(classLoader.getResourceAsStream( - "org/teavm/classlib/impl/unicode/cldr-json.zip"))) { - while (true) { - ZipEntry entry = input.getNextEntry(); - if (entry == null) { - break; - } - if (!entry.getName().endsWith(".json")) { - continue; - } - if (entry.getName().equals("supplemental/weekData.json")) { - readWeekData(input); - continue; - } else if (entry.getName().equals("supplemental/likelySubtags.json")) { - readLikelySubtags(input); - } - int objectIndex = entry.getName().lastIndexOf('/'); - String objectName = entry.getName().substring(objectIndex + 1); - String localeName = entry.getName().substring(0, objectIndex); - if (localeName.startsWith("/")) { - localeName = localeName.substring(1); - } - if (!localeName.equals("root") && !availableLocales.contains(localeName)) { - continue; - } - LocaleInfo localeInfo = knownLocales.get(localeName); - if (localeInfo == null) { - localeInfo = new LocaleInfo(); - knownLocales.put(localeName, localeInfo); - } - switch (objectName) { - case "languages.json": - readLanguages(localeName, localeInfo, input); - break; - case "territories.json": - readCountries(localeName, localeInfo, input); - break; - } - } - } catch (IOException e) { - throw new RuntimeException("Error reading CLDR file", e); - } - } - - private void readLanguages(String localeCode, LocaleInfo locale, InputStream input) { - JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); - JsonObject languagesJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() - .get("localeDisplayNames").getAsJsonObject().get("languages").getAsJsonObject(); - for (Map.Entry property : languagesJson.entrySet()) { - String language = property.getKey(); - if (availableLanguages.contains(language)) { - locale.languages.put(language, property.getValue().getAsString()); - } - } - } - - private void readCountries(String localeCode, LocaleInfo locale, InputStream input) { - JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); - JsonObject countriesJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() - .get("localeDisplayNames").getAsJsonObject().get("territories").getAsJsonObject(); - for (Map.Entry property : countriesJson.entrySet()) { - String country = property.getKey(); - if (availableCountries.contains(country)) { - locale.territories.put(country, property.getValue().getAsString()); - } - } - } - - private void readWeekData(InputStream input) { - JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); - JsonObject weekJson = root.get("supplemental").getAsJsonObject().get("weekData").getAsJsonObject(); - JsonObject minDaysJson = weekJson.get("minDays").getAsJsonObject(); - for (Map.Entry property : minDaysJson.entrySet()) { - minDaysMap.put(property.getKey(), property.getValue().getAsInt()); - } - JsonObject firstDayJson = weekJson.get("firstDay").getAsJsonObject(); - for (Map.Entry property : firstDayJson.entrySet()) { - firstDayMap.put(property.getKey(), getNumericDay(property.getValue().getAsString())); - } - } - - private void readLikelySubtags(InputStream input) { - JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); - JsonObject likelySubtagsJson = root.get("supplemental").getAsJsonObject().get("likelySubtags") - .getAsJsonObject(); - for (Map.Entry property : likelySubtagsJson.entrySet()) { - likelySubtags.put(property.getKey(), property.getValue().getAsString()); - } - } - - private int getNumericDay(String day) { - switch (day) { - case "sun": - return 1; - case "mon": - return 2; - case "tue": - return 3; - case "wed": - return 4; - case "thu": - return 5; - case "fri": - return 6; - case "sat": - return 7; - default: - throw new IllegalArgumentException("Can't recognize day name: " + day); - } - } - - @Override - public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { - init(); - switch (methodRef.getName()) { - case "readWeeksFromCDLR": - generateReadWeeksFromCDLR(writer); - break; - case "readLikelySubtagsFromCLDR": - generateReadLikelySubtagsFromCLDR(writer); - break; - case "readAvailableLocales": - generateReadAvailableLocales(writer); - break; - } - } - - private void generateDefender(SourceWriter writer, String property) throws IOException { - writer.append("if (").appendClass("java.util.Locale").append(".$CLDR.").append(property) - .append(")").ws().append("{").indent().softNewLine(); - writer.append("return;").softNewLine(); - writer.outdent().append("}").softNewLine(); - } - - private void generateReadAvailableLocales(SourceWriter writer) throws IOException { - generateDefender(writer, "availableLocales"); - writer.appendClass("java.util.Locale").append(".$CLDR.availableLocales = ["); - boolean first = true; - for (String locale : availableLocales) { - if (!first) { - writer.append(',').ws(); - } - first = false; - writer.append('"').append(Renderer.escapeString(locale)).append('"'); - } - writer.append("];").softNewLine(); - } - - private void generateReadWeeksFromCDLR(SourceWriter writer) throws IOException { - generateDefender(writer, "minDays"); - writer.appendClass("java.util.Locale").append(".$CLDR.minDays = {").indent().softNewLine(); - boolean first = true; - for (Map.Entry entry : minDaysMap.entrySet()) { - if (!first) { - writer.append(",").softNewLine(); - } - first = false; - writer.append('"').append(Renderer.escapeString(entry.getKey())).append('"').ws().append(':') - .ws().append(entry.getValue()); - } - writer.outdent().append("};").softNewLine(); - - writer.appendClass("java.util.Locale").append(".$CLDR.firstDay = {").indent().softNewLine(); - first = true; - for (Map.Entry entry : firstDayMap.entrySet()) { - if (!first) { - writer.append(",").softNewLine(); - } - first = false; - writer.append('"').append(Renderer.escapeString(entry.getKey())).append('"').ws().append(':') - .ws().append(entry.getValue()); - } - writer.outdent().append("};").softNewLine(); - } - - private void generateReadLikelySubtagsFromCLDR(SourceWriter writer) throws IOException { - generateDefender(writer, "likelySubtags"); - writer.appendClass("java.util.Locale").append(".$CLDR.likelySubtags = {").indent().softNewLine(); - boolean first = true; - for (Map.Entry entry : likelySubtags.entrySet()) { - if (!first) { - writer.append(",").softNewLine(); - } - first = false; - writer.append('"').append(Renderer.escapeString(entry.getKey())).append('"').ws().append(':') - .ws().append('"').append(Renderer.escapeString(entry.getValue())).append('"'); - } - writer.outdent().append("};").softNewLine(); - } - - static class LocaleInfo { - Map languages = new LinkedHashMap<>(); - Map territories = new LinkedHashMap<>(); - String[] eras; - } -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java index 50ba9f5b0..dc4561ad9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCalendar.java @@ -36,7 +36,8 @@ 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.lang.TComparable; -import org.teavm.javascript.ni.GeneratedBy; +import org.teavm.platform.metadata.IntResource; +import org.teavm.platform.metadata.ResourceMap; public abstract class TCalendar implements TSerializable, TCloneable, TComparable { protected boolean areFieldsSet; @@ -154,14 +155,10 @@ public abstract class TCalendar implements TSerializable, TCloneable, TComparabl isSet = new boolean[FIELD_COUNT]; areFieldsSet = isTimeSet = false; setLenient(true); - readWeeksFromCDLR(); setFirstDayOfWeek(resolveFirstDayOfWeek(locale)); setMinimalDaysInFirstWeek(resolveMinimalDaysInFirstWeek(locale)); } - // Generated by JCLPlugin - private static native void readWeeksFromCDLR(); - private static String resolveCountry(TLocale locale) { String country = locale.getCountry(); if (country.isEmpty()) { @@ -174,28 +171,16 @@ public abstract class TCalendar implements TSerializable, TCloneable, TComparabl private static int resolveFirstDayOfWeek(TLocale locale) { String country = resolveCountry(locale); - int day = getFirstDayOfWeek(country); - if (day < 0) { - day = getFirstDayOfWeek("001"); - } - return day; + ResourceMap dayMap = CLDRHelper.getFirstDayOfWeek(); + return dayMap.has(country) ? dayMap.get(country).getValue() : dayMap.get("001").getValue(); } - @GeneratedBy(CalendarNativeGenerator.class) - private static native int getFirstDayOfWeek(String localeCode); - private static int resolveMinimalDaysInFirstWeek(TLocale locale) { String country = resolveCountry(locale); - int days = getMinimalDaysInFirstWeek(country); - if (days < 0) { - days = getMinimalDaysInFirstWeek("001"); - } - return days; + ResourceMap dayMap = CLDRHelper.getMinimalDaysInFirstWeek(); + return dayMap.has(country) ? dayMap.get(country).getValue() : dayMap.get("001").getValue(); } - @GeneratedBy(CalendarNativeGenerator.class) - private static native int getMinimalDaysInFirstWeek(String localeCode); - abstract public void add(int field, int value); public boolean after(Object calendar) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLocale.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLocale.java index 587cc60b2..34a9b130f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLocale.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLocale.java @@ -36,8 +36,7 @@ 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.dependency.PluggableDependency; -import org.teavm.javascript.ni.GeneratedBy; +import org.teavm.platform.metadata.ResourceArray; import org.teavm.platform.metadata.ResourceMap; import org.teavm.platform.metadata.StringResource; @@ -77,9 +76,6 @@ public final class TLocale implements TCloneable, TSerializable { private transient String languageCode; private transient String variantCode; - // Redefined by JCLPlugin - private static native void readAvailableLocales(); - public TLocale(String language) { this(language, "", ""); } @@ -126,12 +122,11 @@ public final class TLocale implements TCloneable, TSerializable { } public static TLocale[] getAvailableLocales() { - readAvailableLocales(); if (availableLocales == null) { - String[] strings = getAvailableLocaleStrings(); - availableLocales = new TLocale[strings.length]; - for (int i = 0; i < strings.length; ++i) { - String string = strings[i]; + ResourceArray strings = CLDRHelper.getAvailableLocales(); + availableLocales = new TLocale[strings.size()]; + for (int i = 0; i < strings.size(); ++i) { + String string = strings.get(i).getValue(); int countryIndex = string.indexOf('-'); if (countryIndex > 0) { availableLocales[i] = new TLocale(string.substring(0, countryIndex), @@ -144,10 +139,6 @@ public final class TLocale implements TCloneable, TSerializable { return Arrays.copyOf(availableLocales, availableLocales.length); } - @GeneratedBy(LocaleNativeGenerator.class) - @PluggableDependency(LocaleNativeGenerator.class) - private static native String[] getAvailableLocaleStrings(); - public String getCountry() { return countryCode; }